Compare commits

..

87 Commits

Author SHA1 Message Date
Milan Broz
66fa12a521 Release 1.4.0
git-svn-id: https://cryptsetup.googlecode.com/svn/tags/v1_4_0@656 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-26 18:00:15 +00:00
Milan Broz
c490ef638b Version 1.4.0.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@655 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-26 17:57:58 +00:00
Milan Broz
f5d777e412 Silent some extra gcc warnings in tests.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@654 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-26 13:19:37 +00:00
Milan Broz
28eddd2f52 Fix isLuks message (should appear only in verbose mode).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@653 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-25 19:09:44 +00:00
Milan Broz
eb4720819e Update nl.po.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@652 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-25 17:47:24 +00:00
Milan Broz
088a927c07 Update de.po.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@651 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-17 22:16:54 +00:00
Jonas Meurer
3c3e9570c4 fix typo in german translation
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@650 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-17 15:31:18 +00:00
Milan Broz
b6e046835e Update on disk format to 1.2.1.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@647 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-16 13:32:13 +00:00
Milan Broz
158a5de3b4 Update po files.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@645 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-15 20:28:04 +00:00
Milan Broz
02e36d7606 Removes obsolete valgrind suppression (Thanks to okozina)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@644 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-15 20:27:58 +00:00
Milan Broz
38ff882096 Use system wide libcryptsetup in examples.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@643 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-15 20:27:51 +00:00
Milan Broz
58a27a18ca Reencode Changelog to UTF8.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@642 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-10 20:01:51 +00:00
Milan Broz
94fb0b7781 Fix flag description comment.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@638 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-10 18:09:26 +00:00
Milan Broz
c401fe3d04 Add 1.4.0 release notes
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@637 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-10 17:38:55 +00:00
Milan Broz
3b10bf9558 Print warning if detached header path is unusable.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@636 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-10 17:38:40 +00:00
Milan Broz
d6016b1c2d Revert get_last_error change for test-api (crypt_init should test for error message).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@635 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 22:10:43 +00:00
Milan Broz
9908cd4746 Prepare 1.4.0-rc1 (some minor fixes still needed).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@634 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 21:20:01 +00:00
Milan Broz
a24a594d1a Fix makefile for examples.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@633 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 21:11:42 +00:00
Milan Broz
56e73526ad Add license to example files (LGPL).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@632 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 21:05:20 +00:00
Milan Broz
e640f5e006 Rewrite examples to more simple format.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@631 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 20:58:10 +00:00
Milan Broz
cb7fa0b9c7 Add simple makefile for examples.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@630 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 20:58:01 +00:00
Milan Broz
60d59b0bc0 Add LUKS on-disk format docs, update TODO.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@629 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 18:25:41 +00:00
Milan Broz
4f33a537ae Fix some complier warnings.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@628 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 15:47:31 +00:00
Milan Broz
96bddb363f Detect static uuid library if static build is requested.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@627 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 15:22:57 +00:00
Milan Broz
dac000e1df Move setting of error text to crypt_log to catch all errors.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@626 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 13:46:24 +00:00
Milan Broz
be246c16ab Fix exit code if passphrases do not match in luksAddKey. (Issue 109)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@625 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 13:46:14 +00:00
Milan Broz
cc3b39980b Fix luksKillSLot exit code if slot is inactive or invalid. (Issue 108)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@624 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 13:46:03 +00:00
Milan Broz
8c54d938ac Add crypt_last_error() API call (using crypt context).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@623 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 13:45:53 +00:00
Milan Broz
d7960b9307 Simplify global error call.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@622 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-09 13:45:38 +00:00
Milan Broz
4e9fa4d2bb Fix some doxygen docs warnings and mistakes.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@621 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-08 20:27:54 +00:00
Milan Broz
7a773f70f3 Fix doxyfile location.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@620 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-08 19:27:20 +00:00
Milan Broz
b72473eddf Add doxyfile.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@619 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-08 19:27:11 +00:00
Milan Broz
4d1b67eeb2 Add some examples. (thanks to okozina)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@618 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-08 19:27:03 +00:00
Milan Broz
f54c7939f0 Add doxygen formatted documentation for libcryptsetup API (thanks to okozina).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@617 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-08 19:26:52 +00:00
Milan Broz
19bde65f5b Remove hints for old kernels.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@616 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-08 16:23:54 +00:00
Milan Broz
d2fbc963ca If device is not rotational, do not use Gutmann wipe method.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@615 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-08 16:17:08 +00:00
Milan Broz
61bec51be0 Fix some compile warnings in optional crypto backends.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@614 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-05 09:46:37 +00:00
Milan Broz
84ada5ddf6 Support Nettle 2.4 crypto backend (for ripemd160).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@613 36d66b0a-2a48-0410-832c-cd162a569da5
2011-10-05 08:33:33 +00:00
Milan Broz
7158c32b96 Fix man page (thanks to Karl O. Pinc)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@612 36d66b0a-2a48-0410-832c-cd162a569da5
2011-09-27 16:51:23 +00:00
Milan Broz
1a8bae8884 Add keyslot option for luksOpen (thanks to okozina).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@611 36d66b0a-2a48-0410-832c-cd162a569da5
2011-09-22 20:26:37 +00:00
Milan Broz
538169fb5b Fix some memory leaks (thanks to okozina).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@610 36d66b0a-2a48-0410-832c-cd162a569da5
2011-09-21 22:42:18 +00:00
Milan Broz
963ee0e6ee Add some valgrind checks (thanks to okozina).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@609 36d66b0a-2a48-0410-832c-cd162a569da5
2011-09-21 22:42:03 +00:00
Milan Broz
d20e2ff02d Do not allow format of already formatted context.
(Thanks to okozina@redhat.com)

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@608 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-26 19:46:29 +00:00
Milan Broz
d5e48fcb00 Enhance check of device size before writing LUKS header.
(Thanks to okozina@redhat.com)

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@607 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-26 19:46:17 +00:00
Milan Broz
4d99773009 Remove internal loop definitions from header file.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@606 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-26 19:46:04 +00:00
Milan Broz
f3ed801e8b Use /dev/loop-control if possible (kernel 3.1).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@605 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-22 22:33:24 +00:00
Milan Broz
1954792876 Add fi.po.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@604 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-22 21:54:29 +00:00
Milan Broz
95009fff4b Add some API test and rewrite some parts.
(Thanks to okozina@redhat.com)

[not yet finished]

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@603 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-22 21:54:11 +00:00
Milan Broz
b8a7125225 crypt_check_data_device_size() needs to compare values in bytes
(Thanks to okozina@redhat.com)

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@602 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-22 21:53:59 +00:00
Milan Broz
6cede067a2 Fix two mem leaks in crypt_init_by_name_and_header().
(Thanks to okozina@redhat.com)

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@601 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-22 21:53:48 +00:00
Milan Broz
906c7897e1 LUKS header and Type needs to be set in context before crypt_check_data_device_size() is called.
(Thanks to okozina@redhat.com)

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@600 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-22 21:53:38 +00:00
Milan Broz
c5b64b5479 Add more paranoid checks for LUKS header and keyslot attributes.
(Thanks to okozina@redhat.com)

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@599 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-22 21:53:27 +00:00
Milan Broz
4a295781d1 Silent gcc warnings with -Wconst-qual switch.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@598 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-15 16:32:52 +00:00
Milan Broz
1f9efdf59a Check UUID of active device to match header when initializing context.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@597 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-15 16:32:44 +00:00
Milan Broz
1f776bc979 Do not allow crypt_load() on already initialised context.
Signed-off-by: Ondrej Kozina <okozina@redhat.com>

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@596 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-15 16:32:36 +00:00
Milan Broz
104130c4c4 Update po files.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@595 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-15 16:32:24 +00:00
Arno Wagner
51d74c6029 typi fixed in ASCII version
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@593 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-05 08:33:09 +00:00
Milan Broz
7fe10e3d7b Add API tests for plain device.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@591 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-02 12:16:00 +00:00
Arno Wagner
25c3271cd0 synced ASCII version
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@590 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-01 23:50:58 +00:00
Milan Broz
7665f8e805 Improve check for invalid offset and size values. (thx to okozina)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@588 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-01 12:27:34 +00:00
Milan Broz
6361e86daf Add loop control stub for testing new loop device interface.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@587 36d66b0a-2a48-0410-832c-cd162a569da5
2011-08-01 10:40:45 +00:00
Arno Wagner
3c5481709b synced rhe text version
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@585 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-30 18:40:45 +00:00
Milan Broz
c30fe505c5 Add check of decrypted image to test.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@581 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-25 21:49:14 +00:00
Milan Broz
a9ce2210bc Fix gcrypt final() function backend call.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@580 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-25 21:15:41 +00:00
Milan Broz
e5244bc47c Fix new tests to use sha1 (ripemd160 not supported in some backends).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@579 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-25 15:24:16 +00:00
Milan Broz
23e144daf4 * Remove hash/hmac restart from crypto backend and make it part of hash/hmac final.
Some backend implementation did reset context by default, so this
should create backend api consistent.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@578 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-25 15:24:04 +00:00
Milan Broz
03a8ba4d17 Add experimental LUKS recovery script (recreate header from active mapping).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@577 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-25 10:42:35 +00:00
Milan Broz
f80b506b65 * Allow different data offset setting for detached header.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@576 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-20 17:39:38 +00:00
Milan Broz
f7f9e291f4 * Add --header option for detached metadata (on-disk LUKS header) device.
* Add crypt_init_by_name_and_header() and crypt_set_data_device() to API.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@575 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-20 17:39:26 +00:00
Milan Broz
1bf26b9a90 * Revert default initialisation of volume key in crypt_init_by_name().
* Do not allow key retrieval while suspended (key could be wiped).
* Do not allow suspend for non-LUKS devices.
* Support retries and timeout parameters for luksSuspend.

Add luksSuspend/Resume test.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@574 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-19 13:55:34 +00:00
Milan Broz
261d0d05a5 Add crypt_get_iv_offset() function to API.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@573 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-18 13:03:15 +00:00
Milan Broz
9c71c74d59 Add --enable-discards option to allow discards/TRIM requests.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@572 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-17 22:35:40 +00:00
Milan Broz
39e6cfcb8a Use struct volume key thorough.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@571 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-17 22:35:30 +00:00
Milan Broz
913ef7c07e Rewrite dm query/create function backend.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@570 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-17 22:35:17 +00:00
Arno Wagner
69bd90055f updated txt version
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@569 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-14 22:15:37 +00:00
Arno Wagner
7d496a6b69 added warning to only use the fiorst 128 ASCII cars to text
version of the FAQ


git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@564 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-08 20:38:30 +00:00
Milan Broz
642a838343 Update de.po.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@562 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-07 14:33:08 +00:00
Milan Broz
a1306ed01c Remove old API functions (all functions using crypt_options).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@561 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-07 14:32:42 +00:00
Milan Broz
790ef04304 Fix error message.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@560 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-01 16:41:59 +00:00
Milan Broz
d44d07c9eb * Add --shared option for creating non-overlapping crypt segments.
* Add shared flag to libcryptsetup api.
* Fix plain crypt format parameters to include size option (API change).

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@559 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-01 16:38:58 +00:00
Arno Wagner
5b8fb6f135 additional typo fix
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@558 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-01 00:12:12 +00:00
Arno Wagner
84079a1a49 update of ascii version
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@556 36d66b0a-2a48-0410-832c-cd162a569da5
2011-07-01 00:01:57 +00:00
Milan Broz
1b7c97c333 Use EINVAL if device status returns invalid device.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@552 36d66b0a-2a48-0410-832c-cd162a569da5
2011-06-14 13:19:58 +00:00
Milan Broz
96d67485d9 Seems that dmsetup table is broken in recent lvm2, let's support "x: table" as well.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@551 36d66b0a-2a48-0410-832c-cd162a569da5
2011-06-13 16:45:09 +00:00
Milan Broz
a5757c35f0 Fix return code for status command when device doesn't exists.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@550 36d66b0a-2a48-0410-832c-cd162a569da5
2011-06-13 16:44:42 +00:00
Milan Broz
3f49ffd526 Update fr.po.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@549 36d66b0a-2a48-0410-832c-cd162a569da5
2011-05-27 21:35:46 +00:00
Milan Broz
dfd018235b Set devel version.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@540 36d66b0a-2a48-0410-832c-cd162a569da5
2011-05-24 15:51:45 +00:00
65 changed files with 7872 additions and 3929 deletions

View File

@@ -1,3 +1,54 @@
2011-10-25 Milan Broz <mbroz@redhat.com>
* Print informative message in isLuks only in verbose mode.
* Version 1.4.0.
2011-10-10 Milan Broz <mbroz@redhat.com>
* Version 1.4.0-rc1.
2011-10-05 Milan Broz <mbroz@redhat.com>
* Support Nettle 2.4 crypto backend (for ripemd160).
* If device is not rotational, do not use Gutmann wipe method.
* Add crypt_last_error() API call.
* Fix luksKillSLot exit code if slot is inactive or invalid.
* Fix exit code if passphrases do not match in luksAddKey.
* Add LUKS on-disk format description into package.
2011-09-22 Milan Broz <mbroz@redhat.com>
* Support key-slot option for luksOpen (use only explicit keyslot).
2011-08-22 Milan Broz <mbroz@redhat.com>
* Add more paranoid checks for LUKS header and keyslot attributes.
* Fix crypt_load to properly check device size.
* Use new /dev/loop-control (kernel 3.1) if possible.
* Enhance check of device size before writing LUKS header.
* Do not allow context format of already formatted device.
2011-07-25 Milan Broz <mbroz@redhat.com>
* Remove hash/hmac restart from crypto backend and make it part of hash/hmac final.
* Improve check for invalid offset and size values.
2011-07-19 Milan Broz <mbroz@redhat.com>
* Revert default initialisation of volume key in crypt_init_by_name().
* Do not allow key retrieval while suspended (key could be wiped).
* Do not allow suspend for non-LUKS devices.
* Support retries and timeout parameters for luksSuspend.
* Add --header option for detached metadata (on-disk LUKS header) device.
* Add crypt_init_by_name_and_header() and crypt_set_data_device() to API.
* Allow different data offset setting for detached header.
2011-07-07 Milan Broz <mbroz@redhat.com>
* Remove old API functions (all functions using crypt_options).
* Add --enable-discards option to allow discards/TRIM requests.
* Add crypt_get_iv_offset() function to API.
2011-07-01 Milan Broz <mbroz@redhat.com>
* Add --shared option for creating non-overlapping crypt segments.
* Add shared flag to libcryptsetup api.
* Fix plain crypt format parameters to include size option (API change).
2011-06-08 Milan Broz <mbroz@redhat.com>
* Fix return code for status command when device doesn't exists.
2011-05-24 Milan Broz <mbroz@redhat.com>
* Version 1.3.1.
@@ -363,7 +414,7 @@
* configure.in (AC_OUTPUT): Add m4/Makefile.
(AM_GNU_GETTEXT_VERSION): Bump to 0.15.
2006-10-22 David H<EFBFBD>rdeman <david@hardeman.nu>
2006-10-22 David Härdeman <david@hardeman.nu>
* Allow hashing of keys passed through stdin.
@@ -430,7 +481,7 @@
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
* lib/setup.c (get_key): Applied patch from David H<EFBFBD>rdeman
* lib/setup.c (get_key): Applied patch from David Härdeman
<david@2gen.com> for reading binary keys from stdin using
the "-" as key file.
@@ -447,7 +498,7 @@
2006-07-23 Clemens Fruhwirth <clemens@endorphin.org>
* Applied patches from David H<EFBFBD>rdeman <david@2gen.com> to fix 64
* Applied patches from David Härdeman <david@2gen.com> to fix 64
bit compiler warning issues.
2006-05-19 Clemens Fruhwirth <clemens@endorphin.org>
@@ -466,7 +517,7 @@
* configure.in: Release 1.0.3.
* Applied patch by Johannes Wei<EFBFBD>l for more meaningful exit codes
* Applied patch by Johannes Weißl for more meaningful exit codes
and password retries
2006-03-30 Clemens Fruhwirth <clemens@endorphin.org>

479
FAQ
View File

@@ -6,7 +6,8 @@ Sections
4. Troubleshooting
5. Security Aspects
6. Backup and Data Recovery
7. Issues with Specific Versions of cryptsetup
7. Interoperability with other Disk Encryption Tools
8. Issues with Specific Versions of cryptsetup
A. Contributors
@@ -17,11 +18,15 @@ A. Contributors
This is the FAQ (Frequently Asked Questions) for cryptsetup. It
covers Linux disk encryption with plain dm-crypt (one passphrase,
no management, no descriptor on disk) and LUKS (multiple user keys
with one master key, anti-forensics, descriptor block at start of
device, ...). The latest version should usually be available at
no management, no metadata on disk) and LUKS (multiple user keys
with one master key, anti-forensic features, metadata block at
start of device, ...). The latest version of this FAQ should
usually be available at
http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions
* WARNINGS
ATTENTION: If you are going to read just one thing, make it the
section on Backup and Data Recovery. By far the most questions on
the cryptsetup mailing list are from people that just managed to
@@ -31,6 +36,28 @@ A. Contributors
limitations imposed by the LUKS security model BEFORE you face such
a disaster!
PASSPHRASES: Some people have had difficulties when upgrading
distributions. It is highly advisable to only use the 94 printable
characters from the first 128 characters of the ASCII table, as
they will always have the same binary representation. Other
characters may have different encoding depending on system
configuration and your passphrase will not work with a different
encoding. A table of the standardized first 128 ASCII caracters
can, e.g. be found on http://en.wikipedia.org/wiki/ASCII
* System Specific warnings
- Ubuntu as of 4/2011: It seems the installer offers to create
LUKS partitions in a way that several people mistook for an offer
to activate their existing LUKS partition. The installer gives no
or an inadequate warning and will destroy your old LUKS header,
causing permanent data loss. See also the section on Backup and
Data Recovery.
This issue has been acknowledged by the Ubuntu dev team, see here:
http://launchpad.net/bugs/420080
* Who wrote this?
@@ -38,8 +65,9 @@ A. Contributors
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. Please note that by contributing to this FAQ, you accept
the license described below.
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
@@ -150,8 +178,9 @@ A. Contributors
* How do I use LUKS with a loop-device?
Just the same as with any block device. If you want, for example,
to use a 100MiB file as LUKS container, do something like this:
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
file as LUKS container, do something like this:
head -c 100M /dev/zero > luksfile # create empty file
losetup /dev/loop0 luksfile # map luksfile to /dev/loop0
@@ -173,6 +202,16 @@ A. Contributors
new key-slot.
* Encrytion 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
way round, but you have to be aware that you then need to give the
pasphrase for each individual disk and RAID autotetection will not
work anymore. Therefore it is better to encrypt the RAID device,
e.g. /dev/dm0 .
* How do I read a dm-crypt key from file?
Note that the file will still be hashed first, just like keyboard
@@ -344,10 +383,14 @@ A. Contributors
However, this operation will not change volume key iteration count
(MK iterations in output of "cryptsetup luksDump"). In order to
change that, you will have to backup the data in the LUKS
container, luksFormat on the slow machine and restore the data.
Note that in the original LUKS specification this value was fixed
to 10, but it is now derived from the PBKDF2 benchmark as well and
set to iterations in 0.125 sec or 1000, whichever is larger.
container (i.e. your encrypted data), luksFormat on the slow
machine and restore the data. Note that in the original LUKS
specification this value was fixed to 10, but it is now derived
from the PBKDF2 benchmark as well and set to iterations in 0.125
sec or 1000, whichever is larger. Also note that MK iterations
are not very security relevant. But as each key-slot already takes
1 second, spending the additional 0.125 seconds really does not
matter.
* "blkid" sees a LUKS UUID and an ext2/swap UUID on the same device.
@@ -409,12 +452,13 @@ A. Contributors
ciphers. With the usual modes in cryptsetup (CBC, ESSIV, XTS), you
get up to a completely changed 512 byte block per bit error. A
corrupt block causes a lot more havoc than the occasionally
flipped single bit and can result various obscure errors.
flipped single bit and can result in various obscure errors.
Note however that a verify run on copying between encrypted or
unencrypted devices can also show you corruption when the copying
itself did not report any problems. If you find defect RAM, assume
all backups and copied data to be suspect, unless you did a verify.
Note, that a verify run on copying between encrypted or
unencrypted devices will reliably detect corruption, even when the
copying itself did not report any problems. If you find defect
RAM, assume all backups and copied data to be suspect, unless you
did a verify.
* How do I test RAM?
@@ -455,6 +499,31 @@ A. Contributors
5. Security Aspects
* Is LUKS insecure? Everybody can see I have encrypted data!
In practice it does not really matter. In most civilized countries
you can just refuse to hand over the keys, no harm done. In some
countries they can force you to hand over the keys, if they suspect
encryption. However the suspicion is enough, they do not have to
prove anything. This is for practical reasons, as even the presence
of a header (like the LUKS header) is not enough to prove that you
have any keys. It might have been an experiment, for example. Or it
was used as encrypted swap with a key from /dev/random. So they
make you prove you do not have encrypted data. Of course that is
just as impossible as the other way round.
This means that if you have a large set of random-looking data,
they can already lock you up. Hidden containers (encryption hidden
within encryption), as possible with Truecrypt, do not help
either. They will just assume the hidden container is there and
unless you hand over the key, you will stay locked up. Don't have
a hidden container? Though luck. Anybody could claim that.
Still, if you are concerned about the LUKS header, use plain
dm-crypt with a good passphrase. See also Section 2, "What is the
difference between "plain" and LUKS format?"
* Should I initialize (overwrite) a new LUKS/dm-crypt partition?
If you just create a filesystem on it, most of the old data will
@@ -561,8 +630,8 @@ A. Contributors
to the last stage ("Acceptance") and think about what to do now.
There is one exception that I know of: If your LUKS container is
still open, then it may be possible to extract the master key from
the running system. Ask on the mailing-list on how to do that and
make sure nobody switches off the machine.
the running system. See Item "How do I recover the master key from
a mapped LUKS container?" in Section "Backup and Data Recovery".
* What is a "salt"?
@@ -595,6 +664,11 @@ A. Contributors
* Is LUKS secure with a low-entropy (bad) passphrase?
Note: You should only use the 94 printable characters from 7 bit
ASCII code to prevent your passphrase from failing when the
character encoding changes, e.g. because of a system upgrade, see
also the note at the very start of this FAQ under "WARNINGS".
This needs a bit of theory. The quality of your passphrase is
directly related to its entropy (information theoretic, not
thermodynamic). The entropy says how many bits of "uncertainty" or
@@ -629,7 +703,7 @@ A. Contributors
days on a single CPU and is entirely feasible. To put that into
perspective, using a number of Amazon EC2 High-CPU Extra Large
instances (each gives about 8 real cores), this tests costs
currently about $48, but can be made to run arbitrarily fast.
currently about 50USD/EUR, but can be made to run arbitrarily fast.
On the other hand, choosing 1.5 lines from, say, the Wheel of Time
is in itself not more secure, but the book selection adds quite a
@@ -661,7 +735,7 @@ A. Contributors
0.0001 seconds on a modern CPU.
Example 2: The user did a bit better and has 32 chars of English
text. That would give use about 32 bits of entropy. With 1 second
text. That would be about 32 bits of entropy. With 1 second
iteration, that means an attacker on the same CPU needs around 136
years. That is pretty impressive for such a weak passphrase.
Without the iterations, it would be more like 50 days on a modern
@@ -703,6 +777,13 @@ A. Contributors
this danger significantly.
* What about iteration count with plain dm-crypt?
Simple: There is none. There is also no salting. If you use plain
dm-crypt, the only way to be secure is to use a high entropy
passphrase. If in doubt, use LUKS instead.
* Is LUKS with default parameters less secure on a slow CPU?
Unfortunately, yes. However the only aspect affected is the
@@ -793,28 +874,138 @@ A. Contributors
6. Backup and Data Recovery
* Why do I need Backup?
First, disks die. The rate for well-treated (!) disk is about 5%
per year, which is high enough to worry about. There is some
indication that this may be even worse for some SSDs. This applies
both to LUKS and plain dm-crypt partitions.
Second, for LUKS, if anything damages the LUKS header or the
key-stripe area then decrypting the LUKS device can become
impossible. This is a frequent occuurence. For example an
accidental format as FAT or some software overwriting the first
sector where it suspects a partition boot sector typically makes a
LUKS partition permanently inacessible. See more below on LUKS
header damage.
So, data-backup in some form is non-optional. For LUKS, you may
also want to store a header backup in some secure location. This
only needs an update if you change passphrases.
* How do I backup a LUKS header?
While you could just copy the appropriate number of bytes from the
start of the LUKS partition, the best way is to use command option
"luksHeaderBackup" of cryptsetup. This protects also against
errors when non-standard parameters have been used in LUKS
partition creation. Example:
cryptsetup luksHeaderBackup --header-backup-file h /dev/mapper/c1
To restore, use the inverse command, i.e.
cryptsetup luksHeaderRestore --header-backup-file h /dev/mapper/c1
* How do I backup a LUKS or dm-crypt partition?
There are two options, a sector-image and a plain file or
filesystem backup of the contents of the partition. The sector
image is already encrypted, but cannot be compressed and contains
all empty space. The filesystem backup can be compressed, can
contain only part of the encrypted device, but needs to be
encrypted separately if so desired.
A sector-image will contain the whole partition in encrypted form,
for LUKS the LUKS header, the keys-slots and the data area. It can
be done under Linux e.g. with dd_rescue (for a direct image copy)
and with "cat" or "dd". Example:
cat /dev/sda10 > sda10.img
dd_rescue /dev/sda10 sda10.img
You can also use any other backup software that is capable of making
a sector image of a partition. Note that compression is
ineffective for encrypted data, hence it does not make sense to
use it.
For a filesystem backup, you decrypt and mount the encrypted
partition and back it up as you would a normal filesystem. In this
case the backup is not encrypted, unless your encryption method
does that. For example you can encrypt a backup with "tar" as
follows with GnuPG:
tar cjf - <path> | gpg --cipher-algo AES -c - > backup.tbz2.gpg
And verify the backup like this if you are at "path":
cat backup.tbz2.gpg | gpg - | tar djf -
Note: Allways verify backups, especially encrypted ones.
In both cases GnuPG will ask you interactively for your symmetric
key. The verify will only output errors. Use "tar dvjf -" to get
all comparison results. To make sure no data is written to disk
unencrypted, turn off swap if it is not encrypted before doing the
backup.
You can of course use different or no compression and you can use
an asymmetric key if you have one and have a backup of the secret
key that belongs to it.
A second option for a filestem-level backup that can be used when
the backup is also on local disk (e.g. an external USB drive) is
to use a LUKS container there and copy the files to be backed up
between both mounted containers. Also see next item.
* Do I need a backup of the full partition? Would the header and
key-slots not be enough?
Backup protects you against two things: Disk loss or corruption
and user error. By far the most questions on the dm-crypt mailing
list about how to recover a damaged LUKS partition are related
to user error. For example, if you create a new filesystem on a
LUKS partition, chances are good that all data is lost
permanently.
For this case, a header+key-slot backup would often be enough. But
keep in mind that a well-treated (!) HDD has roughly a failure
risk of 5% per year. It is highly advisable to have a complete
backup to protect against this case.
* *What do I need to backup if I use "decrypt_derived"?
This is a script in Debian, intended for mounting /tmp or swap with
a key derived from the master key of an already decrypted device.
If you use this for an device with data that should be persistent,
you need to make sure you either do not lose access to that master
key or have a backup of the data. If you derive from a LUKS
device, a header backup of that device would cover backing up the
master key. Keep in mind that this does not protect against disk
loss.
Note: If you recreate the LUKS header of the device you derive from
(using luksFormat), the master key changes even if you use the same
passphrase(s) and you will not be able to decrypt the derived
device with the new LUKS header.
* Does a backup compromise security?
Depends on how you do it. First, a backup is non-optional with
encrypted data just the same way it is with non-encrypted data.
Disks do break and they do not care whether they make plain or
encrypted data inaccessible. As a gideline, a well-treated HDD (!)
breaks with about 5% probability per year. This means everybody
will be hit sooner or later.
Depends on how you do it. However if you do not have one, you are
going to eventually lose your encrypted data.
However there are risks introduced by backups. For example if you
There are risks introduced by backups. For example if you
change/disable a key-slot in LUKS, a binary backup of the partition
will still have the old key-slot. To deal with this, you have to
be able to change the key-slot on the backup as well, or use a
different set-up. One option is to have a different passphrase on
the backup and to make the backup with both containers open.
Another one is to make a backup of the original, opened container
to a single file, e.g. with tar, and to encrypt that file with
public-key-cryptography, e.g. with GnuPG. You can then keep the
secret key in a safe place, because it is only used to decrypt a
backup. The key the backup is encrypted with can be stored without
special security measures, as long as an attacker cannot replace
it with his own key.
be able to change the key-slot on the backup as well, securely
erase the backup or do a filesystem-level backup instead of a binary
one.
If you use dm-crypt, backup is simpler: As there is no key
management, the main risk is that you cannot wipe the backup when
@@ -822,19 +1013,22 @@ A. Contributors
should consist of forgetting the passphrase and that you can do
without actual access to the backup.
In both cases, there is an additional (usually small) risk: An
attacker can see how many sectors and which ones have been changed
since the backup. This is not possible with the public-key method
though.
In both cases, there is an additional (usually small) risk with
binary backups: An attacker can see how many sectors and which
ones have been changed since the backup. To prevent this, use a
filesystem level backup methid that encrypts the whole backup in
one go, e.g. as described above with tar and GnuPG.
My personal advice is to use one USB disk (low value date) or
My personal advice is to use one USB disk (low value data) or
three disks (high value data) in rotating order for backups, and
either use different passphrases or keep them easily accessible
in case you need to disable a key-slot. If you do network-backup
or tape-backup, I strongly recommend to go the public-key path,
especially as you typically cannot reliably delete data in these
scenarios. (Well, you can burn the tape if it is under your
control...)
either use independent LUKS partitions on them, or use encrypted
backup with tar and GnuPG.
If you do network-backup or tape-backup, I strongly recommend to
go the filesystem backup path with independent encryption, as you
typically cannot reliably delete data in these scenarios,
especially in a cloud setting. (Well, you can burn the tape if it
is under your control...)
* What happens if I overwrite the start of a LUKS partition or damage
@@ -860,6 +1054,63 @@ A. Contributors
damage the key-slots in part or in full. See also last item.
* How do I recover the master key from a mapped LUKS container?
This is typically only needed if you managed to damage your LUKS
header, but the container is still mapped, i.e. "luksOpen"ed.
WARNING: This exposes the master key of the LUKS container. Note
that both ways to recreate a LUKS header with the old master key
described below will write the master key to disk. Unless you are
sure you have securely erased it afterwards, e.g. by writing it to
an encrypted partition, RAM disk or by erasing the filesystem you
wrote it to by a complete overwrite, you should change the master
key afterwards. Changing the master key requires a full data
backup, luksFormat and then restore of the backup.
First, there is a script by Milan that tries to automatize the
whole process, including generating a new LUKS header with the old
master key:
http://code.google.com/p/cryptsetup/source/browse/trunk/misc/luks-header-from-active
You can also do this manually. Here is how:
- Get the master key from the device mapper. This is done by the
following command. Substitute c5 for whatever you mapped to:
# dmsetup table --target crypt --showkey /dev/mapper/c5
Result:
0 200704 crypt aes-cbc-essiv:sha256
a1704d9715f73a1bb4db581dcacadaf405e700d591e93e2eaade13ba653d0d09
0 7:0 4096
The result is actually one line, wrapped here for clarity. The long
hex string is the master key.
- Convert the master key to a binary file representation. You can
do this manually, e.g. with hexedit. You can also use the tool
"xxd" from vim like this:
echo "a1704d9....53d0d09" | xxd -r -p > master_key
- Do a luksFormat to create a new LUKS header. Unmapthe device
before you do that (luksClose). Replace \dev\dsa10 with the device
the LUKS container is on:
cryptsetup luksFormat --master-key-file=master_key \dev\sda10
Note that if the container was created with other than the default
settings of the cryptsetup version you are using, you need to give
additional parameters specifying the deviations. If in doubt, just
do the first step, keep the whole result safe and try with the
script by Milan. It does recover the other parameters as well.
Side note: This is the way the decrypt_derived script gets at the
master key. It just omits the conversion and hashes the master key
string.
* What does the on-disk structure of dm-crypt look like?
There is none. dm-crypt takes a block device and gives encrypted
@@ -910,75 +1161,83 @@ A. Contributors
http://code.google.com/p/cryptsetup/wiki/Specification
* How do I backup a LUKS header?
While you could just copy the appropriate number of bytes from the
start of the LUKS partition, the best way is to use command option
"luksHeaderBackup" of cryptsetup. This protects also against
errors when non-standard parameters have been used in LUKS
partition creation. Example:
cryptsetup luksHeaderBackup --header-backup-file h /dev/mapper/c1
To restore, use the inverse command, i.e.
cryptsetup luksHeaderRestore --header-backup-file h /dev/mapper/c1
* How do I backup a LUKS partition?
You do a sector-image of the whole partition. This will contain
the LUKS header, the keys-slots and the data ares. It can be done
under Linux e.g. with dd_rescue (for a direct image copy) and with
"cat" or "dd". Example:
cat /dev/sda10 > sda10.img
dd_rescue /dev/sda10 sda10.img
You can also use any other backup software that is capable of making
a sector image of a partition. Note that compression is
ineffective for encrypted data, hence it does not make sense to
use it.
* Do I need a backup of the full partition? Would the header and
key-slots not be enough?
Backup protects you against two things: Disk loss or corruption
and user error. By far the most questions on the dm-crypt mailing
list about how to recover a damaged LUKS partition are related
to user error. For example, if you create a new filesystem on a
LUKS partition, chances are good that all data is lost
permanently.
For this case, a header+key-slot backup would often be enough. But
keep in mind that a well-treated (!) HDD has roughly a failure
risk of 5% per year. It is highly advisable to have a complete
backup to protect against this case.
* Are there security risks from a backup of the LUKS header or a
whole LUKS partition?
Yes. One risk is that if you remove access rights for specific
key-slots by deleting their contents, the data can still be
accessed with invalidated passphrase and the backup. The other
risk is that if you erase a LUKS partition, a backup could still
grant access, especially if you only erased the LUKS header and
not the whole partition.
* I think this is overly complicated. Is there an alternative?
Yes, you can use plain dm-crypt. It does not allow multiple
Not really. Encryption comes at a price. You can use plain
dm-crypt to simplify things a bit. It does not allow multiple
passphrases, but on the plus side, it has zero on disk description
and if you overwrite some part of a plain dm-crypt partition,
exactly the overwritten parts are lost (rounded up to sector
borders).
7. Issues with Specific Versions of cryptsetup
7. Interoperability with other Disk Encryption Tools
* What is this section about?
Cryptsetup for plain dm-crypt can be used to access a number of
on-disk formats created by tools like loop-aes patched into
losetup. This somtimes works and sometimes does not. This section
collects insights into what works, what does not and where more
information is required.
Additional information may be found in the mailing-list archives,
mentioned at the start of this FAQ document. If you have a
solution working that is not yet documented here and think a wider
audience may be intertested, please email the FAQ maintainer.
* loop-aes: General observations.
One problem is that there are different versions of losetup around.
loop-aes is a patch for losetup. Possible problems and deviations
from cryptsetup option syntax include:
- Offsets specifed in bytes (cryptsetup: 512 byte sectors)
- The need to specify an IV offset
- Encryption mode needs specifying (e.g. "-c twofish-cbc-plain")
- Key size needs specifying (e.g. "-s 128" for 128 bit keys)
- Passphrase hash algorithm needs specifying
Also note that because plain dm-crypt and loop-aes format does not
have metadata, autodetection, while feasible in most cases, would
be a lot of work that nobody really wants to do. If you still have
the old set-up, using a verbosity option (-v) on mapping with the
old tool or having a look into the system logs after setup could
give you the information you need.
* loop-aes patched into losetup on debian 5.x, kernel 2.6.32
In this case, the main problem seems to be that this variant of
losetup takes the offset (-o option) in bytes, while cryptsetup
takes it in sectors of 512 bytes each. Example: The losetupp
command
losetup -e twofish -o 2560 /dev/loop0 /dev/sdb1
mount /dev/loop0 mountpoint
translates to
cryptsetup create -c twofish -o 5 --skip 5 e1 /dev/sdb1
mount /dev/mapper/e1 mountpoint
* loop-aes with 160 bit key
This seems to be sometimes used with twofish and blowfish and
represents a 160 bit ripemed160 hash output padded to 196 bit key
length. It seems the corresponding options for cryptsetup are
--cipher twofish-cbc-null -s 192 -h ripemd160:20
8. Issues with Specific Versions of cryptsetup
* When using the create command for plain dm-crypt with cryptsetup

View File

@@ -1,4 +1,4 @@
EXTRA_DIST = FAQ docs
EXTRA_DIST = FAQ docs misc
SUBDIRS = \
lib \
src \
@@ -7,3 +7,6 @@ SUBDIRS = \
po
ACLOCAL_AMFLAGS = -I m4
clean-local:
-rm -rf docs/doxygen_api_docs

9
TODO
View File

@@ -1,5 +1,6 @@
Version 1.4.0:
- Remove old API (all calls using crypt_options)
- Support separation of metadata device
- Wipe device flag
Version 1.5.0:
- Export wipe device functions
- Support K/M suffixes for align payload (new switch?).
- FIPS patches (RNG, volume key restrictions, move changekey to library)
- online reencryption api?
- integrate more metadata formats

View File

@@ -1,53 +0,0 @@
dnl MODULE_HELPER(NAME, HELP, DEFAULT, COMMANDS)
AC_DEFUN([MODULE_HELPER],[
unset have_module
AC_ARG_ENABLE([$1], [$2],,[
if test "x${enable_all}" = "xdefault"; then
enable_[$1]=[$3]
else
enable_[$1]="${enable_all}"
fi
])
if test "x${enable_[$1]}" != "xno"; then
$4
AC_MSG_CHECKING([whether to build $1 module])
if test -n "${have_module+set}"; then
if test "x${enable_[$1]}" = "xauto"; then
if test "x${enable_plugins}" != "xno"; then
AC_MSG_RESULT([yes, as plugin])
build_static=no
build_shared=yes
else
AC_MSG_RESULT([yes])
build_static=yes
build_shared=no
fi
elif test "x${enable_[$1]}" = "xshared"; then
if test "x${enable_plugins}" != "xno"; then
AC_MSG_RESULT([yes, as plugin])
build_static=no
build_shared=yes
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([Can't build [$1] module, plugins are disabled])
fi
else
AC_MSG_RESULT([yes])
build_static=yes
build_shared=no
fi
elif test "x${enable_[$1]}" != "xauto"; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([Unable to build $1 plugin, see messages above])
else
AC_MSG_RESULT([no])
build_static=no
build_shared=no
fi
else
AC_MSG_CHECKING([whether to build $1 module])
AC_MSG_RESULT([no])
build_static=no
build_shared=no
fi
])

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[1.3.1])
AC_INIT([cryptsetup],[1.4.0])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=3:0:2
LIBCRYPTSETUP_VERSION_INFO=4:0:0
AC_CONFIG_SRCDIR(src/cryptsetup.c)
AC_CONFIG_MACRO_DIR([m4])
@@ -124,13 +124,11 @@ AC_DEFUN([CONFIGURE_NETTLE], [
[AC_MSG_ERROR('You need Nettle cryptographic library.')])
saved_LIBS=$LIBS
AC_CHECK_LIB(nettle, nettle_sha512_init,,
[AC_MSG_ERROR('You need Nettle library version 2.1 or more recent.')])
AC_CHECK_LIB(nettle, nettle_ripemd160_init,,
[AC_MSG_ERROR('You need Nettle library version 2.4 or more recent.')])
CRYPTO_LIBS=$LIBS
LIBS=$saved_LIBS
AC_MSG_WARN([Nettle backend does NOT provide backward compatibility (missing ripemd160 hash).])
CRYPTO_STATIC_LIBS=$CRYPTO_LIBS
])
@@ -220,6 +218,11 @@ if test x$enable_static_cryptsetup = xyes; then
AC_CHECK_LIB(devmapper, dm_task_set_uuid,,
AC_MSG_ERROR([Cannot link with static device-mapper library.]))
dnl Try to detect uuid static library.
LIBS="$saved_LIBS -static"
AC_CHECK_LIB(uuid, uuid_generate,,
AC_MSG_ERROR([Cannot find static uuid library.]))
LIBS=$saved_LIBS
PKG_CONFIG=$saved_PKG_CONFIG
fi

280
docs/doxyfile Normal file
View File

@@ -0,0 +1,280 @@
# Doxyfile 1.7.4
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "cryptsetup API"
PROJECT_NUMBER =
PROJECT_BRIEF = "Public cryptsetup API"
PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen_api_docs
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
TYPEDEF_HIDES_STRUCT = YES
SYMBOL_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = "doxygen_index" "../lib/libcryptsetup.h"
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH = "examples"
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

123
docs/doxygen_index Normal file
View File

@@ -0,0 +1,123 @@
/**
* @mainpage Cryptsetup API
*
* The documentation covers public parts of cryptsetup API. In the following sections you'll find
* the examples that describe some features of cryptsetup API.
*
* <OL type="A">
* <LI>@ref cexamples "Cryptsetup API examples"</LI>
* <OL type="1">
* <LI>@ref cluks "crypt_luks_usage" - cryptsetup LUKS device type usage examples</LI>
* <UL>
* <LI>@ref cinit "crypt_init()"</LI>
* <LI>@ref cformat "crypt_format()" - header and payload on mutual device</LI>
* <LI>@ref ckeys "Keyslot operations" </LI>
* <UL>
* <LI>@ref ckeyslot_vol "crypt_keyslot_add_by_volume_key()"</LI>
* <LI>@ref ckeyslot_pass "crypt_keyslot_add_by_passphrase()"</LI>
* </UL>
* <LI>@ref cload "crypt_load()"
* <LI>@ref cactivate "crypt_activate_by_passphrase()"</LI>
* <LI>@ref cactive_pars "crypt_get_active_device()"</LI>
* <LI>@ref cinit_by_name "crypt_init_by_name()"</LI>
* <LI>@ref cdeactivate "crypt_deactivate()"</LI>
* <LI>@ref cluks_ex "crypt_luks_usage.c"</LI>
* </UL>
* <LI>@ref clog "crypt_log_usage" - cryptsetup logging API examples</LI>
* </OL>
* </OL>
*
* @section cexamples Cryptsetup API examples
* @section cluks crypt_luks_usage - cryptsetup LUKS device type usage
* @subsection cinit crypt_init()
*
* Every time you need to do something with cryptsetup or dmcrypt device
* you need a valid context. The first step to start your work is
* @ref crypt_init call. You can call it either with path
* to the block device or path to the regular file. If you don't supply the path,
* empty context is initialized.
*
* @subsection cformat crypt_format() - header and payload on mutual device
*
* This section covers basic use cases for formatting LUKS devices. Format operation
* sets device type in context and in case of LUKS header is written at the beginning
* of block device. In the example bellow we use the scenario where LUKS header and data
* are both stored on the same device. There's also a possibility to store header and
* data separately.
*
* <B>Bear in mind</B> that @ref crypt_format() is destructive operation and it
* overwrites part of the backing block device.
*
* @subsection ckeys Keyslot operations examples
*
* After successful @ref crypt_format of LUKS device, volume key is not stored
* in a persistent way on the device. Keyslot area is an array beyond LUKS header, where
* volume key is stored in the encrypted form using user input passphrase. For more info about
* LUKS keyslots and how it's actually protected, please look at
* <A HREF="http://code.google.com/p/cryptsetup/wiki/Specification">LUKS specification</A>.
* There are two basic methods to create a new keyslot:
*
* @subsection ckeyslot_vol crypt_keyslot_add_by_volume_key()
*
* Creates a new keyslot directly by encrypting volume_key stored in the device
* context. Passphrase should be supplied or user is prompted if passphrase param is
* NULL.
*
* @subsection ckeyslot_pass crypt_keyslot_add_by_passphrase()
*
* Creates a new keyslot for the volume key by opening existing active keyslot,
* extracting volume key from it and storing it into a new keyslot
* protected by a new passphrase
*
* @subsection cload crypt_load()
*
* Function loads header from backing block device into device context.
*
* @subsection cactivate crypt_activate_by_passphrase()
*
* Activates crypt device by user supplied password for keyslot containing the volume_key.
* If <I>keyslot</I> parameter is set to <I>CRYPT_ANY_SLOT</I> then all active keyslots
* are tried one by one until the volume key is found.
*
* @subsection cactive_pars crypt_get_active_device()
*
* This call returns structure containing runtime attributes of active device.
*
* @subsection cinit_by_name crypt_init_by_name()
*
* In case you need to do operations with active device (device which already
* has its corresponding mapping) and you miss valid device context stored in
* *crypt_device reference, you should use this call. Function tries to
* get path to backing device from DM, initializes context for it and loads LUKS
* header.
*
* @subsection cdeactivate crypt_deactivate()
*
* Deactivates crypt device (removes DM mapping and safely erases volume key from kernel).
*
* @subsection cluks_ex crypt_luks_usage.c - Complex example
*
* To compile and run use following commands in examples directory:
*
* @code
* make
* ./crypt_luks_usage _path_to_[block_device]_file
* @endcode
*
* Note that you need to have the cryptsetup library compiled. @include crypt_luks_usage.c
*
* @section clog crypt_log_usage - cryptsetup logging API example
*
* Example describes basic use case for cryptsetup logging. To compile and run
* use following commands in examples directory:
*
* @code
* make
* ./crypt_log_usage
* @endcode
*
* Note that you need to have the cryptsetup library compiled. @include crypt_log_usage.c
*
* @example crypt_luks_usage.c
* @example crypt_log_usage.c
*/

17
docs/examples/Makefile Normal file
View File

@@ -0,0 +1,17 @@
TARGETS=crypt_log_usage crypt_luks_usage
CFLAGS=-O0 -g -Wall -D_GNU_SOURCE
LDLIBS=-lcryptsetup
CC=gcc
all: $(TARGETS)
crypt_log_usage: crypt_log_usage.o
$(CC) -o $@ $^ $(LDLIBS)
crypt_luks_usage: crypt_luks_usage.o
$(CC) -o $@ $^ $(LDLIBS)
clean:
rm -f *.o *~ core $(TARGETS)
.PHONY: clean

View File

@@ -0,0 +1,96 @@
/*
* An example of using logging through libcryptsetup API
*
* Copyright (C) 2011, Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#include <libcryptsetup.h>
/*
* This is an example of function that can be registered using crypt_set_log_callback API.
*
* Its prototype is void (*log)(int level, const char *msg, void *usrptr) as defined
* in crypt_set_log_callback
*/
static void simple_syslog_wrapper(int level, const char *msg, void *usrptr)
{
const char *prefix = (const char *)usrptr;
int priority;
switch(level) {
case CRYPT_LOG_NORMAL: priority = LOG_NOTICE; break;
case CRYPT_LOG_ERROR: priority = LOG_ERR; break;
case CRYPT_LOG_VERBOSE: priority = LOG_INFO; break;
case CRYPT_LOG_DEBUG: priority = LOG_DEBUG; break;
default:
fprintf(stderr, "Unsupported log level requested!\n");
return;
}
if (prefix)
syslog(priority, "%s:%s", prefix, msg);
else
syslog(priority, "%s", msg);
}
int main(void)
{
struct crypt_device *cd;
char usrprefix[] = "cslog_example";
int r;
if (geteuid()) {
printf("Using of libcryptsetup requires super user privileges.\n");
return 1;
}
openlog("cryptsetup", LOG_CONS | LOG_PID, LOG_USER);
/* Initialize empty crypt device context */
r = crypt_init(&cd, NULL);
if (r < 0) {
printf("crypt_init() failed.\n");
return 2;
}
/* crypt_set_log_callback() - register a log function for crypt context */
crypt_set_log_callback(cd, &simple_syslog_wrapper, (void *)usrprefix);
/* send messages ithrough the crypt_log() interface */
crypt_log(cd, CRYPT_LOG_NORMAL, "This is normal log message");
crypt_log(cd, CRYPT_LOG_ERROR, "This is error log message");
crypt_log(cd, CRYPT_LOG_VERBOSE, "This is verbose log message");
crypt_log(cd, CRYPT_LOG_DEBUG, "This is debug message");
/* release crypt context */
crypt_free(cd);
/* Initialize default (global) log function */
crypt_set_log_callback(NULL, &simple_syslog_wrapper, NULL);
crypt_log(NULL, CRYPT_LOG_NORMAL, "This is normal log message");
crypt_log(NULL, CRYPT_LOG_ERROR, "This is error log message");
crypt_log(NULL, CRYPT_LOG_VERBOSE, "This is verbose log message");
crypt_log(NULL, CRYPT_LOG_DEBUG, "This is debug message");
closelog();
return 0;
}

View File

@@ -0,0 +1,294 @@
/*
* An example of using LUKS device through libcryptsetup API
*
* Copyright (C) 2011, Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <libcryptsetup.h>
static int format_and_add_keyslots(const char *path)
{
struct crypt_device *cd;
struct crypt_params_luks1 params;
int r;
/*
* crypt_init() call precedes most of operations of cryptsetup API. The call is used
* to initialize crypt device context stored in structure referenced by _cd_ in
* the example. Second parameter is used to pass underlaying device path.
*
* Note:
* If path refers to a regular file it'll be attached to a first free loop device.
* crypt_init() operation fails in case there's no more loop device available.
* Also, loop device will have the AUTOCLEAR flag set, so the file loopback will
* be detached automatically.
*/
r = crypt_init(&cd, path);
if (r < 0 ) {
printf("crypt_init() failed for %s.\n", path);
return r;
}
printf("Context is attached to block device %s.\n", crypt_get_device_name(cd));
/*
* So far no data were written on your device. This will change with call of
* crypt_format() only if you specify CRYPT_LUKS1 as device type.
*/
printf("Device %s will be formatted to LUKS device after 5 seconds.\n"
"Press CTRL+C now if you want to cancel this operation.\n", path);
sleep(5);
/*
* Prepare LUKS format parameters
*
* hash parameter defines PBKDF2 hash algorithm used in LUKS header.
* For compatibility reason we use SHA1 here.
*/
params.hash = "sha1";
/*
* data_alignment parameter is relevant only in case of the luks header
* and the payload are both stored on same device.
*
* if you set data_alignment = 0, cryptsetup will autodetect
* data_alignment according to underlaying device topology.
*/
params.data_alignment = 0;
/*
* data_device parameter defines that no external device
* for luks header will be used
*/
params.data_device = NULL;
/*
* NULLs for uuid and volume_key means that these attributes will be
* generated during crypt_format(). Volume key is generated with respect
* to key size parameter passed to function.
*
* crypt_format() checks device size (LUKS header must fit there).
*/
r = crypt_format(cd, /* crypt context */
CRYPT_LUKS1, /* LUKS1 is standard LUKS header */
"aes", /* used cipher */
"xts-plain64", /* used block mode and IV generator*/
NULL, /* generate UUID */
NULL, /* generate volume key from RNG */
256 / 8, /* 256bit key - here AES-128 in XTS mode, size is in bytes */
&params); /* parameters above */
if(r < 0) {
printf("crypt_format() failed on device %s\n", crypt_get_device_name(cd));
crypt_free(cd);
return r;
}
/*
* The device now contains LUKS1 header, but there is
* no active keyslot with encrypted volume key yet.
*/
/*
* cryptt_kesylot_add_* call stores volume_key in encrypted form into keyslot.
* Without keyslot you can't manipulate with LUKS device after the context will be freed.
*
* To create a new keyslot you need to supply the existing one (to get the volume key from) or
* you need to supply the volume key.
*
* After format, we have volume key stored internally in context so add new keyslot
* using this internal volume key.
*/
r = crypt_keyslot_add_by_volume_key(cd, /* crypt context */
CRYPT_ANY_SLOT, /* just use first free slot */
NULL, /* use internal volume key */
0, /* unused (size of volume key) */
"foo", /* passphrase - NULL means query*/
3); /* size of passphrase */
if (r < 0) {
printf("Adding keyslot failed.\n");
crypt_free(cd);
return r;
}
printf("The first keyslot is initialized.\n");
/*
* Add another keyslot, now using the first keyslot.
* It will decrypt volume key from the first keyslot and creates new one with another passphrase.
*/
r = crypt_keyslot_add_by_passphrase(cd, /* crypt context */
CRYPT_ANY_SLOT, /* just use first free slot */
"foo", 3, /* passphrase for the old keyslot */
"bar", 3); /* passphrase for the new kesylot */
if (r < 0) {
printf("Adding keyslot failed.\n");
crypt_free(cd);
return r;
}
printf("The second keyslot is initialized.\n");
crypt_free(cd);
return 0;
}
static int activate_and_check_status(const char *path, const char *device_name)
{
struct crypt_device *cd;
struct crypt_active_device cad;
int r;
/*
* LUKS device activation example.
* It's sequence of sub-steps: device initialization, LUKS header load
* and the device activation itself.
*/
r = crypt_init(&cd, path);
if (r < 0 ) {
printf("crypt_init() failed for %s.\n", path);
return r;
}
/*
* crypt_load() is used to load the LUKS header from block device
* into crypt_device context.
*/
r = crypt_load(cd, /* crypt context */
CRYPT_LUKS1, /* requested type */
NULL); /* additional parameters (not used) */
if (r < 0) {
printf("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
crypt_free(cd);
return r;
}
/*
* Device activation creates device-mapper devie mapping with name device_name.
*/
r = crypt_activate_by_passphrase(cd, /* crypt context */
device_name, /* device name to activate */
CRYPT_ANY_SLOT,/* which slot use (ANY - try all) */
"foo", 3, /* passphrase */
CRYPT_ACTIVATE_READONLY); /* flags */
if (r < 0) {
printf("Device %s activation failed.\n", device_name);
crypt_free(cd);
return r;
}
printf("LUKS device %s/%s is active.\n", crypt_get_dir(), device_name);
printf("\tcipher used: %s\n", crypt_get_cipher(cd));
printf("\tcipher mode: %s\n", crypt_get_cipher_mode(cd));
printf("\tdevice UUID: %s\n", crypt_get_uuid(cd));
/*
* Get info about active device (query DM backend)
*/
r = crypt_get_active_device(cd, device_name, &cad);
if (r < 0) {
printf("Get info about active device %s failed.\n", device_name);
crypt_deactivate(cd, device_name);
crypt_free(cd);
return r;
}
printf("Active device parameters for %s:\n"
"\tDevice offset (in sectors): %" PRIu64 "\n"
"\tIV offset (in sectors) : %" PRIu64 "\n"
"\tdevice size (in sectors) : %" PRIu64 "\n"
"\tread-only flag : %s\n",
device_name, cad.offset, cad.iv_offset, cad.size,
cad.flags & CRYPT_ACTIVATE_READONLY ? "1" : "0");
crypt_free(cd);
return 0;
}
static int handle_active_device(const char *device_name)
{
struct crypt_device *cd;
int r;
/*
* crypt_init_by_name() initializes device context and loads LUKS header from backing device
*/
r = crypt_init_by_name(&cd, device_name);
if (r < 0) {
printf("crypt_init_by_name() failed for %s.\n", device_name);
return r;
}
if (crypt_status(cd, device_name) == CRYPT_ACTIVE)
printf("Device %s is still active.\n", device_name);
else {
printf("Something failed perhaps, device %s is not active.\n", device_name);
crypt_free(cd);
return -1;
}
/*
* crypt_deactivate() is used to deactivate device
*/
r = crypt_deactivate(cd, device_name);
if (r < 0) {
printf("crypt_deactivate() failed.\n");
crypt_free(cd);
return r;
}
printf("Device %s is now deactivated.\n", device_name);
crypt_free(cd);
return 0;
}
int main(int argc, char **argv)
{
if (geteuid()) {
printf("Using of libcryptsetup requires super user privileges.\n");
return 1;
}
if (argc != 2) {
printf("usage: ./crypt_luks_usage <path>\n"
"<path> refers to either a regular file or a block device.\n"
" WARNING: the file or device will be wiped.\n");
return 2;
}
if (format_and_add_keyslots(argv[1]))
return 3;
if (activate_and_check_status(argv[1], "example_device"))
return 4;
if (handle_active_device("example_device"))
return 5;
return 0;
}

BIN
docs/on-disk-format.pdf Normal file

Binary file not shown.

131
docs/v1.4.0-ReleaseNotes Normal file
View File

@@ -0,0 +1,131 @@
Cryptsetup 1.4.0 Release Notes
==============================
Changes since version 1.3.1
Important changes
~~~~~~~~~~~~~~~~~
WARNING: This release removes old deprecated API from libcryptsetup
(all functions using struct crypt_options).
This require libcrypsetup version change and
rebuild of applications using cryptsetup library.
All new API symbols are backward compatible.
* If device is not rotational disk, cryptsetup no longer tries
to wipe keyslot with Gutmann algorithm for magnetic media erase
but simply rewrites area once by random data.
* The on-disk LUKS header can now be detached (e.g. placed on separate
device or in file) using new --header option.
This option is only relevant for LUKS devices and can be used in
luksFormat, luksOpen, luksSuspend, luksResume and resize commands.
If used with luksFormat the --align-payload option is taken
as absolute sector alignment on ciphertext device and can be zero.
Example:
Create LUKS device with ciphertext device on /dev/sdb and header
on device /dev/sdc. Use all space on /dev/sdb (no reserved area for header).
cryptsetup luksFormat /dev/sdb --header /dev/sdc --align-payload 0
Activate such device:
cryptsetup luksOpen /dev/sdb --header /dev/sdc test_disk
You can use file for LUKS header (loop device will be used while
manipulating with such detached header), just you have to create
large enough file in advance.
dd if=/dev/zero of=/mnt/luks_header bs=1M count=4
cryptsetup luksFormat /dev/sdb --header /mnt/luks_header --align-payload 0
Activation is the same as above.
cryptsetup luksOpen /dev/sdb --header /mnt/luks_header test_disk
All keyslot operations need to be run on _header_ not on ciphertext device,
an example:
cryptsetup luksAddKey /mnt/luks_header
If you do not use --align-payload 0, you can later restore LUKS header
on device itself (and use it as normal LUKS device without detached header).
WARNING: There is no possible check that specified ciphertext device
matches detached on-disk header. Use with care, it can destroy
your data in case of a mistake.
WARNING: Storing LUKS header in a file means that anti-forensic splitter
cannot properly work (there is filesystem allocation layer between
header and disk).
* Support --enable-discards option to allow discards/TRIM requests.
Since kernel 3.1, dm-crypt devices optionally (not by default) support
block discards (TRIM) comands.
If you want to enable this operation, you have to enable it manually
on every activation using --enable-discards
cryptsetup luksOpen --enable-discards /dev/sdb test_disk
WARNING: There are several security consequences, please read at least
http://asalor.blogspot.com/2011/08/trim-dm-crypt-problems.html
before you enable it.
* Add --shared option for creating non-overlapping crypt segments.
The --shared options checks that mapped segments are not overlapping
and allows non-exclusive access to underlying device.
Only plain crypt devices can be used in this mode.
Example - map 64M of device disk and following 32 M area as another disk.
cryptsetup create outer_disk /dev/sdb --offset 0 --size 65536
cryptsetup create inner_disk /dev/sdb --offset 65536 --size 32768 --shared
(It can be used to simulate trivial hidden disk concepts.)
libcryptsetup API changes:
* Added options to suport detached metadata device
crypt_init_by_name_and_header()
crypt_set_data_device()
* Add crypt_last_error() API call.
* Fix plain crypt format parameters to include size option.
* Add crypt_get_iv_offset() function.
* Remove old API functions (all functions using crypt_options).
* Support key-slot option for luksOpen (use only explicit keyslot).
You can now specify key slot in luksOpen and limit checking
only to specified slot.
* Support retries and timeout parameters for luksSuspend.
(The same way as in luksOpen.)
* Add doxygen-like documentation (it will be available on project page later).
(To generate it manually run doxygen in docs directory.)
Other changes
~~~~~~~~~~~~~
* Fix crypt_load to properly check device size.
* Do not allow context format of already formatted device.
* Do not allow key retrieval while suspended (key could be wiped).
* Do not allow suspend for non-LUKS devices.
* Fix luksKillSLot exit code if slot is inactive or invalid.
* Fix exit code if passphrases do not match in luksAddKey.
* Fix return code for status command when device doesn't exists.
* Fix verbose messages in isLuks command.
* Support Nettle 2.4 crypto backend (supports ripemd160).
* Add LUKS on-disk format description into package.
* Enhance check of device size before writing LUKS header.
* Add more paranoid checks for LUKS header and keyslot attributes.
* Use new /dev/loop-control (kernel 3.1) if possible.
* Remove hash/hmac restart from crypto backend and make it part of hash/hmac final.
* Improve check for invalid offset and size values.
* Revert default initialisation of volume key in crypt_init_by_name().
* Add more regression tests.
* Add some libcryptsetup example files (see docs/examples).

View File

@@ -53,6 +53,7 @@ libcryptsetup_la_SOURCES = \
utils_loop.c \
utils_loop.h \
utils_devpath.c \
utils_wipe.c \
libdevmapper.c \
utils_dm.h \
volumekey.c \

View File

@@ -54,8 +54,6 @@ static int hash(const char *hash_name, size_t key_size, char *key,
key += len;
key_size -= len;
if (key_size && crypt_hash_restart(md))
r = 1;
}
crypt_hash_destroy(md);

View File

@@ -16,7 +16,6 @@ uint32_t crypt_backend_flags(void);
/* HASH */
int crypt_hash_size(const char *name);
int crypt_hash_init(struct crypt_hash **ctx, const char *name);
int crypt_hash_restart(struct crypt_hash *ctx);
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length);
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length);
int crypt_hash_destroy(struct crypt_hash *ctx);
@@ -25,7 +24,6 @@ int crypt_hash_destroy(struct crypt_hash *ctx);
int crypt_hmac_size(const char *name);
int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
const void *buffer, size_t length);
int crypt_hmac_restart(struct crypt_hmac *ctx);
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length);
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length);
int crypt_hmac_destroy(struct crypt_hmac *ctx);

View File

@@ -117,10 +117,9 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
return 0;
}
int crypt_hash_restart(struct crypt_hash *ctx)
static void crypt_hash_restart(struct crypt_hash *ctx)
{
gcry_md_reset(ctx->hd);
return 0;
}
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
@@ -141,6 +140,8 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
return -EINVAL;
memcpy(buffer, hash, length);
crypt_hash_restart(ctx);
return 0;
}
@@ -191,10 +192,9 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
return 0;
}
int crypt_hmac_restart(struct crypt_hmac *ctx)
static void crypt_hmac_restart(struct crypt_hmac *ctx)
{
gcry_md_reset(ctx->hd);
return 0;
}
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
@@ -215,6 +215,8 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
return -EINVAL;
memcpy(buffer, hash, length);
crypt_hmac_restart(ctx);
return 0;
}

View File

@@ -176,11 +176,6 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
return 0;
}
int crypt_hash_restart(struct crypt_hash *ctx)
{
return 0;
}
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
{
ssize_t r;
@@ -261,11 +256,6 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
return 0;
}
int crypt_hmac_restart(struct crypt_hmac *ctx)
{
return 0;
}
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
{
ssize_t r;

View File

@@ -81,6 +81,14 @@ static struct hash_alg hash_algs[] = {
(digest_func) hmac_sha512_digest,
(set_key_func) hmac_sha512_set_key,
},
{ "ripemd160", RIPEMD160_DIGEST_SIZE,
(init_func) ripemd160_init,
(update_func) ripemd160_update,
(digest_func) ripemd160_digest,
(update_func) hmac_ripemd160_update,
(digest_func) hmac_ripemd160_digest,
(set_key_func) hmac_ripemd160_set_key,
},
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, }
};
@@ -159,10 +167,9 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
return 0;
}
int crypt_hash_restart(struct crypt_hash *ctx)
static void crypt_hash_restart(struct crypt_hash *ctx)
{
ctx->hash->init(&ctx->nettle_ctx);
return 0;
}
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
@@ -177,6 +184,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
return -EINVAL;
ctx->hash->digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
crypt_hash_restart(ctx);
return 0;
}
@@ -225,10 +233,9 @@ bad:
return -EINVAL;
}
int crypt_hmac_restart(struct crypt_hmac *ctx)
static void crypt_hmac_restart(struct crypt_hmac *ctx)
{
ctx->hash->hmac_set_key(&ctx->nettle_ctx, ctx->key_length, ctx->key);
return 0;
}
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
@@ -243,6 +250,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
return -EINVAL;
ctx->hash->hmac_digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
crypt_hmac_restart(ctx);
return 0;
}

View File

@@ -121,7 +121,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
return 0;
}
int crypt_hash_restart(struct crypt_hash *ctx)
static int crypt_hash_restart(struct crypt_hash *ctx)
{
if (PK11_DigestBegin(ctx->md) != SECSuccess)
return -EINVAL;
@@ -131,7 +131,7 @@ int crypt_hash_restart(struct crypt_hash *ctx)
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
{
if (PK11_DigestOp(ctx->md, (unsigned char *)buffer, length) != SECSuccess)
if (PK11_DigestOp(ctx->md, CONST_CAST(unsigned char *)buffer, length) != SECSuccess)
return -EINVAL;
return 0;
@@ -154,6 +154,9 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
if (tmp_len < length)
return -EINVAL;
if (crypt_hash_restart(ctx))
return -EINVAL;
return 0;
}
@@ -179,7 +182,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
SECItem noParams;
keyItem.type = siBuffer;
keyItem.data = (unsigned char *)buffer;
keyItem.data = CONST_CAST(unsigned char *)buffer;
keyItem.len = (int)length;
noParams.type = siBuffer;
@@ -220,7 +223,7 @@ bad:
return -EINVAL;
}
int crypt_hmac_restart(struct crypt_hmac *ctx)
static int crypt_hmac_restart(struct crypt_hmac *ctx)
{
if (PK11_DigestBegin(ctx->md) != SECSuccess)
return -EINVAL;
@@ -230,7 +233,7 @@ int crypt_hmac_restart(struct crypt_hmac *ctx)
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
{
if (PK11_DigestOp(ctx->md, (unsigned char *)buffer, length) != SECSuccess)
if (PK11_DigestOp(ctx->md, CONST_CAST(unsigned char *)buffer, length) != SECSuccess)
return -EINVAL;
return 0;
@@ -253,6 +256,9 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
if (tmp_len < length)
return -EINVAL;
if (crypt_hmac_restart(ctx))
return -EINVAL;
return 0;
}

View File

@@ -98,7 +98,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
return 0;
}
int crypt_hash_restart(struct crypt_hash *ctx)
static int crypt_hash_restart(struct crypt_hash *ctx)
{
if (EVP_DigestInit(&ctx->md, ctx->hash_id) != 1)
return -EINVAL;
@@ -131,6 +131,9 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
if (tmp_len < length)
return -EINVAL;
if (crypt_hash_restart(ctx))
return -EINVAL;
return 0;
}
@@ -171,10 +174,9 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
return 0;
}
int crypt_hmac_restart(struct crypt_hmac *ctx)
static void crypt_hmac_restart(struct crypt_hmac *ctx)
{
HMAC_Init_ex(&ctx->md, NULL, 0, ctx->hash_id, NULL);
return 0;
}
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
@@ -199,6 +201,8 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
if (tmp_len < length)
return -EINVAL;
crypt_hmac_restart(ctx);
return 0;
}

View File

@@ -15,17 +15,14 @@
#include "utils_loop.h"
#include "utils_dm.h"
/* to silent gcc -Wcast-qual for const cast */
#define CONST_CAST(x) (x)(uintptr_t)
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#define DEFAULT_DISK_ALIGNMENT 1048576 /* 1MiB */
#define DEFAULT_MEM_ALIGNMENT 4096
/* private struct crypt_options flags */
#define CRYPT_FLAG_FREE_DEVICE (1 << 24)
#define CRYPT_FLAG_FREE_CIPHER (1 << 25)
#define CRYPT_FLAG_PRIVATE_MASK ((unsigned int)-1 << 24)
#define MAX_ERROR_LENGTH 512
#define at_least(a, b) ({ __typeof__(a) __at_least = (a); (__at_least >= (b))?__at_least:(b); })
@@ -42,11 +39,9 @@ void crypt_free_volume_key(struct volume_key *vk);
int crypt_confirm(struct crypt_device *cd, const char *msg);
void set_error_va(const char *fmt, va_list va);
void set_error(const char *fmt, ...);
const char *get_error(void);
char *crypt_lookup_dev(const char *dev_id);
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
int sector_size_for_device(const char *device);
int device_read_ahead(const char *dev, uint32_t *read_ahead);
@@ -54,25 +49,21 @@ ssize_t write_blockwise(int fd, void *buf, size_t count);
ssize_t read_blockwise(int fd, void *_buf, size_t count);
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset);
int device_ready(struct crypt_device *cd, const char *device, int mode);
int get_device_infos(const char *device,
int open_exclusive,
int *readonly,
uint64_t *size);
int device_size(const char *device, uint64_t *size);
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
int device_check_and_adjust(struct crypt_device *cd,
const char *device,
int open_exclusive,
enum devcheck device_check,
uint64_t *size,
uint64_t *offset,
int *read_only);
int wipe_device_header(const char *device, int sectors);
uint32_t *flags);
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
#define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
#define log_std(c, x...) logger(c, CRYPT_LOG_NORMAL, __FILE__, __LINE__, x)
#define log_verbose(c, x...) logger(c, CRYPT_LOG_VERBOSE, __FILE__, __LINE__, x)
#define log_err(c, x...) do { \
logger(c, CRYPT_LOG_ERROR, __FILE__, __LINE__, x); \
set_error(x); } while(0)
#define log_err(c, x...) logger(c, CRYPT_LOG_ERROR, __FILE__, __LINE__, x)
int crypt_get_debug_level(void);
void debug_processes_using_device(const char *name);
@@ -95,5 +86,29 @@ int crypt_plain_hash(struct crypt_device *ctx,
const char *hash_name,
char *key, size_t key_size,
const char *passphrase, size_t passphrase_size);
int PLAIN_activate(struct crypt_device *cd,
const char *name,
struct volume_key *vk,
uint64_t size,
uint32_t flags);
/**
* Different methods used to erase sensitive data concerning
* either encrypted payload area or master key inside keyslot
* area
*/
typedef enum {
CRYPT_WIPE_ZERO, /**< overwrite area using zero blocks */
CRYPT_WIPE_DISK, /**< erase disk (using Gutmann method if it is rotational disk)*/
CRYPT_WIPE_SSD, /**< erase solid state disk (random write) */
CRYPT_WIPE_RANDOM /**< overwrite area using some up to now unspecified
* random algorithm */
} crypt_wipe_type;
int crypt_wipe(const char *device,
uint64_t offset,
uint64_t sectors,
crypt_wipe_type type,
int flags);
#endif /* INTERNAL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@ CRYPTSETUP_1.0 {
global:
crypt_init;
crypt_init_by_name;
crypt_init_by_name_and_header;
crypt_set_log_callback;
crypt_set_confirm_callback;
crypt_set_password_callback;
@@ -10,6 +11,7 @@ CRYPTSETUP_1.0 {
crypt_set_iterarion_time;
crypt_set_password_verify;
crypt_set_uuid;
crypt_set_data_device;
crypt_memory_lock;
crypt_format;
@@ -36,6 +38,7 @@ CRYPTSETUP_1.0 {
crypt_get_cipher_mode;
crypt_get_uuid;
crypt_get_data_offset;
crypt_get_iv_offset;
crypt_get_volume_key_size;
crypt_get_device_name;
@@ -47,6 +50,7 @@ CRYPTSETUP_1.0 {
crypt_keyslot_max;
crypt_keyslot_status;
crypt_last_error;
crypt_get_error;
crypt_get_dir;
crypt_set_debug_level;
@@ -54,22 +58,6 @@ CRYPTSETUP_1.0 {
crypt_header_backup;
crypt_header_restore;
crypt_create_device;
crypt_update_device;
crypt_resize_device;
crypt_query_device;
crypt_remove_device;
crypt_luksFormat;
crypt_luksOpen;
crypt_luksKillSlot;
crypt_luksRemoveKey;
crypt_luksAddKey;
crypt_luksUUID;
crypt_isLuks;
crypt_luksDump;
crypt_put_options;
local:
*;
};

View File

@@ -119,6 +119,9 @@ static void _dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj,
if (crypt_maj >= 1 && crypt_min >= 8)
_dm_crypt_flags |= DM_PLAIN64_SUPPORTED;
if (crypt_maj >= 1 && crypt_min >= 11)
_dm_crypt_flags |= DM_DISCARDS_SUPPORTED;
/* Repeat test if dm-crypt is not present */
if (crypt_maj > 0)
_dm_crypt_checked = 1;
@@ -206,7 +209,7 @@ void dm_exit(void)
}
/* Return path to DM device */
char *dm_device_path(int major, int minor)
char *dm_device_path(const char *prefix, int major, int minor)
{
struct dm_task *dmt;
const char *name;
@@ -222,7 +225,7 @@ char *dm_device_path(int major, int minor)
return NULL;
}
if (snprintf(path, sizeof(path), "/dev/mapper/%s", name) < 0)
if (snprintf(path, sizeof(path), "%s%s", prefix ?: "", name) < 0)
path[0] = '\0';
dm_task_destroy(dmt);
@@ -238,25 +241,39 @@ static void hex_key(char *hexkey, size_t key_size, const char *key)
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
}
static char *get_params(const char *device, uint64_t skip, uint64_t offset,
const char *cipher, size_t key_size, const char *key)
static char *get_params(struct crypt_dm_active_device *dmd)
{
char *params;
char *hexkey;
int r, max_size;
char *params, *hexkey;
const char *features = "";
hexkey = crypt_safe_alloc(key_size * 2 + 1);
if (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
if (dm_flags() & DM_DISCARDS_SUPPORTED) {
features = " 1 allow_discards";
log_dbg("Discard/TRIM is allowed.");
} else
log_dbg("Discard/TRIM is not supported by the kernel.");
}
hexkey = crypt_safe_alloc(dmd->vk->keylength * 2 + 1);
if (!hexkey)
return NULL;
hex_key(hexkey, key_size, key);
hex_key(hexkey, dmd->vk->keylength, dmd->vk->key);
params = crypt_safe_alloc(strlen(hexkey) + strlen(cipher) + strlen(device) + 64);
max_size = strlen(hexkey) + strlen(dmd->cipher) +
strlen(dmd->device) + strlen(features) + 64;
params = crypt_safe_alloc(max_size);
if (!params)
goto out;
sprintf(params, "%s %s %" PRIu64 " %s %" PRIu64,
cipher, hexkey, skip, device, offset);
r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
dmd->cipher, hexkey, dmd->iv_offset, dmd->device,
dmd->offset, features);
if (r < 0 || r >= max_size) {
crypt_safe_free(params);
params = NULL;
}
out:
crypt_safe_free(hexkey);
return params;
@@ -396,29 +413,20 @@ static void dm_prepare_uuid(const char *name, const char *type, const char *uuid
}
int dm_create_device(const char *name,
const char *device,
const char *cipher,
const char *type,
const char *uuid,
uint64_t size,
uint64_t skip,
uint64_t offset,
size_t key_size,
const char *key,
int read_only,
struct crypt_dm_active_device *dmd,
int reload)
{
struct dm_task *dmt = NULL;
struct dm_info dmi;
char *params = NULL;
char *error = NULL;
char dev_uuid[DM_UUID_LEN] = {0};
int r = -EINVAL;
uint32_t read_ahead = 0;
uint32_t cookie = 0;
uint16_t udev_flags = 0;
params = get_params(device, skip, offset, cipher, key_size, key);
params = get_params(dmd);
if (!params)
goto out_no_removal;
@@ -433,7 +441,7 @@ int dm_create_device(const char *name,
if (!dm_task_set_name(dmt, name))
goto out_no_removal;
} else {
dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));
dm_prepare_uuid(name, type, dmd->uuid, dev_uuid, sizeof(dev_uuid));
if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
goto out_no_removal;
@@ -450,13 +458,13 @@ int dm_create_device(const char *name,
if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
goto out_no_removal;
if (read_only && !dm_task_set_ro(dmt))
if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
goto out_no_removal;
if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params))
if (!dm_task_add_target(dmt, 0, dmd->size, DM_CRYPT_TARGET, params))
goto out_no_removal;
#ifdef DM_READ_AHEAD_MINIMUM_FLAG
if (device_read_ahead(device, &read_ahead) &&
if (device_read_ahead(dmd->device, &read_ahead) &&
!dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
goto out_no_removal;
#endif
@@ -470,7 +478,7 @@ int dm_create_device(const char *name,
goto out;
if (!dm_task_set_name(dmt, name))
goto out;
if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
if (dmd->uuid && !dm_task_set_uuid(dmt, dev_uuid))
goto out;
if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
goto out;
@@ -488,18 +496,9 @@ out:
cookie = 0;
}
if (r < 0 && !reload) {
if (get_error())
error = strdup(get_error());
if (r < 0 && !reload)
dm_remove_device(name, 0, 0);
if (error) {
set_error(error);
free(error);
}
}
out_no_removal:
if (cookie && _dm_use_udev())
(void)_dm_udev_wait(cookie);
@@ -513,10 +512,9 @@ out_no_removal:
return r;
}
int dm_status_device(const char *name)
static int dm_status_dmi(const char *name, struct dm_info *dmi)
{
struct dm_task *dmt;
struct dm_info dmi;
uint64_t start, length;
char *target_type, *params;
void *next = NULL;
@@ -531,10 +529,10 @@ int dm_status_device(const char *name)
if (!dm_task_run(dmt))
goto out;
if (!dm_task_get_info(dmt, &dmi))
if (!dm_task_get_info(dmt, dmi))
goto out;
if (!dmi.exists) {
if (!dmi->exists) {
r = -ENODEV;
goto out;
}
@@ -545,7 +543,7 @@ int dm_status_device(const char *name)
start != 0 || next)
r = -EINVAL;
else
r = (dmi.open_count > 0);
r = 0;
out:
if (dmt)
dm_task_destroy(dmt);
@@ -553,25 +551,43 @@ out:
return r;
}
int dm_query_device(const char *name,
char **device,
uint64_t *size,
uint64_t *skip,
uint64_t *offset,
char **cipher,
int *key_size,
char **key,
int *read_only,
int *suspended,
char **uuid)
int dm_status_device(const char *name)
{
int r;
struct dm_info dmi;
r = dm_status_dmi(name, &dmi);
if (r < 0)
return r;
return (dmi.open_count > 0);
}
int dm_status_suspended(const char *name)
{
int r;
struct dm_info dmi;
r = dm_status_dmi(name, &dmi);
if (r < 0)
return r;
return dmi.suspended ? 1 : 0;
}
int dm_query_device(const char *name, uint32_t get_flags,
struct crypt_dm_active_device *dmd)
{
struct dm_task *dmt;
struct dm_info dmi;
uint64_t start, length, val64;
char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3];
char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3], *arg;
const char *tmp_uuid;
void *next = NULL;
int i, r = -EINVAL;
unsigned int i;
int r = -EINVAL;
memset(dmd, 0, sizeof(*dmd));
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
goto out;
@@ -592,19 +608,20 @@ int dm_query_device(const char *name,
goto out;
}
tmp_uuid = dm_task_get_uuid(dmt);
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (!target_type || strcmp(target_type, DM_CRYPT_TARGET) != 0 ||
start != 0 || next)
goto out;
if (size)
*size = length;
dmd->size = length;
rcipher = strsep(&params, " ");
/* cipher */
if (cipher)
*cipher = strdup(rcipher);
if (get_flags & DM_ACTIVE_CIPHER)
dmd->cipher = strdup(rcipher);
/* skip */
key_ = strsep(&params, " ");
@@ -614,57 +631,86 @@ int dm_query_device(const char *name,
if (*params != ' ')
goto out;
params++;
if (skip)
*skip = val64;
dmd->iv_offset = val64;
/* device */
rdevice = strsep(&params, " ");
if (device)
*device = crypt_lookup_dev(rdevice);
if (get_flags & DM_ACTIVE_DEVICE)
dmd->device = crypt_lookup_dev(rdevice);
/*offset */
if (!params)
goto out;
val64 = strtoull(params, &params, 10);
if (*params)
dmd->offset = val64;
/* Features section, available since crypt target version 1.11 */
if (*params) {
if (*params != ' ')
goto out;
params++;
/* Number of arguments */
val64 = strtoull(params, &params, 10);
if (*params != ' ')
goto out;
params++;
for (i = 0; i < val64; i++) {
if (!params)
goto out;
arg = strsep(&params, " ");
if (!strcasecmp(arg, "allow_discards"))
dmd->flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
else /* unknown option */
goto out;
}
/* All parameters shold be processed */
if (params)
goto out;
}
/* Never allow to return empty key */
if ((get_flags & DM_ACTIVE_KEY) && dmi.suspended) {
log_dbg("Cannot read volume key while suspended.");
r = -EINVAL;
goto out;
if (offset)
*offset = val64;
}
/* key_size */
if (key_size)
*key_size = strlen(key_) / 2;
/* key */
if (key_size && key) {
*key = crypt_safe_alloc(*key_size);
if (!*key) {
if (get_flags & DM_ACTIVE_KEYSIZE) {
dmd->vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL);
if (!dmd->vk) {
r = -ENOMEM;
goto out;
}
buffer[2] = '\0';
for(i = 0; i < *key_size; i++) {
memcpy(buffer, &key_[i * 2], 2);
(*key)[i] = strtoul(buffer, &endp, 16);
if (endp != &buffer[2]) {
crypt_safe_free(key);
*key = NULL;
goto out;
if (get_flags & DM_ACTIVE_KEY) {
buffer[2] = '\0';
for(i = 0; i < dmd->vk->keylength; i++) {
memcpy(buffer, &key_[i * 2], 2);
dmd->vk->key[i] = strtoul(buffer, &endp, 16);
if (endp != &buffer[2]) {
crypt_free_volume_key(dmd->vk);
dmd->vk = NULL;
r = -EINVAL;
goto out;
}
}
}
}
memset(key_, 0, strlen(key_));
if (read_only)
*read_only = dmi.read_only;
if (dmi.read_only)
dmd->flags |= CRYPT_ACTIVATE_READONLY;
if (suspended)
*suspended = dmi.suspended;
if (uuid && (tmp_uuid = dm_task_get_uuid(dmt)) &&
!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
*uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
if (!tmp_uuid)
dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
else if (get_flags & DM_ACTIVE_UUID) {
if (!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
}
r = (dmi.open_count > 0);
out:
@@ -764,3 +810,26 @@ int dm_is_dm_kernel_name(const char *name)
{
return strncmp(name, "dm-", 3) ? 0 : 1;
}
int dm_check_segment(const char *name, uint64_t offset, uint64_t size)
{
struct crypt_dm_active_device dmd;
int r;
log_dbg("Checking segments for device %s.", name);
r = dm_query_device(name, 0, &dmd);
if (r < 0)
return r;
if (offset >= (dmd.offset + dmd.size) || (offset + size) <= dmd.offset)
r = 0;
else
r = -EBUSY;
log_dbg("seg: %" PRIu64 " - %" PRIu64 ", new %" PRIu64 " - %" PRIu64 "%s",
dmd.offset, dmd.offset + dmd.size, offset, offset + size,
r ? " (overlapping)" : " (ok)");
return r;
}

View File

@@ -185,22 +185,24 @@ int LOOPAES_activate(struct crypt_device *cd,
const char *base_cipher,
unsigned int keys_count,
struct volume_key *vk,
uint64_t offset,
uint64_t skip,
uint32_t flags)
{
uint64_t size;
char *cipher = NULL;
uint32_t req_flags;
char *cipher;
const char *device;
int read_only, r;
int r;
struct crypt_dm_active_device dmd = {
.device = crypt_get_device_name(cd),
.cipher = NULL,
.uuid = crypt_get_uuid(cd),
.vk = vk,
.offset = crypt_get_data_offset(cd),
.iv_offset = crypt_get_iv_offset(cd),
.size = 0,
.flags = flags
};
size = 0;
/* Initial IV (skip) is always the same as offset */
device = crypt_get_device_name(cd);
read_only = flags & CRYPT_ACTIVATE_READONLY;
r = device_check_and_adjust(cd, device, 1, &size, &offset, &read_only);
r = device_check_and_adjust(cd, dmd.device, DEV_EXCL, &dmd.size, &dmd.offset, &flags);
if (r)
return r;
@@ -214,12 +216,10 @@ int LOOPAES_activate(struct crypt_device *cd,
if (r < 0)
return -ENOMEM;
log_dbg("Trying to activate loop-AES device %s using cipher %s.", name, cipher);
r = dm_create_device(name, device,
cipher, CRYPT_LOOPAES,
crypt_get_uuid(cd),
size, skip, offset, vk->keylength, vk->key,
read_only, 0);
dmd.cipher = cipher;
log_dbg("Trying to activate loop-AES device %s using cipher %s.", name, dmd.cipher);
r = dm_create_device(name, CRYPT_LOOPAES, &dmd, 0);
if (!r && !(dm_flags() & req_flags)) {
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping.\n"));

View File

@@ -4,6 +4,9 @@
#include <unistd.h>
#include "config.h"
struct crypt_device;
struct volume_key;
#define LOOPAES_KEYS_MAX 65
int LOOPAES_parse_keyfile(struct crypt_device *cd,
@@ -18,7 +21,5 @@ int LOOPAES_activate(struct crypt_device *cd,
const char *base_cipher,
unsigned int keys_count,
struct volume_key *vk,
uint64_t offset,
uint64_t skip,
uint32_t flags);
#endif

View File

@@ -51,12 +51,21 @@ static int devfd=-1;
static int setup_mapping(const char *cipher, const char *name,
const char *device,
const char *key, size_t keyLength,
struct volume_key *vk,
unsigned int sector, size_t srcLength,
int mode, struct crypt_device *ctx)
{
int device_sector_size = sector_size_for_device(device);
uint64_t size;
struct crypt_dm_active_device dmd = {
.device = device,
.cipher = cipher,
.uuid = NULL,
.vk = vk,
.offset = sector,
.iv_offset = 0,
.size = 0,
.flags = (mode == O_RDONLY) ? CRYPT_ACTIVATE_READONLY : 0
};
/*
* we need to round this to nearest multiple of the underlying
@@ -66,11 +75,11 @@ static int setup_mapping(const char *cipher, const char *name,
log_err(ctx, _("Unable to obtain sector size for %s"), device);
return -EINVAL;
}
size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
cleaner_size = size;
return dm_create_device(name, device, cipher, "TEMP", NULL, size, 0, sector,
keyLength, key, (mode == O_RDONLY), 0);
dmd.size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
cleaner_size = dmd.size;
return dm_create_device(name, "TEMP", &dmd, 0);
}
static void sigint_handler(int sig __attribute__((unused)))
@@ -88,29 +97,10 @@ static void sigint_handler(int sig __attribute__((unused)))
static const char *_error_hint(char *cipherMode, size_t keyLength)
{
const char *hint= "";
#ifdef __linux__
char c, tmp[4] = {0};
struct utsname uts;
int i = 0, kernel_minor;
/* Nothing to suggest here */
if (uname(&uts) || strncmp(uts.release, "2.6.", 4))
return hint;
/* Get kernel minor without suffixes */
while (i < 3 && (c = uts.release[i + 4]))
tmp[i++] = isdigit(c) ? c : '\0';
kernel_minor = atoi(tmp);
if (!strncmp(cipherMode, "xts", 3) && (keyLength != 256 && keyLength != 512))
hint = _("Key size in XTS mode must be 256 or 512 bits.\n");
else if (!strncmp(cipherMode, "xts", 3) && kernel_minor < 24)
hint = _("Block mode XTS is available since kernel 2.6.24.\n");
if (!strncmp(cipherMode, "lrw", 3) && (keyLength != 256 && keyLength != 512))
hint = _("Key size in LRW mode must be 256 or 512 bits.\n");
else if (!strncmp(cipherMode, "lrw", 3) && kernel_minor < 20)
hint = _("Block mode LRW is available since kernel 2.6.20.\n");
#endif
return hint;
}
@@ -118,7 +108,7 @@ static const char *_error_hint(char *cipherMode, size_t keyLength)
handler and global vars for cleaning */
static int LUKS_endec_template(char *src, size_t srcLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
struct volume_key *vk,
const char *device,
unsigned int sector,
ssize_t (*func)(int, void *, size_t),
@@ -146,12 +136,12 @@ static int LUKS_endec_template(char *src, size_t srcLength,
cleaner_name = name;
r = setup_mapping(dmCipherSpec, name, device,
key, keyLength, sector, srcLength, mode, ctx);
vk, sector, srcLength, mode, ctx);
if(r < 0) {
log_err(ctx, _("Failed to setup dm-crypt key mapping for device %s.\n"
"Check that kernel supports %s cipher (check syslog for more info).\n%s"),
device, dmCipherSpec,
_error_hint(hdr->cipherMode, keyLength * 8));
_error_hint(hdr->cipherMode, vk->keylength * 8));
r = -EIO;
goto out1;
}
@@ -188,22 +178,22 @@ static int LUKS_endec_template(char *src, size_t srcLength,
int LUKS_encrypt_to_storage(char *src, size_t srcLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
struct volume_key *vk,
const char *device,
unsigned int sector,
struct crypt_device *ctx)
{
return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device,
return LUKS_endec_template(src,srcLength,hdr,vk, device,
sector, write_blockwise, O_RDWR, ctx);
}
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
struct volume_key *vk,
const char *device,
unsigned int sector,
struct crypt_device *ctx)
{
return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device,
return LUKS_endec_template(dst,dstLength,hdr,vk, device,
sector, read_blockwise, O_RDONLY, ctx);
}

View File

@@ -19,8 +19,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
@@ -29,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <uuid/uuid.h>
#include "luks.h"
@@ -46,6 +45,79 @@ static inline int round_up_modulo(int x, int m) {
return div_round_up(x, m) * m;
}
/* Get size of struct luks_phrd with all keyslots material space */
static uint64_t LUKS_device_sectors(size_t keyLen, unsigned int stripes)
{
uint64_t keyslot_sectors, sector;
int i;
keyslot_sectors = div_round_up(keyLen * stripes, SECTOR_SIZE);
sector = round_up_modulo(LUKS_PHDR_SIZE, LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
for (i = 0; i < LUKS_NUMKEYS; i++) {
sector = round_up_modulo(sector, LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
sector += keyslot_sectors;
}
return sector;
}
static int LUKS_check_device_size(const char *device,
uint64_t min_sectors,
size_t keyLength)
{
uint64_t dev_size, req_sectors;
req_sectors = LUKS_device_sectors(keyLength, LUKS_STRIPES);
if (min_sectors > req_sectors)
req_sectors = min_sectors;
if(device_size(device, &dev_size)) {
log_dbg("Cannot get device size for device %s.", device);
return -EIO;
}
return (req_sectors > (dev_size >> SECTOR_SHIFT));
}
/* Check keyslot to prevent access outside of header and keyslot area */
static int LUKS_check_keyslot_size(const struct luks_phdr *phdr, unsigned int keyIndex)
{
uint32_t secs_per_stripes;
/* First sectors is the header itself */
if (phdr->keyblock[keyIndex].keyMaterialOffset * SECTOR_SIZE < LUKS_ALIGN_KEYSLOTS) {
log_dbg("Invalid offset %u in keyslot %u.",
phdr->keyblock[keyIndex].keyMaterialOffset, keyIndex);
return 1;
}
/* Ignore following check for detached header where offset can be zero. */
if (phdr->payloadOffset == 0)
return 0;
if (phdr->payloadOffset <= phdr->keyblock[keyIndex].keyMaterialOffset) {
log_dbg("Invalid offset %u in keyslot %u (beyond data area offset %u).",
phdr->keyblock[keyIndex].keyMaterialOffset, keyIndex,
phdr->payloadOffset);
return 1;
}
secs_per_stripes = div_round_up(phdr->keyBytes * phdr->keyblock[keyIndex].stripes, SECTOR_SIZE);
if (phdr->payloadOffset < (phdr->keyblock[keyIndex].keyMaterialOffset + secs_per_stripes)) {
log_dbg("Invalid keyslot size %u (offset %u, stripes %u) in "
"keyslot %u (beyond data area offset %u).",
secs_per_stripes,
phdr->keyblock[keyIndex].keyMaterialOffset,
phdr->keyblock[keyIndex].stripes,
keyIndex, phdr->payloadOffset);
return 1;
}
return 0;
}
static const char *dbg_slot_state(crypt_keyslot_info ki)
{
switch(ki) {
@@ -148,7 +220,7 @@ int LUKS_hdr_restore(
buffer_size = hdr_file.payloadOffset << SECTOR_SHIFT;
if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) {
log_err(ctx, _("Backup file do not contain valid LUKS header.\n"));
log_err(ctx, _("Backup file doesn't contain valid LUKS header.\n"));
r = -EINVAL;
goto out;
}
@@ -216,7 +288,7 @@ int LUKS_hdr_restore(
close(devfd);
/* Be sure to reload new data */
r = LUKS_read_phdr(device, hdr, 0, ctx);
r = LUKS_read_phdr(device, hdr, 1, ctx);
out:
if (devfd != -1)
close(devfd);
@@ -237,8 +309,6 @@ static int _check_and_convert_hdr(const char *device,
log_dbg("LUKS header not detected.");
if (require_luks_device)
log_err(ctx, _("Device %s is not a valid LUKS device.\n"), device);
else
set_error(_("Device %s is not a valid LUKS device."), device);
r = -EINVAL;
} else if((hdr->version = ntohs(hdr->version)) != 1) { /* Convert every uint16/32_t item from network byte order */
log_err(ctx, _("Unsupported LUKS version %d.\n"), hdr->version);
@@ -256,7 +326,17 @@ static int _check_and_convert_hdr(const char *device,
hdr->keyblock[i].passwordIterations = ntohl(hdr->keyblock[i].passwordIterations);
hdr->keyblock[i].keyMaterialOffset = ntohl(hdr->keyblock[i].keyMaterialOffset);
hdr->keyblock[i].stripes = ntohl(hdr->keyblock[i].stripes);
if (LUKS_check_keyslot_size(hdr, i)) {
log_err(ctx, _("LUKS keyslot %u is invalid.\n"), i);
// FIXME: allow header recovery
r = -EINVAL;
}
}
/* Avoid unterminated strings */
hdr->cipherName[LUKS_CIPHERNAME_L - 1] = '\0';
hdr->cipherMode[LUKS_CIPHERMODE_L - 1] = '\0';
hdr->uuid[UUID_STRING_L - 1] = '\0';
}
return r;
@@ -312,7 +392,6 @@ int LUKS_read_phdr(const char *device,
{
ssize_t hdr_size = sizeof(struct luks_phdr);
int devfd = 0, r = 0;
uint64_t size;
log_dbg("Reading LUKS header of size %d from device %s",
hdr_size, device);
@@ -328,15 +407,7 @@ int LUKS_read_phdr(const char *device,
else
r = _check_and_convert_hdr(device, hdr, require_luks_device, ctx);
#ifdef BLKGETSIZE64
if (r == 0 && (ioctl(devfd, BLKGETSIZE64, &size) < 0 ||
size < (uint64_t)hdr->payloadOffset)) {
log_err(ctx, _("LUKS header detected but device %s is too small.\n"), device);
r = -EINVAL;
}
#endif
close(devfd);
return r;
}
@@ -353,6 +424,11 @@ int LUKS_write_phdr(const char *device,
log_dbg("Updating LUKS header of size %d on device %s",
sizeof(struct luks_phdr), device);
if (LUKS_check_device_size(device, hdr->payloadOffset, hdr->keyBytes)) {
log_err(ctx, _("Device %s is too small.\n"), device);
return -EINVAL;
}
devfd = open(device,O_RDWR | O_DIRECT | O_SYNC);
if(-1 == devfd) {
log_err(ctx, _("Cannot open device %s.\n"), device);
@@ -412,6 +488,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
unsigned int alignOffset,
uint32_t iteration_time_ms,
uint64_t *PBKDF2_per_sec,
const char *metadata_device,
struct crypt_device *ctx)
{
unsigned int i=0;
@@ -421,7 +498,8 @@ int LUKS_generate_phdr(struct luks_phdr *header,
int currentSector;
char luksMagic[] = LUKS_MAGIC;
if (alignPayload == 0)
/* For separate metadata device allow zero alignment */
if (alignPayload == 0 && !metadata_device)
alignPayload = DEFAULT_DISK_ALIGNMENT / SECTOR_SIZE;
if (PBKDF2_HMAC_ready(hashSpec) < 0) {
@@ -485,10 +563,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
currentSector = round_up_modulo(currentSector + blocksPerStripeSet,
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
}
currentSector = round_up_modulo(currentSector, alignPayload);
/* alignOffset - offset from natural device alignment provided by topology info */
header->payloadOffset = currentSector + alignOffset;
if (metadata_device) {
/* for separate metadata device use alignPayload directly */
header->payloadOffset = alignPayload;
} else {
/* alignOffset - offset from natural device alignment provided by topology info */
currentSector = round_up_modulo(currentSector, alignPayload);
header->payloadOffset = currentSector + alignOffset;
}
uuid_unparse(partitionUuid, header->uuid);
@@ -525,7 +608,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
uint64_t *PBKDF2_per_sec,
struct crypt_device *ctx)
{
char derivedKey[hdr->keyBytes];
struct volume_key *derived_key;
char *AfKey = NULL;
unsigned int AFEKSize;
uint64_t PBKDF2_temp;
@@ -560,23 +643,26 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
log_dbg("Key slot %d use %d password iterations.", keyIndex, hdr->keyblock[keyIndex].passwordIterations);
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!derived_key)
return -ENOMEM;
r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt,
LUKS_SALTSIZE, CRYPT_RND_NORMAL);
if (r < 0)
return r;
// assert((vk->keylength % TWOFISH_BLOCKSIZE) == 0); FIXME
r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen,
hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE,
hdr->keyblock[keyIndex].passwordIterations,
derivedKey, hdr->keyBytes);
derived_key->key, hdr->keyBytes);
if (r < 0)
goto out;
/*
* AF splitting, the masterkey stored in vk->key is split to AfKey
*/
assert(vk->keylength == hdr->keyBytes);
AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength;
AfKey = crypt_safe_alloc(AFEKSize);
if (!AfKey) {
@@ -596,14 +682,12 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
r = LUKS_encrypt_to_storage(AfKey,
AFEKSize,
hdr,
derivedKey,
hdr->keyBytes,
derived_key,
device,
hdr->keyblock[keyIndex].keyMaterialOffset,
ctx);
if (r < 0) {
if(!get_error())
log_err(ctx, _("Failed to write to key storage.\n"));
log_err(ctx, _("Failed to write to key storage.\n"));
goto out;
}
@@ -619,7 +703,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
r = 0;
out:
crypt_safe_free(AfKey);
memset(derivedKey, 0, sizeof(derivedKey));
crypt_free_volume_key(derived_key);
return r;
}
@@ -651,7 +735,7 @@ static int LUKS_open_key(const char *device,
struct crypt_device *ctx)
{
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
char derivedKey[hdr->keyBytes];
struct volume_key *derived_key;
char *AfKey;
size_t AFEKSize;
int r;
@@ -662,8 +746,11 @@ static int LUKS_open_key(const char *device,
if (ki < CRYPT_SLOT_ACTIVE)
return -ENOENT;
// assert((vk->keylength % TWOFISH_BLOCKSIZE) == 0); FIXME
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!derived_key)
return -ENOMEM;
assert(vk->keylength == hdr->keyBytes);
AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength;
AfKey = crypt_safe_alloc(AFEKSize);
if (!AfKey)
@@ -672,7 +759,7 @@ static int LUKS_open_key(const char *device,
r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen,
hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE,
hdr->keyblock[keyIndex].passwordIterations,
derivedKey, hdr->keyBytes);
derived_key->key, hdr->keyBytes);
if (r < 0)
goto out;
@@ -680,8 +767,7 @@ static int LUKS_open_key(const char *device,
r = LUKS_decrypt_from_storage(AfKey,
AFEKSize,
hdr,
derivedKey,
hdr->keyBytes,
derived_key,
device,
hdr->keyblock[keyIndex].keyMaterialOffset,
ctx);
@@ -699,7 +785,7 @@ static int LUKS_open_key(const char *device,
log_verbose(ctx, _("Key slot %d unlocked.\n"), keyIndex);
out:
crypt_safe_free(AfKey);
memset(derivedKey, 0, sizeof(derivedKey));
crypt_free_volume_key(derived_key);
return r;
}
@@ -736,72 +822,6 @@ int LUKS_open_key_with_hdr(const char *device,
return -EPERM;
}
/*
* Wipe patterns according to Gutmann's Paper
*/
static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn)
{
unsigned int i;
unsigned char write_modes[][3] = {
{"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"},
{"\x49\x24\x92"}, {"\x24\x92\x49"}, {"\x00\x00\x00"},
{"\x11\x11\x11"}, {"\x22\x22\x22"}, {"\x33\x33\x33"},
{"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
{"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"},
{"\xaa\xaa\xaa"}, {"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"},
{"\xdd\xdd\xdd"}, {"\xee\xee\xee"}, {"\xff\xff\xff"},
{"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
{"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
};
for(i = 0; i < buffer_size / 3; ++i) {
memcpy(buffer, write_modes[turn], 3);
buffer += 3;
}
}
static int wipe(const char *device, unsigned int from, unsigned int to)
{
int devfd, r = 0;
char *buffer;
unsigned int i, bufLen;
ssize_t written;
devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
if(devfd == -1)
return -EINVAL;
bufLen = (to - from) * SECTOR_SIZE;
buffer = malloc(bufLen);
if(!buffer) {
close(devfd);
return -ENOMEM;
}
for(i = 0; i < 39; ++i) {
if (i < 5) crypt_random_get(NULL, buffer, bufLen,
CRYPT_RND_NORMAL);
else if(i >= 5 && i < 32) wipeSpecial(buffer, bufLen, i - 5);
else if(i >= 32 && i < 38) crypt_random_get(NULL, buffer, bufLen,
CRYPT_RND_NORMAL);
else if(i >= 38 && i < 39) memset(buffer, 0xFF, bufLen);
written = write_lseek_blockwise(devfd, buffer, bufLen,
from * SECTOR_SIZE);
if (written < 0 || written != bufLen) {
r = -EIO;
break;
}
}
free(buffer);
close(devfd);
return r;
}
int LUKS_del_key(const char *device,
unsigned int keyIndex,
struct luks_phdr *hdr,
@@ -826,7 +846,9 @@ int LUKS_del_key(const char *device,
stripesLen = hdr->keyBytes * hdr->keyblock[keyIndex].stripes;
endOffset = startOffset + div_round_up(stripesLen, SECTOR_SIZE);
r = wipe(device, startOffset, endOffset);
r = crypt_wipe(device, startOffset * SECTOR_SIZE,
(endOffset - startOffset) * SECTOR_SIZE,
CRYPT_WIPE_DISK, 0);
if (r) {
log_err(ctx, _("Cannot wipe device %s.\n"), device);
return r;
@@ -897,3 +919,37 @@ int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable)
log_dbg("Key slot %d was %s in LUKS header.", keyslot, enable ? "enabled" : "disabled");
return 0;
}
int LUKS1_activate(struct crypt_device *cd,
const char *name,
struct volume_key *vk,
uint32_t flags)
{
int r;
char *dm_cipher = NULL;
struct crypt_dm_active_device dmd = {
.device = crypt_get_device_name(cd),
.cipher = NULL,
.uuid = crypt_get_uuid(cd),
.vk = vk,
.offset = crypt_get_data_offset(cd),
.iv_offset = 0,
.size = 0,
.flags = flags
};
r = device_check_and_adjust(cd, dmd.device, DEV_EXCL,
&dmd.size, &dmd.offset, &flags);
if (r)
return r;
r = asprintf(&dm_cipher, "%s-%s", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
if (r < 0)
return -ENOMEM;
dmd.cipher = dm_cipher;
r = dm_create_device(name, CRYPT_LUKS1, &dmd, 0);
free(dm_cipher);
return r;
}

View File

@@ -88,6 +88,7 @@ int LUKS_generate_phdr(
unsigned int alignOffset,
uint32_t iteration_time_ms,
uint64_t *PBKDF2_per_sec,
const char *metadata_device,
struct crypt_device *ctx);
int LUKS_read_phdr(
@@ -160,7 +161,7 @@ int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable);
int LUKS_encrypt_to_storage(
char *src, size_t srcLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
struct volume_key *vk,
const char *device,
unsigned int sector,
struct crypt_device *ctx);
@@ -168,9 +169,14 @@ int LUKS_encrypt_to_storage(
int LUKS_decrypt_from_storage(
char *dst, size_t dstLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
struct volume_key *vk,
const char *device,
unsigned int sector,
struct crypt_device *ctx);
int LUKS1_activate(struct crypt_device *cd,
const char *name,
struct volume_key *vk,
uint32_t flags);
#endif

View File

@@ -167,9 +167,6 @@ static int pkcs5_pbkdf2(const char *hash,
memset(T, 0, hLen);
for (u = 1; u <= c ; u++) {
if (crypt_hmac_restart(hmac))
goto out;
if (u == 1) {
memcpy(tmp, S, Slen);
tmp[Slen + 0] = (i & 0xff000000) >> 24;

File diff suppressed because it is too large Load Diff

View File

@@ -38,46 +38,6 @@
#include "libcryptsetup.h"
#include "internal.h"
static char *error=NULL;
__attribute__((format(printf, 1, 0)))
void set_error_va(const char *fmt, va_list va)
{
int r;
if(error) {
free(error);
error = NULL;
}
if(!fmt) return;
r = vasprintf(&error, fmt, va);
if (r < 0) {
free(error);
error = NULL;
return;
}
if (r && error[r - 1] == '\n')
error[r - 1] = '\0';
}
__attribute__((format(printf, 1, 2)))
void set_error(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
set_error_va(fmt, va);
va_end(va);
}
const char *get_error(void)
{
return error;
}
static int get_alignment(int fd)
{
int alignment = DEFAULT_MEM_ALIGNMENT;
@@ -336,10 +296,23 @@ int device_ready(struct crypt_device *cd, const char *device, int mode)
return r;
}
int get_device_infos(const char *device,
int open_exclusive,
int *readonly,
uint64_t *size)
int device_size(const char *device, uint64_t *size)
{
int devfd, r = 0;
devfd = open(device, O_RDONLY);
if(devfd == -1)
return -EINVAL;
if (ioctl(devfd, BLKGETSIZE64, size) < 0)
r = -EINVAL;
close(devfd);
return r;
}
static int get_device_infos(const char *device, enum devcheck device_check,
int *readonly, uint64_t *size)
{
struct stat st;
unsigned long size_small;
@@ -353,7 +326,7 @@ int get_device_infos(const char *device,
return -EINVAL;
/* never wipe header on mounted device */
if (open_exclusive && S_ISBLK(st.st_mode))
if (device_check == DEV_EXCL && S_ISBLK(st.st_mode))
flags |= O_EXCL;
/* Try to open read-write to check whether it is a read-only device */
@@ -363,7 +336,7 @@ int get_device_infos(const char *device,
fd = open(device, O_RDONLY | flags);
}
if (fd == -1 && open_exclusive && errno == EBUSY)
if (fd == -1 && device_check == DEV_EXCL && errno == EBUSY)
return -EBUSY;
if (fd == -1)
@@ -396,10 +369,10 @@ out:
int device_check_and_adjust(struct crypt_device *cd,
const char *device,
int open_exclusive,
enum devcheck device_check,
uint64_t *size,
uint64_t *offset,
int *read_only)
uint32_t *flags)
{
int r, real_readonly;
uint64_t real_size;
@@ -407,7 +380,7 @@ int device_check_and_adjust(struct crypt_device *cd,
if (!device)
return -ENOTBLK;
r = get_device_infos(device, open_exclusive, &real_readonly, &real_size);
r = get_device_infos(device, device_check, &real_readonly, &real_size);
if (r < 0) {
if (r == -EBUSY)
log_err(cd, _("Cannot use device %s which is in use "
@@ -419,62 +392,49 @@ int device_check_and_adjust(struct crypt_device *cd,
return r;
}
if (*offset >= real_size) {
log_err(cd, _("Requested offset is beyond real size of device %s.\n"),
device);
return -EINVAL;
}
if (!*size) {
*size = real_size;
if (!*size) {
log_err(cd, _("Device %s has zero size.\n"), device);
return -ENOTBLK;
}
if (*size < *offset) {
log_err(cd, _("Device %s is too small.\n"), device);
return -EINVAL;
}
*size -= *offset;
}
/* in case of size is set by parameter */
if ((real_size - *offset) < *size) {
log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64
", backing device size = %" PRIu64,
device, *offset, *size, real_size);
log_err(cd, _("Device %s is too small.\n"), device);
return -EINVAL;
}
if (device_check == DEV_SHARED) {
log_dbg("Checking crypt segments for device %s.", device);
r = crypt_sysfs_check_crypt_segment(device, *offset, *size);
if (r < 0) {
log_err(cd, _("Cannot use device %s (crypt segments "
"overlaps or in use by another device).\n"),
device);
return r;
}
}
if (real_readonly)
*read_only = 1;
*flags |= CRYPT_ACTIVATE_READONLY;
log_dbg("Calculated device size is %" PRIu64 " sectors (%s), offset %" PRIu64 ".",
*size, *read_only ? "RO" : "RW", *offset);
*size, real_readonly ? "RO" : "RW", *offset);
return 0;
}
int wipe_device_header(const char *device, int sectors)
{
struct stat st;
char *buffer;
int size = sectors * SECTOR_SIZE;
int r = -1;
int devfd;
int flags = O_RDWR | O_DIRECT | O_SYNC;
if (stat(device, &st) < 0)
return -EINVAL;
/* never wipe header on mounted device */
if (S_ISBLK(st.st_mode))
flags |= O_EXCL;
devfd = open(device, flags);
if(devfd == -1)
return errno == EBUSY ? -EBUSY : -EINVAL;
buffer = malloc(size);
if (!buffer) {
close(devfd);
return -ENOMEM;
}
memset(buffer, 0, size);
r = write_blockwise(devfd, buffer, size) < size ? -EIO : 0;
free(buffer);
close(devfd);
return r;
}
/* MEMLOCK */
#define DEFAULT_PROCESS_PRIORITY -18

View File

@@ -235,6 +235,7 @@ static int crypt_get_key_tty(const char *prompt,
if (strncmp(pass, pass_verify, key_size_max)) {
log_err(cd, _("Passphrases do not match.\n"));
r = -EPERM;
goto out_err;
}
}

View File

@@ -24,11 +24,15 @@
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "utils_dm.h"
char *crypt_lookup_dev(const char *dev_id);
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_level)
{
@@ -146,7 +150,7 @@ char *crypt_lookup_dev(const char *dev_id)
devname++;
if (dm_is_dm_kernel_name(devname))
devpath = dm_device_path(major, minor);
devpath = dm_device_path("/dev/mapper/", major, minor);
else if (snprintf(path, sizeof(path), "/dev/%s", devname) > 0)
devpath = strdup(path);
@@ -163,3 +167,102 @@ char *crypt_lookup_dev(const char *dev_id)
return devpath;
}
static int crypt_sysfs_get_major_minor(const char *kname, int *major, int *minor)
{
char path[PATH_MAX], tmp[64] = {0};
int fd, r = 0;
if (snprintf(path, sizeof(path), "/sys/block/%s/dev", kname) < 0)
return 0;
if ((fd = open(path, O_RDONLY)) < 0)
return 0;
r = read(fd, tmp, sizeof(tmp));
close(fd);
if (r <= 0)
return 0;
tmp[63] = '\0';
if (sscanf(tmp, "%d:%d", major, minor) != 2)
return 0;
return 1;
}
static int crypt_sysfs_get_holders_dir(const char *device, char *path, int size)
{
struct stat st;
if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
return 0;
if (snprintf(path, size, "/sys/dev/block/%d:%d/holders",
major(st.st_rdev), minor(st.st_rdev)) < 0)
return 0;
return 1;
}
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size)
{
DIR *dir;
struct dirent *d;
char path[PATH_MAX], *dmname;
int major, minor, r = 0;
if (!crypt_sysfs_get_holders_dir(device, path, sizeof(path)))
return -EINVAL;
if (!(dir = opendir(path)))
return -EINVAL;
while (!r && (d = readdir(dir))) {
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
if (!dm_is_dm_kernel_name(d->d_name)) {
r = -EBUSY;
break;
}
if (!crypt_sysfs_get_major_minor(d->d_name, &major, &minor)) {
r = -EINVAL;
break;
}
if (!(dmname = dm_device_path(NULL, major, minor))) {
r = -EINVAL;
break;
}
r = dm_check_segment(dmname, offset, size);
free(dmname);
}
closedir(dir);
return r;
}
int crypt_sysfs_get_rotational(int major, int minor, int *rotational)
{
char path[PATH_MAX], 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)
return 0;
r = read(fd, tmp, sizeof(tmp));
close(fd);
if (r <= 0)
return 0;
if (sscanf(tmp, "%d", rotational) != 1)
return 0;
return 1;
}

View File

@@ -5,41 +5,56 @@
#include <inttypes.h>
struct crypt_device;
struct volume_key;
/* Device mapper backend - kernel support flags */
#define DM_KEY_WIPE_SUPPORTED (1 << 0) /* key wipe message */
#define DM_LMK_SUPPORTED (1 << 1) /* lmk mode */
#define DM_SECURE_SUPPORTED (1 << 2) /* wipe (secure) buffer flag */
#define DM_PLAIN64_SUPPORTED (1 << 3) /* plain64 IV */
#define DM_DISCARDS_SUPPORTED (1 << 4) /* discards/TRIM option is supported */
uint32_t dm_flags(void);
#define DM_ACTIVE_DEVICE (1 << 0)
#define DM_ACTIVE_CIPHER (1 << 1)
#define DM_ACTIVE_UUID (1 << 2)
#define DM_ACTIVE_KEYSIZE (1 << 3)
#define DM_ACTIVE_KEY (1 << 4)
struct crypt_dm_active_device {
const char *device;
const char *cipher;
const char *uuid;
/* Active key for device */
struct volume_key *vk;
/* struct crypt_active_device */
uint64_t offset; /* offset in sectors */
uint64_t iv_offset; /* IV initilisation sector */
uint64_t size; /* active device size */
uint32_t flags; /* activation flags */
};
const char *dm_get_dir(void);
int dm_init(struct crypt_device *context, int check_kernel);
void dm_exit(void);
int dm_remove_device(const char *name, int force, uint64_t size);
int dm_status_device(const char *name);
int dm_query_device(const char *name,
char **device,
uint64_t *size,
uint64_t *skip,
uint64_t *offset,
char **cipher,
int *key_size,
char **key,
int *read_only,
int *suspended,
char **uuid);
int dm_create_device(const char *name, const char *device, const char *cipher,
const char *type, const char *uuid,
uint64_t size, uint64_t skip, uint64_t offset,
size_t key_size, const char *key,
int read_only, int reload);
int dm_status_suspended(const char *name);
int dm_query_device(const char *name, uint32_t get_flags,
struct crypt_dm_active_device *dmd);
int dm_create_device(const char *name,
const char *type,
struct crypt_dm_active_device *dmd,
int reload);
int dm_suspend_and_wipe_key(const char *name);
int dm_resume_and_reinstate_key(const char *name,
size_t key_size,
const char *key);
char *dm_device_path(int major, int minor);
char *dm_device_path(const char *prefix, int major, int minor);
int dm_is_dm_device(int major, int minor);
int dm_is_dm_kernel_name(const char *name);
int dm_check_segment(const char *name, uint64_t offset, uint64_t size);
#endif /* _UTILS_DM_H */

View File

@@ -29,7 +29,17 @@
#include "utils_loop.h"
char *crypt_loop_get_device(void)
#define LOOP_DEV_MAJOR 7
#ifndef LO_FLAGS_AUTOCLEAR
#define LO_FLAGS_AUTOCLEAR 4
#endif
#ifndef LOOP_CTL_GET_FREE
#define LOOP_CTL_GET_FREE 0x4C82
#endif
static char *crypt_loop_get_device_old(void)
{
char dev[20];
int i, loop_fd;
@@ -56,6 +66,32 @@ char *crypt_loop_get_device(void)
return NULL;
}
char *crypt_loop_get_device(void)
{
char dev[64];
int i, loop_fd;
struct stat st;
loop_fd = open("/dev/loop-control", O_RDONLY);
if (loop_fd < 0)
return crypt_loop_get_device_old();
i = ioctl(loop_fd, LOOP_CTL_GET_FREE);
if (i < 0) {
close(loop_fd);
return NULL;
}
close(loop_fd);
if (sprintf(dev, "/dev/loop%d", i) < 0)
return NULL;
if (stat(dev, &st) || !S_ISBLK(st.st_mode))
return NULL;
return strdup(dev);
}
int crypt_loop_attach(const char *loop, const char *file, int offset,
int autoclear, int *readonly)
{

View File

@@ -3,12 +3,6 @@
/* loopback device helpers */
#define LOOP_DEV_MAJOR 7
#ifndef LO_FLAGS_AUTOCLEAR
#define LO_FLAGS_AUTOCLEAR 4
#endif
char *crypt_loop_get_device(void);
char *crypt_loop_backing_file(const char *loop);
int crypt_loop_device(const char *loop);

172
lib/utils_wipe.c Normal file
View File

@@ -0,0 +1,172 @@
/*
* utils_wipe - wipe a device
*
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2011, 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
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include "libcryptsetup.h"
#include "internal.h"
#define MAXIMUM_WIPE_BYTES 1024 * 1024 * 32 /* 32 MiB */
static ssize_t _crypt_wipe_zero(int fd, char *buffer, uint64_t offset, uint64_t size)
{
memset(buffer, 0, size);
return write_lseek_blockwise(fd, buffer, size, offset);
}
/*
* Wipe using Peter Gutmann method described in
* http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
*/
static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn)
{
unsigned int i;
unsigned char write_modes[][3] = {
{"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"},
{"\x49\x24\x92"}, {"\x24\x92\x49"}, {"\x00\x00\x00"},
{"\x11\x11\x11"}, {"\x22\x22\x22"}, {"\x33\x33\x33"},
{"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
{"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"},
{"\xaa\xaa\xaa"}, {"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"},
{"\xdd\xdd\xdd"}, {"\xee\xee\xee"}, {"\xff\xff\xff"},
{"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
{"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
};
for(i = 0; i < buffer_size / 3; ++i) {
memcpy(buffer, write_modes[turn], 3);
buffer += 3;
}
}
static ssize_t _crypt_wipe_disk(int fd, char *buffer, uint64_t offset, uint64_t size)
{
unsigned int i;
ssize_t written;
for(i = 0; i < 39; ++i) {
if (i < 5) crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
else if(i >= 5 && i < 32) wipeSpecial(buffer, size, i - 5);
else if(i >= 32 && i < 38) crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
else if(i >= 38 && i < 39) memset(buffer, 0xFF, size);
written = write_lseek_blockwise(fd, buffer, size, offset);
if (written < 0 || written != (ssize_t)size)
return written;
}
return written;
}
static ssize_t _crypt_wipe_random(int fd, char *buffer, uint64_t offset, uint64_t size)
{
crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
return write_lseek_blockwise(fd, buffer, size, offset);
}
static ssize_t _crypt_wipe_ssd(int fd, char *buffer, uint64_t offset, uint64_t size)
{
// FIXME: for now just rewrite it by random
return _crypt_wipe_random(fd, buffer, offset, size);
}
int crypt_wipe(const char *device,
uint64_t offset,
uint64_t size,
crypt_wipe_type type,
int exclusive)
{
struct stat st;
char *buffer;
int devfd, flags, rotational;
ssize_t written;
if (!size || size % SECTOR_SIZE || (size > MAXIMUM_WIPE_BYTES)) {
log_dbg("Unsuported wipe size for device %s: %ld.",
device, (unsigned long)size);
return -EINVAL;
}
if (stat(device, &st) < 0) {
log_dbg("Device %s not found.", device);
return -EINVAL;
}
if (type == CRYPT_WIPE_DISK) {
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)
type = CRYPT_WIPE_SSD;
}
buffer = malloc(size);
if (!buffer)
return -ENOMEM;
flags = O_WRONLY | O_DIRECT | O_SYNC;
/* use O_EXCL only for block devices */
if (exclusive && S_ISBLK(st.st_mode))
flags |= O_EXCL;
devfd = open(device, flags);
if (devfd == -1) {
free(buffer);
return errno == EBUSY ? -EBUSY : -EINVAL;
}
// FIXME: use fixed block size and loop here
switch (type) {
case CRYPT_WIPE_ZERO:
written = _crypt_wipe_zero(devfd, buffer, offset, size);
break;
case CRYPT_WIPE_DISK:
written = _crypt_wipe_disk(devfd, buffer, offset, size);
case CRYPT_WIPE_SSD:
written = _crypt_wipe_ssd(devfd, buffer, offset, size);
break;
case CRYPT_WIPE_RANDOM:
written = _crypt_wipe_random(devfd, buffer, offset, size);
default:
log_dbg("Unsuported wipe type requested: (%d)", type);
written = -1;
}
close(devfd);
free(buffer);
if (written != (ssize_t)size || written < 0)
return -EIO;
return 0;
}

View File

@@ -33,6 +33,8 @@ struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key)
vk->keylength = keylength;
if (key)
memcpy(&vk->key, key, keylength);
else
memset(&vk->key, 0, keylength);
return vk;
}

View File

@@ -14,7 +14,8 @@ For basic (plain) dm-crypt mappings, there are four operations.
creates a mapping with <name> backed by device <device>.
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify-passphrase,
\-\-key-file, \-\-key-size, \-\-offset, \-\-skip, \-\-size, \-\-readonly]
\-\-key-file, \-\-key-size, \-\-offset, \-\-skip, \-\-size, \-\-readonly, \-\-shared,
\-\-allow-discards]
.PP
\fIremove\fR <name>
.IP
@@ -31,9 +32,16 @@ resizes an active mapping <name>.
If \-\-size (in sectors) is not specified, the size of the underlying block device is used.
.SH LUKS EXTENSION
LUKS, Linux Unified Key Setup, is a standard for hard disk encryption.
It standardizes a partition header, as well as the format of the bulk data.
LUKS can manage multiple passwords, that can be revoked effectively
and that are protected against dictionary attacks with PBKDF2.
It standardizes a partition header as well as the format of the bulk data.
LUKS can manage multiple passwords that can be individually revoked and
effectively scrubbed from persistent media, and that are protected
against dictionary attacks with PBKDF2.
Each password, usually called a
.B key
in this document, is associated with a slot, of which there are typically 8.
Key operations that do not specify a slot affect the first slot
matching the supplied key.
These are valid LUKS actions:
@@ -51,7 +59,8 @@ opens the LUKS partition <device> and sets up a mapping <name> after
successful verification of the supplied key material
(either via key file by \-\-key-file, or via prompting).
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-readonly].
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-readonly, \-\-allow-discards,
\-\-header, \-\-key-slot].
.PP
\fIluksClose\fR <name>
.IP
@@ -66,13 +75,15 @@ After that operation you have to use \fIluksResume\fR to reinstate
encryption key (and resume device) or \fIluksClose\fR to remove mapped device.
\fBWARNING:\fR never try to suspend device where is the cryptsetup binary itself.
\fB<options>\fR can be [\-\-header].
.PP
\fIluksResume\fR <name>
.IP
Resumes suspended device and reinstates encryption key. You will need provide passphrase
identical to \fIluksOpen\fR command (using prompting or key file).
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size]
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-header]
.PP
\fIluksAddKey\fR <device> [<new key file>]
.IP
@@ -84,7 +95,7 @@ The key file with the new material is supplied as a positional argument.
.PP
\fIluksRemoveKey\fR <device> [<key file>]
.IP
remove supplied key or key file from LUKS device
remove supplied key or key file from LUKS device in the manner of \fIluksKillSlot\fR.
.PP
\fIluksChangeKey\fR <device> [<new key file>]
.IP
@@ -186,8 +197,8 @@ and not used it in IV sector calculations, you have to explicitly use
Use \fB\-\-hash\fR to override hash function for password hashing
(otherwise it is detected according to key size).
\fB<options>\fR can be [\-\-key-file, \-\-key-size, \-\-offset, \-\-skip,
\-\-hash, \-\-readonly].
\fB<options>\fR can be [\-\-key-file, \-\-key-size, \-\-offset, \-\-skip,
\-\-hash, \-\-readonly, \-\-allow-discards].
.PP
\fIloopaesClose\fR <name>
.IP
@@ -284,7 +295,7 @@ to show default RNG.
.B "\-\-key-slot, \-S"
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 and \fIluksAddKey\fR.
This option can be used for \fIluksFormat\fR, \fIluksOpen\fR and \fIluksAddKey\fR.
.TP
.B "\-\-key-size, \-s"
set key size in bits.
@@ -319,6 +330,12 @@ This option is only relevant for \fIcreate\fR and \fIloopaesOpen\fR action.
.B "\-\-readonly"
set up a read-only mapping.
.TP
.B "\-\-shared"
create another non-overlapping mapping to one common ciphertext device,
e.g. to create hidden device inside another encrypted device.
This option is only relevant for \fIcreate\fR action.
Use \-\-offset, \-\-size and \-\-skip to specify mapped area.
.TP
.B "\-\-iter-time, \-i"
The number of milliseconds to spend with PBKDF2 password processing.
This option is only relevant to the LUKS operations as
@@ -347,6 +364,9 @@ If not specified, cryptsetup tries to use topology info provided by kernel
for underlying device to get optimal alignment.
If not available (or calculated value is multiple of default) data is by
default aligned to 1 MiB boundary (2048 512-byte sectors).
For detached LUKS header it specifies offset on data device.
See also \-\-header option.
.TP
.B "\-\-uuid=\fIUUID\fR"
Use provided \fIUUID\fR in \fIluksFormat\fR command instead of generating
@@ -355,6 +375,35 @@ new one or change existing UUID in \fIluksUUID\fR command.
The UUID must be provided in standard UUID format
(e.g. 12345678-1234-1234-1234-123456789abc).
.TP
.B "\-\-allow-discards\fR"
Allow using of discards (TRIM) requests for device.
This option is only relevant for \fIcreate\fR, \fIluksOpen\fR or \fIloopaesOpen\fR.
\fBWARNING:\fR Assess the specific security risks carefully before enabling this
option. For example, allowing discards on encrypted devices may lead to the leak
of information about the ciphertext device (filesystem type, used space etc.)
if the discarded blocks can be located easily on the device later.
Kernel version 3.1 or more recent is required.
For older versions is the option ignored.
.TP
.B "\-\-header\fR"
Set detached (separated) metadata device or file with LUKS header.
This options allows separation of ciphertext device and on-disk metadata header.
This option is only relevant for LUKS devices and can be used in \fIluksFormat\fR,
\fIluksOpen\fR, \fIluksSuspend\fR, \fIluksResume\fR and \fIresize\fR commands.
If used with \fIluksFormat\fR the \-\-align-payload option is taken
as absolute sector alignment on ciphertext device and can be zero.
For other commands with separated metadata device you have to always specify
path to metadata device (not to the ciphertext device).
\fBWARNING:\fR There is no possible check that specified ciphertext device
is correct if on-disk header is detached. Use with care.
.TP
.B "\-\-version"
Show the version.
.SH RETURN CODES

45
misc/luks-header-from-active Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
# Try to get LUKS info and master key from active mapping and prepare parameters for cryptsetup.
#
# Copyright (C) 2010,2011 Milan Broz <asi@ucw.cz>
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
fail() { echo -e $1 ; exit 1 ; }
field() { echo $(dmsetup table --target crypt --showkeys $DEVICE | sed 's/.*: //' | cut -d' ' -f$1) ; }
field_cryptsetup() { echo $(cryptsetup status $DEVICE | grep $1 | sed "s/.*$1:\s*//;s/\ .*//") ; }
which xxd >/dev/null || fail "You need xxd (part of vim package) installed to convert key."
[ -z "$2" ] && fail "Recover LUKS header from active mapping, use:\n $0 crypt_mapped_device mk_file_name"
DEVICE=$1
MK_FILE=$2
[ -z "$(field 4)" ] && fail "Mapping $1 not active or it is not crypt target."
# FIXME:
# - add UUID
# - check for CRYPT-LUKS1-* DM-UUID
CIPHER=$(field_cryptsetup cipher)
OFFSET=$(field_cryptsetup offset)
REAL_DEVICE=$(field_cryptsetup device)
KEY_SIZE=$(field_cryptsetup keysize)
KEY=$(field 5)
[ -z "$CIPHER" -o -z "$OFFSET" -o "$OFFSET" -le 383 -o -z "$KEY" ] && fail "Incompatible device, sorry."
echo "Generating master key to file $MK_FILE."
echo -E -n $KEY| xxd -r -p >$MK_FILE
echo "You can now try to reformat LUKS device using:"
echo " cryptsetup luksFormat -c $CIPHER -s $KEY_SIZE --align-payload=$OFFSET --master-key-file=$MK_FILE $REAL_DEVICE"

View File

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

645
po/cs.po

File diff suppressed because it is too large Load Diff

1027
po/de.po

File diff suppressed because it is too large Load Diff

1105
po/fi.po Normal file

File diff suppressed because it is too large Load Diff

626
po/fr.po

File diff suppressed because it is too large Load Diff

428
po/it.po

File diff suppressed because it is too large Load Diff

641
po/nl.po

File diff suppressed because it is too large Load Diff

618
po/pl.po

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <limits.h>
#include <libcryptsetup.h>
#include <popt.h>
@@ -43,6 +44,7 @@ static const char *opt_key_file = NULL;
static const char *opt_master_key_file = NULL;
static const char *opt_header_backup_file = NULL;
static const char *opt_uuid = NULL;
static const char *opt_header_device = NULL;
static int opt_key_size = 0;
static long opt_keyfile_size = 0;
static long opt_new_keyfile_size = 0;
@@ -61,6 +63,8 @@ static int opt_align_payload = 0;
static int opt_random = 0;
static int opt_urandom = 0;
static int opt_dump_master_key = 0;
static int opt_shared = 0;
static int opt_allow_discards = 0;
static const char **action_argv;
static int action_argc;
@@ -187,6 +191,13 @@ static void _log(int level, const char *msg, void *usrptr __attribute__((unused)
}
}
static void _quiet_log(int level, const char *msg, void *usrptr)
{
if (!opt_verbose && (level == CRYPT_LOG_ERROR || level == CRYPT_LOG_NORMAL))
level = CRYPT_LOG_VERBOSE;
_log(level, msg, usrptr);
}
static void show_status(int errcode)
{
char error[256], *error_;
@@ -224,10 +235,12 @@ static int action_create(int arg __attribute__((unused)))
.hash = opt_hash ?: DEFAULT_PLAIN_HASH,
.skip = opt_skip,
.offset = opt_offset,
.size = opt_size,
};
char *password = NULL;
size_t passwordLen;
size_t key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
uint32_t activate_flags = 0;
int r;
if (params.hash && !strcmp(params.hash, "plain"))
@@ -262,11 +275,20 @@ static int action_create(int arg __attribute__((unused)))
if (r < 0)
goto out;
if (opt_readonly)
activate_flags |= CRYPT_ACTIVATE_READONLY;
if (opt_shared)
activate_flags |= CRYPT_ACTIVATE_SHARED;
if (opt_allow_discards)
activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (opt_key_file)
/* With hashing, read the whole keyfile */
r = crypt_activate_by_keyfile(cd, action_argv[0],
CRYPT_ANY_SLOT, opt_key_file, params.hash ? 0 : key_size,
opt_readonly ? CRYPT_ACTIVATE_READONLY : 0);
activate_flags);
else {
r = crypt_get_key(_("Enter passphrase: "),
&password, &passwordLen, opt_keyfile_size,
@@ -277,17 +299,8 @@ static int action_create(int arg __attribute__((unused)))
goto out;
r = crypt_activate_by_passphrase(cd, action_argv[0],
CRYPT_ANY_SLOT, password, passwordLen,
opt_readonly ? CRYPT_ACTIVATE_READONLY : 0);
CRYPT_ANY_SLOT, password, passwordLen, activate_flags);
}
/* FIXME: workaround, new api missing format parameter for size.
* Properly fix it after bumping library version,
* add start_offset and size into "PLAIN" format specifiers.
*/
if (r >= 0 && opt_size)
r = crypt_resize(cd, action_argv[0], opt_size);
out:
crypt_free(cd);
crypt_safe_free(password);
@@ -304,6 +317,7 @@ static int action_loopaesOpen(int arg __attribute__((unused)))
.skip = opt_skip_valid ? opt_skip : opt_offset,
};
unsigned int key_size = (opt_key_size ?: DEFAULT_LOOPAES_KEYBITS) / 8;
uint32_t activate_flags = 0;
int r;
if (!opt_key_file) {
@@ -311,6 +325,12 @@ static int action_loopaesOpen(int arg __attribute__((unused)))
return -EINVAL;
}
if (opt_readonly)
activate_flags |= CRYPT_ACTIVATE_READONLY;
if (opt_allow_discards)
activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if ((r = crypt_init(&cd, action_argv[0])))
goto out;
@@ -319,9 +339,8 @@ static int action_loopaesOpen(int arg __attribute__((unused)))
if (r < 0)
goto out;
r = crypt_activate_by_keyfile(cd, action_argv[1],
CRYPT_ANY_SLOT, opt_key_file, opt_keyfile_size,
opt_readonly ? CRYPT_ACTIVATE_READONLY : 0);
r = crypt_activate_by_keyfile(cd, action_argv[1], CRYPT_ANY_SLOT,
opt_key_file, opt_keyfile_size, activate_flags);
out:
crypt_free(cd);
@@ -346,7 +365,7 @@ static int action_resize(int arg __attribute__((unused)))
struct crypt_device *cd = NULL;
int r;
r = crypt_init_by_name(&cd, action_argv[0]);
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
if (r == 0)
r = crypt_resize(cd, action_argv[0], opt_size);
@@ -366,10 +385,11 @@ static int action_status(int arg __attribute__((unused)))
ci = crypt_status(NULL, action_argv[0]);
switch (ci) {
case CRYPT_INVALID:
r = -ENODEV;
r = -EINVAL;
break;
case CRYPT_INACTIVE:
log_std("%s/%s is inactive.\n", crypt_get_dir(), action_argv[0]);
r = -ENODEV;
break;
case CRYPT_ACTIVE:
case CRYPT_BUSY:
@@ -400,6 +420,8 @@ static int action_status(int arg __attribute__((unused)))
log_std(" skipped: %" PRIu64 " sectors\n", cad.iv_offset);
log_std(" mode: %s\n", cad.flags & CRYPT_ACTIVATE_READONLY ?
"readonly" : "read/write");
if (cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
log_std(" flags: discards\n");
}
out:
crypt_free(cd);
@@ -435,6 +457,7 @@ fail:
static int action_luksFormat(int arg __attribute__((unused)))
{
int r = -EINVAL, keysize;
const char *header_device;
char *msg = NULL, *key = NULL, cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
char *password = NULL;
size_t passwordLen;
@@ -442,9 +465,13 @@ static int action_luksFormat(int arg __attribute__((unused)))
struct crypt_params_luks1 params = {
.hash = opt_hash ?: DEFAULT_LUKS1_HASH,
.data_alignment = opt_align_payload,
.data_device = opt_header_device ? action_argv[0] : NULL,
};
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]) == -1) {
header_device = opt_header_device ?: action_argv[0];
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."),
header_device) == -1) {
log_err(_("memory allocation error in action_luksFormat"));
r = -ENOMEM;
goto out;
@@ -457,12 +484,15 @@ static int action_luksFormat(int arg __attribute__((unused)))
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1),
cipher, NULL, cipher_mode);
if (r < 0) {
log_err("No known cipher specification pattern detected.\n");
log_err(_("No known cipher specification pattern detected.\n"));
goto out;
}
if ((r = crypt_init(&cd, action_argv[0])))
if ((r = crypt_init(&cd, header_device))) {
if (opt_header_device)
log_err(_("Cannot use %s as on-disk header.\n"), header_device);
goto out;
}
keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8;
@@ -507,31 +537,54 @@ out:
static int action_luksOpen(int arg __attribute__((unused)))
{
struct crypt_device *cd = NULL;
const char *data_device, *header_device;
uint32_t flags = 0;
int r;
if ((r = crypt_init(&cd, action_argv[0])))
if (opt_header_device) {
header_device = opt_header_device;
data_device = action_argv[0];
} else {
header_device = action_argv[0];
data_device = NULL;
}
if ((r = crypt_init(&cd, header_device)))
goto out;
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
goto out;
if (data_device &&
(r = crypt_set_data_device(cd, data_device)))
goto out;
if (!data_device && (crypt_get_data_offset(cd) < 8)) {
log_err(_("Reduced data offset is allowed only for detached LUKS header.\n"));
r = -EINVAL;
goto out;
}
crypt_set_timeout(cd, opt_timeout);
crypt_set_password_retry(cd, opt_tries);
if (opt_iteration_time)
crypt_set_iterarion_time(cd, opt_iteration_time);
if (opt_readonly)
flags |= CRYPT_ACTIVATE_READONLY;
if (opt_allow_discards)
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (opt_key_file) {
crypt_set_password_retry(cd, 1);
r = crypt_activate_by_keyfile(cd, action_argv[1],
CRYPT_ANY_SLOT, opt_key_file, opt_keyfile_size,
opt_key_slot, opt_key_file, opt_keyfile_size,
flags);
} else
r = crypt_activate_by_passphrase(cd, action_argv[1],
CRYPT_ANY_SLOT, NULL, 0, flags);
opt_key_slot, NULL, 0, flags);
out:
crypt_free(cd);
return r;
@@ -603,6 +656,7 @@ static int action_luksKillSlot(int arg __attribute__((unused)))
case CRYPT_SLOT_INACTIVE:
log_err(_("Key %d not active. Can't wipe.\n"), opt_key_slot);
case CRYPT_SLOT_INVALID:
r = -EINVAL;
goto out;
}
@@ -816,6 +870,7 @@ static int action_isLuks(int arg __attribute__((unused)))
if ((r = crypt_init(&cd, action_argv[0])))
goto out;
crypt_set_log_callback(cd, _quiet_log, NULL);
r = crypt_load(cd, CRYPT_LUKS1, NULL);
out:
crypt_free(cd);
@@ -925,7 +980,7 @@ static int action_luksSuspend(int arg __attribute__((unused)))
struct crypt_device *cd = NULL;
int r;
r = crypt_init_by_name(&cd, action_argv[0]);
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
if (!r)
r = crypt_suspend(cd, action_argv[0]);
@@ -938,11 +993,11 @@ static int action_luksResume(int arg __attribute__((unused)))
struct crypt_device *cd = NULL;
int r;
if ((r = crypt_init_by_name(&cd, action_argv[0])))
if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device)))
goto out;
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
goto out;
crypt_set_timeout(cd, opt_timeout);
crypt_set_password_retry(cd, opt_tries);
if (opt_key_file)
r = crypt_resume_by_keyfile(cd, action_argv[0], CRYPT_ANY_SLOT,
@@ -1003,6 +1058,7 @@ static __attribute__ ((noreturn)) void usage(poptContext popt_context,
poptPrintUsage(popt_context, stderr, 0);
if (error)
log_err("%s: %s\n", more, error);
poptFreeContext(popt_context);
exit(exitcode);
}
@@ -1136,7 +1192,10 @@ int main(int argc, const char **argv)
{ "header-backup-file",'\0', POPT_ARG_STRING, &opt_header_backup_file, 0, N_("File with LUKS header and keyslots backup."), NULL },
{ "use-random", '\0', POPT_ARG_NONE, &opt_random, 0, N_("Use /dev/random for generating volume key."), NULL },
{ "use-urandom", '\0', POPT_ARG_NONE, &opt_urandom, 0, N_("Use /dev/urandom for generating volume key."), NULL },
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
{ "shared", '\0', POPT_ARG_NONE, &opt_shared, 0, N_("Share device with another non-overlapping crypt segment."), NULL },
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
{ "allow-discards", '\0', POPT_ARG_NONE, &opt_allow_discards, 0, N_("Allow discards (aka TRIM) requests for device."), NULL },
{ "header", '\0', POPT_ARG_STRING, &opt_header_device, 0, N_("Device or file with separated LUKS header."), NULL },
POPT_TABLEEND
};
poptContext popt_context;
@@ -1159,8 +1218,11 @@ int main(int argc, const char **argv)
unsigned long long ull_value;
char *endp;
errno = 0;
ull_value = strtoull(popt_tmp, &endp, 0);
if (*endp || !*popt_tmp)
if (*endp || !*popt_tmp ||
(errno == ERANGE && ull_value == ULLONG_MAX) ||
(errno != 0 && ull_value == 0))
r = POPT_ERROR_BADNUMBER;
switch(r) {
@@ -1185,6 +1247,7 @@ int main(int argc, const char **argv)
poptBadOption(popt_context, POPT_BADOPTION_NOALIAS));
if (opt_version_mode) {
log_std("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
poptFreeContext(popt_context);
exit(EXIT_SUCCESS);
}
@@ -1217,6 +1280,21 @@ int main(int argc, const char **argv)
/* FIXME: rewrite this from scratch */
if (opt_shared && strcmp(aname, "create")) {
usage(popt_context, EXIT_FAILURE,
_("Option --shared is allowed only for create operation.\n"),
poptGetInvocationName(popt_context));
}
if (opt_allow_discards &&
strcmp(aname, "luksOpen") &&
strcmp(aname, "create") &&
strcmp(aname, "loopaesOpen")) {
usage(popt_context, EXIT_FAILURE,
_("Option --allow-discards is allowed only for luksOpen, loopaesOpen and create operation.\n"),
poptGetInvocationName(popt_context));
}
if (opt_key_size &&
strcmp(aname, "luksFormat") &&
strcmp(aname, "create") &&
@@ -1235,7 +1313,7 @@ int main(int argc, const char **argv)
if (!strcmp(aname, "luksKillSlot") && action_argc > 1)
opt_key_slot = atoi(action_argv[1]);
if (opt_key_slot != CRYPT_ANY_SLOT &&
(opt_key_slot < 0 || opt_key_slot > crypt_keyslot_max(CRYPT_LUKS1)))
(opt_key_slot < 0 || opt_key_slot >= crypt_keyslot_max(CRYPT_LUKS1)))
usage(popt_context, EXIT_FAILURE, _("Key slot is invalid."),
poptGetInvocationName(popt_context));
@@ -1281,5 +1359,7 @@ int main(int argc, const char **argv)
_dbg_version_and_cmd(argc, argv);
}
return run_action(action);
r = run_action(action);
poptFreeContext(popt_context);
return r;
}

View File

@@ -1,7 +1,14 @@
TESTS = api-test compat-test loopaes-test align-test mode-test password-hash-test
TESTS = api-test compat-test loopaes-test align-test discards-test mode-test password-hash-test
EXTRA_DIST = compatimage.img.bz2 \
compat-test loopaes-test align-test mode-test password-hash-test
EXTRA_DIST = compatimage.img.bz2 valid_header_file.bz2 \
evil_hdr-payload_overwrite.bz2 \
evil_hdr-stripes_payload_dmg.bz2 \
evil_hdr-luks_hdr_damage.bz2 \
evil_hdr-small_luks_device.bz2 \
compat-test loopaes-test align-test discards-test mode-test password-hash-test \
cryptsetup-valg-supps valg.sh valg-api.sh
CLEANFILES = cryptsetup-tst* valglog*
differ_SOURCES = differ.c
differ_CFLAGS = -Wall -O2
@@ -9,9 +16,15 @@ differ_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/
api_test_CFLAGS = -g -Wall -O0 -I$(top_srcdir)/lib/ -I$(top_srcdir)/lib/luks1
check_PROGRAMS = api-test differ
compatimage.img:
@bzip2 -k -d compatimage.img.bz2
valgrind-check: api-test differ
@VALG=1 ./compat-test
@INFOSTRING="api-test-000" ./valg-api.sh ./api-test
.PHONY: valgrind-check

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,12 @@ CRYPTSETUP=../src/cryptsetup
DEV_NAME=dummy
DEV_NAME2=dummy2
DEV_NAME3=dummy3
ORIG_IMG=luks-test-orig
IMG=luks-test
KEY1=key1
KEY2=key2
KEY5=key5
LUKS_HEADER="S0-5 S6-7 S8-39 S40-71 S72-103 S104-107 S108-111 R112-131 R132-163 S164-167 S168-207 A0-591"
KEY_SLOT0="S208-211 S212-215 R216-247 A248-251 A251-255"
@@ -18,20 +20,26 @@ KEY_SLOT1="S256-259 S260-263 R264-295 A296-299 A300-303"
KEY_MATERIAL1="R69632-133632"
KEY_MATERIAL1_EXT="S69632-133632"
KEY_SLOT5="S448-451 S452-455 R456-487 A488-491 A492-495"
KEY_MATERIAL5="R331776-395264"
KEY_MATERIAL5_EXT="S331776-395264"
TEST_UUID="12345678-1234-1234-1234-123456789abc"
LOOPDEV=$(losetup -f 2>/dev/null)
function remove_mapping()
{
[ -b /dev/mapper/$DEV_NAME3 ] && dmsetup remove $DEV_NAME3
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
losetup -d $LOOPDEV >/dev/null 2>&1
rm -f $ORIG_IMG $IMG $KEY1 $KEY2 >/dev/null 2>&1
rm -f $ORIG_IMG $IMG $KEY1 $KEY2 $KEY5 >/dev/null 2>&1
}
function fail()
{
[ -n "$1" ] && echo "$1"
remove_mapping
echo "FAILED"
exit 2
@@ -75,6 +83,10 @@ function prepare()
dd if=/dev/urandom of=$KEY2 count=1 bs=16 >/dev/null 2>&1
fi
if [ ! -e $KEY5 ]; then
dd if=/dev/urandom of=$KEY5 count=1 bs=16 >/dev/null 2>&1
fi
cp $IMG $ORIG_IMG
[ -n "$1" ] && echo "CASE: $1"
}
@@ -92,14 +104,35 @@ function check_exists()
check $1
}
function valgrind_setup()
{
which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind"
CRYPTSETUP_BIN=$($CRYPTSETUP --lt-debug --version 2>&1 \
| grep "newargv\[0\]" \
| sed 's/.*newargv\[0\]\:[[:space:]]\+\(.*\)$/\1/g')
[ -z "$CRYPTSETUP_BIN" ] && fail "Unable to get location of cryptsetup executable."
export LD_LIBRARY_PATH="../lib/.libs:$LD_LIBRARY_PATH"
}
function valgrind_run()
{
INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_BIN} "$@"
}
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
[ -z "$LOOPDEV" ] && skip "Cannot find free loop device, test skipped."
[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run
# LUKS tests
prepare "[1] open - compat image - acceptance check" new
echo "compatkey" | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail
check_exists
ORG_SHA1=$(sha1sum -b /dev/mapper/$DEV_NAME | cut -f 1 -d' ')
[ "$ORG_SHA1" = 676062b66ebf36669dab705442ea0762dfc091b0 ] || fail
prepare "[2] open - compat image - denial check" new
echo "wrongkey" | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME 2>/dev/null && fail
@@ -127,6 +160,8 @@ echo "key1" | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail
# Unsuccessful Key Delete - nothing may change
prepare "[7] unsuccessful delete"
echo "invalid" | $CRYPTSETUP luksKillSlot $LOOPDEV 1 2>/dev/null && fail
$CRYPTSETUP -q luksKillSlot $LOOPDEV 8 2>/dev/null && fail
$CRYPTSETUP -q luksKillSlot $LOOPDEV 7 2>/dev/null && fail
check
# Delete Key Test
@@ -255,6 +290,7 @@ $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail
$CRYPTSETUP -q resize $DEV_NAME || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "19997 sectors" || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
$CRYPTSETUP -q status $DEV_NAME >/dev/null && fail
echo "key0" | $CRYPTSETUP create $DEV_NAME --hash sha1 $LOOPDEV || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
echo "key0" | $CRYPTSETUP -q create $DEV_NAME --hash sha1 $LOOPDEV || fail
@@ -354,5 +390,61 @@ echo "key0" | $CRYPTSETUP luksRemoveKey $LOOPDEV -l 2 2>/dev/null && fail
echo "key01" | $CRYPTSETUP luksRemoveKey $LOOPDEV -d 4 2>/dev/null && fail
echo -e "key0\n" | $CRYPTSETUP luksRemoveKey $LOOPDEV -d- -l 4 || fail
prepare "[25] Create non-overlapping segments" wipe
echo "key0" | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha1 --offset 0 --size 256 || fail
echo "key0" | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha1 --offset 512 --size 256 2>/dev/null && fail
echo "key0" | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha1 --offset 512 --size 256 --shared || fail
echo "key0" | $CRYPTSETUP create $DEV_NAME3 $LOOPDEV --hash sha1 --offset 255 --size 256 --shared 2>/dev/null && fail
echo "key0" | $CRYPTSETUP create $DEV_NAME3 $LOOPDEV --hash sha1 --offset 256 --size 257 --shared 2>/dev/null && fail
echo "key0" | $CRYPTSETUP create $DEV_NAME3 $LOOPDEV --hash sha1 --offset 256 --size 1024 --shared 2>/dev/null && fail
echo "key0" | $CRYPTSETUP create $DEV_NAME3 $LOOPDEV --hash sha1 --offset 256 --size 256 --shared || fail
$CRYPTSETUP -q remove $DEV_NAME3 || fail
$CRYPTSETUP -q remove $DEV_NAME2 || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
prepare "[26] Suspend/Resume" wipe
# only LUKS is supported
echo "key0" | $CRYPTSETUP create $DEV_NAME --hash sha1 $LOOPDEV || fail
$CRYPTSETUP luksSuspend $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP -q remove $DEV_NAME || fail
$CRYPTSETUP luksSuspend $DEV_NAME 2>/dev/null && fail
# LUKS
echo "key0" | $CRYPTSETUP -q luksFormat $LOOPDEV || fail
echo "key0" | $CRYPTSETUP -q luksOpen $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP luksSuspend $DEV_NAME || fail
$CRYPTSETUP -q resize $DEV_NAME 2>/dev/null && fail
echo "xxx" | $CRYPTSETUP luksResume $DEV_NAME -T 1 2>/dev/null && fail
echo "key0" | $CRYPTSETUP luksResume $DEV_NAME || fail
$CRYPTSETUP -q luksClose $DEV_NAME || fail
prepare "[27] luksOpen with specified key slot number" wipe
# first, let's try passphrase option
echo "key5" | $CRYPTSETUP luksFormat -S 5 $LOOPDEV || fail
check $LUKS_HEADER $KEY_SLOT5 $KEY_MATERIAL5
echo "key5" | $CRYPTSETUP luksOpen -S 4 $LOOPDEV $DEV_NAME && fail
[ -b /dev/mapper/$DEV_NAME ] && fail
echo "key5" | $CRYPTSETUP luksOpen -S 5 $LOOPDEV $DEV_NAME || fail
check_exists
$CRYPTSETUP luksClose $DEV_NAME || fail
echo -e "key5\nkey0" | $CRYPTSETUP luksAddKey -S 0 $LOOPDEV || fail
check $LUKS_HEADER $KEY_SLOT0 $KEY_MATERIAL0
echo "key5" | $CRYPTSETUP luksOpen -S 0 $LOOPDEV $DEV_NAME && fail
[ -b /dev/mapper/$DEV_NAME ] && fail
echo "key0" | $CRYPTSETUP luksOpen -S 5 $LOOPDEV $DEV_NAME && fail
[ -b /dev/mapper/$DEV_NAME ] && fail
# second, try it with keyfiles
$CRYPTSETUP luksFormat -q -S 5 -d $KEY5 $LOOPDEV || fail
check $LUKS_HEADER $KEY_SLOT5 $KEY_MATERIAL5
$CRYPTSETUP luksAddKey -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail
check $LUKS_HEADER $KEY_SLOT1 $KEY_MATERIAL1
$CRYPTSETUP luksOpen -S 5 -d $KEY5 $LOOPDEV $DEV_NAME || fail
check_exists
$CRYPTSETUP luksClose $DEV_NAME || fail
$CRYPTSETUP luksOpen -S 1 -d $KEY5 $LOOPDEV $DEV_NAME && fail
[ -b /dev/mapper/$DEV_NAME ] && fail
$CRYPTSETUP luksOpen -S 5 -d $KEY1 $LOOPDEV $DEV_NAME && fail
[ -b /dev/mapper/$DEV_NAME ] && fail
remove_mapping
exit 0

View File

@@ -0,0 +1,36 @@
# Supresion file for valgrind
# known problem in libgcrypt
{
leak_in_libgcrypt_00
Memcheck:Leak
fun:malloc
obj:/lib64/libgcrypt.so*
...
obj:/lib64/libgcrypt.so*
fun:crypt_backend_init
fun:init_crypto
...
}
# following leaks/errors are addressed to libpopt...
{
popt_read_error
Memcheck:Addr4
obj:/lib*/libpopt.so*
fun:poptGetNextOpt
fun:main
}
{
popt_leak_poptGetNextOpt_00
Memcheck:Leak
fun:realloc
fun:poptGetNextOpt
fun:main
}
{
popt_leak_poptGetNextOpt_01
Memcheck:Leak
fun:malloc
fun:poptGetNextOpt
fun:main
}

81
tests/discards-test Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/bash
CRYPTSETUP="../src/cryptsetup"
DEV_NAME="discard-t3st"
DEV=""
cleanup() {
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
udevadm settle >/dev/null 2>&1
rmmod scsi_debug 2>/dev/null
sleep 2
}
fail()
{
echo "FAILED"
cleanup
exit 100
}
add_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
DEV=$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV="/dev/$DEV"
[ -b $DEV ] || fail "Cannot find $DEV."
}
function check_version()
{
VER_STR=$(dmsetup targets | grep crypt | cut -f 2 -dv)
VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
# option supported in 1.11
test $VER_MAJ -gt 1 && return 0
test $VER_MIN -ge 11 && return 0
return 1
}
if [ $(id -u) != 0 ]; then
echo "WARNING: You must be root to run this test, test skipped."
exit 0
fi
modprobe --dry-run scsi_debug || exit 0
modprobe dm-crypt >/dev/null 2>&1
if ! check_version ; then
echo "Probably old kernel, test skipped."
exit 0
fi
add_device dev_size_mb=16 sector_size=512 num_tgts=1 lbpu=1
# FIXME test hash of device (unmap -> zero)
# for now just check that flag is enabled
echo "[1] Allowing discards for LUKS device"
echo xxx | $CRYPTSETUP luksFormat $DEV -q -i1 || fail
echo xxx | $CRYPTSETUP luksOpen $DEV $DEV_NAME --allow-discards || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
$CRYPTSETUP resize $DEV_NAME --size 100 || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
dmsetup table $DEV_NAME | grep allow_discards >/dev/null || fail
$CRYPTSETUP luksClose $DEV_NAME || fail
echo "[2] Allowing discards for plain device"
echo xxx | $CRYPTSETUP create $DEV_NAME $DEV --hash sha1 --allow-discards || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
$CRYPTSETUP resize $DEV_NAME --size 100 || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
dmsetup table $DEV_NAME | grep allow_discards >/dev/null || fail
$CRYPTSETUP remove $DEV_NAME || fail
cleanup

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -51,7 +51,7 @@ add_device() {
dmcrypt_check() # device outstring
{
X=$(dmsetup table $1 2>/dev/null | cut -d' ' -f 4)
X=$(dmsetup table $1 2>/dev/null | sed 's/.*: //' | cut -d' ' -f 4)
if [ $X = $2 ] ; then
echo -n "[table OK]"
else

View File

@@ -63,7 +63,7 @@ crypt_key() # hash keysize pwd/file name outkey [limit]
fi
fi
VKEY=$(dmsetup table $DEV2 --showkeys 2>/dev/null | cut -d' ' -f 5)
VKEY=$(dmsetup table $DEV2 --showkeys 2>/dev/null | sed 's/.*: //' | cut -d' ' -f 5)
if [ "$VKEY" != "$5" ] ; then
echo " [FAILED]"
echo "expected: $5"

11
tests/valg-api.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
SUP="--suppressions=./cryptsetup-valg-supps"
CHILD="--trace-children=no --child-silent-after-fork=yes"
MALLOC="--malloc-fill=aa"
FREE="--free-fill=21"
STACK="--max-stackframe=300000"
EXTRAS="--read-var-info=yes --show-reachable=yes"
LOGFILE="--log-file=./valglog.$(date +%s)_${INFOSTRING}"
LEAKCHECK="--leak-check=full --track-origins=yes"
exec valgrind $SUP $GETSUP $CHILD $MALLOC $FREE $STACK $EXTRAS $LOGFILE $LEAKCHECK "$@"

11
tests/valg.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
SUP="--suppressions=./cryptsetup-valg-supps"
CHILD="--trace-children=yes --child-silent-after-fork=yes"
MALLOC="--malloc-fill=aa"
FREE="--free-fill=21"
STACK="--max-stackframe=300000"
EXTRAS="--read-var-info=yes --show-reachable=yes"
LOGFILE="--log-file=./valglog.$(date +%s)_${INFOSTRING}"
LEAKCHECK="--leak-check=full --track-origins=yes"
exec valgrind $SUP $GETSUP $CHILD $MALLOC $FREE $STACK $EXTRAS $LOGFILE $LEAKCHECK "$@"

BIN
tests/valid_header_file.bz2 Normal file

Binary file not shown.