mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 00:10:04 +01:00
Compare commits
322 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54c7a2b0aa | ||
|
|
9cabc9bf05 | ||
|
|
dfd46df8a5 | ||
|
|
25cd4f3a1d | ||
|
|
d5b594dd12 | ||
|
|
803686ea4b | ||
|
|
3add769b51 | ||
|
|
d5a72cd65a | ||
|
|
d63163e46c | ||
|
|
62d690492c | ||
|
|
54d81a6258 | ||
|
|
56679a6e4a | ||
|
|
e0788d9d61 | ||
|
|
833e066853 | ||
|
|
02f860140d | ||
|
|
027cebade3 | ||
|
|
bb8dbfdf5b | ||
|
|
8e380183f8 | ||
|
|
4f89028c67 | ||
|
|
6b4c33d3a5 | ||
|
|
7a2e6990ca | ||
|
|
98ba2f2333 | ||
|
|
4e4d933d7b | ||
|
|
91c739958c | ||
|
|
1a6e1ae918 | ||
|
|
aedf39a9ca | ||
|
|
a274cd3a74 | ||
|
|
6be21469fb | ||
|
|
e0d3ff8aeb | ||
|
|
0614ab6b07 | ||
|
|
49e55c0f42 | ||
|
|
be4edbb460 | ||
|
|
4d30237f7a | ||
|
|
a3c0f6784b | ||
|
|
6d4c2db3b1 | ||
|
|
1436f2a0a0 | ||
|
|
e6a46bf827 | ||
|
|
9563aa33c8 | ||
|
|
6225c901fe | ||
|
|
cad0cbf0c8 | ||
|
|
1fc441f091 | ||
|
|
22849ccd11 | ||
|
|
a809224ec7 | ||
|
|
ae23ecb9b2 | ||
|
|
0db77f3ace | ||
|
|
779c80c581 | ||
|
|
00ced59c1a | ||
|
|
20595f4b14 | ||
|
|
2e97d8f8e8 | ||
|
|
7effba0f71 | ||
|
|
2ad69eba90 | ||
|
|
4d218e4cbd | ||
|
|
a0346a09ce | ||
|
|
f6e85be3ed | ||
|
|
04e921846f | ||
|
|
e37f3728d7 | ||
|
|
2062ece2ab | ||
|
|
a5fa6f1015 | ||
|
|
9bdd5bf4fe | ||
|
|
110ce5607e | ||
|
|
78f938b0e9 | ||
|
|
ad2f50316f | ||
|
|
cf534f3759 | ||
|
|
75c105f853 | ||
|
|
680eb76e45 | ||
|
|
e364041b40 | ||
|
|
de37457a75 | ||
|
|
057db3b3b3 | ||
|
|
461011ad2a | ||
|
|
aa7346bb36 | ||
|
|
5206543902 | ||
|
|
7f93a49cc3 | ||
|
|
bec86e3d5a | ||
|
|
3ba95a822f | ||
|
|
486ec44c3e | ||
|
|
8dc4877697 | ||
|
|
7415c5858d | ||
|
|
8e5411f468 | ||
|
|
3bf40bb8dd | ||
|
|
79956a4d47 | ||
|
|
2d755335de | ||
|
|
d7762c09dd | ||
|
|
957201e758 | ||
|
|
004dc271a4 | ||
|
|
a9b24ccc82 | ||
|
|
c57071a43a | ||
|
|
df27f04f61 | ||
|
|
f3e398afc5 | ||
|
|
65877efe8b | ||
|
|
96acd87f0b | ||
|
|
fcb35d4e73 | ||
|
|
0d47e5eb76 | ||
|
|
f30bbbffe7 | ||
|
|
6b88461553 | ||
|
|
700b558fb6 | ||
|
|
58b5be440f | ||
|
|
626801f7df | ||
|
|
77a345d4cb | ||
|
|
18901fd501 | ||
|
|
5b86cb5cc2 | ||
|
|
ce23225e46 | ||
|
|
09c229fe6c | ||
|
|
db56125708 | ||
|
|
5736b0a114 | ||
|
|
a21c0503f8 | ||
|
|
e52d5f3d98 | ||
|
|
0e96b9d010 | ||
|
|
dcba8c28f2 | ||
|
|
da93a3320b | ||
|
|
53607a0274 | ||
|
|
67d19f3570 | ||
|
|
54c1f71bd3 | ||
|
|
a7e2809466 | ||
|
|
3f66e9fe4b | ||
|
|
f547d0fac3 | ||
|
|
cdf272315e | ||
|
|
31303718da | ||
|
|
4192bdd731 | ||
|
|
c18aa03552 | ||
|
|
b2283f045a | ||
|
|
8e3863aa20 | ||
|
|
79899badd0 | ||
|
|
691b7a63f2 | ||
|
|
154731306b | ||
|
|
d67548adfe | ||
|
|
cfeaaa02fc | ||
|
|
c5270f85d3 | ||
|
|
45931a890d | ||
|
|
1a5c169c06 | ||
|
|
d8fbf43022 | ||
|
|
3be96efe0b | ||
|
|
99a2486b09 | ||
|
|
c3c65ee864 | ||
|
|
db0f5f8d22 | ||
|
|
8b162ca258 | ||
|
|
4f990d5a74 | ||
|
|
1349efa34d | ||
|
|
cf99ecb5a9 | ||
|
|
0d818d0a92 | ||
|
|
42b0ab437a | ||
|
|
a36de633d5 | ||
|
|
8a43d49b89 | ||
|
|
ae9c9cf369 | ||
|
|
db44c27674 | ||
|
|
efa2c7b08b | ||
|
|
a9441043bc | ||
|
|
aaf0cfa3c1 | ||
|
|
2a2444b961 | ||
|
|
2526ec92bd | ||
|
|
9bddc52601 | ||
|
|
1b96e93f91 | ||
|
|
6127b6959f | ||
|
|
330007beb2 | ||
|
|
cbfd48d949 | ||
|
|
f64064fe71 | ||
|
|
f2521889c2 | ||
|
|
642d41970d | ||
|
|
acd069fd27 | ||
|
|
c810b0514e | ||
|
|
e600024908 | ||
|
|
fd5b88449a | ||
|
|
433758e4cb | ||
|
|
5b8f762ab2 | ||
|
|
72db6e4de2 | ||
|
|
2780ccdd62 | ||
|
|
fdcabdfd28 | ||
|
|
40b876f550 | ||
|
|
5cb5aeba36 | ||
|
|
6a1f49c244 | ||
|
|
8613651f18 | ||
|
|
be4fea1928 | ||
|
|
2c4542a590 | ||
|
|
3ce5359523 | ||
|
|
fe4175b551 | ||
|
|
310bf08568 | ||
|
|
c040b4821d | ||
|
|
20149281a4 | ||
|
|
87f1017f80 | ||
|
|
664eff9e76 | ||
|
|
36eb33bc86 | ||
|
|
df8fb84723 | ||
|
|
4de648a77a | ||
|
|
929dc47be4 | ||
|
|
5f222517f0 | ||
|
|
940690be82 | ||
|
|
37ec687237 | ||
|
|
ca75cd940f | ||
|
|
607fd2b977 | ||
|
|
e689eb4a0a | ||
|
|
b6a63c8d5c | ||
|
|
209f1db984 | ||
|
|
dd3fddb0e9 | ||
|
|
ab080ab544 | ||
|
|
d1466f23ed | ||
|
|
918c1a6de1 | ||
|
|
37d52bf01b | ||
|
|
46de69d0e6 | ||
|
|
0946c704bf | ||
|
|
90853cc3ab | ||
|
|
521184ba8b | ||
|
|
05da2ed2c2 | ||
|
|
d4ecc8e24a | ||
|
|
6ae0d725d3 | ||
|
|
6190ad928d | ||
|
|
0451e1c23a | ||
|
|
7eccb7ff50 | ||
|
|
29f21208a0 | ||
|
|
099a2b9d17 | ||
|
|
3b4424226f | ||
|
|
f4a582e3e2 | ||
|
|
e4c4049741 | ||
|
|
83f02e6682 | ||
|
|
069ba220d2 | ||
|
|
54dab83a9e | ||
|
|
caf1f06bcb | ||
|
|
c7dde8f0e8 | ||
|
|
546f0fd0bc | ||
|
|
9163bcef4b | ||
|
|
e030e3bd15 | ||
|
|
c950cf265f | ||
|
|
9ae7b7d1be | ||
|
|
0bd8b9823a | ||
|
|
b86c5a93b3 | ||
|
|
1e3ba81613 | ||
|
|
a83cc1dbf4 | ||
|
|
94d732b411 | ||
|
|
50be50c521 | ||
|
|
b16feb6853 | ||
|
|
32c578729c | ||
|
|
710aad20d3 | ||
|
|
d742e01a32 | ||
|
|
50d5cfa8bc | ||
|
|
80d21c039e | ||
|
|
549ab64358 | ||
|
|
e8d09733d4 | ||
|
|
5f05949425 | ||
|
|
5dc654433c | ||
|
|
05af3a3383 | ||
|
|
2eab3e6402 | ||
|
|
16c82312f3 | ||
|
|
bd494d23c5 | ||
|
|
95daec798b | ||
|
|
ef21960600 | ||
|
|
a4585423fd | ||
|
|
5aef0809d4 | ||
|
|
4d9c7d39f4 | ||
|
|
6a532cb1b5 | ||
|
|
d93e4212cd | ||
|
|
72c111bac4 | ||
|
|
d05f020d5a | ||
|
|
dde57477fc | ||
|
|
ffb6ecc488 | ||
|
|
6123541d80 | ||
|
|
e510dd9c60 | ||
|
|
0461d9e822 | ||
|
|
4f7262aa96 | ||
|
|
eac953c6e4 | ||
|
|
d7fc953fa2 | ||
|
|
f35f34b909 | ||
|
|
34a2176689 | ||
|
|
21756a1969 | ||
|
|
17a8e85cb8 | ||
|
|
1b191e14d0 | ||
|
|
98db3bc0bf | ||
|
|
46cf1c6ce0 | ||
|
|
fbf4c5daf3 | ||
|
|
c81260b3c3 | ||
|
|
8d69e19ac1 | ||
|
|
6ab93841e9 | ||
|
|
52cbbdaf38 | ||
|
|
0996a43dbb | ||
|
|
3faaa8b227 | ||
|
|
c26bb0f38a | ||
|
|
911ffe81f0 | ||
|
|
ecf993834c | ||
|
|
3cbb43a73a | ||
|
|
db97d3d8c8 | ||
|
|
7199662fbb | ||
|
|
a14a2137e7 | ||
|
|
16ac703008 | ||
|
|
24e2ee5812 | ||
|
|
b0d8815dab | ||
|
|
831a0af508 | ||
|
|
488202feee | ||
|
|
193402ad41 | ||
|
|
1b86b7cb4b | ||
|
|
e5dc991ffd | ||
|
|
89e09afdf6 | ||
|
|
bec7fcb14a | ||
|
|
f45d4d0755 | ||
|
|
64558a57e3 | ||
|
|
29e4414c35 | ||
|
|
c2e12440d2 | ||
|
|
1685aa5978 | ||
|
|
6874f564c1 | ||
|
|
4882f70040 | ||
|
|
1aca317c77 | ||
|
|
af2730fe2a | ||
|
|
a6d64d1d44 | ||
|
|
d15dd89bb7 | ||
|
|
961682aa6b | ||
|
|
2f37cfe569 | ||
|
|
5b5c6dccc0 | ||
|
|
d58a5c8cae | ||
|
|
1d5788f779 | ||
|
|
97224b072a | ||
|
|
15442c1747 | ||
|
|
ff9db165eb | ||
|
|
48332d248f | ||
|
|
07815c24cd | ||
|
|
49b018c765 | ||
|
|
65f975655c | ||
|
|
0c1efd1f8a | ||
|
|
bc1cbd8065 | ||
|
|
50a2d89add | ||
|
|
99643a82ae | ||
|
|
fcc35f459c | ||
|
|
a5aa91ed99 | ||
|
|
d83b872c55 | ||
|
|
8ec2651ad7 | ||
|
|
53e269c5f1 | ||
|
|
8b8e206c07 |
4
AUTHORS
4
AUTHORS
@@ -1,3 +1,3 @@
|
||||
Christophe Saout <christophe@saout.de>
|
||||
Jana Saout <jana@saout.de>
|
||||
Clemens Fruhwirth <clemens@endorphin.org>
|
||||
Milan Broz <asi@ucw.cz>
|
||||
Milan Broz <gmazyland@gmail.com>
|
||||
|
||||
15
COPYING.LGPL
15
COPYING.LGPL
@@ -500,3 +500,18 @@ necessary. Here is a sample; alter the names:
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
-----
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations
|
||||
including the two.
|
||||
|
||||
You must obey the GNU Lesser General Public License in all respects
|
||||
for all of the code used other than OpenSSL. If you modify
|
||||
file(s) with this exception, you may extend this exception to your
|
||||
version of the file(s), but you are not obligated to do so. If you
|
||||
do not wish to do so, delete this exception statement from your
|
||||
version. If you delete this exception statement from all source
|
||||
files in the program, then also delete it here.
|
||||
|
||||
868
ChangeLog
868
ChangeLog
@@ -1,866 +1,6 @@
|
||||
2012-07-10 Milan Broz <gmazyland@gmail.com>
|
||||
* Version 1.5.0.
|
||||
Since version 1.6 this file is no longer maintained.
|
||||
|
||||
2012-06-25 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --device-size option for reencryption tool.
|
||||
* Switch to use unit suffix for --reduce-device-size option.
|
||||
* Remove open device debugging feature (no longer needed).
|
||||
* Fix library name for FIPS check.
|
||||
See docs/*ReleaseNotes for release changes documentation.
|
||||
|
||||
2012-06-20 Milan Broz <gmazyland@gmail.com>
|
||||
* Version 1.5.0-rc2.
|
||||
|
||||
2012-06-18 Milan Broz <gmazyland@gmail.com>
|
||||
* Introduce cryptsetup-reencrypt - experimental offline LUKS reencryption tool.
|
||||
* Fix luks-header-from-active script (do not use LUKS header on-disk, add UUID).
|
||||
* Add --test-passphrase option for luksOpen (check passphrase only).
|
||||
|
||||
2012-06-11 Milan Broz <gmazyland@gmail.com>
|
||||
* Introduce veritysetup for dm-verity target management.
|
||||
* Version 1.5.0-rc1.
|
||||
|
||||
2012-06-10 Milan Broz <gmazyland@gmail.com>
|
||||
* Both data and header device can now be a file.
|
||||
* Loop is automatically allocated in crypt_set_data_device().
|
||||
* Require only up to last keyslot area for header device (ignore data offset).
|
||||
* Fix header backup and restore to work on files with large data offset.
|
||||
|
||||
2012-05-27 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix readonly activation if underlying device is readonly (1.4.0).
|
||||
* Include stddef.h in libdevmapper.h (size_t definition).
|
||||
* Version 1.4.3.
|
||||
|
||||
2012-05-21 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --enable-fips for linking with fipscheck library.
|
||||
* Initialize binary and library selfcheck if running in FIPS mode.
|
||||
* Use FIPS RNG in FIPS mode for KEY and SALT (only gcrypt backend supported).
|
||||
|
||||
2012-05-09 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix keyslot removal (wipe keyslot) for device with 4k hw block (1.4.0).
|
||||
* Allow empty cipher (cipher_null) for testing.
|
||||
|
||||
2012-05-02 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix loop mapping on readonly file.
|
||||
* Relax --shared test, allow mapping even for overlapping segments.
|
||||
* Support shared flag for LUKS devices (dangerous).
|
||||
* Switch on retry on device remove for libdevmapper.
|
||||
* Allow "private" activation (skip some udev global rules) flag.
|
||||
|
||||
2012-04-09 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix header check to support old (cryptsetup 1.0.0) header alignment. (1.4.0)
|
||||
* Version 1.4.2.
|
||||
|
||||
2012-03-16 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --keyfile-offset and --new-keyfile-offset parameters to API and CLI.
|
||||
* Add repair command and crypt_repair() for known LUKS metadata problems repair.
|
||||
* Allow to specify --align-payload only for luksFormat.
|
||||
|
||||
2012-03-16 Milan Broz <mbroz@redhat.com>
|
||||
* Unify password verification option.
|
||||
* Support password verification with quiet flag if possible. (1.2.0)
|
||||
* Fix retry if entered passphrases (with verify option) do not match.
|
||||
* Support UUID=<LUKS_UUID> format for device specification.
|
||||
|
||||
2012-02-11 Milan Broz <mbroz@redhat.com>
|
||||
* Add --master-key-file option to luksOpen (open using volume key).
|
||||
|
||||
2012-01-12 Milan Broz <mbroz@redhat.com>
|
||||
* Fix use of empty keyfile.
|
||||
|
||||
2011-11-13 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error message for luksClose and detached LUKS header.
|
||||
* Allow --header for status command to get full info with detached header.
|
||||
|
||||
2011-11-09 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.4.1.
|
||||
|
||||
2011-11-05 Milan Broz <mbroz@redhat.com>
|
||||
* Merge pycryptsetup (Python libcryptsetup bindings).
|
||||
* Fix stupid typo in set_iteration_time API call.
|
||||
* Fix cryptsetup status output if parameter is device path.
|
||||
|
||||
2011-10-27 Milan Broz <mbroz@redhat.com>
|
||||
* Fix crypt_get_volume_key_size() for plain device.
|
||||
* Fix FSF address in license text.
|
||||
|
||||
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.
|
||||
|
||||
2011-05-17 Milan Broz <mbroz@redhat.com>
|
||||
* Fix keyfile=- processing in create command (1.3.0).
|
||||
* Simplify device path status check.
|
||||
|
||||
2011-05-03 Milan Broz <mbroz@redhat.com>
|
||||
* Do not ignore size argument for create command (1.2.0).
|
||||
|
||||
2011-04-18 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error paths in blockwise code and lseek_write call.
|
||||
* Add Nettle crypto backend support.
|
||||
|
||||
2011-04-05 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.3.0.
|
||||
|
||||
2011-03-22 Milan Broz <mbroz@redhat.com>
|
||||
* Also support --skip and --hash option for loopaesOpen.
|
||||
* Fix return code when passphrase is read from pipe.
|
||||
* Document cryptsetup exit codes.
|
||||
|
||||
2011-03-18 Milan Broz <mbroz@redhat.com>
|
||||
* Respect maximum keyfile size paramater.
|
||||
* Introduce maximum default keyfile size, add configure option.
|
||||
* Require the whole key read from keyfile in create command (broken in 1.2.0).
|
||||
* Fix offset option for loopaesOpen.
|
||||
* Lock memory also in luksDump command.
|
||||
* Version 1.3.0-rc2.
|
||||
|
||||
2011-03-14 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.3.0-rc1.
|
||||
|
||||
2011-03-11 Milan Broz <mbroz@redhat.com>
|
||||
* Add loop manipulation code and support mapping of images in file.
|
||||
* Add backing device loop info into status message.
|
||||
* Add luksChangeKey command.
|
||||
|
||||
2011-03-05 Milan Broz <mbroz@redhat.com>
|
||||
* Add exception to COPYING for binary distribution linked with OpenSSL library.
|
||||
* Set secure data flag (wipe all ioclt buffers) if devmapper library supports it.
|
||||
|
||||
2011-01-29 Milan Broz <mbroz@redhat.com>
|
||||
* Fix mapping removal if device disappeared but node still exists.
|
||||
* Fix luksAddKey return code if master key is used.
|
||||
|
||||
2011-01-25 Milan Broz <mbroz@redhat.com>
|
||||
* Add loop-AES handling (loopaesOpen and loopaesClose commands).
|
||||
(requires kernel 2.6.38 and above)
|
||||
|
||||
2011-01-05 Milan Broz <mbroz@redhat.com>
|
||||
* Fix static build (--disable-static-cryptsetup now works properly).
|
||||
|
||||
2010-12-30 Milan Broz <mbroz@redhat.com>
|
||||
* Add compile time crypto backends implementation
|
||||
(gcrypt, OpenSSL, NSS and userspace Linux kernel crypto api).
|
||||
* Currently NSS is lacking ripemd160, cannot provide full plain compatibility.
|
||||
* Use --with-crypto_backend=[gcrypt|openssl|nss|kernel] to configure.
|
||||
|
||||
2010-12-20 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.2.0.
|
||||
|
||||
2010-11-25 Milan Broz <mbroz@redhat.com>
|
||||
* Fix crypt_activate_by_keyfile() to work with PLAIN devices.
|
||||
* Fix create command to properly handle keyfile size.
|
||||
|
||||
2010-11-16 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.2.0-rc1.
|
||||
|
||||
2010-11-13 Milan Broz <mbroz@redhat.com>
|
||||
* Fix password callback call.
|
||||
* Fix default plain password entry from terminal in activate_by_passphrase.
|
||||
* Add --dump-master-key option for luksDump to allow volume key dump.
|
||||
* Allow to activate by internally cached volume key
|
||||
(format/activate without keyslots active - used for temporary devices).
|
||||
* Initialize volume key from active device in crypt_init_by_name()
|
||||
* Fix cryptsetup binary exitcodes.
|
||||
* Increase library version (still binary compatible with 1.1.x release).
|
||||
|
||||
2010-11-01 Milan Broz <mbroz@redhat.com>
|
||||
* No longer support luksDelKey, reload and --non-exclusive.
|
||||
* Remove some obsolete info from man page.
|
||||
* Add crypt_get_type(), crypt_resize(), crypt_keyslot_max()
|
||||
and crypt_get_active_device() to API.
|
||||
* Rewrite all implementations in cryptsetup to new API.
|
||||
* Fix luksRemoveKey to behave as documented (do not ask
|
||||
for remaining keyslot passphrase).
|
||||
* Add more regression tests for commands.
|
||||
* Disallow mapping of device which is already in use (mapped or mounted).
|
||||
* Disallow luksFormat on device in use.
|
||||
|
||||
2010-10-27 Milan Broz <mbroz@redhat.com>
|
||||
* Rewrite cryptsetup luksFormat, luksOpen, luksAddKey to use new API
|
||||
to allow adding new features.
|
||||
* Implement --use-random and --use-urandom for luksFormat to allow
|
||||
setting of RNG for volume key generator.
|
||||
* Add crypt_set_rng_type() and crypt_get_rng_type() to API.
|
||||
* Add crypt_set_uuid() to API.
|
||||
* Allow UUID setting in luksFormat and luksUUID (--uuid parameter).
|
||||
* Add --keyfile-size and --new-keyfile-size (in bytes) size and disallow overloading
|
||||
of --key-size for limiting keyfile reads.
|
||||
* Fix luksFormat to properly use key file with --master-key-file switch.
|
||||
* Fix possible double free when handling master key file.
|
||||
|
||||
2010-10-17 Milan Broz <mbroz@redhat.com>
|
||||
* Add crypt_get_device_name() to API (get underlying device name).
|
||||
* Change detection for static libraries.
|
||||
* Fix pkg-config use in automake scripts.
|
||||
* Remove --disable-shared-library switch and handle static library build
|
||||
by common libtool logic (using --enable-static).
|
||||
* Add --enable-static-cryptsetup option to build cryptsetup.static binary
|
||||
together with shared build.
|
||||
|
||||
2010-08-05 Milan Broz <mbroz@redhat.com>
|
||||
* Wipe iteration and salt after KillSlot in LUKS header.
|
||||
* Rewrite file differ test to C (and fix it to really work).
|
||||
* Switch to 1MiB default alignment of data.
|
||||
For more info see https://bugzilla.redhat.com/show_bug.cgi?id=621684
|
||||
* Do not query non-existent device twice (cryptsetup status /dev/nonexistent).
|
||||
* Check if requested hash is supported before writing LUKS header.
|
||||
|
||||
2010-07-28 Arno Wagner <arno@wagner.name>
|
||||
* Add FAQ (Frequently Asked Questions) file to distribution.
|
||||
|
||||
2010-07-03 Milan Broz <mbroz@redhat.com>
|
||||
* Fix udev support for old libdevmapper with not compatible definition.
|
||||
* Version 1.1.3.
|
||||
|
||||
2010-06-01 Milan Broz <mbroz@redhat.com>
|
||||
* Fix device alignment ioctl calls parameters.
|
||||
* Fix activate_by_* API calls to handle NULL device name as documented.
|
||||
|
||||
2010-05-30 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.1.2.
|
||||
|
||||
2010-05-27 Milan Broz <mbroz@redhat.com>
|
||||
* Fix luksFormat/luksOpen reading passphrase from stdin and "-" keyfile.
|
||||
* Support --key-file/-d option for luksFormat.
|
||||
* Fix description of --key-file and add --verbose and --debug options to man page.
|
||||
* Add verbose log level and move unlocking message there.
|
||||
* Remove device even if underlying device disappeared.
|
||||
* Fix (deprecated) reload device command to accept new device argument.
|
||||
|
||||
2010-05-23 Milan Broz <mbroz@redhat.com>
|
||||
* Fix luksClose operation for stacked DM devices.
|
||||
* Version 1.1.1.
|
||||
|
||||
2010-05-03 Milan Broz <mbroz@redhat.com>
|
||||
* Fix automatic dm-crypt module loading.
|
||||
* Escape hyphens in man page.
|
||||
* Version 1.1.1-rc2.
|
||||
|
||||
2010-04-30 Milan Broz <mbroz@redhat.com>
|
||||
* Try to use pkgconfig for device mapper library.
|
||||
* Detect old dm-crypt module and disable LUKS suspend/resume.
|
||||
* Fix apitest to work on older systems.
|
||||
* Allow no hash specification in plain device constructor.
|
||||
* Fix luksOpen reading of passphrase on stdin (if "-" keyfile specified).
|
||||
* Fix isLuks to initialise crypto backend (blkid instead is suggested anyway).
|
||||
* Version 1.1.1-rc1.
|
||||
|
||||
2010-04-12 Milan Broz <mbroz@redhat.com>
|
||||
* Fix package config to use proper package version.
|
||||
* Avoid class C++ keyword in library header.
|
||||
* Detect and use devmapper udev support if available (disable by --disable-udev).
|
||||
|
||||
2010-04-06 Milan Broz <mbroz@redhat.com>
|
||||
* Prefer some device paths in status display.
|
||||
* Support device topology detectionfor data alignment.
|
||||
|
||||
2010-02-25 Milan Broz <mbroz@redhat.com>
|
||||
* Do not verify unlocking passphrase in luksAddKey command.
|
||||
* Properly initialise crypto backend in header backup/restore commands.
|
||||
|
||||
2010-01-17 Milan Broz <mbroz@redhat.com>
|
||||
* If gcrypt compiled with capabilities, document workaround for cryptsetup (see lib/gcrypt.c).
|
||||
* Version 1.1.0.
|
||||
|
||||
2010-01-10 Milan Broz <mbroz@redhat.com>
|
||||
* Fix initialisation of gcrypt duting luksFormat.
|
||||
* Convert hash name to lower case in header (fix sha1 backward comatible header)
|
||||
* Check for minimum required gcrypt version.
|
||||
|
||||
2009-12-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix key slot iteration count calculation (small -i value was the same as default).
|
||||
* The slot and key digest iteration minimun is now 1000.
|
||||
* The key digest iteration # is calculated from iteration time (approx 1/8 of that).
|
||||
* Version 1.1.0-rc4.
|
||||
|
||||
2009-12-11 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error handling during reading passhrase.
|
||||
|
||||
2009-12-01 Milan Broz <mbroz@redhat.com>
|
||||
* Allow changes of default compiled-in cipher parameters through configure.
|
||||
* Switch default key size for LUKS to 256bits.
|
||||
* Switch default plain mode to aes-cbc-essiv:sha256 (default is backward incompatible!).
|
||||
|
||||
2009-11-14 Milan Broz <mbroz@redhat.com>
|
||||
* Add CRYPT_ prefix to enum defined in libcryptsetup.h.
|
||||
* Fix status call to fail when running as non-root user.
|
||||
* Check in configure if selinux libraries are required in static version.
|
||||
* Add temporary debug code to find processes locking internal device.
|
||||
* Simplify build system, use autopoint and clean gettext processing.
|
||||
* Use proper NLS macros and detection (so the message translation works again).
|
||||
* Version 1.1.0-rc3.
|
||||
|
||||
2009-09-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix exported symbols and versions in libcryptsetup.
|
||||
* Do not use internal lib functions in cryptsetup.
|
||||
* Add crypt_log to library.
|
||||
* Fix crypt_remove_device (remove, luksClose) implementation.
|
||||
* Move dm backend initialisation to library calls.
|
||||
* Move duplicate Command failed message to verbose level (error is printed always).
|
||||
* Add some password and used algorithms notes to man page.
|
||||
* Version 1.1.0-rc2.
|
||||
|
||||
2009-09-28 Milan Broz <mbroz@redhat.com>
|
||||
* Add luksHeaderBackup and luksHeaderRestore commands.
|
||||
* Fail passphrase read if piped input no longer exists.
|
||||
* Version 1.1.0-rc1.
|
||||
|
||||
2009-09-15 Milan Broz <mbroz@redhat.com>
|
||||
* Initialize crypto library before LUKS header load.
|
||||
* Fix manpage to not require --size which expands to device size by default.
|
||||
|
||||
2009-09-10 Milan Broz <mbroz@redhat.com>
|
||||
* Clean up Makefiles and configure script.
|
||||
* Version 1.1.0-test0.
|
||||
|
||||
2009-09-08 Milan Broz <mbroz@redhat.com>
|
||||
* Use dm-uuid for all crypt devices, contains device type and name now.
|
||||
* Try to read first sector from device to properly check that device is ready.
|
||||
|
||||
2009-09-02 Milan Broz <mbroz@redhat.com>
|
||||
* Add luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase).
|
||||
|
||||
2009-08-30 Milan Broz <mbroz@redhat.com>
|
||||
* Require device device-mapper to build and do not use backend wrapper for dm calls.
|
||||
* Move memory locking and dm initialization to command layer.
|
||||
* Increase priority of process if memory is locked.
|
||||
* Add log macros and make logging modre consitent.
|
||||
* Move command successful messages to verbose level.
|
||||
* Introduce --debug parameter.
|
||||
* Move device utils code and provide context parameter (for log).
|
||||
* Keyfile now must be provided by path, only stdin file descriptor is used (api only).
|
||||
* Do not call isatty() on closed keyfile descriptor.
|
||||
* Run performance check for PBKDF2 from LUKS code, do not mix hash algoritms results.
|
||||
* Add ability to provide pre-generated master key and UUID in LUKS header format.
|
||||
* Add LUKS function to verify master key digest.
|
||||
* Move key slot manuipulation function into LUKS specific code.
|
||||
* Replace global options struct with separate parameters in helper functions.
|
||||
* Add new libcryptsetup API (documented in libcryptsetup.h).
|
||||
* Implement old API calls using new functions.
|
||||
* Remove old API code helper functions.
|
||||
* Add --master-key-file option for luksFormat and luksAddKey.
|
||||
|
||||
2009-08-17 Milan Broz <mbroz@redhat.com>
|
||||
* Fix PBKDF2 speed calculation for large passhrases.
|
||||
* Allow using passphrase provided in options struct for LuksOpen.
|
||||
* Allow restrict keys size in LuksOpen.
|
||||
|
||||
2009-07-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix errors when compiled with LUKS_DEBUG.
|
||||
* Print error when getline fails.
|
||||
* Remove po/cryptsetup-luks.pot, it's autogenerated.
|
||||
* Return ENOENT for empty keyslots, EINVAL will be used later for other type of error.
|
||||
* Switch PBKDF2 from internal SHA1 to libgcrypt, make hash algorithm not hardcoded to SHA1 here.
|
||||
* Add required parameters for changing hash used in LUKS key setup scheme.
|
||||
* Do not export simple XOR helper now used only inside AF functions.
|
||||
* Completely remove internal SHA1 implementanion code, not needed anymore.
|
||||
* Enable hash algorithm selection for LUKS through -h luksFormat option.
|
||||
|
||||
2009-07-28 Milan Broz <mbroz@redhat.com>
|
||||
* Pad luks header to 512 sector size.
|
||||
* Rework read/write blockwise to not split operation to many pieces.
|
||||
* Use posix_memalign if available.
|
||||
|
||||
2009-07-22 Milan Broz <mbroz@redhat.com>
|
||||
* Fix segfault if provided slot in luksKillslot is invalid.
|
||||
* Remove unneeded timeout when remove of temporary device succeeded.
|
||||
|
||||
2009-07-22 Milan Broz <mbroz@redhat.com>
|
||||
* version 1.0.7
|
||||
|
||||
2009-07-16 Milan Broz <mbroz@redhat.com>
|
||||
* Allow removal of last slot in luksRemoveKey and luksKillSlot.
|
||||
|
||||
2009-07-11 Milan Broz <mbroz@redhat.com>
|
||||
|
||||
* Add --disable-selinux option and fix static build if selinux is required.
|
||||
* Reject unsupported --offset and --skip options for luksFormat and update man page.
|
||||
|
||||
2009-06-22 Milan Broz <mbroz@redhat.com>
|
||||
|
||||
* Summary of changes in subversion for 1.0.7-rc1:
|
||||
* Various man page fixes.
|
||||
* Set UUID in device-mapper for LUKS devices.
|
||||
* Retain readahead of underlying device.
|
||||
* Display device name when asking for password.
|
||||
* Check device size when loading LUKS header. Remove misleading error message later.
|
||||
* Add error hint if dm-crypt mapping failed.
|
||||
* Use better error messages if device doesn't exist or is already used by other mapping.
|
||||
* Fix make distcheck.
|
||||
* Check if all slots are full during luksAddKey.
|
||||
* Fix segfault in set_error.
|
||||
* Code cleanups, remove precompiled pot files, remove unnecessary files from po directory
|
||||
* Fix uninitialized return value variable in setup.c.
|
||||
* Code cleanups. (thanks to Ivan Stankovic)
|
||||
* Fix wrong output for remaining key at key deletion.
|
||||
* Allow deletion of key slot while other keys have the same key information.
|
||||
* Add missing AM_PROG_CC_C_O to configure.in
|
||||
* Remove duplicate sentence in man page.
|
||||
* Wipe start of device (possible fs signature) before LUKS-formatting.
|
||||
* Do not process configure.in in hidden directories.
|
||||
* Return more descriptive error in case of IO or header format error.
|
||||
* Use remapping to error target instead of calling udevsettle for temporary crypt device.
|
||||
* Check device mapper communication and warn user if device-mapper support missing in kernel.
|
||||
* Fix signal handler to properly close device.
|
||||
* write_lseek_blockwise: declare innerCount outside the if block.
|
||||
* add -Wall to the default CFLAGS. fix some signedness issues.
|
||||
* Error handling improvement.
|
||||
* Add non-exclusive override to interface definition.
|
||||
* Refactor key slot selection into keyslot_from_option.
|
||||
|
||||
2007-05-01 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/backends.c, man/cryptsetup.8: Apply patch from Ludwig Nussel
|
||||
<ludwig.nussel@suse.de>, for old SuSE compat hashing.
|
||||
|
||||
2007-04-16 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Summary of changes in subversion:
|
||||
Fix segfault for key size > 32 bytes.
|
||||
Kick ancient header version conversion.
|
||||
Fix http://bugs.debian.org/403075
|
||||
No passwort retrying for I/O errors.
|
||||
Fix hang on "-i 0".
|
||||
Fix parenthesization error that prevented --tries from working
|
||||
correctly.
|
||||
|
||||
2006-11-28 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* m4/gettext.m4: Upgrade to gettext-0.15.
|
||||
* m4/glibc2.m4: New file, from gettext-0.15.
|
||||
* m4/intmax.m4: New file, from gettext-0.15.
|
||||
* m4/inttypes-h.m4: New file, from gettext-0.15.
|
||||
* m4/inttypes-pri.m4: Upgrade to gettext-0.15.
|
||||
* m4/lib-link.m4: Upgrade to gettext-0.15.
|
||||
* m4/lib-prefix.m4: Upgrade to gettext-0.15.
|
||||
* m4/lock.m4: New file, from gettext-0.15.
|
||||
* m4/longdouble.m4: New file, from gettext-0.15.
|
||||
* m4/longlong.m4: New file, from gettext-0.15.
|
||||
* m4/nls.m4: Upgrade to gettext-0.15.
|
||||
* m4/po.m4: Upgrade to gettext-0.15.
|
||||
* m4/printf-posix.m4: New file, from gettext-0.15.
|
||||
* m4/signed.m4: New file, from gettext-0.15.
|
||||
* m4/size_max.m4: New file, from gettext-0.15.
|
||||
* m4/visibility.m4: New file, from gettext-0.15.
|
||||
* m4/wchar_t.m4: New file, from gettext-0.15.
|
||||
* m4/wint_t.m4: New file, from gettext-0.15.
|
||||
* m4/xsize.m4: New file, from gettext-0.15.
|
||||
* m4/Makefile.am: New file.
|
||||
* configure.in (AC_OUTPUT): Add m4/Makefile.
|
||||
(AM_GNU_GETTEXT_VERSION): Bump to 0.15.
|
||||
|
||||
2006-10-22 David Härdeman <david@hardeman.nu>
|
||||
|
||||
* Allow hashing of keys passed through stdin.
|
||||
|
||||
2006-10-13 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.4 release
|
||||
|
||||
2006-10-13 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: Document --tries switch; patch by Jonas
|
||||
Meurer.
|
||||
|
||||
2006-10-13 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c: Added terminal timeout rewrite as forwarded by
|
||||
Jonas Meurer
|
||||
|
||||
2006-10-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Merged patch from Marc Merlin <marc@merlins.org> to allow user
|
||||
selection of key slot.
|
||||
|
||||
2006-09-26 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* m4/codeset.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/gettext.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/glibc2.m4: New file, from gettext-0.14.4.
|
||||
* m4/glibc21.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/iconv.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/intdiv0.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/intmax.m4: New file, from gettext-0.14.4.
|
||||
* m4/inttypes.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/inttypes_h.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/inttypes-pri.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/isc-posix.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lcmessage.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lib-ld.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lib-link.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lib-prefix.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/longdouble.m4: New file, from gettext-0.14.4.
|
||||
* m4/longlong.m4: New file, from gettext-0.14.4.
|
||||
* m4/nls.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/po.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/printf-posix.m4: New file, from gettext-0.14.4.
|
||||
* m4/progtest.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/signed.m4: New file, from gettext-0.14.4.
|
||||
* m4/size_max.m4: New file, from gettext-0.14.4.
|
||||
* m4/stdint_h.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/uintmax_t.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/ulonglong.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/wchar_t.m4: New file, from gettext-0.14.4.
|
||||
* m4/wint_t.m4: New file, from gettext-0.14.4.
|
||||
* m4/xsize.m4: New file, from gettext-0.14.4.
|
||||
* Makefile.am (ACLOCAL_AMFLAGS): New variable.
|
||||
* configure.in (AM_GNU_GETTEXT_VERSION): Bump to 0.14.4.
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.4-rc2
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/Makefile.am: Add a few regression tests
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* 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.
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (__crypt_luks_add_key): For checking options struct
|
||||
(optionsCheck) filter out CRYPT_FLAG_VERIFY and
|
||||
CRYPT_FLAG_VERIFY_IF_POSSIBLE, so that in no case password verification is done
|
||||
for password retrieval.
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Merge Patch from http://bugs.gentoo.org/show_bug.cgi?id=132126 for sepol
|
||||
|
||||
2006-07-23 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Applied patches from David Härdeman <david@2gen.com> to fix 64
|
||||
bit compiler warning issues.
|
||||
|
||||
2006-05-19 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Applied patches from Jonas Meurer
|
||||
- fix terminal status after timeout
|
||||
- add remark for --tries to manpage
|
||||
- allow more than 32 chars from standard input.
|
||||
- exit status fix for cryptsetup status.
|
||||
|
||||
2006-05-06 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (yesDialog): Fix getline problem for 64-bit archs.
|
||||
|
||||
2006-04-05 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Release 1.0.3.
|
||||
|
||||
* Applied patch by Johannes Weißl for more meaningful exit codes
|
||||
and password retries
|
||||
|
||||
2006-03-30 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (__crypt_create_device): (char *) -> (const char *)
|
||||
|
||||
2006-03-30 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Apply alignPayload patch from Peter Palfrader <weasel@debian.org>
|
||||
|
||||
2006-03-15 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.3-rc3. Most unplease release ever.
|
||||
* lib/setup.c (__crypt_create_device): More verbose error message.
|
||||
|
||||
2006-02-26 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c: Revert to 1.0.1 key reading.
|
||||
|
||||
2006-02-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: merge patch from Jonas Meurer
|
||||
|
||||
2006-02-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.3-rc2
|
||||
|
||||
2006-02-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/libdevmapper.c (dm_create_device): Remove dup check here.
|
||||
* lib/setup.c (__crypt_luks_open): Adopt same dup check as regular
|
||||
create command.
|
||||
|
||||
2006-02-22 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Spin 1.0.3-rc1
|
||||
|
||||
2006-02-22 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (action_create): Change defaulting.
|
||||
(action_luksFormat): Change defaulting.
|
||||
|
||||
* lib/setup.c (parse_into_name_and_mode): Revert that default
|
||||
change. This is FORBIDDEN here, as it will change cryptsetup
|
||||
entire default. This is BAD in a non-LUKS world.
|
||||
|
||||
2006-02-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keyencryption.c (setup_mapping): Add proper size restriction to mapping.
|
||||
(LUKS_endec_template): Add more verbose error message.
|
||||
|
||||
2006-02-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/libdevmapper.c (dm_query_device): Incorporate patch from
|
||||
Bastian Blank
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=344313
|
||||
|
||||
2006-02-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c: Rename show_error -> show_status.
|
||||
|
||||
2006-02-20 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/libdevmapper.c (dm_create_device): Prevent existing mapping
|
||||
from being removed when a mapping with the same name is added
|
||||
|
||||
* Add timeout patch from Jonas Meurer
|
||||
|
||||
* src/cryptsetup.c: Remove conditional error printing to enable
|
||||
printing the no-error msg (Command successful). Verify passphrase
|
||||
for LUKS volumes.
|
||||
(main): Add no-verify-passphrase
|
||||
|
||||
* lib/setup.c (parse_into_name_and_mode): Change default mode complition to essiv:sha256.
|
||||
|
||||
2006-01-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (help): Merge patch from Gentoo: change gettext(..) to _(..).
|
||||
|
||||
2005-12-06 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: Correct "seconds" to "microseconds" in the explaination for -i.
|
||||
|
||||
2005-11-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (main): Add version string.
|
||||
|
||||
2005-11-08 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/backends.c: compile fix.
|
||||
|
||||
2005-09-11 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (get_key): Fixed another incompatibility from my
|
||||
get_key rewrite with original cryptsetup.
|
||||
|
||||
2005-09-11 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Merged changes from Florian Knauf's fk02 branch.
|
||||
|
||||
2005-09-08 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (get_key): Fixed another incompatiblity with
|
||||
original cryptsetup.
|
||||
|
||||
2005-08-20 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Checked in a patch from Michael Gebetsroither <gebi@sbox.tugraz.at>
|
||||
to silent all confirmation dialogs.
|
||||
|
||||
2005-06-23 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (help): print PACKAGE_STRING
|
||||
|
||||
2005-06-20 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keymanage.c (LUKS_set_key): Security check against header manipulation
|
||||
|
||||
* src/cryptsetup.c (action_luksDelKey): Safety check in luksDelKey
|
||||
|
||||
* luks/keymanage.c: Changed disk layout generation to align key material to 4k boundaries.
|
||||
(LUKS_is_last_keyslot): Added LUKS_is_last_keyslot function.
|
||||
|
||||
* Applied patch from Bill Nottingham fixing a lot of prototypes.
|
||||
|
||||
* src/cryptsetup.c (action_luksOpen): Add support for -r flag.
|
||||
|
||||
* configure.in: Version bump 1.0.1
|
||||
|
||||
2005-06-16 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (__crypt_luks_open): Remove mem leaking of dmCipherSpec.
|
||||
(get_key): Fix missing zero termination for read string.
|
||||
|
||||
2005-06-12 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keyencryption.c (setup_mapping): Added CRYPT_FLAG_READONLY in case of O_RDONLY mode
|
||||
|
||||
2005-06-11 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Version bump 1.0.1-pre
|
||||
|
||||
2005-06-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/utils.c: Added write_llseek_blocksize method to support sector wiping on sector_size != 512
|
||||
media
|
||||
|
||||
2005-05-23 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (crypt_luksDelKey): Added missing return statement
|
||||
(setup_leave): Added missing return statement
|
||||
|
||||
* luks/keyencryption.c (clear_mapping): Added missing return statement
|
||||
|
||||
2005-05-19 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/utils.c (write_blockwise, read_blockwise): Changed to soft bsize instead of SECTOR_SIZE
|
||||
|
||||
* luks/keymanage.c (wipe): Changed open mode to O_DIRECT | O_SYNC, and changed write
|
||||
to use the blockwise write helper
|
||||
|
||||
2005-04-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: Corrected an error, thanks to Dick Middleton.
|
||||
|
||||
2005-04-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/sha/hmac.c: Add 64 bit bug fix courtesy to
|
||||
Oliver Paukstadt <pstadt@sourcentral.org>.
|
||||
|
||||
* luks/pbkdf.c, luks/keyencryption.c, luks/keymanage.c, luks/af.c: Added a license
|
||||
disclaimer and remove option for "any future GPL versions".
|
||||
|
||||
2005-03-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: man page Makefile. Version bump 1.0.
|
||||
|
||||
* man/cryptsetup.8: finalize man page and move to section 8.
|
||||
|
||||
* src/cryptsetup.c (action_luksFormat): Add "are you sure" for interactive sessions.
|
||||
|
||||
* lib/setup.c (crypt_luksDump), src/cryptsetup.c: add LUKS dump command
|
||||
|
||||
2005-03-24 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c, luks/Makefile.am (test), lib/setup.c (setup_enter):
|
||||
rename luksInit to luksFormat
|
||||
|
||||
2005-03-12 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.1: Add man page.
|
||||
|
||||
* lib/setup.c: Remove unneccessary LUKS_write_phdr call, so the
|
||||
phdr is written after passphrase reading, so the user can change
|
||||
his mind, and not have a partial written LUKS header on it's disk.
|
||||
|
||||
2005-02-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keymanage.c (LUKS_write_phdr): converted argument phdr to
|
||||
pointer, and make a copy of phdr for conversion
|
||||
|
||||
* configure.in: Version dump.
|
||||
|
||||
* luks/keyencryption.c: Convert to read|write_blockwise.
|
||||
|
||||
* luks/keymanage.c: Convert to read|write_blockwise.
|
||||
|
||||
* lib/utils.c: Add read|write_blockwise functions, to use in
|
||||
O_DIRECT file accesses.
|
||||
|
||||
2004-03-11 Thursday 15:52 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* lib/blockdev.h: BLKGETSIZE64 really uses size_t as third
|
||||
argument, the rest is wrong.
|
||||
|
||||
2004-03-10 Wednesday 17:50 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* lib/: libcryptsetup.h, libdevmapper.c: Small fixes.
|
||||
|
||||
2004-03-09 Tuesday 21:41 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* lib/internal.h, lib/libcryptsetup.h, lib/libdevmapper.c,
|
||||
lib/setup.c, po/de.po, src/cryptsetup.c: Added internal flags to
|
||||
keep track of malloc'ed return values in struct crypt_options and
|
||||
add a function to free the memory. Also add a readonly flag to
|
||||
libcryptsetup.
|
||||
|
||||
2004-03-09 Tuesday 16:03 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* ChangeLog, configure.in, setup-gettext, lib/Makefile.am,
|
||||
lib/backends.c, lib/blockdev.h, lib/gcrypt.c, lib/internal.h,
|
||||
lib/libcryptsetup.h, lib/libdevmapper.c, lib/setup.c,
|
||||
lib/utils.c, po/de.po, src/Makefile.am, src/cryptsetup.c: More
|
||||
reorganization work.
|
||||
|
||||
2004-03-08 Monday 01:38 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* ChangeLog, Makefile.am, acinclude.m4, configure.in,
|
||||
lib/Makefile.am, lib/backends.c, lib/blockdev.h, lib/gcrypt.c,
|
||||
lib/libdevmapper.c, lib/setup.c, lib/utils.c, po/de.po,
|
||||
src/Makefile.am: BLKGETSIZE64 fixes and started modularity
|
||||
enhancements
|
||||
|
||||
2004-03-04 Thursday 21:06 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* Makefile.am, po/de.po, src/cryptsetup.c, src/cryptsetup.h: First
|
||||
backward compatible working version.
|
||||
|
||||
2004-03-04 Thursday 00:42 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* NEWS, AUTHORS, ChangeLog, Makefile.am, README, autogen.sh,
|
||||
configure.in, setup-gettext, po/ChangeLog, po/LINGUAS,
|
||||
po/POTFILES.in, po/de.po, src/cryptsetup.c, src/cryptsetup.h,
|
||||
src/Makefile.am (utags: initial): Initial checkin.
|
||||
|
||||
2004-03-04 Thursday 00:42 Christophe Saout <christophe@saout.de>
|
||||
|
||||
* NEWS, AUTHORS, ChangeLog, Makefile.am, README, autogen.sh,
|
||||
configure.in, setup-gettext, po/ChangeLog, po/LINGUAS,
|
||||
po/POTFILES.in, po/de.po, src/cryptsetup.c, src/cryptsetup.h,
|
||||
src/Makefile.am: Initial revision
|
||||
See version control history for full commit messages.
|
||||
http://code.google.com/p/cryptsetup/source/list
|
||||
|
||||
2
README
2
README
@@ -18,7 +18,7 @@ MAILING LIST:
|
||||
|
||||
DOWNLOAD:
|
||||
|
||||
http://code.google.com/p/cryptsetup/downloads/
|
||||
https://www.kernel.org/pub/linux/utils/cryptsetup/
|
||||
|
||||
SOURCE CODE:
|
||||
|
||||
|
||||
10
TODO
10
TODO
@@ -1,7 +1,9 @@
|
||||
Version 1.6.0:
|
||||
Version 1.7:
|
||||
- Export wipe device functions
|
||||
- Support K/M suffixes for align payload (new switch?).
|
||||
- FIPS: move changekey to library
|
||||
- online reencryption api?
|
||||
- integrate more metadata formats
|
||||
- TRIM for keyslots
|
||||
- Do we need crypt_data_path() - path to data device (if differs)?
|
||||
- Resync ETA time is not accurate, calculate it better (last minute window?).
|
||||
- crypto backend should initialise itself only once (debug log)
|
||||
- Extend existing LUKS header to use another KDF? (https://password-hashing.net/)
|
||||
- Fix all crazy automake warnings (or switch to Cmake).
|
||||
|
||||
@@ -22,7 +22,7 @@ DIE=0
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
|
||||
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
|
||||
(libtool --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have libtool installed."
|
||||
@@ -78,7 +78,7 @@ autopoint --force $AP_OPTS
|
||||
libtoolize --force --copy
|
||||
aclocal -I m4 $AL_OPTS
|
||||
autoheader $AH_OPTS
|
||||
automake --add-missing --gnu $AM_OPTS
|
||||
automake --add-missing --copy --gnu $AM_OPTS
|
||||
autoconf $AC_OPTS
|
||||
|
||||
if test x$NOCONFIGURE = x; then
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[1.5.0])
|
||||
AC_INIT([cryptsetup],[1.6.5])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=7:0:3
|
||||
LIBCRYPTSETUP_VERSION_INFO=10:0:6
|
||||
dnl library file name for FIPS selfcheck
|
||||
LIBCRYPTSETUP_VERSION_FIPS="libcryptsetup.so.4"
|
||||
FIPS_MODULE_FILE="/etc/system-fips"
|
||||
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h:config.h.in])
|
||||
AM_INIT_AUTOMAKE(dist-bzip2)
|
||||
|
||||
# We do not want to run test in parallel. Really.
|
||||
# http://lists.gnu.org/archive/html/automake/2013-01/msg00060.html
|
||||
|
||||
# For old automake use this
|
||||
#AM_INIT_AUTOMAKE(dist-xz)
|
||||
AM_INIT_AUTOMAKE([dist-xz 1.12 serial-tests])
|
||||
|
||||
if test "x$prefix" = "xNONE"; then
|
||||
sysconfdir=/etc
|
||||
@@ -27,11 +34,12 @@ AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
AC_ENABLE_STATIC(no)
|
||||
LT_INIT
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
|
||||
ctype.h unistd.h locale.h)
|
||||
ctype.h unistd.h locale.h byteswap.h endian.h)
|
||||
|
||||
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
|
||||
@@ -41,13 +49,18 @@ AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_SUBST(UUID_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
AC_CHECK_FUNCS([posix_memalign])
|
||||
AC_SEARCH_LIBS([clock_gettime],[rt posix4])
|
||||
AC_CHECK_FUNCS([posix_memalign clock_gettime])
|
||||
|
||||
if test "x$enable_largefile" = "xno" ; then
|
||||
AC_MSG_ERROR([Building with --disable-largefile is not supported, it can cause data corruption.])
|
||||
fi
|
||||
|
||||
AC_C_CONST
|
||||
AC_C_BIGENDIAN
|
||||
AC_TYPE_OFF_T
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
AC_FUNC_FSEEKO
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
|
||||
dnl ==========================================================================
|
||||
@@ -73,6 +86,8 @@ if test "x$with_fips" = "xyes"; then
|
||||
AC_DEFINE(ENABLE_FIPS, 1, [Enable FIPS mode restrictions])
|
||||
AC_DEFINE_UNQUOTED(LIBCRYPTSETUP_VERSION_FIPS, ["$LIBCRYPTSETUP_VERSION_FIPS"],
|
||||
[library file name for FIPS selfcheck])
|
||||
AC_DEFINE_UNQUOTED(FIPS_MODULE_FILE, ["$FIPS_MODULE_FILE"],
|
||||
[file checked to determine if running in FIPS mode])
|
||||
|
||||
if test "x$enable_static" = "xyes" -o "x$enable_static_cryptsetup" = "xyes" ; then
|
||||
AC_MSG_ERROR([Static build is not compatible with FIPS.])
|
||||
@@ -91,6 +106,21 @@ AC_DEFUN([NO_FIPS], [
|
||||
fi
|
||||
])
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl pwquality library (cryptsetup CLI only)
|
||||
AC_ARG_ENABLE([pwquality], AS_HELP_STRING([--enable-pwquality],[enable password quality checking]),
|
||||
[with_pwquality=$enableval],
|
||||
[with_pwquality=no])
|
||||
|
||||
if test "x$with_pwquality" = "xyes"; then
|
||||
AC_DEFINE(ENABLE_PWQUALITY, 1, [Enable password quality checking])
|
||||
PKG_CHECK_MODULES([PWQUALITY], [pwquality >= 1.0.0],,
|
||||
AC_MSG_ERROR([You need pwquality library.]))
|
||||
|
||||
dnl FIXME: this is really hack for now
|
||||
PWQUALITY_STATIC_LIBS="$PWQUALITY_LIBS -lcrack -lz"
|
||||
fi
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl Crypto backend functions
|
||||
|
||||
@@ -100,6 +130,14 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
|
||||
else
|
||||
GCRYPT_REQ_VERSION=1.1.42
|
||||
fi
|
||||
dnl Check if we can use gcrypt PBKDF2 (1.6.0 supports empty password)
|
||||
AC_ARG_ENABLE([gcrypt-pbkdf2], AS_HELP_STRING([--enable-gcrypt-pbkdf2],[force enable internal gcrypt PBKDF2]),
|
||||
if test "x$enableval" = "xyes"; then
|
||||
[use_internal_pbkdf2=0]
|
||||
else
|
||||
[use_internal_pbkdf2=1]
|
||||
fi,
|
||||
[AM_PATH_LIBGCRYPT([1.6.1], [use_internal_pbkdf2=0], [use_internal_pbkdf2=1])])
|
||||
AM_PATH_LIBGCRYPT($GCRYPT_REQ_VERSION,,[AC_MSG_ERROR([You need the gcrypt library.])])
|
||||
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
@@ -124,12 +162,13 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
|
||||
AC_MSG_ERROR([You need openssl library.]))
|
||||
CRYPTO_CFLAGS=$OPENSSL_CFLAGS
|
||||
CRYPTO_LIBS=$OPENSSL_LIBS
|
||||
use_internal_pbkdf2=0
|
||||
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
saved_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
PKG_CHECK_MODULES([OPENSSL], [openssl])
|
||||
CRYPTO_STATIC_LIBS=$OPENSSL_LIBS
|
||||
PKG_CHECK_MODULES([OPENSSL_STATIC], [openssl])
|
||||
CRYPTO_STATIC_LIBS=$OPENSSL_STATIC_LIBS
|
||||
PKG_CONFIG=$saved_PKG_CONFIG
|
||||
fi
|
||||
NO_FIPS([])
|
||||
@@ -152,15 +191,17 @@ AC_DEFUN([CONFIGURE_NSS], [
|
||||
|
||||
CRYPTO_CFLAGS=$NSS_CFLAGS
|
||||
CRYPTO_LIBS=$NSS_LIBS
|
||||
use_internal_pbkdf2=1
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
AC_DEFUN([CONFIGURE_KERNEL], [
|
||||
AC_CHECK_HEADERS(linux/if_alg.h,,
|
||||
[AC_MSG_ERROR([You need Linux kernel with userspace crypto interface.])])
|
||||
[AC_MSG_ERROR([You need Linux kernel headers with userspace crypto interface.])])
|
||||
# AC_CHECK_DECLS([AF_ALG],,
|
||||
# [AC_MSG_ERROR([You need Linux kernel with userspace crypto interface.])],
|
||||
# [#include <sys/socket.h>])
|
||||
use_internal_pbkdf2=1
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
@@ -169,12 +210,13 @@ AC_DEFUN([CONFIGURE_NETTLE], [
|
||||
[AC_MSG_ERROR([You need Nettle cryptographic library.])])
|
||||
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(nettle, nettle_ripemd160_init,,
|
||||
[AC_MSG_ERROR([You need Nettle library version 2.4 or more recent.])])
|
||||
AC_CHECK_LIB(nettle, nettle_pbkdf2_hmac_sha256,,
|
||||
[AC_MSG_ERROR([You need Nettle library version 2.6 or more recent.])])
|
||||
CRYPTO_LIBS=$LIBS
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
CRYPTO_STATIC_LIBS=$CRYPTO_LIBS
|
||||
use_internal_pbkdf2=0
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
@@ -238,6 +280,19 @@ AC_ARG_WITH([crypto_backend],
|
||||
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [gcrypt]]),
|
||||
[], with_crypto_backend=gcrypt
|
||||
)
|
||||
|
||||
dnl Kernel crypto API backend needed for benchmark and tcrypt
|
||||
AC_ARG_ENABLE([kernel_crypto], AS_HELP_STRING([--disable-kernel_crypto],
|
||||
[disable kernel userspace crypto (no benchmark and tcrypt)]),
|
||||
[with_kernel_crypto=$enableval],
|
||||
[with_kernel_crypto=yes])
|
||||
|
||||
if test "x$with_kernel_crypto" = "xyes"; then
|
||||
AC_CHECK_HEADERS(linux/if_alg.h,,
|
||||
[AC_MSG_ERROR([You need Linux kernel headers with userspace crypto interface. (Or use --disable-kernel_crypto.)])])
|
||||
AC_DEFINE(ENABLE_AF_ALG, 1, [Enable using of kernel userspace crypto])
|
||||
fi
|
||||
|
||||
case $with_crypto_backend in
|
||||
gcrypt) CONFIGURE_GCRYPT([]) ;;
|
||||
openssl) CONFIGURE_OPENSSL([]) ;;
|
||||
@@ -252,6 +307,9 @@ AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test $with_crypto_backend = nss)
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test $with_crypto_backend = kernel)
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test $with_crypto_backend = nettle)
|
||||
|
||||
AM_CONDITIONAL(CRYPTO_INTERNAL_PBKDF2, test $use_internal_pbkdf2 = 1)
|
||||
AC_DEFINE_UNQUOTED(USE_INTERNAL_PBKDF2, [$use_internal_pbkdf2], [Use internal PBKDF2])
|
||||
|
||||
dnl Magic for cryptsetup.static build.
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
saved_PKG_CONFIG=$PKG_CONFIG
|
||||
@@ -287,6 +345,9 @@ fi
|
||||
AC_SUBST([DEVMAPPER_LIBS])
|
||||
AC_SUBST([DEVMAPPER_STATIC_LIBS])
|
||||
|
||||
AC_SUBST([PWQUALITY_LIBS])
|
||||
AC_SUBST([PWQUALITY_STATIC_LIBS])
|
||||
|
||||
AC_SUBST([CRYPTO_CFLAGS])
|
||||
AC_SUBST([CRYPTO_LIBS])
|
||||
AC_SUBST([CRYPTO_STATIC_LIBS])
|
||||
@@ -294,6 +355,7 @@ AC_SUBST([CRYPTO_STATIC_LIBS])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION_FIPS])
|
||||
AC_SUBST([FIPS_MODULE_FILE])
|
||||
|
||||
dnl ==========================================================================
|
||||
AC_ARG_ENABLE([dev-random], AS_HELP_STRING([--enable-dev-random],
|
||||
@@ -324,8 +386,12 @@ AC_ARG_ENABLE([python], AS_HELP_STRING([--enable-python],[enable Python bindings
|
||||
[with_python=$enableval],
|
||||
[with_python=no])
|
||||
|
||||
AC_ARG_WITH([python_version],
|
||||
AS_HELP_STRING([--with-python_version=VERSION], [required Python version [2.6]]),
|
||||
[PYTHON_VERSION=$withval], [PYTHON_VERSION=2.6])
|
||||
|
||||
if test "x$with_python" = "xyes"; then
|
||||
AM_PATH_PYTHON([2.4])
|
||||
AM_PATH_PYTHON([$PYTHON_VERSION])
|
||||
|
||||
if ! test -x "$PYTHON-config" ; then
|
||||
AC_MSG_ERROR([Cannot find python development packages to build bindings])
|
||||
@@ -333,6 +399,9 @@ if test "x$with_python" = "xyes"; then
|
||||
|
||||
PYTHON_INCLUDES=$($PYTHON-config --includes)
|
||||
AC_SUBST(PYTHON_INCLUDES)
|
||||
|
||||
PYTHON_LIBS=$($PYTHON-config --libs)
|
||||
AC_SUBST(PYTHON_LIBS)
|
||||
fi
|
||||
AM_CONDITIONAL([PYTHON_CRYPTSETUP], [test "x$with_python" = "xyes"])
|
||||
|
||||
@@ -344,8 +413,9 @@ CS_NUM_WITH([plain-keybits],[key length in bits for plain mode], [256])
|
||||
|
||||
CS_STR_WITH([luks1-hash], [hash function for LUKS1 header], [sha1])
|
||||
CS_STR_WITH([luks1-cipher], [cipher for LUKS1], [aes])
|
||||
CS_STR_WITH([luks1-mode], [cipher mode for LUKS1], [cbc-essiv:sha256])
|
||||
CS_STR_WITH([luks1-mode], [cipher mode for LUKS1], [xts-plain64])
|
||||
CS_NUM_WITH([luks1-keybits],[key length in bits for LUKS1], [256])
|
||||
CS_NUM_WITH([luks1-iter-time],[PBKDF2 iteration time for LUKS1 (in ms)], [1000])
|
||||
|
||||
CS_STR_WITH([loopaes-cipher], [cipher for loop-AES mode], [aes])
|
||||
CS_NUM_WITH([loopaes-keybits],[key length in bits for loop-AES mode], [256])
|
||||
@@ -367,6 +437,7 @@ lib/crypto_backend/Makefile
|
||||
lib/luks1/Makefile
|
||||
lib/loopaes/Makefile
|
||||
lib/verity/Makefile
|
||||
lib/tcrypt/Makefile
|
||||
src/Makefile
|
||||
po/Makefile.in
|
||||
man/Makefile
|
||||
887
docs/ChangeLog.old
Normal file
887
docs/ChangeLog.old
Normal file
@@ -0,0 +1,887 @@
|
||||
2012-12-21 Milan Broz <gmazyland@gmail.com>
|
||||
* Since version 1.6 This file is no longer maintained.
|
||||
* See version control log http://code.google.com/p/cryptsetup/source/list
|
||||
|
||||
2012-10-11 Milan Broz <gmazyland@gmail.com>
|
||||
* Added keyslot checker (by Arno Wagner).
|
||||
* Version 1.5.1.
|
||||
|
||||
2012-09-11 Milan Broz <gmazyland@gmail.com>
|
||||
* Add crypt_keyslot_area() API call.
|
||||
|
||||
2012-08-27 Milan Broz <gmazyland@gmail.com>
|
||||
* Optimize seek to keyfile-offset (Issue #135, thx to dreisner).
|
||||
* Fix luksHeaderBackup for very old v1.0 unaligned LUKS headers.
|
||||
|
||||
2012-08-12 Milan Broz <gmazyland@gmail.com>
|
||||
* Allocate loop device late (only when real block device needed).
|
||||
* Rework underlying device/file access functions.
|
||||
* Create hash image if doesn't exist in veritysetup format.
|
||||
* Provide better error message if running as non-root user (device-mapper, loop).
|
||||
|
||||
2012-07-10 Milan Broz <gmazyland@gmail.com>
|
||||
* Version 1.5.0.
|
||||
|
||||
2012-06-25 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --device-size option for reencryption tool.
|
||||
* Switch to use unit suffix for --reduce-device-size option.
|
||||
* Remove open device debugging feature (no longer needed).
|
||||
* Fix library name for FIPS check.
|
||||
|
||||
2012-06-20 Milan Broz <gmazyland@gmail.com>
|
||||
* Version 1.5.0-rc2.
|
||||
|
||||
2012-06-18 Milan Broz <gmazyland@gmail.com>
|
||||
* Introduce cryptsetup-reencrypt - experimental offline LUKS reencryption tool.
|
||||
* Fix luks-header-from-active script (do not use LUKS header on-disk, add UUID).
|
||||
* Add --test-passphrase option for luksOpen (check passphrase only).
|
||||
|
||||
2012-06-11 Milan Broz <gmazyland@gmail.com>
|
||||
* Introduce veritysetup for dm-verity target management.
|
||||
* Version 1.5.0-rc1.
|
||||
|
||||
2012-06-10 Milan Broz <gmazyland@gmail.com>
|
||||
* Both data and header device can now be a file.
|
||||
* Loop is automatically allocated in crypt_set_data_device().
|
||||
* Require only up to last keyslot area for header device (ignore data offset).
|
||||
* Fix header backup and restore to work on files with large data offset.
|
||||
|
||||
2012-05-27 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix readonly activation if underlying device is readonly (1.4.0).
|
||||
* Include stddef.h in libdevmapper.h (size_t definition).
|
||||
* Version 1.4.3.
|
||||
|
||||
2012-05-21 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --enable-fips for linking with fipscheck library.
|
||||
* Initialize binary and library selfcheck if running in FIPS mode.
|
||||
* Use FIPS RNG in FIPS mode for KEY and SALT (only gcrypt backend supported).
|
||||
|
||||
2012-05-09 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix keyslot removal (wipe keyslot) for device with 4k hw block (1.4.0).
|
||||
* Allow empty cipher (cipher_null) for testing.
|
||||
|
||||
2012-05-02 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix loop mapping on readonly file.
|
||||
* Relax --shared test, allow mapping even for overlapping segments.
|
||||
* Support shared flag for LUKS devices (dangerous).
|
||||
* Switch on retry on device remove for libdevmapper.
|
||||
* Allow "private" activation (skip some udev global rules) flag.
|
||||
|
||||
2012-04-09 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix header check to support old (cryptsetup 1.0.0) header alignment. (1.4.0)
|
||||
* Version 1.4.2.
|
||||
|
||||
2012-03-16 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --keyfile-offset and --new-keyfile-offset parameters to API and CLI.
|
||||
* Add repair command and crypt_repair() for known LUKS metadata problems repair.
|
||||
* Allow to specify --align-payload only for luksFormat.
|
||||
|
||||
2012-03-16 Milan Broz <mbroz@redhat.com>
|
||||
* Unify password verification option.
|
||||
* Support password verification with quiet flag if possible. (1.2.0)
|
||||
* Fix retry if entered passphrases (with verify option) do not match.
|
||||
* Support UUID=<LUKS_UUID> format for device specification.
|
||||
|
||||
2012-02-11 Milan Broz <mbroz@redhat.com>
|
||||
* Add --master-key-file option to luksOpen (open using volume key).
|
||||
|
||||
2012-01-12 Milan Broz <mbroz@redhat.com>
|
||||
* Fix use of empty keyfile.
|
||||
|
||||
2011-11-13 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error message for luksClose and detached LUKS header.
|
||||
* Allow --header for status command to get full info with detached header.
|
||||
|
||||
2011-11-09 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.4.1.
|
||||
|
||||
2011-11-05 Milan Broz <mbroz@redhat.com>
|
||||
* Merge pycryptsetup (Python libcryptsetup bindings).
|
||||
* Fix stupid typo in set_iteration_time API call.
|
||||
* Fix cryptsetup status output if parameter is device path.
|
||||
|
||||
2011-10-27 Milan Broz <mbroz@redhat.com>
|
||||
* Fix crypt_get_volume_key_size() for plain device.
|
||||
* Fix FSF address in license text.
|
||||
|
||||
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.
|
||||
|
||||
2011-05-17 Milan Broz <mbroz@redhat.com>
|
||||
* Fix keyfile=- processing in create command (1.3.0).
|
||||
* Simplify device path status check.
|
||||
|
||||
2011-05-03 Milan Broz <mbroz@redhat.com>
|
||||
* Do not ignore size argument for create command (1.2.0).
|
||||
|
||||
2011-04-18 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error paths in blockwise code and lseek_write call.
|
||||
* Add Nettle crypto backend support.
|
||||
|
||||
2011-04-05 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.3.0.
|
||||
|
||||
2011-03-22 Milan Broz <mbroz@redhat.com>
|
||||
* Also support --skip and --hash option for loopaesOpen.
|
||||
* Fix return code when passphrase is read from pipe.
|
||||
* Document cryptsetup exit codes.
|
||||
|
||||
2011-03-18 Milan Broz <mbroz@redhat.com>
|
||||
* Respect maximum keyfile size paramater.
|
||||
* Introduce maximum default keyfile size, add configure option.
|
||||
* Require the whole key read from keyfile in create command (broken in 1.2.0).
|
||||
* Fix offset option for loopaesOpen.
|
||||
* Lock memory also in luksDump command.
|
||||
* Version 1.3.0-rc2.
|
||||
|
||||
2011-03-14 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.3.0-rc1.
|
||||
|
||||
2011-03-11 Milan Broz <mbroz@redhat.com>
|
||||
* Add loop manipulation code and support mapping of images in file.
|
||||
* Add backing device loop info into status message.
|
||||
* Add luksChangeKey command.
|
||||
|
||||
2011-03-05 Milan Broz <mbroz@redhat.com>
|
||||
* Add exception to COPYING for binary distribution linked with OpenSSL library.
|
||||
* Set secure data flag (wipe all ioclt buffers) if devmapper library supports it.
|
||||
|
||||
2011-01-29 Milan Broz <mbroz@redhat.com>
|
||||
* Fix mapping removal if device disappeared but node still exists.
|
||||
* Fix luksAddKey return code if master key is used.
|
||||
|
||||
2011-01-25 Milan Broz <mbroz@redhat.com>
|
||||
* Add loop-AES handling (loopaesOpen and loopaesClose commands).
|
||||
(requires kernel 2.6.38 and above)
|
||||
|
||||
2011-01-05 Milan Broz <mbroz@redhat.com>
|
||||
* Fix static build (--disable-static-cryptsetup now works properly).
|
||||
|
||||
2010-12-30 Milan Broz <mbroz@redhat.com>
|
||||
* Add compile time crypto backends implementation
|
||||
(gcrypt, OpenSSL, NSS and userspace Linux kernel crypto api).
|
||||
* Currently NSS is lacking ripemd160, cannot provide full plain compatibility.
|
||||
* Use --with-crypto_backend=[gcrypt|openssl|nss|kernel] to configure.
|
||||
|
||||
2010-12-20 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.2.0.
|
||||
|
||||
2010-11-25 Milan Broz <mbroz@redhat.com>
|
||||
* Fix crypt_activate_by_keyfile() to work with PLAIN devices.
|
||||
* Fix create command to properly handle keyfile size.
|
||||
|
||||
2010-11-16 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.2.0-rc1.
|
||||
|
||||
2010-11-13 Milan Broz <mbroz@redhat.com>
|
||||
* Fix password callback call.
|
||||
* Fix default plain password entry from terminal in activate_by_passphrase.
|
||||
* Add --dump-master-key option for luksDump to allow volume key dump.
|
||||
* Allow to activate by internally cached volume key
|
||||
(format/activate without keyslots active - used for temporary devices).
|
||||
* Initialize volume key from active device in crypt_init_by_name()
|
||||
* Fix cryptsetup binary exitcodes.
|
||||
* Increase library version (still binary compatible with 1.1.x release).
|
||||
|
||||
2010-11-01 Milan Broz <mbroz@redhat.com>
|
||||
* No longer support luksDelKey, reload and --non-exclusive.
|
||||
* Remove some obsolete info from man page.
|
||||
* Add crypt_get_type(), crypt_resize(), crypt_keyslot_max()
|
||||
and crypt_get_active_device() to API.
|
||||
* Rewrite all implementations in cryptsetup to new API.
|
||||
* Fix luksRemoveKey to behave as documented (do not ask
|
||||
for remaining keyslot passphrase).
|
||||
* Add more regression tests for commands.
|
||||
* Disallow mapping of device which is already in use (mapped or mounted).
|
||||
* Disallow luksFormat on device in use.
|
||||
|
||||
2010-10-27 Milan Broz <mbroz@redhat.com>
|
||||
* Rewrite cryptsetup luksFormat, luksOpen, luksAddKey to use new API
|
||||
to allow adding new features.
|
||||
* Implement --use-random and --use-urandom for luksFormat to allow
|
||||
setting of RNG for volume key generator.
|
||||
* Add crypt_set_rng_type() and crypt_get_rng_type() to API.
|
||||
* Add crypt_set_uuid() to API.
|
||||
* Allow UUID setting in luksFormat and luksUUID (--uuid parameter).
|
||||
* Add --keyfile-size and --new-keyfile-size (in bytes) size and disallow overloading
|
||||
of --key-size for limiting keyfile reads.
|
||||
* Fix luksFormat to properly use key file with --master-key-file switch.
|
||||
* Fix possible double free when handling master key file.
|
||||
|
||||
2010-10-17 Milan Broz <mbroz@redhat.com>
|
||||
* Add crypt_get_device_name() to API (get underlying device name).
|
||||
* Change detection for static libraries.
|
||||
* Fix pkg-config use in automake scripts.
|
||||
* Remove --disable-shared-library switch and handle static library build
|
||||
by common libtool logic (using --enable-static).
|
||||
* Add --enable-static-cryptsetup option to build cryptsetup.static binary
|
||||
together with shared build.
|
||||
|
||||
2010-08-05 Milan Broz <mbroz@redhat.com>
|
||||
* Wipe iteration and salt after KillSlot in LUKS header.
|
||||
* Rewrite file differ test to C (and fix it to really work).
|
||||
* Switch to 1MiB default alignment of data.
|
||||
For more info see https://bugzilla.redhat.com/show_bug.cgi?id=621684
|
||||
* Do not query non-existent device twice (cryptsetup status /dev/nonexistent).
|
||||
* Check if requested hash is supported before writing LUKS header.
|
||||
|
||||
2010-07-28 Arno Wagner <arno@wagner.name>
|
||||
* Add FAQ (Frequently Asked Questions) file to distribution.
|
||||
|
||||
2010-07-03 Milan Broz <mbroz@redhat.com>
|
||||
* Fix udev support for old libdevmapper with not compatible definition.
|
||||
* Version 1.1.3.
|
||||
|
||||
2010-06-01 Milan Broz <mbroz@redhat.com>
|
||||
* Fix device alignment ioctl calls parameters.
|
||||
* Fix activate_by_* API calls to handle NULL device name as documented.
|
||||
|
||||
2010-05-30 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.1.2.
|
||||
|
||||
2010-05-27 Milan Broz <mbroz@redhat.com>
|
||||
* Fix luksFormat/luksOpen reading passphrase from stdin and "-" keyfile.
|
||||
* Support --key-file/-d option for luksFormat.
|
||||
* Fix description of --key-file and add --verbose and --debug options to man page.
|
||||
* Add verbose log level and move unlocking message there.
|
||||
* Remove device even if underlying device disappeared.
|
||||
* Fix (deprecated) reload device command to accept new device argument.
|
||||
|
||||
2010-05-23 Milan Broz <mbroz@redhat.com>
|
||||
* Fix luksClose operation for stacked DM devices.
|
||||
* Version 1.1.1.
|
||||
|
||||
2010-05-03 Milan Broz <mbroz@redhat.com>
|
||||
* Fix automatic dm-crypt module loading.
|
||||
* Escape hyphens in man page.
|
||||
* Version 1.1.1-rc2.
|
||||
|
||||
2010-04-30 Milan Broz <mbroz@redhat.com>
|
||||
* Try to use pkgconfig for device mapper library.
|
||||
* Detect old dm-crypt module and disable LUKS suspend/resume.
|
||||
* Fix apitest to work on older systems.
|
||||
* Allow no hash specification in plain device constructor.
|
||||
* Fix luksOpen reading of passphrase on stdin (if "-" keyfile specified).
|
||||
* Fix isLuks to initialise crypto backend (blkid instead is suggested anyway).
|
||||
* Version 1.1.1-rc1.
|
||||
|
||||
2010-04-12 Milan Broz <mbroz@redhat.com>
|
||||
* Fix package config to use proper package version.
|
||||
* Avoid class C++ keyword in library header.
|
||||
* Detect and use devmapper udev support if available (disable by --disable-udev).
|
||||
|
||||
2010-04-06 Milan Broz <mbroz@redhat.com>
|
||||
* Prefer some device paths in status display.
|
||||
* Support device topology detectionfor data alignment.
|
||||
|
||||
2010-02-25 Milan Broz <mbroz@redhat.com>
|
||||
* Do not verify unlocking passphrase in luksAddKey command.
|
||||
* Properly initialise crypto backend in header backup/restore commands.
|
||||
|
||||
2010-01-17 Milan Broz <mbroz@redhat.com>
|
||||
* If gcrypt compiled with capabilities, document workaround for cryptsetup (see lib/gcrypt.c).
|
||||
* Version 1.1.0.
|
||||
|
||||
2010-01-10 Milan Broz <mbroz@redhat.com>
|
||||
* Fix initialisation of gcrypt duting luksFormat.
|
||||
* Convert hash name to lower case in header (fix sha1 backward comatible header)
|
||||
* Check for minimum required gcrypt version.
|
||||
|
||||
2009-12-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix key slot iteration count calculation (small -i value was the same as default).
|
||||
* The slot and key digest iteration minimun is now 1000.
|
||||
* The key digest iteration # is calculated from iteration time (approx 1/8 of that).
|
||||
* Version 1.1.0-rc4.
|
||||
|
||||
2009-12-11 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error handling during reading passhrase.
|
||||
|
||||
2009-12-01 Milan Broz <mbroz@redhat.com>
|
||||
* Allow changes of default compiled-in cipher parameters through configure.
|
||||
* Switch default key size for LUKS to 256bits.
|
||||
* Switch default plain mode to aes-cbc-essiv:sha256 (default is backward incompatible!).
|
||||
|
||||
2009-11-14 Milan Broz <mbroz@redhat.com>
|
||||
* Add CRYPT_ prefix to enum defined in libcryptsetup.h.
|
||||
* Fix status call to fail when running as non-root user.
|
||||
* Check in configure if selinux libraries are required in static version.
|
||||
* Add temporary debug code to find processes locking internal device.
|
||||
* Simplify build system, use autopoint and clean gettext processing.
|
||||
* Use proper NLS macros and detection (so the message translation works again).
|
||||
* Version 1.1.0-rc3.
|
||||
|
||||
2009-09-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix exported symbols and versions in libcryptsetup.
|
||||
* Do not use internal lib functions in cryptsetup.
|
||||
* Add crypt_log to library.
|
||||
* Fix crypt_remove_device (remove, luksClose) implementation.
|
||||
* Move dm backend initialisation to library calls.
|
||||
* Move duplicate Command failed message to verbose level (error is printed always).
|
||||
* Add some password and used algorithms notes to man page.
|
||||
* Version 1.1.0-rc2.
|
||||
|
||||
2009-09-28 Milan Broz <mbroz@redhat.com>
|
||||
* Add luksHeaderBackup and luksHeaderRestore commands.
|
||||
* Fail passphrase read if piped input no longer exists.
|
||||
* Version 1.1.0-rc1.
|
||||
|
||||
2009-09-15 Milan Broz <mbroz@redhat.com>
|
||||
* Initialize crypto library before LUKS header load.
|
||||
* Fix manpage to not require --size which expands to device size by default.
|
||||
|
||||
2009-09-10 Milan Broz <mbroz@redhat.com>
|
||||
* Clean up Makefiles and configure script.
|
||||
* Version 1.1.0-test0.
|
||||
|
||||
2009-09-08 Milan Broz <mbroz@redhat.com>
|
||||
* Use dm-uuid for all crypt devices, contains device type and name now.
|
||||
* Try to read first sector from device to properly check that device is ready.
|
||||
|
||||
2009-09-02 Milan Broz <mbroz@redhat.com>
|
||||
* Add luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase).
|
||||
|
||||
2009-08-30 Milan Broz <mbroz@redhat.com>
|
||||
* Require device device-mapper to build and do not use backend wrapper for dm calls.
|
||||
* Move memory locking and dm initialization to command layer.
|
||||
* Increase priority of process if memory is locked.
|
||||
* Add log macros and make logging modre consitent.
|
||||
* Move command successful messages to verbose level.
|
||||
* Introduce --debug parameter.
|
||||
* Move device utils code and provide context parameter (for log).
|
||||
* Keyfile now must be provided by path, only stdin file descriptor is used (api only).
|
||||
* Do not call isatty() on closed keyfile descriptor.
|
||||
* Run performance check for PBKDF2 from LUKS code, do not mix hash algoritms results.
|
||||
* Add ability to provide pre-generated master key and UUID in LUKS header format.
|
||||
* Add LUKS function to verify master key digest.
|
||||
* Move key slot manuipulation function into LUKS specific code.
|
||||
* Replace global options struct with separate parameters in helper functions.
|
||||
* Add new libcryptsetup API (documented in libcryptsetup.h).
|
||||
* Implement old API calls using new functions.
|
||||
* Remove old API code helper functions.
|
||||
* Add --master-key-file option for luksFormat and luksAddKey.
|
||||
|
||||
2009-08-17 Milan Broz <mbroz@redhat.com>
|
||||
* Fix PBKDF2 speed calculation for large passhrases.
|
||||
* Allow using passphrase provided in options struct for LuksOpen.
|
||||
* Allow restrict keys size in LuksOpen.
|
||||
|
||||
2009-07-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix errors when compiled with LUKS_DEBUG.
|
||||
* Print error when getline fails.
|
||||
* Remove po/cryptsetup-luks.pot, it's autogenerated.
|
||||
* Return ENOENT for empty keyslots, EINVAL will be used later for other type of error.
|
||||
* Switch PBKDF2 from internal SHA1 to libgcrypt, make hash algorithm not hardcoded to SHA1 here.
|
||||
* Add required parameters for changing hash used in LUKS key setup scheme.
|
||||
* Do not export simple XOR helper now used only inside AF functions.
|
||||
* Completely remove internal SHA1 implementanion code, not needed anymore.
|
||||
* Enable hash algorithm selection for LUKS through -h luksFormat option.
|
||||
|
||||
2009-07-28 Milan Broz <mbroz@redhat.com>
|
||||
* Pad luks header to 512 sector size.
|
||||
* Rework read/write blockwise to not split operation to many pieces.
|
||||
* Use posix_memalign if available.
|
||||
|
||||
2009-07-22 Milan Broz <mbroz@redhat.com>
|
||||
* Fix segfault if provided slot in luksKillslot is invalid.
|
||||
* Remove unneeded timeout when remove of temporary device succeeded.
|
||||
|
||||
2009-07-22 Milan Broz <mbroz@redhat.com>
|
||||
* version 1.0.7
|
||||
|
||||
2009-07-16 Milan Broz <mbroz@redhat.com>
|
||||
* Allow removal of last slot in luksRemoveKey and luksKillSlot.
|
||||
|
||||
2009-07-11 Milan Broz <mbroz@redhat.com>
|
||||
|
||||
* Add --disable-selinux option and fix static build if selinux is required.
|
||||
* Reject unsupported --offset and --skip options for luksFormat and update man page.
|
||||
|
||||
2009-06-22 Milan Broz <mbroz@redhat.com>
|
||||
|
||||
* Summary of changes in subversion for 1.0.7-rc1:
|
||||
* Various man page fixes.
|
||||
* Set UUID in device-mapper for LUKS devices.
|
||||
* Retain readahead of underlying device.
|
||||
* Display device name when asking for password.
|
||||
* Check device size when loading LUKS header. Remove misleading error message later.
|
||||
* Add error hint if dm-crypt mapping failed.
|
||||
* Use better error messages if device doesn't exist or is already used by other mapping.
|
||||
* Fix make distcheck.
|
||||
* Check if all slots are full during luksAddKey.
|
||||
* Fix segfault in set_error.
|
||||
* Code cleanups, remove precompiled pot files, remove unnecessary files from po directory
|
||||
* Fix uninitialized return value variable in setup.c.
|
||||
* Code cleanups. (thanks to Ivan Stankovic)
|
||||
* Fix wrong output for remaining key at key deletion.
|
||||
* Allow deletion of key slot while other keys have the same key information.
|
||||
* Add missing AM_PROG_CC_C_O to configure.in
|
||||
* Remove duplicate sentence in man page.
|
||||
* Wipe start of device (possible fs signature) before LUKS-formatting.
|
||||
* Do not process configure.in in hidden directories.
|
||||
* Return more descriptive error in case of IO or header format error.
|
||||
* Use remapping to error target instead of calling udevsettle for temporary crypt device.
|
||||
* Check device mapper communication and warn user if device-mapper support missing in kernel.
|
||||
* Fix signal handler to properly close device.
|
||||
* write_lseek_blockwise: declare innerCount outside the if block.
|
||||
* add -Wall to the default CFLAGS. fix some signedness issues.
|
||||
* Error handling improvement.
|
||||
* Add non-exclusive override to interface definition.
|
||||
* Refactor key slot selection into keyslot_from_option.
|
||||
|
||||
2007-05-01 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/backends.c, man/cryptsetup.8: Apply patch from Ludwig Nussel
|
||||
<ludwig.nussel@suse.de>, for old SuSE compat hashing.
|
||||
|
||||
2007-04-16 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Summary of changes in subversion:
|
||||
Fix segfault for key size > 32 bytes.
|
||||
Kick ancient header version conversion.
|
||||
Fix http://bugs.debian.org/403075
|
||||
No passwort retrying for I/O errors.
|
||||
Fix hang on "-i 0".
|
||||
Fix parenthesization error that prevented --tries from working
|
||||
correctly.
|
||||
|
||||
2006-11-28 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* m4/gettext.m4: Upgrade to gettext-0.15.
|
||||
* m4/glibc2.m4: New file, from gettext-0.15.
|
||||
* m4/intmax.m4: New file, from gettext-0.15.
|
||||
* m4/inttypes-h.m4: New file, from gettext-0.15.
|
||||
* m4/inttypes-pri.m4: Upgrade to gettext-0.15.
|
||||
* m4/lib-link.m4: Upgrade to gettext-0.15.
|
||||
* m4/lib-prefix.m4: Upgrade to gettext-0.15.
|
||||
* m4/lock.m4: New file, from gettext-0.15.
|
||||
* m4/longdouble.m4: New file, from gettext-0.15.
|
||||
* m4/longlong.m4: New file, from gettext-0.15.
|
||||
* m4/nls.m4: Upgrade to gettext-0.15.
|
||||
* m4/po.m4: Upgrade to gettext-0.15.
|
||||
* m4/printf-posix.m4: New file, from gettext-0.15.
|
||||
* m4/signed.m4: New file, from gettext-0.15.
|
||||
* m4/size_max.m4: New file, from gettext-0.15.
|
||||
* m4/visibility.m4: New file, from gettext-0.15.
|
||||
* m4/wchar_t.m4: New file, from gettext-0.15.
|
||||
* m4/wint_t.m4: New file, from gettext-0.15.
|
||||
* m4/xsize.m4: New file, from gettext-0.15.
|
||||
* m4/Makefile.am: New file.
|
||||
* configure.in (AC_OUTPUT): Add m4/Makefile.
|
||||
(AM_GNU_GETTEXT_VERSION): Bump to 0.15.
|
||||
|
||||
2006-10-22 David Härdeman <david@hardeman.nu>
|
||||
|
||||
* Allow hashing of keys passed through stdin.
|
||||
|
||||
2006-10-13 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.4 release
|
||||
|
||||
2006-10-13 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: Document --tries switch; patch by Jonas
|
||||
Meurer.
|
||||
|
||||
2006-10-13 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c: Added terminal timeout rewrite as forwarded by
|
||||
Jonas Meurer
|
||||
|
||||
2006-10-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Merged patch from Marc Merlin <marc@merlins.org> to allow user
|
||||
selection of key slot.
|
||||
|
||||
2006-09-26 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* m4/codeset.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/gettext.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/glibc2.m4: New file, from gettext-0.14.4.
|
||||
* m4/glibc21.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/iconv.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/intdiv0.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/intmax.m4: New file, from gettext-0.14.4.
|
||||
* m4/inttypes.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/inttypes_h.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/inttypes-pri.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/isc-posix.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lcmessage.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lib-ld.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lib-link.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/lib-prefix.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/longdouble.m4: New file, from gettext-0.14.4.
|
||||
* m4/longlong.m4: New file, from gettext-0.14.4.
|
||||
* m4/nls.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/po.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/printf-posix.m4: New file, from gettext-0.14.4.
|
||||
* m4/progtest.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/signed.m4: New file, from gettext-0.14.4.
|
||||
* m4/size_max.m4: New file, from gettext-0.14.4.
|
||||
* m4/stdint_h.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/uintmax_t.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/ulonglong.m4: Upgrade to gettext-0.14.4.
|
||||
* m4/wchar_t.m4: New file, from gettext-0.14.4.
|
||||
* m4/wint_t.m4: New file, from gettext-0.14.4.
|
||||
* m4/xsize.m4: New file, from gettext-0.14.4.
|
||||
* Makefile.am (ACLOCAL_AMFLAGS): New variable.
|
||||
* configure.in (AM_GNU_GETTEXT_VERSION): Bump to 0.14.4.
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.4-rc2
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/Makefile.am: Add a few regression tests
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* 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.
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (__crypt_luks_add_key): For checking options struct
|
||||
(optionsCheck) filter out CRYPT_FLAG_VERIFY and
|
||||
CRYPT_FLAG_VERIFY_IF_POSSIBLE, so that in no case password verification is done
|
||||
for password retrieval.
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Merge Patch from http://bugs.gentoo.org/show_bug.cgi?id=132126 for sepol
|
||||
|
||||
2006-07-23 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Applied patches from David Härdeman <david@2gen.com> to fix 64
|
||||
bit compiler warning issues.
|
||||
|
||||
2006-05-19 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Applied patches from Jonas Meurer
|
||||
- fix terminal status after timeout
|
||||
- add remark for --tries to manpage
|
||||
- allow more than 32 chars from standard input.
|
||||
- exit status fix for cryptsetup status.
|
||||
|
||||
2006-05-06 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (yesDialog): Fix getline problem for 64-bit archs.
|
||||
|
||||
2006-04-05 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Release 1.0.3.
|
||||
|
||||
* Applied patch by Johannes Weißl for more meaningful exit codes
|
||||
and password retries
|
||||
|
||||
2006-03-30 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (__crypt_create_device): (char *) -> (const char *)
|
||||
|
||||
2006-03-30 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Apply alignPayload patch from Peter Palfrader <weasel@debian.org>
|
||||
|
||||
2006-03-15 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.3-rc3. Most unplease release ever.
|
||||
* lib/setup.c (__crypt_create_device): More verbose error message.
|
||||
|
||||
2006-02-26 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c: Revert to 1.0.1 key reading.
|
||||
|
||||
2006-02-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: merge patch from Jonas Meurer
|
||||
|
||||
2006-02-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: 1.0.3-rc2
|
||||
|
||||
2006-02-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/libdevmapper.c (dm_create_device): Remove dup check here.
|
||||
* lib/setup.c (__crypt_luks_open): Adopt same dup check as regular
|
||||
create command.
|
||||
|
||||
2006-02-22 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Spin 1.0.3-rc1
|
||||
|
||||
2006-02-22 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (action_create): Change defaulting.
|
||||
(action_luksFormat): Change defaulting.
|
||||
|
||||
* lib/setup.c (parse_into_name_and_mode): Revert that default
|
||||
change. This is FORBIDDEN here, as it will change cryptsetup
|
||||
entire default. This is BAD in a non-LUKS world.
|
||||
|
||||
2006-02-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keyencryption.c (setup_mapping): Add proper size restriction to mapping.
|
||||
(LUKS_endec_template): Add more verbose error message.
|
||||
|
||||
2006-02-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/libdevmapper.c (dm_query_device): Incorporate patch from
|
||||
Bastian Blank
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=344313
|
||||
|
||||
2006-02-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c: Rename show_error -> show_status.
|
||||
|
||||
2006-02-20 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/libdevmapper.c (dm_create_device): Prevent existing mapping
|
||||
from being removed when a mapping with the same name is added
|
||||
|
||||
* Add timeout patch from Jonas Meurer
|
||||
|
||||
* src/cryptsetup.c: Remove conditional error printing to enable
|
||||
printing the no-error msg (Command successful). Verify passphrase
|
||||
for LUKS volumes.
|
||||
(main): Add no-verify-passphrase
|
||||
|
||||
* lib/setup.c (parse_into_name_and_mode): Change default mode complition to essiv:sha256.
|
||||
|
||||
2006-01-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (help): Merge patch from Gentoo: change gettext(..) to _(..).
|
||||
|
||||
2005-12-06 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: Correct "seconds" to "microseconds" in the explaination for -i.
|
||||
|
||||
2005-11-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (main): Add version string.
|
||||
|
||||
2005-11-08 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/backends.c: compile fix.
|
||||
|
||||
2005-09-11 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (get_key): Fixed another incompatibility from my
|
||||
get_key rewrite with original cryptsetup.
|
||||
|
||||
2005-09-11 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Merged changes from Florian Knauf's fk02 branch.
|
||||
|
||||
2005-09-08 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (get_key): Fixed another incompatiblity with
|
||||
original cryptsetup.
|
||||
|
||||
2005-08-20 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Checked in a patch from Michael Gebetsroither <gebi@sbox.tugraz.at>
|
||||
to silent all confirmation dialogs.
|
||||
|
||||
2005-06-23 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c (help): print PACKAGE_STRING
|
||||
|
||||
2005-06-20 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keymanage.c (LUKS_set_key): Security check against header manipulation
|
||||
|
||||
* src/cryptsetup.c (action_luksDelKey): Safety check in luksDelKey
|
||||
|
||||
* luks/keymanage.c: Changed disk layout generation to align key material to 4k boundaries.
|
||||
(LUKS_is_last_keyslot): Added LUKS_is_last_keyslot function.
|
||||
|
||||
* Applied patch from Bill Nottingham fixing a lot of prototypes.
|
||||
|
||||
* src/cryptsetup.c (action_luksOpen): Add support for -r flag.
|
||||
|
||||
* configure.in: Version bump 1.0.1
|
||||
|
||||
2005-06-16 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (__crypt_luks_open): Remove mem leaking of dmCipherSpec.
|
||||
(get_key): Fix missing zero termination for read string.
|
||||
|
||||
2005-06-12 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keyencryption.c (setup_mapping): Added CRYPT_FLAG_READONLY in case of O_RDONLY mode
|
||||
|
||||
2005-06-11 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: Version bump 1.0.1-pre
|
||||
|
||||
2005-06-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/utils.c: Added write_llseek_blocksize method to support sector wiping on sector_size != 512
|
||||
media
|
||||
|
||||
2005-05-23 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (crypt_luksDelKey): Added missing return statement
|
||||
(setup_leave): Added missing return statement
|
||||
|
||||
* luks/keyencryption.c (clear_mapping): Added missing return statement
|
||||
|
||||
2005-05-19 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/utils.c (write_blockwise, read_blockwise): Changed to soft bsize instead of SECTOR_SIZE
|
||||
|
||||
* luks/keymanage.c (wipe): Changed open mode to O_DIRECT | O_SYNC, and changed write
|
||||
to use the blockwise write helper
|
||||
|
||||
2005-04-21 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.8: Corrected an error, thanks to Dick Middleton.
|
||||
|
||||
2005-04-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/sha/hmac.c: Add 64 bit bug fix courtesy to
|
||||
Oliver Paukstadt <pstadt@sourcentral.org>.
|
||||
|
||||
* luks/pbkdf.c, luks/keyencryption.c, luks/keymanage.c, luks/af.c: Added a license
|
||||
disclaimer and remove option for "any future GPL versions".
|
||||
|
||||
2005-03-25 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* configure.in: man page Makefile. Version bump 1.0.
|
||||
|
||||
* man/cryptsetup.8: finalize man page and move to section 8.
|
||||
|
||||
* src/cryptsetup.c (action_luksFormat): Add "are you sure" for interactive sessions.
|
||||
|
||||
* lib/setup.c (crypt_luksDump), src/cryptsetup.c: add LUKS dump command
|
||||
|
||||
2005-03-24 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* src/cryptsetup.c, luks/Makefile.am (test), lib/setup.c (setup_enter):
|
||||
rename luksInit to luksFormat
|
||||
|
||||
2005-03-12 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* man/cryptsetup.1: Add man page.
|
||||
|
||||
* lib/setup.c: Remove unneccessary LUKS_write_phdr call, so the
|
||||
phdr is written after passphrase reading, so the user can change
|
||||
his mind, and not have a partial written LUKS header on it's disk.
|
||||
|
||||
2005-02-09 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* luks/keymanage.c (LUKS_write_phdr): converted argument phdr to
|
||||
pointer, and make a copy of phdr for conversion
|
||||
|
||||
* configure.in: Version dump.
|
||||
|
||||
* luks/keyencryption.c: Convert to read|write_blockwise.
|
||||
|
||||
* luks/keymanage.c: Convert to read|write_blockwise.
|
||||
|
||||
* lib/utils.c: Add read|write_blockwise functions, to use in
|
||||
O_DIRECT file accesses.
|
||||
|
||||
2004-03-11 Thursday 15:52 Jana Saout <jana@saout.de>
|
||||
|
||||
* lib/blockdev.h: BLKGETSIZE64 really uses size_t as third
|
||||
argument, the rest is wrong.
|
||||
|
||||
2004-03-10 Wednesday 17:50 Jana Saout <jana@saout.de>
|
||||
|
||||
* lib/: libcryptsetup.h, libdevmapper.c: Small fixes.
|
||||
|
||||
2004-03-09 Tuesday 21:41 Jana Saout <jana@saout.de>
|
||||
|
||||
* lib/internal.h, lib/libcryptsetup.h, lib/libdevmapper.c,
|
||||
lib/setup.c, po/de.po, src/cryptsetup.c: Added internal flags to
|
||||
keep track of malloc'ed return values in struct crypt_options and
|
||||
add a function to free the memory. Also add a readonly flag to
|
||||
libcryptsetup.
|
||||
|
||||
2004-03-09 Tuesday 16:03 Jana Saout <jana@saout.de>
|
||||
|
||||
* ChangeLog, configure.in, setup-gettext, lib/Makefile.am,
|
||||
lib/backends.c, lib/blockdev.h, lib/gcrypt.c, lib/internal.h,
|
||||
lib/libcryptsetup.h, lib/libdevmapper.c, lib/setup.c,
|
||||
lib/utils.c, po/de.po, src/Makefile.am, src/cryptsetup.c: More
|
||||
reorganization work.
|
||||
|
||||
2004-03-08 Monday 01:38 Jana Saout <jana@saout.de>
|
||||
|
||||
* ChangeLog, Makefile.am, acinclude.m4, configure.in,
|
||||
lib/Makefile.am, lib/backends.c, lib/blockdev.h, lib/gcrypt.c,
|
||||
lib/libdevmapper.c, lib/setup.c, lib/utils.c, po/de.po,
|
||||
src/Makefile.am: BLKGETSIZE64 fixes and started modularity
|
||||
enhancements
|
||||
|
||||
2004-03-04 Thursday 21:06 Jana Saout <jana@saout.de>
|
||||
|
||||
* Makefile.am, po/de.po, src/cryptsetup.c, src/cryptsetup.h: First
|
||||
backward compatible working version.
|
||||
|
||||
2004-03-04 Thursday 00:42 Jana Saout <jana@saout.de>
|
||||
|
||||
* NEWS, AUTHORS, ChangeLog, Makefile.am, README, autogen.sh,
|
||||
configure.in, setup-gettext, po/ChangeLog, po/LINGUAS,
|
||||
po/POTFILES.in, po/de.po, src/cryptsetup.c, src/cryptsetup.h,
|
||||
src/Makefile.am (utags: initial): Initial checkin.
|
||||
|
||||
2004-03-04 Thursday 00:42 Jana Saout <jana@saout.de>
|
||||
|
||||
* NEWS, AUTHORS, ChangeLog, Makefile.am, README, autogen.sh,
|
||||
configure.in, setup-gettext, po/ChangeLog, po/LINGUAS,
|
||||
po/POTFILES.in, po/de.po, src/cryptsetup.c, src/cryptsetup.h,
|
||||
src/Makefile.am: Initial revision
|
||||
32
docs/v1.5.1-ReleaseNotes
Normal file
32
docs/v1.5.1-ReleaseNotes
Normal file
@@ -0,0 +1,32 @@
|
||||
Cryptsetup 1.5.1 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.5.0
|
||||
|
||||
* The libcryptsetup library now tries to initialize device-mapper backend and
|
||||
loop devices only if they are really needed (lazy initializations).
|
||||
This allows some operations to be run by a non-root user.
|
||||
|
||||
(Unfortunately LUKS header keyslot operations still require temporary dm-crypt
|
||||
device and device-mapper subsystem is available only to superuser.)
|
||||
|
||||
Also clear error messages are provided if running as non-root user and
|
||||
operation requires privileged user.
|
||||
|
||||
* Veritysetup can be now used by a normal user for creating hash image to file
|
||||
and also it can create hash image if doesn't exist.
|
||||
(Previously it required pre-allocated space.)
|
||||
|
||||
* Added crypt_keyslot_area() API call which allows external tools
|
||||
to get exact keyslot offsets and analyse content.
|
||||
|
||||
An example of a tool that searches the keyslot area of a LUKS container
|
||||
for positions where entropy is low and hence there is a high probability
|
||||
of damage is in misc/kesylot_checker.
|
||||
(Thanks to Arno Wagner for the code.)
|
||||
|
||||
* Optimized seek to keyfile-offset if key offset is large.
|
||||
|
||||
* Fixed luksHeaderBackup for very old v1.0 unaligned LUKS headers.
|
||||
|
||||
* Various fixes for problems found by a several static analysis tools.
|
||||
261
docs/v1.6.0-ReleaseNotes
Normal file
261
docs/v1.6.0-ReleaseNotes
Normal file
@@ -0,0 +1,261 @@
|
||||
Cryptsetup 1.6.0 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.0-rc1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Change LUKS default cipher to to use XTS encryption mode,
|
||||
aes-xts-plain64 (i.e. using AES128-XTS).
|
||||
|
||||
XTS mode becomes standard in hard disk encryption.
|
||||
|
||||
You can still use any old mode:
|
||||
- compile cryptsetup with old default:
|
||||
configure --with-luks1-cipher=aes --with-luks1-mode=cbc-essiv:sha256 --with-luks1-keybits=256
|
||||
- format LUKS device with old default:
|
||||
cryptsetup luksFormat -c aes-cbc-essiv:sha256 -s 256 <device>
|
||||
|
||||
|
||||
* Skip tests and fix error messages if running on old systems (or with old kernel).
|
||||
|
||||
* Rename configure.in to configure.ac and fix issues with new automake and pkgconfig
|
||||
and --disable-kernel_crypto option to allow compilation with old kernel headers.
|
||||
|
||||
* Allow repair of 512 bits key header.
|
||||
|
||||
* Fix status of device if path argument is used and fix double path prefix
|
||||
for non-existent device path.
|
||||
|
||||
|
||||
Changes since version 1.5.1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Important changes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Cryptsetup and libcryptsetup is now released under GPLv2+
|
||||
(GPL version 2 or any later).
|
||||
Some internal code handling files (loopaes, verity, tcrypt
|
||||
and crypto backend wrapper) are LGPLv2+.
|
||||
|
||||
Previously code was GPL version 2 only.
|
||||
|
||||
|
||||
* Introducing new unified command open and close.
|
||||
|
||||
Example:
|
||||
cryptsetup open --type plain|luks|loopaes|tcrypt <device> <name>
|
||||
(type defaults to luks)
|
||||
|
||||
with backward-compatible aliases plainOpen, luksOpen, loopaesOpen,
|
||||
tcryptOpen. Basically "open --type xyz" has alias "xyzOpen".
|
||||
|
||||
The "create" command (plain device create) is DEPRECATED but will
|
||||
be still supported.
|
||||
(This command is confusing because of switched arguments order.)
|
||||
|
||||
The close command is generic command to remove mapping and have
|
||||
backward compatible aliases (remove, luksClose, ...) which behaves
|
||||
exactly the same.
|
||||
|
||||
While all old syntax is still supported, I strongly suggest to use
|
||||
new command syntax which is common for all device types (and possible
|
||||
new formats added in future).
|
||||
|
||||
|
||||
* cryptsetup now support directly TCRYPT (TrueCrypt and compatible tc-play)
|
||||
on-disk format
|
||||
(Code is independent implementation not related to original project).
|
||||
|
||||
Only dump (tcryptDump command) and activation (open --type tcrypt or tcryptOpen)
|
||||
of TCRYPT device are supported. No header changes are supported.
|
||||
|
||||
It is intended to easily access containers shared with other operating systems
|
||||
without need to install 3rd party software. For native Linux installations LUKS
|
||||
is the preferred format.
|
||||
|
||||
WARNING: TCRYPT extension requires kernel userspace crypto API to be
|
||||
available (introduced in Linux kernel 2.6.38).
|
||||
If you are configuring kernel yourself, enable "User-space interface
|
||||
for symmetric key cipher algorithms" in "Cryptographic API" section
|
||||
(CRYPTO_USER_API_SKCIPHER .config option).
|
||||
|
||||
Because TCRYPT header is encrypted, you have to always provide valid
|
||||
passphrase and keyfiles. Keyfiles are handled exactly the same as in original
|
||||
format (basically, first 1MB of every keyfile is mixed using CRC32 into pool).
|
||||
|
||||
Cryptsetup should recognize all TCRYPT header variants ever released, except
|
||||
legacy cipher chains using LRW encryption mode with 64 bits encryption block
|
||||
(namely Blowfish in LRW mode is not recognized, this is limitation of kernel
|
||||
crypto API).
|
||||
|
||||
Device activation is supported only for LRW/XTS modes (again, limitation
|
||||
of kernel dmcrypt which do not implements TCRYPT extensions to CBC mode).
|
||||
(So old containers cannot be activated, but you can use libcryptsetup
|
||||
for lost password search, example of such code is included in misc directory.)
|
||||
|
||||
Hidden header are supported using --tcrypt-hidden option, system encryption
|
||||
using --tcrypt-system option.
|
||||
|
||||
For detailed description see man page.
|
||||
|
||||
EXAMPLE:
|
||||
* Dump device parameters of container in file:
|
||||
|
||||
# cryptsetup tcryptDump tst
|
||||
Enter passphrase:
|
||||
|
||||
TCRYPT header information for tst
|
||||
Version: 5
|
||||
Driver req.: 7
|
||||
Sector size: 512
|
||||
MK offset: 131072
|
||||
PBKDF2 hash: sha512
|
||||
Cipher chain: serpent-twofish-aes
|
||||
Cipher mode: xts-plain64
|
||||
MK bits: 1536
|
||||
|
||||
You can also dump master key using --dump-master-key.
|
||||
Dump does not require superuser privilege.
|
||||
|
||||
* Activation of this container
|
||||
|
||||
# cryptsetup tcryptOpen tst tcrypt_dev
|
||||
Enter passphrase:
|
||||
(Chain of dmcrypt devices is activated as /dev/mapper/tcrypt_dev.)
|
||||
|
||||
* See status of active TCRYPT device
|
||||
|
||||
# cryptsetup status tcrypt_dev
|
||||
|
||||
/dev/mapper/tcrypt_dev is active.
|
||||
type: TCRYPT
|
||||
cipher: serpent-twofish-aes-xts-plain64
|
||||
keysize: 1536 bits
|
||||
device: /dev/loop0
|
||||
loop: /tmp/tst
|
||||
offset: 256 sectors
|
||||
size: 65024 sectors
|
||||
skipped: 256 sectors
|
||||
mode: read/write
|
||||
|
||||
* And plaintext filesystem now ready to mount
|
||||
|
||||
# blkid /dev/mapper/tcrypt_dev
|
||||
/dev/mapper/tcrypt_dev: SEC_TYPE="msdos" UUID="9F33-2954" TYPE="vfat"
|
||||
|
||||
|
||||
* Add (optional) support for lipwquality for new LUKS passwords.
|
||||
|
||||
If password is entered through terminal (no keyfile specified)
|
||||
and cryptsetup is compiled with --enable-pwquality, default
|
||||
system pwquality settings are used to check password quality.
|
||||
|
||||
You can always override this check by using new --force-password option.
|
||||
|
||||
For more info about pwquality project see http://libpwquality.fedorahosted.org/
|
||||
|
||||
|
||||
* Proper handle interrupt signals (ctrl+c and TERM signal) in tools
|
||||
|
||||
Code should now handle interrupt properly, release and explicitly wipe
|
||||
in-memory key materials on interrupt.
|
||||
(Direct users of libcryptsetup should always call crypt_free() when
|
||||
code is interrupted to wipe all resources. There is no signal handling
|
||||
in library, it is up to the tool using it.)
|
||||
|
||||
|
||||
* Add new benchmark command
|
||||
|
||||
The "benchmark" command now tries to benchmark PBKDF2 and some block
|
||||
cipher variants. You can specify you own parameters (--cipher/--key-size
|
||||
for block ciphers, --hash for PBKDF2).
|
||||
|
||||
See man page for detailed description.
|
||||
|
||||
WARNING: benchmark command requires kernel userspace crypto API to be
|
||||
available (introduced in Linux kernel 2.6.38).
|
||||
If you are configuring kernel yourself, enable "User-space interface
|
||||
for symmetric key cipher algorithms" in "Cryptographic API" section
|
||||
(CRYPTO_USER_API_SKCIPHER .config option).
|
||||
|
||||
EXAMPLE:
|
||||
# cryptsetup benchmark
|
||||
# Tests are approximate using memory only (no storage IO).
|
||||
PBKDF2-sha1 111077 iterations per second
|
||||
PBKDF2-sha256 53718 iterations per second
|
||||
PBKDF2-sha512 18832 iterations per second
|
||||
PBKDF2-ripemd160 89775 iterations per second
|
||||
PBKDF2-whirlpool 23918 iterations per second
|
||||
# Algorithm | Key | Encryption | Decryption
|
||||
aes-cbc 128b 212.0 MiB/s 428.0 MiB/s
|
||||
serpent-cbc 128b 23.1 MiB/s 66.0 MiB/s
|
||||
twofish-cbc 128b 46.1 MiB/s 50.5 MiB/s
|
||||
aes-cbc 256b 163.0 MiB/s 350.0 MiB/s
|
||||
serpent-cbc 256b 23.1 MiB/s 66.0 MiB/s
|
||||
twofish-cbc 256b 47.0 MiB/s 50.0 MiB/s
|
||||
aes-xts 256b 190.0 MiB/s 190.0 MiB/s
|
||||
serpent-xts 256b 58.4 MiB/s 58.0 MiB/s
|
||||
twofish-xts 256b 49.0 MiB/s 49.5 MiB/s
|
||||
aes-xts 512b 175.0 MiB/s 175.0 MiB/s
|
||||
serpent-xts 512b 59.0 MiB/s 58.0 MiB/s
|
||||
twofish-xts 512b 48.5 MiB/s 49.5 MiB/s
|
||||
|
||||
Or you can specify cipher yourself:
|
||||
# cryptsetup benchmark --cipher cast5-cbc-essiv:sha256 -s 128
|
||||
# Tests are approximate using memory only (no storage IO).
|
||||
# Algorithm | Key | Encryption | Decryption
|
||||
cast5-cbc 128b 32.4 MiB/s 35.0 MiB/s
|
||||
|
||||
WARNING: these tests do not use dmcrypt, only crypto API.
|
||||
You have to benchmark the whole device stack and you can get completely
|
||||
different results. But is is usable for basic comparison.
|
||||
(Note for example AES-NI decryption optimization effect in example above.)
|
||||
|
||||
Features
|
||||
~~~~~~~~
|
||||
|
||||
* Do not maintain ChangeLog file anymore, see git log for detailed changes,
|
||||
e.g. here http://code.google.com/p/cryptsetup/source/list
|
||||
|
||||
* Move change key into library, add crypt_keyslot_change_by_passphrase().
|
||||
This change is useful mainly in FIPS mode, where we cannot
|
||||
extract volume key directly from libcryptsetup.
|
||||
|
||||
* Add verbose messages during reencryption.
|
||||
|
||||
* Default LUKS PBKDF2 iteration time is now configurable.
|
||||
|
||||
* Add simple cipher benchmarking API.
|
||||
|
||||
* Add kernel skcipher backend.
|
||||
|
||||
* Add CRC32 implementation (for TCRYPT).
|
||||
|
||||
* Move PBKDF2 into crypto backend wrapper.
|
||||
This allows use it in other formats, use library implementations and
|
||||
also possible use of different KDF function in future.
|
||||
|
||||
* New PBKDF2 benchmark using getrusage().
|
||||
|
||||
Fixes
|
||||
~~~~~
|
||||
|
||||
* Avoid O_DIRECT open if underlying storage doesn't support it.
|
||||
|
||||
* Fix some non-translated messages.
|
||||
|
||||
* Fix regression in header backup (1.5.1) with container in file.
|
||||
|
||||
* Fix blockwise read/write for end writes near end of device.
|
||||
(was not used in previous versions)
|
||||
|
||||
* Ignore setpriority failure.
|
||||
|
||||
* Code changes to fix/ignore problems found by Coverity static analysis, including
|
||||
- Get page size should never fail.
|
||||
- Fix time of check/use (TOCTOU test) in tools
|
||||
- Fix time of check/use in loop/wipe utils.
|
||||
- Fix time of check/use in device utils.
|
||||
|
||||
* Disallow header restore if context is non-LUKS device.
|
||||
32
docs/v1.6.1-ReleaseNotes
Normal file
32
docs/v1.6.1-ReleaseNotes
Normal file
@@ -0,0 +1,32 @@
|
||||
Cryptsetup 1.6.1 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.0
|
||||
|
||||
* Fix loop-AES keyfile parsing.
|
||||
Loop-AES keyfile should be text keyfile, reject keyfiles which
|
||||
are not properly terminated.
|
||||
|
||||
* Fix passphrase pool overflow for too long TCRYPT passphrase.
|
||||
(Maximal TCRYPT passphrase length is 64 characters.)
|
||||
|
||||
* Return EPERM (translated to exit code 2) for too long TCRYPT passphrase.
|
||||
|
||||
* Fix deactivation of device when failed underlying node disappeared.
|
||||
|
||||
* Fix API deactivate call for TCRYPT format and NULL context parameter.
|
||||
|
||||
* Improve keyslot checker example documentation.
|
||||
|
||||
* Report error message if deactivation fails and device is still busy.
|
||||
|
||||
* Make passphrase prompts more consistent (and remove "LUKS" form prompt).
|
||||
|
||||
* Fix some missing headers (compilation failed with alternative libc).
|
||||
|
||||
* Remove not functional API UUID support for plain & loopaes devices.
|
||||
(not persistent activation UUID).
|
||||
|
||||
* Properly cleanup devices on interrupt in api-test.
|
||||
|
||||
* Support all tests run if kernel is in FIPS mode.
|
||||
25
docs/v1.6.2-ReleaseNotes
Normal file
25
docs/v1.6.2-ReleaseNotes
Normal file
@@ -0,0 +1,25 @@
|
||||
Cryptsetup 1.6.2 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.1
|
||||
|
||||
* Print error and fail if more device arguments are present for isLuks command.
|
||||
|
||||
* Fix cipher specification string parsing (found by gcc -fsanitize=address option).
|
||||
|
||||
* Try to map TCRYPT system encryption through partition
|
||||
(allows to activate mapping when other partition on the same device is mounted).
|
||||
|
||||
* Print a warning if system encryption is used and device is a partition.
|
||||
(TCRYPT system encryption uses whole device argument.)
|
||||
|
||||
* Disallow explicit small payload offset for LUKS detached header.
|
||||
LUKS detached header only allows data payload 0 (whole data device is used)
|
||||
or explicit offset larger than header + keyslots size.
|
||||
|
||||
* Fix boundary condition for verity device that caused failure for certain device sizes.
|
||||
|
||||
* Various fixes to documentation, including update FAQ, default modes
|
||||
and TCRYPT description.
|
||||
|
||||
* Workaround for some recent changes in automake (serial-tests).
|
||||
50
docs/v1.6.3-ReleaseNotes
Normal file
50
docs/v1.6.3-ReleaseNotes
Normal file
@@ -0,0 +1,50 @@
|
||||
Cryptsetup 1.6.3 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.2
|
||||
|
||||
* Fix cryptsetup reencryption tool to work properly
|
||||
with devices using 4kB sectors.
|
||||
|
||||
* Always use page size if running through loop device,
|
||||
this fixes failures for external LUKS header and
|
||||
filesystem requiring 4kB block size.
|
||||
|
||||
* Fix TCRYPT system encryption mapping for multiple partitions.
|
||||
Since this commit, one can use partition directly as device parameter.
|
||||
If you need to activate such partition from image in file,
|
||||
please first use map partitioned loop device (losetup -P)
|
||||
on image.
|
||||
(Cryptsetup require partition offsets visible in kernel sysfs
|
||||
in this mode.)
|
||||
|
||||
* Support activation of old TrueCrypt containers using CBC mode
|
||||
and whitening (created in TrueCrypt version < 4.1).
|
||||
This requires Linux kernel 3.13 or later.
|
||||
(Containers with cascade CBC ciphers are not supported.)
|
||||
|
||||
* Properly display keys in dump --dump-master-key command
|
||||
for TrueCrypt CBC containers.
|
||||
|
||||
* Rewrite cipher benchmark loop which was unreliable
|
||||
on very fast machines.
|
||||
|
||||
* Add warning if LUKS device was activated using non-cryptsetup
|
||||
library which did not set UUID properly (e.g. cryptmount).
|
||||
(Some commands, like luksSuspend, are not available then.)
|
||||
|
||||
* Support length limitation also for plain (no hash) length.
|
||||
This can be used for mapping problematic cryptosystems which
|
||||
wipes some key (losetup sometimes set last 32 byte to zero,
|
||||
which can be now configured as --hash plain:31 parameter).
|
||||
|
||||
* Fix hash limit if parameter is not a number.
|
||||
(The whole key was set to zero instead of command failure.)
|
||||
|
||||
* Unify --key-slot behavior in cryptsetup_reencrypt tool.
|
||||
|
||||
* Update dracut example scripts for system reencryption on first boot.
|
||||
|
||||
* Add command line option --tcrypt-backup to access TCRYPT backup header.
|
||||
|
||||
* Fix static compilation with OpenSSL.
|
||||
57
docs/v1.6.4-ReleaseNotes
Normal file
57
docs/v1.6.4-ReleaseNotes
Normal file
@@ -0,0 +1,57 @@
|
||||
Cryptsetup 1.6.4 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.3
|
||||
|
||||
* Implement new erase (with alias luksErase) command.
|
||||
|
||||
The erase cryptsetup command can be used to permanently erase
|
||||
all keyslots and make the LUKS container inaccessible.
|
||||
(The only way to unlock such device is to use LUKS header backup
|
||||
created before erase command was used.)
|
||||
|
||||
You do not need to provide any password for this operation.
|
||||
|
||||
This operation is irreversible.
|
||||
|
||||
* Add internal "whirlpool_gcryptbug hash" for accessing flawed
|
||||
Whirlpool hash in gcrypt (requires gcrypt 1.6.1 or above).
|
||||
|
||||
The gcrypt version of Whirlpool hash algorithm was flawed in some
|
||||
situations.
|
||||
|
||||
This means that if you used Whirlpool in LUKS header and upgraded
|
||||
to new gcrypt library your LUKS container become inaccessible.
|
||||
|
||||
Please refer to cryptsetup FAQ for detail how to fix this situation.
|
||||
|
||||
* Allow to use --disable-gcrypt-pbkdf2 during configuration
|
||||
to force use internal PBKDF2 code.
|
||||
|
||||
* Require gcrypt 1.6.1 for imported implementation of PBKDF2
|
||||
(PBKDF2 in gcrypt 1.6.0 is too slow).
|
||||
|
||||
* Add --keep-key to cryptsetup-reencrypt.
|
||||
|
||||
This allows change of LUKS header hash (and iteration count) without
|
||||
the need to reencrypt the whole data area.
|
||||
(Reencryption of LUKS header only without master key change.)
|
||||
|
||||
* By default verify new passphrase in luksChangeKey and luksAddKey
|
||||
commands (if input is from terminal).
|
||||
|
||||
* Fix memory leak in Nettle crypto backend.
|
||||
|
||||
* Support --tries option even for TCRYPT devices in cryptsetup.
|
||||
|
||||
* Support --allow-discards option even for TCRYPT devices.
|
||||
(Note that this could destroy hidden volume and it is not suggested
|
||||
by original TrueCrypt security model.)
|
||||
|
||||
* Link against -lrt for clock_gettime to fix undefined reference
|
||||
to clock_gettime error (introduced in 1.6.2).
|
||||
|
||||
* Fix misleading error message when some algorithms are not available.
|
||||
|
||||
* Count system time in PBKDF2 benchmark if kernel returns no self usage info.
|
||||
(Workaround to broken getrusage() syscall with some hypervisors.)
|
||||
54
docs/v1.6.5-ReleaseNotes
Normal file
54
docs/v1.6.5-ReleaseNotes
Normal file
@@ -0,0 +1,54 @@
|
||||
Cryptsetup 1.6.5 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.4
|
||||
|
||||
* Allow LUKS header operation handling without requiring root privilege.
|
||||
It means that you can manipulate with keyslots as a regular user, only
|
||||
write access to device (or image) is required.
|
||||
|
||||
This requires kernel crypto wrapper (similar to TrueCrypt device handling)
|
||||
to be available (CRYPTO_USER_API_SKCIPHER kernel option).
|
||||
If this kernel interface is not available, code fallbacks to old temporary
|
||||
keyslot device creation (where root privilege is required).
|
||||
|
||||
Note that activation, deactivation, resize and suspend operations still
|
||||
need root privilege (limitation of kernel device-mapper backend).
|
||||
|
||||
* Fix internal PBKDF2 key derivation function implementation for alternative
|
||||
crypto backends (kernel, NSS) which do not support PBKDF2 directly and have
|
||||
issues with longer HMAC keys.
|
||||
|
||||
This fixes the problem for long keyfiles where either calculation is too slow
|
||||
(because of internal rehashing in every iteration) or there is a limit
|
||||
(kernel backend seems to not support HMAC key longer than 20480 bytes).
|
||||
|
||||
(Note that for recent version of gcrypt, nettle or openssl the internal
|
||||
PBKDF2 code is not compiled in and crypto library internal functions are
|
||||
used instead.)
|
||||
|
||||
* Support for Python3 for simple Python binding.
|
||||
Python >= 2.6 is now required. You can set Python compiled version by setting
|
||||
--with-python_version configure option (together with --enable-python).
|
||||
|
||||
* Use internal PBKDF2 in Nettle library for Nettle crypto backend.
|
||||
Cryptsetup compilation requires Nettle >= 2.6 (if using Nettle crypto backend).
|
||||
|
||||
* Allow simple status of crypt device without providing metadata header.
|
||||
The command "cryptsetup status" will print basic info, even if you
|
||||
do not provide detached header argument.
|
||||
|
||||
* Allow to specify ECB mode in cryptsetup benchmark.
|
||||
|
||||
* Add some LUKS images for regression testing.
|
||||
Note that if image with Whirlpool fails, the most probable cause is that
|
||||
you have old gcrypt library with flawed whirlpool hash.
|
||||
Read FAQ section 8.3 for more info.
|
||||
|
||||
Cryptsetup API NOTE:
|
||||
The direct terminal handling for passphrase entry will be removed from
|
||||
libcryptsetup in next major version (application should handle it itself).
|
||||
|
||||
It means that you have to always either provide password in buffer or set
|
||||
your own password callback function trhough crypt_set_password_callback().
|
||||
See API documentation (or libcryptsetup.h) for more info.
|
||||
@@ -1,24 +1,22 @@
|
||||
SUBDIRS = crypto_backend luks1 loopaes verity
|
||||
SUBDIRS = crypto_backend luks1 loopaes verity tcrypt
|
||||
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libcryptsetup.pc
|
||||
|
||||
INCLUDES = \
|
||||
AM_CPPFLAGS = -include config.h \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/lib/crypto_backend \
|
||||
-I$(top_srcdir)/lib/luks1 \
|
||||
-I$(top_srcdir)/lib/loopaes \
|
||||
-I$(top_srcdir)/lib/verity \
|
||||
-I$(top_srcdir)/lib/tcrypt \
|
||||
-DDATADIR=\""$(datadir)"\" \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DSYSCONFDIR=\""$(sysconfdir)"\" \
|
||||
-DVERSION=\""$(VERSION)"\" \
|
||||
-D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64
|
||||
-DVERSION=\""$(VERSION)"\"
|
||||
|
||||
lib_LTLIBRARIES = libcryptsetup.la
|
||||
|
||||
@@ -26,15 +24,16 @@ common_ldadd = \
|
||||
crypto_backend/libcrypto_backend.la \
|
||||
luks1/libluks1.la \
|
||||
loopaes/libloopaes.la \
|
||||
verity/libverity.la
|
||||
verity/libverity.la \
|
||||
tcrypt/libtcrypt.la
|
||||
|
||||
libcryptsetup_la_DEPENDENCIES = $(common_ldadd) libcryptsetup.sym
|
||||
|
||||
libcryptsetup_la_LDFLAGS = \
|
||||
libcryptsetup_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
|
||||
-Wl,--version-script=$(top_srcdir)/lib/libcryptsetup.sym \
|
||||
-version-info @LIBCRYPTSETUP_VERSION_INFO@
|
||||
|
||||
libcryptsetup_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
libcryptsetup_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
|
||||
|
||||
libcryptsetup_la_LIBADD = \
|
||||
@UUID_LIBS@ \
|
||||
@@ -51,6 +50,7 @@ libcryptsetup_la_SOURCES = \
|
||||
nls.h \
|
||||
libcryptsetup.h \
|
||||
utils.c \
|
||||
utils_benchmark.c \
|
||||
utils_crypt.c \
|
||||
utils_crypt.h \
|
||||
utils_loop.c \
|
||||
@@ -59,6 +59,7 @@ libcryptsetup_la_SOURCES = \
|
||||
utils_wipe.c \
|
||||
utils_fips.c \
|
||||
utils_fips.h \
|
||||
utils_device.c \
|
||||
libdevmapper.c \
|
||||
utils_dm.h \
|
||||
volumekey.c \
|
||||
|
||||
166
lib/bitops.h
166
lib/bitops.h
@@ -1,13 +1,114 @@
|
||||
/*
|
||||
* No copyright is claimed. This code is in the public domain; do with
|
||||
* it what you wish.
|
||||
*
|
||||
* Written by Karel Zak <kzak@redhat.com>
|
||||
*/
|
||||
#ifndef BITOPS_H
|
||||
#define BITOPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(HAVE_BYTESWAP_H)
|
||||
# include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ENDIAN_H)
|
||||
# include <endian.h>
|
||||
#elif defined(HAVE_SYS_ENDIAN_H) /* BSDs have them here */
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
# include <sys/types.h>
|
||||
# define be16toh(x) betoh16(x)
|
||||
# define be32toh(x) betoh32(x)
|
||||
# define be64toh(x) betoh64(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fallbacks
|
||||
*/
|
||||
#ifndef bswap_16
|
||||
# define bswap_16(x) ((((x) & 0x00FF) << 8) | \
|
||||
(((x) & 0xFF00) >> 8))
|
||||
#endif
|
||||
|
||||
#ifndef bswap_32
|
||||
# define bswap_32(x) ((((x) & 0x000000FF) << 24) | \
|
||||
(((x) & 0x0000FF00) << 8) | \
|
||||
(((x) & 0x00FF0000) >> 8) | \
|
||||
(((x) & 0xFF000000) >> 24))
|
||||
#endif
|
||||
|
||||
#ifndef bswap_64
|
||||
# define bswap_64(x) ((((x) & 0x00000000000000FFULL) << 56) | \
|
||||
(((x) & 0x000000000000FF00ULL) << 40) | \
|
||||
(((x) & 0x0000000000FF0000ULL) << 24) | \
|
||||
(((x) & 0x00000000FF000000ULL) << 8) | \
|
||||
(((x) & 0x000000FF00000000ULL) >> 8) | \
|
||||
(((x) & 0x0000FF0000000000ULL) >> 24) | \
|
||||
(((x) & 0x00FF000000000000ULL) >> 40) | \
|
||||
(((x) & 0xFF00000000000000ULL) >> 56))
|
||||
#endif
|
||||
|
||||
#ifndef htobe16
|
||||
# if !defined(WORDS_BIGENDIAN)
|
||||
# define htobe16(x) bswap_16 (x)
|
||||
# define htole16(x) (x)
|
||||
# define be16toh(x) bswap_16 (x)
|
||||
# define le16toh(x) (x)
|
||||
# define htobe32(x) bswap_32 (x)
|
||||
# define htole32(x) (x)
|
||||
# define be32toh(x) bswap_32 (x)
|
||||
# define le32toh(x) (x)
|
||||
# define htobe64(x) bswap_64 (x)
|
||||
# define htole64(x) (x)
|
||||
# define be64toh(x) bswap_64 (x)
|
||||
# define le64toh(x) (x)
|
||||
# else
|
||||
# define htobe16(x) (x)
|
||||
# define htole16(x) bswap_16 (x)
|
||||
# define be16toh(x) (x)
|
||||
# define le16toh(x) bswap_16 (x)
|
||||
# define htobe32(x) (x)
|
||||
# define htole32(x) bswap_32 (x)
|
||||
# define be32toh(x) (x)
|
||||
# define le32toh(x) bswap_32 (x)
|
||||
# define htobe64(x) (x)
|
||||
# define htole64(x) bswap_64 (x)
|
||||
# define be64toh(x) (x)
|
||||
# define le64toh(x) bswap_64 (x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Byte swab macros (based on linux/byteorder/swab.h)
|
||||
*/
|
||||
#define swab16(x) bswap_16(x)
|
||||
#define swab32(x) bswap_32(x)
|
||||
#define swab64(x) bswap_64(x)
|
||||
|
||||
#define cpu_to_le16(x) ((uint16_t) htole16(x))
|
||||
#define cpu_to_le32(x) ((uint32_t) htole32(x))
|
||||
#define cpu_to_le64(x) ((uint64_t) htole64(x))
|
||||
|
||||
#define cpu_to_be16(x) ((uint16_t) htobe16(x))
|
||||
#define cpu_to_be32(x) ((uint32_t) htobe32(x))
|
||||
#define cpu_to_be64(x) ((uint64_t) htobe64(x))
|
||||
|
||||
#define le16_to_cpu(x) ((uint16_t) le16toh(x))
|
||||
#define le32_to_cpu(x) ((uint32_t) le32toh(x))
|
||||
#define le64_to_cpu(x) ((uint64_t) le64toh(x))
|
||||
|
||||
#define be16_to_cpu(x) ((uint16_t) be16toh(x))
|
||||
#define be32_to_cpu(x) ((uint32_t) be32toh(x))
|
||||
#define be64_to_cpu(x) ((uint64_t) be64toh(x))
|
||||
|
||||
/*
|
||||
* Bit map related macros. Usually provided by libc.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef NBBY
|
||||
# define NBBY CHAR_BIT
|
||||
#endif
|
||||
@@ -19,65 +120,4 @@
|
||||
# define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Byte swab macros (based on linux/byteorder/swab.h)
|
||||
*/
|
||||
#define swab16(x) \
|
||||
((uint16_t)( \
|
||||
(((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
|
||||
(((uint16_t)(x) & (uint16_t)0xff00U) >> 8) ))
|
||||
|
||||
#define swab32(x) \
|
||||
((uint32_t)( \
|
||||
(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
|
||||
(((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
|
||||
(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
|
||||
(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) ))
|
||||
|
||||
#define swab64(x) \
|
||||
((uint64_t)( \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) ))
|
||||
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define cpu_to_le16(x) swab16(x)
|
||||
#define cpu_to_le32(x) swab32(x)
|
||||
#define cpu_to_le64(x) swab64(x)
|
||||
#define cpu_to_be16(x) ((uint16_t)(x))
|
||||
#define cpu_to_be32(x) ((uint32_t)(x))
|
||||
#define cpu_to_be64(x) ((uint64_t)(x))
|
||||
|
||||
#define le16_to_cpu(x) swab16(x)
|
||||
#define le32_to_cpu(x) swab32(x)
|
||||
#define le64_to_cpu(x) swab64(x)
|
||||
#define be16_to_cpu(x) ((uint16_t)(x))
|
||||
#define be32_to_cpu(x) ((uint32_t)(x))
|
||||
#define be64_to_cpu(x) ((uint64_t)(x))
|
||||
|
||||
#else /* !WORDS_BIGENDIAN */
|
||||
|
||||
#define cpu_to_le16(x) ((uint16_t)(x))
|
||||
#define cpu_to_le32(x) ((uint32_t)(x))
|
||||
#define cpu_to_le64(x) ((uint64_t)(x))
|
||||
#define cpu_to_be16(x) swab16(x)
|
||||
#define cpu_to_be32(x) swab32(x)
|
||||
#define cpu_to_be64(x) swab64(x)
|
||||
|
||||
#define le16_to_cpu(x) ((uint16_t)(x))
|
||||
#define le32_to_cpu(x) ((uint32_t)(x))
|
||||
#define le64_to_cpu(x) ((uint64_t)(x))
|
||||
#define be16_to_cpu(x) swab16(x)
|
||||
#define be32_to_cpu(x) swab32(x)
|
||||
#define be64_to_cpu(x) swab64(x)
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
#endif /* BITOPS_H */
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/*
|
||||
* cryptsetup plain device helper functions
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2010-2012 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -19,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -81,7 +83,11 @@ int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
|
||||
/* hash[:hash_length] */
|
||||
if ((s = strchr(hash_name_buf, ':'))) {
|
||||
*s = '\0';
|
||||
hash_size = atoi(++s);
|
||||
s++;
|
||||
if (!*s || sscanf(s, "%zd", &hash_size) != 1) {
|
||||
log_dbg("Hash length is not a number");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (hash_size > key_size) {
|
||||
log_dbg("Hash length %zd > key length %zd",
|
||||
hash_size, key_size);
|
||||
@@ -93,6 +99,15 @@ int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
|
||||
pad_size = 0;
|
||||
}
|
||||
|
||||
/* No hash, copy passphrase directly */
|
||||
if (!strcmp(hash_name_buf, "plain")) {
|
||||
if (passphrase_size < hash_size) {
|
||||
log_dbg("Too short plain passphrase.");
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(key, passphrase, hash_size);
|
||||
r = 0;
|
||||
} else
|
||||
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
|
||||
|
||||
if (r == 0 && pad_size)
|
||||
|
||||
@@ -2,9 +2,10 @@ moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libcrypto_backend.la
|
||||
|
||||
libcrypto_backend_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
libcrypto_backend_la_CFLAGS = $(AM_CFLAGS) -Wall @CRYPTO_CFLAGS@
|
||||
|
||||
libcrypto_backend_la_SOURCES = crypto_backend.h
|
||||
libcrypto_backend_la_SOURCES = crypto_backend.h \
|
||||
crypto_cipher_kernel.c crypto_storage.c pbkdf_check.c crc32.c
|
||||
|
||||
if CRYPTO_BACKEND_GCRYPT
|
||||
libcrypto_backend_la_SOURCES += crypto_gcrypt.c
|
||||
@@ -22,4 +23,8 @@ if CRYPTO_BACKEND_NETTLE
|
||||
libcrypto_backend_la_SOURCES += crypto_nettle.c
|
||||
endif
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE -I$(top_srcdir)/lib
|
||||
if CRYPTO_INTERNAL_PBKDF2
|
||||
libcrypto_backend_la_SOURCES += pbkdf2_generic.c
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -include config.h -I$(top_srcdir)/lib
|
||||
|
||||
116
lib/crypto_backend/crc32.c
Normal file
116
lib/crypto_backend/crc32.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*
|
||||
* First, the polynomial itself and its table of feedback terms. The
|
||||
* polynomial is
|
||||
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
|
||||
*
|
||||
* Note that we take it "backwards" and put the highest-order term in
|
||||
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
|
||||
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
|
||||
* the MSB being 1.
|
||||
*
|
||||
* Note that the usual hardware shift register implementation, which
|
||||
* is what we're using (we're merely optimizing it by doing eight-bit
|
||||
* chunks at a time) shifts bits into the lowest-order term. In our
|
||||
* implementation, that means shifting towards the right. Why do we
|
||||
* do it this way? Because the calculated CRC must be transmitted in
|
||||
* order from highest-order term to lowest-order term. UARTs transmit
|
||||
* characters in order from LSB to MSB. By storing the CRC this way,
|
||||
* we hand it to the UART in the order low-byte to high-byte; the UART
|
||||
* sends each low-bit to hight-bit; and the result is transmission bit
|
||||
* by bit from highest- to lowest-order term without requiring any bit
|
||||
* shuffling on our part. Reception works similarly.
|
||||
*
|
||||
* The feedback terms table consists of 256, 32-bit entries. Notes
|
||||
*
|
||||
* The table can be generated at runtime if desired; code to do so
|
||||
* is shown later. It might not be obvious, but the feedback
|
||||
* terms simply represent the results of eight shift/xor opera-
|
||||
* tions for all combinations of data and CRC register values.
|
||||
*
|
||||
* The values must be right-shifted by eight bits by the "updcrc"
|
||||
* logic; the shift must be unsigned (bring in zeroes). On some
|
||||
* hardware you could probably optimize the shift in assembler by
|
||||
* using byte-swap instructions.
|
||||
* polynomial $edb88320
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "crypto_backend.h"
|
||||
|
||||
|
||||
static const uint32_t crc32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
/*
|
||||
* This a generic crc32() function, it takes seed as an argument,
|
||||
* and does __not__ xor at the end. Then individual users can do
|
||||
* whatever they need.
|
||||
*/
|
||||
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
|
||||
{
|
||||
uint32_t crc = seed;
|
||||
const unsigned char *p = buf;
|
||||
|
||||
while(len-- > 0)
|
||||
crc = crc32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
@@ -2,29 +2,33 @@
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef _CRYPTO_BACKEND_H
|
||||
#define _CRYPTO_BACKEND_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct crypt_hash;
|
||||
struct crypt_hmac;
|
||||
struct crypt_cipher;
|
||||
struct crypt_storage;
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx);
|
||||
|
||||
@@ -52,4 +56,50 @@ int crypt_hmac_destroy(struct crypt_hmac *ctx);
|
||||
enum { CRYPT_RND_NORMAL = 0, CRYPT_RND_KEY = 1, CRYPT_RND_SALT = 2 };
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips);
|
||||
|
||||
/* PBKDF*/
|
||||
int crypt_pbkdf_check(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_size,
|
||||
const char *salt, size_t salt_size,
|
||||
uint64_t *iter_secs);
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
unsigned int iterations);
|
||||
|
||||
#if USE_INTERNAL_PBKDF2
|
||||
/* internal PBKDF2 implementation */
|
||||
int pkcs5_pbkdf2(const char *hash,
|
||||
const char *P, size_t Plen,
|
||||
const char *S, size_t Slen,
|
||||
unsigned int c,
|
||||
unsigned int dkLen, char *DK,
|
||||
unsigned int hash_block_size);
|
||||
#endif
|
||||
|
||||
/* CRC32 */
|
||||
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
|
||||
|
||||
/* ciphers */
|
||||
int crypt_cipher_blocksize(const char *name);
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *buffer, size_t length);
|
||||
int crypt_cipher_destroy(struct crypt_cipher *ctx);
|
||||
int crypt_cipher_encrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length);
|
||||
int crypt_cipher_decrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length);
|
||||
|
||||
/* storage encryption wrappers */
|
||||
int crypt_storage_init(struct crypt_storage **ctx, uint64_t sector_start,
|
||||
const char *cipher, const char *cipher_mode,
|
||||
char *key, size_t key_length);
|
||||
int crypt_storage_destroy(struct crypt_storage *ctx);
|
||||
int crypt_storage_decrypt(struct crypt_storage *ctx, uint64_t sector,
|
||||
size_t count, char *buffer);
|
||||
int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t sector,
|
||||
size_t count, char *buffer);
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_H */
|
||||
|
||||
278
lib/crypto_backend/crypto_cipher_kernel.c
Normal file
278
lib/crypto_backend/crypto_cipher_kernel.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation (skcipher)
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#ifdef ENABLE_AF_ALG
|
||||
|
||||
#include <linux/if_alg.h>
|
||||
|
||||
#ifndef AF_ALG
|
||||
#define AF_ALG 38
|
||||
#endif
|
||||
#ifndef SOL_ALG
|
||||
#define SOL_ALG 279
|
||||
#endif
|
||||
|
||||
struct crypt_cipher {
|
||||
int tfmfd;
|
||||
int opfd;
|
||||
};
|
||||
|
||||
struct cipher_alg {
|
||||
const char *name;
|
||||
int blocksize;
|
||||
};
|
||||
|
||||
/* FIXME: Getting block size should be dynamic from cipher backend. */
|
||||
static struct cipher_alg cipher_algs[] = {
|
||||
{ "cipher_null", 16 },
|
||||
{ "aes", 16 },
|
||||
{ "serpent", 16 },
|
||||
{ "twofish", 16 },
|
||||
{ "anubis", 16 },
|
||||
{ "blowfish", 8 },
|
||||
{ "camellia", 16 },
|
||||
{ "cast5", 8 },
|
||||
{ "cast6", 16 },
|
||||
{ "des", 8 },
|
||||
{ "des3_ede", 8 },
|
||||
{ "khazad", 8 },
|
||||
{ "seed", 16 },
|
||||
{ "tea", 8 },
|
||||
{ "xtea", 8 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct cipher_alg *_get_alg(const char *name)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (name && cipher_algs[i].name) {
|
||||
if (!strcasecmp(name, cipher_algs[i].name))
|
||||
return &cipher_algs[i];
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_cipher_blocksize(const char *name)
|
||||
{
|
||||
struct cipher_alg *ca = _get_alg(name);
|
||||
|
||||
return ca ? ca->blocksize : -EINVAL;
|
||||
}
|
||||
|
||||
/* Shared with hash kernel backend */
|
||||
int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd);
|
||||
|
||||
int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd)
|
||||
{
|
||||
*tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
||||
if (*tfmfd == -1)
|
||||
return -ENOTSUP;
|
||||
|
||||
if (bind(*tfmfd, (struct sockaddr *)sa, sizeof(*sa)) == -1) {
|
||||
close(*tfmfd);
|
||||
*tfmfd = -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
*opfd = accept(*tfmfd, NULL, 0);
|
||||
if (*opfd == -1) {
|
||||
close(*tfmfd);
|
||||
*tfmfd = -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*ciphers
|
||||
*
|
||||
* ENOENT - algorithm not available
|
||||
* ENOTSUP - AF_ALG family not available
|
||||
* (but cannot check specificaly for skcipher API)
|
||||
*/
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *buffer, size_t length)
|
||||
{
|
||||
struct crypt_cipher *h;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "skcipher",
|
||||
};
|
||||
int r;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
|
||||
"%s(%s)", mode, name);
|
||||
|
||||
r = crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd);
|
||||
if (r < 0) {
|
||||
free(h);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (length && strcmp(name, "cipher_null") &&
|
||||
setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, buffer, length) == -1) {
|
||||
crypt_cipher_destroy(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The in/out should be aligned to page boundary */
|
||||
static int crypt_cipher_crypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
uint32_t direction)
|
||||
{
|
||||
int r = 0;
|
||||
ssize_t len;
|
||||
struct af_alg_iv *alg_iv;
|
||||
struct cmsghdr *header;
|
||||
uint32_t *type;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void*)(uintptr_t)in,
|
||||
.iov_len = length,
|
||||
};
|
||||
int iv_msg_size = iv ? CMSG_SPACE(sizeof(*alg_iv) + iv_length) : 0;
|
||||
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
|
||||
struct msghdr msg = {
|
||||
.msg_control = buffer,
|
||||
.msg_controllen = sizeof(buffer),
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
if (!in || !out || !length)
|
||||
return -EINVAL;
|
||||
|
||||
if ((!iv && iv_length) || (iv && !iv_length))
|
||||
return -EINVAL;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
/* Set encrypt/decrypt operation */
|
||||
header = CMSG_FIRSTHDR(&msg);
|
||||
header->cmsg_level = SOL_ALG;
|
||||
header->cmsg_type = ALG_SET_OP;
|
||||
header->cmsg_len = CMSG_LEN(sizeof(*type));
|
||||
type = (void*)CMSG_DATA(header);
|
||||
*type = direction;
|
||||
|
||||
/* Set IV */
|
||||
if (iv) {
|
||||
header = CMSG_NXTHDR(&msg, header);
|
||||
header->cmsg_level = SOL_ALG;
|
||||
header->cmsg_type = ALG_SET_IV;
|
||||
header->cmsg_len = iv_msg_size;
|
||||
alg_iv = (void*)CMSG_DATA(header);
|
||||
alg_iv->ivlen = iv_length;
|
||||
memcpy(alg_iv->iv, iv, iv_length);
|
||||
}
|
||||
|
||||
len = sendmsg(ctx->opfd, &msg, 0);
|
||||
if (len != (ssize_t)length) {
|
||||
r = -EIO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
len = read(ctx->opfd, out, length);
|
||||
if (len != (ssize_t)length)
|
||||
r = -EIO;
|
||||
bad:
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_cipher_encrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return crypt_cipher_crypt(ctx, in, out, length,
|
||||
iv, iv_length, ALG_OP_ENCRYPT);
|
||||
}
|
||||
|
||||
int crypt_cipher_decrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return crypt_cipher_crypt(ctx, in, out, length,
|
||||
iv, iv_length, ALG_OP_DECRYPT);
|
||||
}
|
||||
|
||||
int crypt_cipher_destroy(struct crypt_cipher *ctx)
|
||||
{
|
||||
if (ctx->tfmfd != -1)
|
||||
close(ctx->tfmfd);
|
||||
if (ctx->opfd != -1)
|
||||
close(ctx->opfd);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* ENABLE_AF_ALG */
|
||||
|
||||
int crypt_cipher_blocksize(const char *name)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *buffer, size_t length)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int crypt_cipher_destroy(struct crypt_cipher *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_cipher_encrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
int crypt_cipher_decrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
@@ -2,18 +2,20 @@
|
||||
* GCRYPT crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -26,6 +28,7 @@
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
static int crypto_backend_secmem = 1;
|
||||
static int crypto_backend_whirlpool_bug = -1;
|
||||
static char version[64];
|
||||
|
||||
struct crypt_hash {
|
||||
@@ -40,6 +43,44 @@ struct crypt_hmac {
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* Test for wrong Whirlpool variant,
|
||||
* Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
|
||||
*/
|
||||
static void crypt_hash_test_whirlpool_bug(void)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
char buf[2] = "\0\0", hash_out1[64], hash_out2[64];
|
||||
int r;
|
||||
|
||||
if (crypto_backend_whirlpool_bug >= 0)
|
||||
return;
|
||||
|
||||
crypto_backend_whirlpool_bug = 0;
|
||||
if (crypt_hash_init(&h, "whirlpool"))
|
||||
return;
|
||||
|
||||
/* One shot */
|
||||
if ((r = crypt_hash_write(h, &buf[0], 2)) ||
|
||||
(r = crypt_hash_final(h, hash_out1, 64))) {
|
||||
crypt_hash_destroy(h);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Split buf (crypt_hash_final resets hash state) */
|
||||
if ((r = crypt_hash_write(h, &buf[0], 1)) ||
|
||||
(r = crypt_hash_write(h, &buf[1], 1)) ||
|
||||
(r = crypt_hash_final(h, hash_out2, 64))) {
|
||||
crypt_hash_destroy(h);
|
||||
return;
|
||||
}
|
||||
|
||||
crypt_hash_destroy(h);
|
||||
|
||||
if (memcmp(hash_out1, hash_out2, 64))
|
||||
crypto_backend_whirlpool_bug = 1;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
@@ -68,10 +109,15 @@ int crypt_backend_init(struct crypt_device *ctx)
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
}
|
||||
|
||||
snprintf(version, 64, "gcrypt %s%s",
|
||||
gcry_check_version(NULL),
|
||||
crypto_backend_secmem ? "" : ", secmem disabled");
|
||||
crypto_backend_initialised = 1;
|
||||
crypt_hash_test_whirlpool_bug();
|
||||
|
||||
snprintf(version, 64, "gcrypt %s%s%s",
|
||||
gcry_check_version(NULL),
|
||||
crypto_backend_secmem ? "" : ", secmem disabled",
|
||||
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : ""
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -85,6 +131,23 @@ uint32_t crypt_backend_flags(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
|
||||
{
|
||||
const char *hash_name = name;
|
||||
|
||||
/* "whirlpool_gcryptbug" is out shortcut to flawed whirlpool
|
||||
* in libgcrypt < 1.6.0 */
|
||||
if (name && !strcasecmp(name, "whirlpool_gcryptbug")) {
|
||||
#if GCRYPT_VERSION_NUMBER >= 0x010601
|
||||
if (flags)
|
||||
*flags |= GCRY_MD_FLAG_BUGEMU1;
|
||||
#endif
|
||||
hash_name = "whirlpool";
|
||||
}
|
||||
|
||||
return hash_name;
|
||||
}
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name)
|
||||
{
|
||||
@@ -92,7 +155,7 @@ int crypt_hash_size(const char *name)
|
||||
|
||||
assert(crypto_backend_initialised);
|
||||
|
||||
hash_id = gcry_md_map_name(name);
|
||||
hash_id = gcry_md_map_name(crypt_hash_compat_name(name, NULL));
|
||||
if (!hash_id)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -102,6 +165,7 @@ int crypt_hash_size(const char *name)
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
unsigned int flags = 0;
|
||||
|
||||
assert(crypto_backend_initialised);
|
||||
|
||||
@@ -109,13 +173,13 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash_id = gcry_md_map_name(name);
|
||||
h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
|
||||
if (!h->hash_id) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (gcry_md_open(&h->hd, h->hash_id, 0)) {
|
||||
if (gcry_md_open(&h->hd, h->hash_id, flags)) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -171,6 +235,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
const void *buffer, size_t length)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
unsigned int flags = GCRY_MD_FLAG_HMAC;
|
||||
|
||||
assert(crypto_backend_initialised);
|
||||
|
||||
@@ -178,13 +243,13 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash_id = gcry_md_map_name(name);
|
||||
h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
|
||||
if (!h->hash_id) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (gcry_md_open(&h->hd, h->hash_id, GCRY_MD_FLAG_HMAC)) {
|
||||
if (gcry_md_open(&h->hd, h->hash_id, flags)) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -251,3 +316,39 @@ int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PBKDF */
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
unsigned int iterations)
|
||||
{
|
||||
const char *hash_name = crypt_hash_compat_name(hash, NULL);
|
||||
|
||||
#if USE_INTERNAL_PBKDF2
|
||||
if (!kdf || strncmp(kdf, "pbkdf2", 6))
|
||||
return -EINVAL;
|
||||
|
||||
return pkcs5_pbkdf2(hash_name, password, password_length, salt, salt_length,
|
||||
iterations, key_length, key, 0);
|
||||
|
||||
#else /* USE_INTERNAL_PBKDF2 */
|
||||
int hash_id = gcry_md_map_name(hash_name);
|
||||
int kdf_id;
|
||||
|
||||
if (!hash_id)
|
||||
return -EINVAL;
|
||||
|
||||
if (kdf && !strncmp(kdf, "pbkdf2", 6))
|
||||
kdf_id = GCRY_KDF_PBKDF2;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (gcry_kdf_derive(password, password_length, kdf_id, hash_id,
|
||||
salt, salt_length, iterations, key_length, key))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
#endif /* USE_INTERNAL_PBKDF2 */
|
||||
}
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
* Linux kernel userspace API crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -42,15 +44,16 @@ struct hash_alg {
|
||||
const char *name;
|
||||
const char *kernel_name;
|
||||
int length;
|
||||
unsigned int block_length;
|
||||
};
|
||||
|
||||
static struct hash_alg hash_algs[] = {
|
||||
{ "sha1", "sha1", 20 },
|
||||
{ "sha256", "sha256", 32 },
|
||||
{ "sha512", "sha512", 64 },
|
||||
{ "ripemd160", "rmd160", 20 },
|
||||
{ "whirlpool", "wp512", 64 },
|
||||
{ NULL, 0 }
|
||||
{ "sha1", "sha1", 20, 64 },
|
||||
{ "sha256", "sha256", 32, 64 },
|
||||
{ "sha512", "sha512", 64, 128 },
|
||||
{ "ripemd160", "rmd160", 20, 64 },
|
||||
{ "whirlpool", "wp512", 64, 64 },
|
||||
{ NULL, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
struct crypt_hash {
|
||||
@@ -65,31 +68,8 @@ struct crypt_hmac {
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
static int _socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd)
|
||||
{
|
||||
*tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
||||
if (*tfmfd == -1)
|
||||
goto bad;
|
||||
|
||||
if (bind(*tfmfd, (struct sockaddr *)sa, sizeof(*sa)) == -1)
|
||||
goto bad;
|
||||
|
||||
*opfd = accept(*tfmfd, NULL, 0);
|
||||
if (*opfd == -1)
|
||||
goto bad;
|
||||
|
||||
return 0;
|
||||
bad:
|
||||
if (*tfmfd != -1) {
|
||||
close(*tfmfd);
|
||||
*tfmfd = -1;
|
||||
}
|
||||
if (*opfd != -1) {
|
||||
close(*opfd);
|
||||
*opfd = -1;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Defined in crypt_kernel_ciphers.c */
|
||||
extern int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd);
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
@@ -107,7 +87,7 @@ int crypt_backend_init(struct crypt_device *ctx)
|
||||
if (uname(&uts) == -1 || strcmp(uts.sysname, "Linux"))
|
||||
return -EINVAL;
|
||||
|
||||
if (_socket_init(&sa, &tfmfd, &opfd) < 0)
|
||||
if (crypt_kernel_socket_init(&sa, &tfmfd, &opfd) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
close(tfmfd);
|
||||
@@ -172,7 +152,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
|
||||
strncpy((char *)sa.salg_name, ha->kernel_name, sizeof(sa.salg_name));
|
||||
|
||||
if (_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
|
||||
if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -247,7 +227,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
|
||||
"hmac(%s)", ha->kernel_name);
|
||||
|
||||
if (_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
|
||||
if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -302,3 +282,19 @@ int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* PBKDF */
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
unsigned int iterations)
|
||||
{
|
||||
struct hash_alg *ha = _get_alg(hash);
|
||||
|
||||
if (!ha || !kdf || strncmp(kdf, "pbkdf2", 6))
|
||||
return -EINVAL;
|
||||
|
||||
return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
|
||||
iterations, key_length, key, ha->block_length);
|
||||
}
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
* Nettle crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2011-2012 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -22,6 +24,7 @@
|
||||
#include <errno.h>
|
||||
#include <nettle/sha.h>
|
||||
#include <nettle/hmac.h>
|
||||
#include <nettle/pbkdf2.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
static char *version = "Nettle";
|
||||
@@ -263,8 +266,8 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
int crypt_hmac_destroy(struct crypt_hmac *ctx)
|
||||
{
|
||||
memset(ctx->key, 0, ctx->key_length);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx->key);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
@@ -274,3 +277,29 @@ int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* PBKDF */
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
unsigned int iterations)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
int r;
|
||||
|
||||
if (!kdf || strncmp(kdf, "pbkdf2", 6))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_hmac_init(&h, hash, password, password_length);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
nettle_pbkdf2(&h->nettle_ctx, h->hash->nettle_hmac_update,
|
||||
h->hash->nettle_hmac_digest, h->hash->length, iterations,
|
||||
salt_length, (const uint8_t *)salt, key_length,
|
||||
(uint8_t *)key);
|
||||
crypt_hmac_destroy(h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
* NSS crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -33,14 +35,15 @@ struct hash_alg {
|
||||
SECOidTag oid;
|
||||
CK_MECHANISM_TYPE ck_type;
|
||||
int length;
|
||||
unsigned int block_length;
|
||||
};
|
||||
|
||||
static struct hash_alg hash_algs[] = {
|
||||
{ "sha1", SEC_OID_SHA1, CKM_SHA_1_HMAC, 20 },
|
||||
{ "sha256", SEC_OID_SHA256, CKM_SHA256_HMAC, 32 },
|
||||
{ "sha384", SEC_OID_SHA384, CKM_SHA384_HMAC, 48 },
|
||||
{ "sha512", SEC_OID_SHA512, CKM_SHA512_HMAC, 64 },
|
||||
// { "ripemd160", SEC_OID_RIPEMD160, CKM_RIPEMD160_HMAC, 20 },
|
||||
{ "sha1", SEC_OID_SHA1, CKM_SHA_1_HMAC, 20, 64 },
|
||||
{ "sha256", SEC_OID_SHA256, CKM_SHA256_HMAC, 32, 64 },
|
||||
{ "sha384", SEC_OID_SHA384, CKM_SHA384_HMAC, 48, 128 },
|
||||
{ "sha512", SEC_OID_SHA512, CKM_SHA512_HMAC, 64, 128 },
|
||||
// { "ripemd160", SEC_OID_RIPEMD160, CKM_RIPEMD160_HMAC, 20, 64 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -298,3 +301,19 @@ int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PBKDF */
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
unsigned int iterations)
|
||||
{
|
||||
struct hash_alg *ha = _get_alg(hash);
|
||||
|
||||
if (!ha || !kdf || strncmp(kdf, "pbkdf2", 6))
|
||||
return -EINVAL;
|
||||
|
||||
return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
|
||||
iterations, key_length, key, ha->block_length);
|
||||
}
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
* OPENSSL crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
@@ -22,7 +24,7 @@
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
*
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* You must obey the GNU Lesser General Public License in all respects
|
||||
* for all of the code used other than OpenSSL.
|
||||
*/
|
||||
|
||||
@@ -52,7 +54,7 @@ int crypt_backend_init(struct crypt_device *ctx)
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
|
||||
OpenSSL_add_all_digests();
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
crypto_backend_initialised = 1;
|
||||
return 0;
|
||||
@@ -230,3 +232,27 @@ int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PBKDF */
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
unsigned int iterations)
|
||||
{
|
||||
const EVP_MD *hash_id;
|
||||
|
||||
if (!kdf || strncmp(kdf, "pbkdf2", 6))
|
||||
return -EINVAL;
|
||||
|
||||
hash_id = EVP_get_digestbyname(hash);
|
||||
if (!hash_id)
|
||||
return -EINVAL;
|
||||
|
||||
if (!PKCS5_PBKDF2_HMAC(password, (int)password_length,
|
||||
(unsigned char *)salt, (int)salt_length,
|
||||
(int)iterations, hash_id, (int)key_length, (unsigned char *)key))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
288
lib/crypto_backend/crypto_storage.c
Normal file
288
lib/crypto_backend/crypto_storage.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Generic wrapper for storage encryption modes and Initial Vectors
|
||||
* (reimplementation of some functions from Linux dm-crypt kernel)
|
||||
*
|
||||
* Copyright (C) 2014, Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "bitops.h"
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#define SECTOR_SHIFT 9
|
||||
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
|
||||
|
||||
/*
|
||||
* Internal IV helper
|
||||
* IV documentation: https://code.google.com/p/cryptsetup/wiki/DMCrypt
|
||||
*/
|
||||
struct crypt_sector_iv {
|
||||
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI } type;
|
||||
int iv_size;
|
||||
char *iv;
|
||||
struct crypt_cipher *essiv_cipher;
|
||||
int benbi_shift;
|
||||
};
|
||||
|
||||
/* Block encryption storage context */
|
||||
struct crypt_storage {
|
||||
uint64_t sector_start;
|
||||
struct crypt_cipher *cipher;
|
||||
struct crypt_sector_iv cipher_iv;
|
||||
};
|
||||
|
||||
static int int_log2(unsigned int x)
|
||||
{
|
||||
int r = 0;
|
||||
for (x >>= 1; x > 0; x >>= 1)
|
||||
r++;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
const char *cipher_name, const char *iv_name,
|
||||
char *key, size_t key_length)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->iv_size = crypt_cipher_blocksize(cipher_name);
|
||||
if (ctx->iv_size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!iv_name || !strcmp(cipher_name, "cipher_null")) {
|
||||
ctx->type = IV_NONE;
|
||||
ctx->iv_size = 0;
|
||||
return 0;
|
||||
} else if (!strcasecmp(iv_name, "null")) {
|
||||
ctx->type = IV_NULL;
|
||||
} else if (!strcasecmp(iv_name, "plain64")) {
|
||||
ctx->type = IV_PLAIN64;
|
||||
} else if (!strcasecmp(iv_name, "plain")) {
|
||||
ctx->type = IV_PLAIN;
|
||||
} else if (!strncasecmp(iv_name, "essiv:", 6)) {
|
||||
struct crypt_hash *h = NULL;
|
||||
char *hash_name = strchr(iv_name, ':');
|
||||
int hash_size;
|
||||
char tmp[256];
|
||||
int r;
|
||||
|
||||
if (!hash_name)
|
||||
return -EINVAL;
|
||||
|
||||
hash_size = crypt_hash_size(++hash_name);
|
||||
if (hash_size < 0 || (unsigned)hash_size > sizeof(tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (crypt_hash_init(&h, hash_name))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_hash_write(h, key, key_length);
|
||||
if (r) {
|
||||
crypt_hash_destroy(h);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_hash_final(h, tmp, hash_size);
|
||||
crypt_hash_destroy(h);
|
||||
if (r) {
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_cipher_init(&ctx->essiv_cipher, cipher_name, "ecb",
|
||||
tmp, hash_size);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ctx->type = IV_ESSIV;
|
||||
} else if (!strncasecmp(iv_name, "benbi", 5)) {
|
||||
int log = int_log2(ctx->iv_size);
|
||||
if (log > SECTOR_SHIFT)
|
||||
return -EINVAL;
|
||||
|
||||
ctx->type = IV_BENBI;
|
||||
ctx->benbi_shift = SECTOR_SHIFT - log;
|
||||
} else
|
||||
return -ENOENT;
|
||||
|
||||
ctx->iv = malloc(ctx->iv_size);
|
||||
if (!ctx->iv)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
switch (ctx->type) {
|
||||
case IV_NONE:
|
||||
break;
|
||||
case IV_NULL:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
break;
|
||||
case IV_PLAIN:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
*(uint32_t *)ctx->iv = cpu_to_le32(sector & 0xffffffff);
|
||||
break;
|
||||
case IV_PLAIN64:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
*(uint64_t *)ctx->iv = cpu_to_le64(sector);
|
||||
break;
|
||||
case IV_ESSIV:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
*(uint64_t *)ctx->iv = cpu_to_le64(sector);
|
||||
return crypt_cipher_encrypt(ctx->essiv_cipher,
|
||||
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
|
||||
break;
|
||||
case IV_BENBI:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
val = cpu_to_be64((sector << ctx->benbi_shift) + 1);
|
||||
memcpy(ctx->iv + ctx->iv_size - sizeof(val), &val, sizeof(val));
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypt_sector_iv_destroy(struct crypt_sector_iv *ctx)
|
||||
{
|
||||
if (ctx->type == IV_ESSIV)
|
||||
crypt_cipher_destroy(ctx->essiv_cipher);
|
||||
|
||||
if (ctx->iv) {
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
free(ctx->iv);
|
||||
}
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Block encryption storage wrappers */
|
||||
|
||||
int crypt_storage_init(struct crypt_storage **ctx,
|
||||
uint64_t sector_start,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
char *key, size_t key_length)
|
||||
{
|
||||
struct crypt_storage *s;
|
||||
char mode_name[64];
|
||||
char *cipher_iv = NULL;
|
||||
int r = -EIO;
|
||||
|
||||
s = malloc(sizeof(*s));
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
/* Remove IV if present */
|
||||
strncpy(mode_name, cipher_mode, sizeof(mode_name));
|
||||
mode_name[sizeof(mode_name) - 1] = 0;
|
||||
cipher_iv = strchr(mode_name, '-');
|
||||
if (cipher_iv) {
|
||||
*cipher_iv = '\0';
|
||||
cipher_iv++;
|
||||
}
|
||||
|
||||
r = crypt_cipher_init(&s->cipher, cipher, mode_name, key, key_length);
|
||||
if (r) {
|
||||
crypt_storage_destroy(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, cipher_iv, key, key_length);
|
||||
if (r) {
|
||||
crypt_storage_destroy(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
s->sector_start = sector_start;
|
||||
|
||||
*ctx = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_storage_decrypt(struct crypt_storage *ctx,
|
||||
uint64_t sector, size_t count,
|
||||
char *buffer)
|
||||
{
|
||||
unsigned int i;
|
||||
int r = 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, sector + i);
|
||||
if (r)
|
||||
break;
|
||||
r = crypt_cipher_decrypt(ctx->cipher,
|
||||
&buffer[i * SECTOR_SIZE],
|
||||
&buffer[i * SECTOR_SIZE],
|
||||
SECTOR_SIZE,
|
||||
ctx->cipher_iv.iv,
|
||||
ctx->cipher_iv.iv_size);
|
||||
if (r)
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_storage_encrypt(struct crypt_storage *ctx,
|
||||
uint64_t sector, size_t count,
|
||||
char *buffer)
|
||||
{
|
||||
unsigned int i;
|
||||
int r = 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, sector + i);
|
||||
if (r)
|
||||
break;
|
||||
r = crypt_cipher_encrypt(ctx->cipher,
|
||||
&buffer[i * SECTOR_SIZE],
|
||||
&buffer[i * SECTOR_SIZE],
|
||||
SECTOR_SIZE,
|
||||
ctx->cipher_iv.iv,
|
||||
ctx->cipher_iv.iv_size);
|
||||
if (r)
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_storage_destroy(struct crypt_storage *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
crypt_sector_iv_destroy(&ctx->cipher_iv);
|
||||
|
||||
if (ctx->cipher)
|
||||
crypt_cipher_destroy(ctx->cipher);
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
426
lib/crypto_backend/pbkdf2_generic.c
Normal file
426
lib/crypto_backend/pbkdf2_generic.c
Normal file
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Implementation of Password-Based Cryptography as per PKCS#5
|
||||
* Copyright (C) 2002,2003 Simon Josefsson
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <alloca.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
static int hash_buf(const char *src, size_t src_len,
|
||||
char *dst, size_t dst_len,
|
||||
const char *hash_name)
|
||||
{
|
||||
struct crypt_hash *hd = NULL;
|
||||
int r;
|
||||
|
||||
if (crypt_hash_init(&hd, hash_name))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_hash_write(hd, src, src_len);
|
||||
|
||||
if (!r)
|
||||
r = crypt_hash_final(hd, dst, dst_len);
|
||||
|
||||
crypt_hash_destroy(hd);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* 5.2 PBKDF2
|
||||
*
|
||||
* PBKDF2 applies a pseudorandom function (see Appendix B.1 for an
|
||||
* example) to derive keys. The length of the derived key is essentially
|
||||
* unbounded. (However, the maximum effective search space for the
|
||||
* derived key may be limited by the structure of the underlying
|
||||
* pseudorandom function. See Appendix B.1 for further discussion.)
|
||||
* PBKDF2 is recommended for new applications.
|
||||
*
|
||||
* PBKDF2 (P, S, c, dkLen)
|
||||
*
|
||||
* Options: PRF underlying pseudorandom function (hLen
|
||||
* denotes the length in octets of the
|
||||
* pseudorandom function output)
|
||||
*
|
||||
* Input: P password, an octet string (ASCII or UTF-8)
|
||||
* S salt, an octet string
|
||||
* c iteration count, a positive integer
|
||||
* dkLen intended length in octets of the derived
|
||||
* key, a positive integer, at most
|
||||
* (2^32 - 1) * hLen
|
||||
*
|
||||
* Output: DK derived key, a dkLen-octet string
|
||||
*/
|
||||
|
||||
/*
|
||||
* if hash_block_size is not zero, the HMAC key is pre-hashed
|
||||
* inside this function.
|
||||
* This prevents situation when crypto backend doesn't support
|
||||
* long HMAC keys or it tries hash long key in every iteration
|
||||
* (because of crypt_final() cannot do simple key reset.
|
||||
*/
|
||||
|
||||
#define MAX_PRF_BLOCK_LEN 80
|
||||
|
||||
int pkcs5_pbkdf2(const char *hash,
|
||||
const char *P, size_t Plen,
|
||||
const char *S, size_t Slen,
|
||||
unsigned int c, unsigned int dkLen,
|
||||
char *DK, unsigned int hash_block_size)
|
||||
{
|
||||
struct crypt_hmac *hmac;
|
||||
char U[MAX_PRF_BLOCK_LEN];
|
||||
char T[MAX_PRF_BLOCK_LEN];
|
||||
char P_hash[MAX_PRF_BLOCK_LEN];
|
||||
int i, k, rc = -EINVAL;
|
||||
unsigned int u, hLen, l, r;
|
||||
size_t tmplen = Slen + 4;
|
||||
char *tmp;
|
||||
|
||||
tmp = alloca(tmplen);
|
||||
if (tmp == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
hLen = crypt_hmac_size(hash);
|
||||
if (hLen == 0 || hLen > MAX_PRF_BLOCK_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (c == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (dkLen == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
*
|
||||
* Steps:
|
||||
*
|
||||
* 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
|
||||
* stop.
|
||||
*/
|
||||
|
||||
if (dkLen > 4294967295U)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* 2. Let l be the number of hLen-octet blocks in the derived key,
|
||||
* rounding up, and let r be the number of octets in the last
|
||||
* block:
|
||||
*
|
||||
* l = CEIL (dkLen / hLen) ,
|
||||
* r = dkLen - (l - 1) * hLen .
|
||||
*
|
||||
* Here, CEIL (x) is the "ceiling" function, i.e. the smallest
|
||||
* integer greater than, or equal to, x.
|
||||
*/
|
||||
|
||||
l = dkLen / hLen;
|
||||
if (dkLen % hLen)
|
||||
l++;
|
||||
r = dkLen - (l - 1) * hLen;
|
||||
|
||||
/*
|
||||
* 3. For each block of the derived key apply the function F defined
|
||||
* below to the password P, the salt S, the iteration count c, and
|
||||
* the block index to compute the block:
|
||||
*
|
||||
* T_1 = F (P, S, c, 1) ,
|
||||
* T_2 = F (P, S, c, 2) ,
|
||||
* ...
|
||||
* T_l = F (P, S, c, l) ,
|
||||
*
|
||||
* where the function F is defined as the exclusive-or sum of the
|
||||
* first c iterates of the underlying pseudorandom function PRF
|
||||
* applied to the password P and the concatenation of the salt S
|
||||
* and the block index i:
|
||||
*
|
||||
* F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
|
||||
*
|
||||
* where
|
||||
*
|
||||
* U_1 = PRF (P, S || INT (i)) ,
|
||||
* U_2 = PRF (P, U_1) ,
|
||||
* ...
|
||||
* U_c = PRF (P, U_{c-1}) .
|
||||
*
|
||||
* Here, INT (i) is a four-octet encoding of the integer i, most
|
||||
* significant octet first.
|
||||
*
|
||||
* 4. Concatenate the blocks and extract the first dkLen octets to
|
||||
* produce a derived key DK:
|
||||
*
|
||||
* DK = T_1 || T_2 || ... || T_l<0..r-1>
|
||||
*
|
||||
* 5. Output the derived key DK.
|
||||
*
|
||||
* Note. The construction of the function F follows a "belt-and-
|
||||
* suspenders" approach. The iterates U_i are computed recursively to
|
||||
* remove a degree of parallelism from an opponent; they are exclusive-
|
||||
* ored together to reduce concerns about the recursion degenerating
|
||||
* into a small set of values.
|
||||
*
|
||||
*/
|
||||
|
||||
/* If hash_block_size is provided, hash password in advance. */
|
||||
if (hash_block_size > 0 && Plen > hash_block_size) {
|
||||
if (hash_buf(P, Plen, P_hash, hLen, hash))
|
||||
return -EINVAL;
|
||||
|
||||
if (crypt_hmac_init(&hmac, hash, P_hash, hLen))
|
||||
return -EINVAL;
|
||||
memset(P_hash, 0, sizeof(P_hash));
|
||||
} else {
|
||||
if (crypt_hmac_init(&hmac, hash, P, Plen))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 1; (unsigned int) i <= l; i++) {
|
||||
memset(T, 0, hLen);
|
||||
|
||||
for (u = 1; u <= c ; u++) {
|
||||
if (u == 1) {
|
||||
memcpy(tmp, S, Slen);
|
||||
tmp[Slen + 0] = (i & 0xff000000) >> 24;
|
||||
tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
|
||||
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
|
||||
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
|
||||
|
||||
if (crypt_hmac_write(hmac, tmp, tmplen))
|
||||
goto out;
|
||||
} else {
|
||||
if (crypt_hmac_write(hmac, U, hLen))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (crypt_hmac_final(hmac, U, hLen))
|
||||
goto out;
|
||||
|
||||
for (k = 0; (unsigned int) k < hLen; k++)
|
||||
T[k] ^= U[k];
|
||||
}
|
||||
|
||||
memcpy(DK + (i - 1) * hLen, T, (unsigned int) i == l ? r : hLen);
|
||||
}
|
||||
rc = 0;
|
||||
out:
|
||||
crypt_hmac_destroy(hmac);
|
||||
memset(U, 0, sizeof(U));
|
||||
memset(T, 0, sizeof(T));
|
||||
memset(tmp, 0, tmplen);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
|
||||
struct test_vector {
|
||||
const char *hash;
|
||||
unsigned int hash_block_length;
|
||||
unsigned int iterations;
|
||||
const char *password;
|
||||
unsigned int password_length;
|
||||
const char *salt;
|
||||
unsigned int salt_length;
|
||||
const char *output;
|
||||
unsigned int output_length;
|
||||
};
|
||||
|
||||
struct test_vector test_vectors[] = {
|
||||
/* RFC 3962 */
|
||||
{
|
||||
"sha1", 64, 1,
|
||||
"password", 8,
|
||||
"ATHENA.MIT.EDUraeburn", 21,
|
||||
"\xcd\xed\xb5\x28\x1b\xb2\xf8\x01"
|
||||
"\x56\x5a\x11\x22\xb2\x56\x35\x15"
|
||||
"\x0a\xd1\xf7\xa0\x4b\xb9\xf3\xa3"
|
||||
"\x33\xec\xc0\xe2\xe1\xf7\x08\x37", 32
|
||||
}, {
|
||||
"sha1", 64, 2,
|
||||
"password", 8,
|
||||
"ATHENA.MIT.EDUraeburn", 21,
|
||||
"\x01\xdb\xee\x7f\x4a\x9e\x24\x3e"
|
||||
"\x98\x8b\x62\xc7\x3c\xda\x93\x5d"
|
||||
"\xa0\x53\x78\xb9\x32\x44\xec\x8f"
|
||||
"\x48\xa9\x9e\x61\xad\x79\x9d\x86", 32
|
||||
}, {
|
||||
"sha1", 64, 1200,
|
||||
"password", 8,
|
||||
"ATHENA.MIT.EDUraeburn", 21,
|
||||
"\x5c\x08\xeb\x61\xfd\xf7\x1e\x4e"
|
||||
"\x4e\xc3\xcf\x6b\xa1\xf5\x51\x2b"
|
||||
"\xa7\xe5\x2d\xdb\xc5\xe5\x14\x2f"
|
||||
"\x70\x8a\x31\xe2\xe6\x2b\x1e\x13", 32
|
||||
}, {
|
||||
"sha1", 64, 5,
|
||||
"password", 8,
|
||||
"\0224VxxV4\022", 8, // "\x1234567878563412
|
||||
"\xd1\xda\xa7\x86\x15\xf2\x87\xe6"
|
||||
"\xa1\xc8\xb1\x20\xd7\x06\x2a\x49"
|
||||
"\x3f\x98\xd2\x03\xe6\xbe\x49\xa6"
|
||||
"\xad\xf4\xfa\x57\x4b\x6e\x64\xee", 32
|
||||
}, {
|
||||
"sha1", 64, 1200,
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 64,
|
||||
"pass phrase equals block size", 29,
|
||||
"\x13\x9c\x30\xc0\x96\x6b\xc3\x2b"
|
||||
"\xa5\x5f\xdb\xf2\x12\x53\x0a\xc9"
|
||||
"\xc5\xec\x59\xf1\xa4\x52\xf5\xcc"
|
||||
"\x9a\xd9\x40\xfe\xa0\x59\x8e\xd1", 32
|
||||
}, {
|
||||
"sha1", 64, 1200,
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 65,
|
||||
"pass phrase exceeds block size", 30,
|
||||
"\x9c\xca\xd6\xd4\x68\x77\x0c\xd5"
|
||||
"\x1b\x10\xe6\xa6\x87\x21\xbe\x61"
|
||||
"\x1a\x8b\x4d\x28\x26\x01\xdb\x3b"
|
||||
"\x36\xbe\x92\x46\x91\x5e\xc8\x2a", 32
|
||||
}, {
|
||||
"sha1", 64, 50,
|
||||
"\360\235\204\236", 4, // g-clef ("\xf09d849e)
|
||||
"EXAMPLE.COMpianist", 18,
|
||||
"\x6b\x9c\xf2\x6d\x45\x45\x5a\x43"
|
||||
"\xa5\xb8\xbb\x27\x6a\x40\x3b\x39"
|
||||
"\xe7\xfe\x37\xa0\xc4\x1e\x02\xc2"
|
||||
"\x81\xff\x30\x69\xe1\xe9\x4f\x52", 32
|
||||
}, {
|
||||
/* RFC-6070 */
|
||||
"sha1", 64, 1,
|
||||
"password", 8,
|
||||
"salt", 4,
|
||||
"\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
|
||||
"\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6", 20
|
||||
}, {
|
||||
"sha1", 64, 2,
|
||||
"password", 8,
|
||||
"salt", 4,
|
||||
"\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
|
||||
"\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57", 20
|
||||
}, {
|
||||
"sha1", 64, 4096,
|
||||
"password", 8,
|
||||
"salt", 4,
|
||||
"\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
|
||||
"\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20
|
||||
}, {
|
||||
"sha1", 64, 16777216,
|
||||
"password", 8,
|
||||
"salt", 4,
|
||||
"\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
|
||||
"\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84", 20
|
||||
}, {
|
||||
"sha1", 64, 4096,
|
||||
"passwordPASSWORDpassword", 24,
|
||||
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
|
||||
"\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8"
|
||||
"\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96"
|
||||
"\x4c\xf2\xf0\x70\x38", 25
|
||||
}, {
|
||||
"sha1", 64, 4096,
|
||||
"pass\0word", 9,
|
||||
"sa\0lt", 5,
|
||||
"\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
|
||||
"\xd7\xf0\x34\x25\xe0\xc3", 16
|
||||
}, {
|
||||
/* empty password test */
|
||||
"sha1", 64, 2,
|
||||
"", 0,
|
||||
"salt", 4,
|
||||
"\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2"
|
||||
"\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97", 20
|
||||
}, {
|
||||
/* Password exceeds block size test */
|
||||
"sha256", 64, 1200,
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 65,
|
||||
"pass phrase exceeds block size", 30,
|
||||
"\x22\x34\x4b\xc4\xb6\xe3\x26\x75"
|
||||
"\xa8\x09\x0f\x3e\xa8\x0b\xe0\x1d"
|
||||
"\x5f\x95\x12\x6a\x2c\xdd\xc3\xfa"
|
||||
"\xcc\x4a\x5e\x6d\xca\x04\xec\x58", 32
|
||||
}, {
|
||||
"sha512", 128, 1200,
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 129,
|
||||
"pass phrase exceeds block size", 30,
|
||||
"\x0f\xb2\xed\x2c\x0e\x6e\xfb\x7d"
|
||||
"\x7d\x8e\xdd\x58\x01\xb4\x59\x72"
|
||||
"\x99\x92\x16\x30\x5e\xa4\x36\x8d"
|
||||
"\x76\x14\x80\xf3\xe3\x7a\x22\xb9", 32
|
||||
}, {
|
||||
"whirlpool", 64, 1200,
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 65,
|
||||
"pass phrase exceeds block size", 30,
|
||||
"\x9c\x1c\x74\xf5\x88\x26\xe7\x6a"
|
||||
"\x53\x58\xf4\x0c\x39\xe7\x80\x89"
|
||||
"\x07\xc0\x31\x19\x9a\x50\xa2\x48"
|
||||
"\xf1\xd9\xfe\x78\x64\xe5\x84\x50", 32
|
||||
}
|
||||
};
|
||||
|
||||
static void printhex(const char *s, const char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
printf("%s: ", s);
|
||||
for (i = 0; i < len; i++)
|
||||
printf("\\x%02x", (unsigned char)buf[i]);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static int pkcs5_pbkdf2_test_vectors(void)
|
||||
{
|
||||
char result[64];
|
||||
unsigned int i, j;
|
||||
struct test_vector *vec;
|
||||
|
||||
for (i = 0; i < (sizeof(test_vectors) / sizeof(*test_vectors)); i++) {
|
||||
vec = &test_vectors[i];
|
||||
for (j = 1; j <= vec->output_length; j++) {
|
||||
if (pkcs5_pbkdf2(vec->hash,
|
||||
vec->password, vec->password_length,
|
||||
vec->salt, vec->salt_length,
|
||||
vec->iterations,
|
||||
j, result, vec->hash_block_length)) {
|
||||
printf("pbkdf2 failed, vector %d\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (memcmp(result, vec->output, j) != 0) {
|
||||
printf("vector %u\n", i);
|
||||
printhex(" got", result, j);
|
||||
printhex("want", vec->output, j);
|
||||
return -EINVAL;
|
||||
}
|
||||
memset(result, 0, sizeof(result));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
101
lib/crypto_backend/pbkdf_check.c
Normal file
101
lib/crypto_backend/pbkdf_check.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* PBKDF performance check
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
static long time_ms(struct rusage *start, struct rusage *end)
|
||||
{
|
||||
int count_kernel_time = 0;
|
||||
long ms;
|
||||
|
||||
if (crypt_backend_flags() & CRYPT_BACKEND_KERNEL)
|
||||
count_kernel_time = 1;
|
||||
|
||||
/*
|
||||
* FIXME: if there is no self usage info, count system time.
|
||||
* This seem like getrusage() bug in some hypervisors...
|
||||
*/
|
||||
if (!end->ru_utime.tv_sec && !start->ru_utime.tv_sec &&
|
||||
!end->ru_utime.tv_usec && !start->ru_utime.tv_usec)
|
||||
count_kernel_time = 1;
|
||||
|
||||
ms = (end->ru_utime.tv_sec - start->ru_utime.tv_sec) * 1000;
|
||||
ms += (end->ru_utime.tv_usec - start->ru_utime.tv_usec) / 1000;
|
||||
|
||||
if (count_kernel_time) {
|
||||
ms += (end->ru_stime.tv_sec - start->ru_stime.tv_sec) * 1000;
|
||||
ms += (end->ru_stime.tv_usec - start->ru_stime.tv_usec) / 1000;
|
||||
}
|
||||
|
||||
return ms;
|
||||
}
|
||||
|
||||
/* This code benchmarks PBKDF and returns iterations/second using specified hash */
|
||||
int crypt_pbkdf_check(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_size,
|
||||
const char *salt, size_t salt_size,
|
||||
uint64_t *iter_secs)
|
||||
{
|
||||
struct rusage rstart, rend;
|
||||
int r = 0, step = 0;
|
||||
long ms = 0;
|
||||
char buf;
|
||||
unsigned int iterations;
|
||||
|
||||
if (!kdf || !hash)
|
||||
return -EINVAL;
|
||||
|
||||
iterations = 1 << 15;
|
||||
while (ms < 500) {
|
||||
if (getrusage(RUSAGE_SELF, &rstart) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_pbkdf(kdf, hash, password, password_size, salt,
|
||||
salt_size, &buf, 1, iterations);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (getrusage(RUSAGE_SELF, &rend) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
ms = time_ms(&rstart, &rend);
|
||||
if (ms > 500)
|
||||
break;
|
||||
|
||||
if (ms <= 62)
|
||||
iterations <<= 4;
|
||||
else if (ms <= 125)
|
||||
iterations <<= 3;
|
||||
else if (ms <= 250)
|
||||
iterations <<= 2;
|
||||
else
|
||||
iterations <<= 1;
|
||||
|
||||
if (++step > 10 || !iterations)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (iter_secs)
|
||||
*iter_secs = (iterations * 1000) / ms;
|
||||
return r;
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library internal
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -22,10 +24,6 @@
|
||||
#ifndef INTERNAL_H
|
||||
#define INTERNAL_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
@@ -63,31 +61,51 @@ struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key);
|
||||
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, unsigned keylength);
|
||||
void crypt_free_volume_key(struct volume_key *vk);
|
||||
|
||||
/* Device backend */
|
||||
struct device;
|
||||
int device_alloc(struct device **device, const char *path);
|
||||
void device_free(struct device *device);
|
||||
const char *device_path(const struct device *device);
|
||||
const char *device_block_path(const struct device *device);
|
||||
void device_topology_alignment(struct device *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment);
|
||||
int device_block_size(struct device *device);
|
||||
int device_read_ahead(struct device *device, uint32_t *read_ahead);
|
||||
int device_size(struct device *device, uint64_t *size);
|
||||
int device_open(struct device *device, int flags);
|
||||
|
||||
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
||||
int device_block_adjust(struct crypt_device *cd,
|
||||
struct device *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t device_offset,
|
||||
uint64_t *size,
|
||||
uint32_t *flags);
|
||||
size_t size_round_up(size_t size, unsigned int block);
|
||||
|
||||
/* Receive backend devices from context helpers */
|
||||
struct device *crypt_metadata_device(struct crypt_device *cd);
|
||||
struct device *crypt_data_device(struct crypt_device *cd);
|
||||
|
||||
int crypt_confirm(struct crypt_device *cd, const char *msg);
|
||||
|
||||
char *crypt_lookup_dev(const char *dev_id);
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
|
||||
int crypt_dev_is_rotational(int major, int minor);
|
||||
int crypt_dev_is_partition(const char *dev_path);
|
||||
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size);
|
||||
char *crypt_get_base_device(const char *dev_path);
|
||||
uint64_t crypt_dev_partition_offset(const char *dev_path);
|
||||
|
||||
int sector_size_for_device(const char *device);
|
||||
int device_read_ahead(const char *dev, uint32_t *read_ahead);
|
||||
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 device_size(const char *device, uint64_t *size);
|
||||
ssize_t write_blockwise(int fd, int bsize, void *buf, size_t count);
|
||||
ssize_t read_blockwise(int fd, int bsize, void *_buf, size_t count);
|
||||
ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset);
|
||||
|
||||
unsigned crypt_getpagesize(void);
|
||||
int init_crypto(struct crypt_device *ctx);
|
||||
|
||||
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
||||
int device_check_and_adjust(struct crypt_device *cd,
|
||||
const char *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t *size,
|
||||
uint64_t *offset,
|
||||
uint32_t *flags);
|
||||
|
||||
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
|
||||
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
|
||||
#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)
|
||||
@@ -98,11 +116,6 @@ int crypt_get_debug_level(void);
|
||||
int crypt_memlock_inc(struct crypt_device *ctx);
|
||||
int crypt_memlock_dec(struct crypt_device *ctx);
|
||||
|
||||
void get_topology_alignment(const char *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment);
|
||||
|
||||
int crypt_random_init(struct crypt_device *ctx);
|
||||
int crypt_random_get(struct crypt_device *ctx, char *buf, size_t len, int quality);
|
||||
void crypt_random_exit(void);
|
||||
@@ -131,7 +144,7 @@ typedef enum {
|
||||
* random algorithm */
|
||||
} crypt_wipe_type;
|
||||
|
||||
int crypt_wipe(const char *device,
|
||||
int crypt_wipe(struct device *device,
|
||||
uint64_t offset,
|
||||
uint64_t sectors,
|
||||
crypt_wipe_type type,
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2014, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -87,7 +89,7 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||
int crypt_init_by_name(struct crypt_device **cd, const char *name);
|
||||
|
||||
/**
|
||||
* @defgroup loglevel "Cryptsetup logging"
|
||||
* @defgroup loglevel Cryptsetup logging
|
||||
*
|
||||
* Set of functions and defines used in cryptsetup for
|
||||
* logging purposes
|
||||
@@ -174,6 +176,8 @@ void crypt_set_confirm_callback(struct crypt_device *cd,
|
||||
* @note Only zero terminated passwords can be entered this way, for complex
|
||||
* use API functions directly.
|
||||
* @note Maximal length of password is limited to @e length @e - @e 1 (minimal 511 chars)
|
||||
* @note Internal compiled-in terminal input is DEPRECATED and will be removed
|
||||
* in future versions.
|
||||
*
|
||||
* @see Callback function is used in these call provided, that certain conditions are met:
|
||||
* @li crypt_keyslot_add_by_passphrase
|
||||
@@ -237,7 +241,7 @@ void crypt_set_password_verify(struct crypt_device *cd, int password_verify);
|
||||
int crypt_set_data_device(struct crypt_device *cd, const char *device);
|
||||
|
||||
/**
|
||||
* @defgroup rng "Cryptsetup RNG"
|
||||
* @defgroup rng Cryptsetup RNG
|
||||
*
|
||||
* @addtogroup rng
|
||||
* @{
|
||||
@@ -283,7 +287,7 @@ int crypt_get_rng_type(struct crypt_device *cd);
|
||||
int crypt_memory_lock(struct crypt_device *cd, int lock);
|
||||
|
||||
/**
|
||||
* @defgroup crypt_type "Cryptsetup on-disk format types"
|
||||
* @defgroup crypt_type Cryptsetup on-disk format types
|
||||
*
|
||||
* Set of functions, \#defines and structs related
|
||||
* to on-disk format types
|
||||
@@ -302,6 +306,8 @@ int crypt_memory_lock(struct crypt_device *cd, int lock);
|
||||
#define CRYPT_LOOPAES "LOOPAES"
|
||||
/** dm-verity mode */
|
||||
#define CRYPT_VERITY "VERITY"
|
||||
/** TCRYPT (TrueCrypt-compatible) mode */
|
||||
#define CRYPT_TCRYPT "TCRYPT"
|
||||
|
||||
/**
|
||||
* Get device type
|
||||
@@ -359,13 +365,6 @@ struct crypt_params_loopaes {
|
||||
* @see crypt_format, crypt_load
|
||||
*
|
||||
*/
|
||||
/** No on-disk header (only hashes) */
|
||||
#define CRYPT_VERITY_NO_HEADER (1 << 0)
|
||||
/** Verity hash in userspace before activation */
|
||||
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
|
||||
/** Create hash - format hash device */
|
||||
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
|
||||
|
||||
struct crypt_params_verity {
|
||||
const char *hash_name; /**< hash function */
|
||||
const char *data_device; /**< data_device (CRYPT_VERITY_CREATE_HASH) */
|
||||
@@ -380,6 +379,41 @@ struct crypt_params_verity {
|
||||
uint32_t flags; /**< CRYPT_VERITY* flags */
|
||||
};
|
||||
|
||||
/** No on-disk header (only hashes) */
|
||||
#define CRYPT_VERITY_NO_HEADER (1 << 0)
|
||||
/** Verity hash in userspace before activation */
|
||||
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
|
||||
/** Create hash - format hash device */
|
||||
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
|
||||
|
||||
/**
|
||||
*
|
||||
* Structure used as parameter for TCRYPT device type
|
||||
*
|
||||
* @see crypt_load
|
||||
*
|
||||
*/
|
||||
struct crypt_params_tcrypt {
|
||||
const char *passphrase; /**< passphrase to unlock header (input only) */
|
||||
size_t passphrase_size; /**< passphrase size (input only, max length is 64) */
|
||||
const char **keyfiles; /**< keyfile paths to unlock header (input only) */
|
||||
unsigned int keyfiles_count;/**< keyfiles count (input only) */
|
||||
const char *hash_name; /**< hash function for PBKDF */
|
||||
const char *cipher; /**< cipher chain c1[-c2[-c3]] */
|
||||
const char *mode; /**< cipher block mode */
|
||||
size_t key_size; /**< key size in bytes (the whole chain) */
|
||||
uint32_t flags; /**< CRYPT_TCRYPT* flags */
|
||||
};
|
||||
|
||||
/** Include legacy modes ehn scannig for header*/
|
||||
#define CRYPT_TCRYPT_LEGACY_MODES (1 << 0)
|
||||
/** Try to load hidden header (describing hidden device) */
|
||||
#define CRYPT_TCRYPT_HIDDEN_HEADER (1 << 1)
|
||||
/** Try to load backup header */
|
||||
#define CRYPT_TCRYPT_BACKUP_HEADER (1 << 2)
|
||||
/** Device contains encrypted system (with boot loader) */
|
||||
#define CRYPT_TCRYPT_SYSTEM_HEADER (1 << 3)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -498,6 +532,8 @@ int crypt_suspend(struct crypt_device *cd,
|
||||
* @return unlocked key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note Only LUKS device type is supported
|
||||
* @note If passphrase is @e NULL always use crypt_set_password_callback.
|
||||
* Internal terminal password query is DEPRECATED and will be removed in next version.
|
||||
*/
|
||||
int crypt_resume_by_passphrase(struct crypt_device *cd,
|
||||
const char *name,
|
||||
@@ -516,6 +552,9 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
|
||||
* @param keyfile_offset number of bytes to skip at start of keyfile
|
||||
*
|
||||
* @return unlocked key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note If passphrase is @e NULL always use crypt_set_password_callback.
|
||||
* Internal terminal password query is DEPRECATED and will be removed in next version.
|
||||
*/
|
||||
int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
|
||||
const char *name,
|
||||
@@ -540,7 +579,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
|
||||
void crypt_free(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* @defgroup keyslot "Cryptsetup LUKS keyslots"
|
||||
* @defgroup keyslot Cryptsetup LUKS keyslots
|
||||
* @addtogroup keyslot
|
||||
* @{
|
||||
*
|
||||
@@ -562,6 +601,9 @@ void crypt_free(struct crypt_device *cd);
|
||||
* @param new_passphrase_size size of @e new_passphrase (binary data)
|
||||
*
|
||||
* @return allocated key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note If passphrase is @e NULL always use crypt_set_password_callback.
|
||||
* Internal terminal password query is DEPRECATED and will be removed in next version.
|
||||
*/
|
||||
int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -571,14 +613,34 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
||||
size_t new_passphrase_size);
|
||||
|
||||
/**
|
||||
* Get number of keyslots supported for device type.
|
||||
* Change defined key slot using provided passphrase
|
||||
*
|
||||
* @param type crypt device type
|
||||
* @pre @e cd contains initialized and formatted LUKS device context
|
||||
*
|
||||
* @return slot count or negative errno otherwise if device
|
||||
* doesn't not support keyslots.
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot_old old keyslot or @e CRYPT_ANY_SLOT
|
||||
* @param keyslot_new new keyslot (can be the same as old)
|
||||
* @param passphrase passphrase used to unlock volume key, @e NULL for query
|
||||
* @param passphrase_size size of passphrase (binary data)
|
||||
* @param new_passphrase passphrase for new keyslot, @e NULL for query
|
||||
* @param new_passphrase_size size of @e new_passphrase (binary data)
|
||||
*
|
||||
* @return allocated key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note This function is just internal implementation of luksChange
|
||||
* command to avoid reading of volume key outside libcryptsetup boundary
|
||||
* in FIPS mode.
|
||||
*
|
||||
* @note If passphrase is @e NULL always use crypt_set_password_callback.
|
||||
* Internal terminal password query is DEPRECATED and will be removed in next version.
|
||||
*/
|
||||
int crypt_keyslot_max(const char *type);
|
||||
int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
||||
int keyslot_old,
|
||||
int keyslot_new,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
const char *new_passphrase,
|
||||
size_t new_passphrase_size);
|
||||
|
||||
/**
|
||||
* Add key slot using provided key file path
|
||||
@@ -597,7 +659,6 @@ int crypt_keyslot_max(const char *type);
|
||||
* @return allocated key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note Note that @e keyfile can be "-" for STDIN
|
||||
*
|
||||
*/
|
||||
int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -631,6 +692,8 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
|
||||
*
|
||||
* @return allocated key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note If passphrase is @e NULL always use crypt_set_password_callback.
|
||||
* Internal terminal password query is DEPRECATED and will be removed in next version.
|
||||
*/
|
||||
int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -656,7 +719,7 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup aflags "Device runtime attributes"
|
||||
* @defgroup aflags Device runtime attributes
|
||||
*
|
||||
* Activation flags
|
||||
*
|
||||
@@ -714,6 +777,9 @@ int crypt_get_active_device(struct crypt_device *cd,
|
||||
* @param flags activation flags
|
||||
*
|
||||
* @return unlocked key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note If passphrase is @e NULL always use crypt_set_password_callback.
|
||||
* Internal terminal password query is DEPRECATED and will be removed in next version.
|
||||
*/
|
||||
int crypt_activate_by_passphrase(struct crypt_device *cd,
|
||||
const char *name,
|
||||
@@ -770,6 +836,8 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
|
||||
* @note For VERITY the volume key means root hash required for activation.
|
||||
* Because kernel dm-verity is always read only, you have to provide
|
||||
* CRYPT_ACTIVATE_READONLY flag always.
|
||||
* @note For TCRYPT the volume key should be always NULL and because master
|
||||
* key from decrypted header is used instead.
|
||||
*/
|
||||
int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
@@ -802,6 +870,9 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
|
||||
* @param passphrase_size size of @e passphrase
|
||||
*
|
||||
* @return unlocked key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note For TCRYPT cipher chain is the volume key concatenated
|
||||
* for all ciphers in chain.
|
||||
*/
|
||||
int crypt_volume_key_get(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -824,7 +895,7 @@ int crypt_volume_key_verify(struct crypt_device *cd,
|
||||
size_t volume_key_size);
|
||||
|
||||
/**
|
||||
* @defgroup devstat "Crypt and Verity device status"
|
||||
* @defgroup devstat Crypt and Verity device status
|
||||
* @addtogroup devstat
|
||||
* @{
|
||||
*/
|
||||
@@ -942,6 +1013,66 @@ int crypt_get_verity_info(struct crypt_device *cd,
|
||||
struct crypt_params_verity *vp);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup benchmark Benchmarking
|
||||
*
|
||||
* Benchmarking of algorithms
|
||||
*
|
||||
* @addtogroup benchmark
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Informational benchmark for ciphers
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param cipher (e.g. "aes")
|
||||
* @param cipher_mode (e.g. "xts"), IV generator is ignored
|
||||
* @param volume_key_size size of volume key in bytes
|
||||
* @param iv_size size of IV in bytes
|
||||
* @param buffer_size size of encryption buffer in bytes used in test
|
||||
* @param encryption_mbs measured encryption speed in MiB/s
|
||||
* @param decryption_mbs measured decryption speed in MiB/s
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
* @note If encryption_buffer_size is too small and encryption time
|
||||
* cannot be properly measured, -ERANGE is returned.
|
||||
*/
|
||||
int crypt_benchmark(struct crypt_device *cd,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
size_t volume_key_size,
|
||||
size_t iv_size,
|
||||
size_t buffer_size,
|
||||
double *encryption_mbs,
|
||||
double *decryption_mbs);
|
||||
|
||||
/**
|
||||
* Informational benchmark for KDF
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param kdf Key derivation function (e.g. "pbkdf2")
|
||||
* @param hash Hash algorithm used in KDF (e.g. "sha256")
|
||||
* @param password password for benchmark
|
||||
* @param password_size size of password
|
||||
* @param salt salt for benchmark
|
||||
* @param salt_size size of salt
|
||||
* @param iterations_sec returns measured KDF iterations per second
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*/
|
||||
int crypt_benchmark_kdf(struct crypt_device *cd,
|
||||
const char *kdf,
|
||||
const char *hash,
|
||||
const char *password,
|
||||
size_t password_size,
|
||||
const char *salt,
|
||||
size_t salt_size,
|
||||
uint64_t *iterations_sec);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @addtogroup keyslot
|
||||
* @{
|
||||
@@ -972,6 +1103,32 @@ typedef enum {
|
||||
crypt_keyslot_info crypt_keyslot_status(struct crypt_device *cd, int keyslot);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Get number of keyslots supported for device type.
|
||||
*
|
||||
* @param type crypt device type
|
||||
*
|
||||
* @return slot count or negative errno otherwise if device
|
||||
* doesn't not support keyslots.
|
||||
*/
|
||||
int crypt_keyslot_max(const char *type);
|
||||
|
||||
/**
|
||||
* Get keyslot area pointers (relative to metadata device)
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot keyslot number
|
||||
* @param offset offset on metadata device (in bytes)
|
||||
* @param length length of keyslot area (in bytes)
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
*/
|
||||
int crypt_keyslot_area(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
uint64_t *offset,
|
||||
uint64_t *length);
|
||||
|
||||
/**
|
||||
* Backup header and keyslots to file
|
||||
*
|
||||
@@ -1032,7 +1189,7 @@ void crypt_get_error(char *buf, size_t size);
|
||||
const char *crypt_get_dir(void);
|
||||
|
||||
/**
|
||||
* @defgroup dbg "Library debug level"
|
||||
* @defgroup dbg Library debug level
|
||||
*
|
||||
* Set library debug level
|
||||
*
|
||||
|
||||
@@ -26,6 +26,7 @@ CRYPTSETUP_1.0 {
|
||||
crypt_free;
|
||||
|
||||
crypt_keyslot_add_by_passphrase;
|
||||
crypt_keyslot_change_by_passphrase;
|
||||
crypt_keyslot_add_by_keyfile;
|
||||
crypt_keyslot_add_by_keyfile_offset;
|
||||
crypt_keyslot_add_by_volume_key;
|
||||
@@ -39,6 +40,8 @@ CRYPTSETUP_1.0 {
|
||||
crypt_volume_key_verify;
|
||||
crypt_status;
|
||||
crypt_dump;
|
||||
crypt_benchmark;
|
||||
crypt_benchmark_kdf;
|
||||
crypt_get_cipher;
|
||||
crypt_get_cipher_mode;
|
||||
crypt_get_uuid;
|
||||
@@ -55,6 +58,7 @@ CRYPTSETUP_1.0 {
|
||||
crypt_get_rng_type;
|
||||
|
||||
crypt_keyslot_max;
|
||||
crypt_keyslot_area;
|
||||
crypt_keyslot_status;
|
||||
crypt_last_error;
|
||||
crypt_get_error;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* libdevmapper - device-mapper backend for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -26,6 +28,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -38,10 +41,11 @@
|
||||
|
||||
/* Set if dm-crypt version was probed */
|
||||
static int _dm_crypt_checked = 0;
|
||||
static int _quiet_log = 0;
|
||||
static uint32_t _dm_crypt_flags = 0;
|
||||
|
||||
static int _dm_use_count = 0;
|
||||
static struct crypt_device *_context = NULL;
|
||||
static int _dm_use_count = 0;
|
||||
|
||||
/* Check if we have DM flag to instruct kernel to force wipe buffers */
|
||||
#if !HAVE_DECL_DM_TASK_SECURE_DATA
|
||||
@@ -81,11 +85,14 @@ static void set_dm_error(int level,
|
||||
|
||||
va_start(va, f);
|
||||
if (vasprintf(&msg, f, va) > 0) {
|
||||
if (level < 4) {
|
||||
log_err(_context, msg);
|
||||
if (level < 4 && !_quiet_log) {
|
||||
log_err(_context, "%s", msg);
|
||||
log_err(_context, "\n");
|
||||
} else
|
||||
log_dbg(msg);
|
||||
} else {
|
||||
/* We do not use DM visual stack backtrace here */
|
||||
if (strncmp(msg, "<backtrace>", 11))
|
||||
log_dbg("%s", msg);
|
||||
}
|
||||
}
|
||||
free(msg);
|
||||
va_end(va);
|
||||
@@ -93,6 +100,18 @@ static void set_dm_error(int level,
|
||||
|
||||
static int _dm_simple(int task, const char *name, int udev_wait);
|
||||
|
||||
static int _dm_satisfies_version(unsigned target_maj, unsigned target_min,
|
||||
unsigned actual_maj, unsigned actual_min)
|
||||
{
|
||||
if (actual_maj > target_maj)
|
||||
return 1;
|
||||
|
||||
if (actual_maj == target_maj && actual_min >= target_min)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj,
|
||||
unsigned crypt_min, unsigned crypt_patch)
|
||||
{
|
||||
@@ -104,24 +123,27 @@ static void _dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj,
|
||||
log_dbg("Detected dm-crypt version %i.%i.%i, dm-ioctl version %u.%u.%u.",
|
||||
crypt_maj, crypt_min, crypt_patch, dm_maj, dm_min, dm_patch);
|
||||
|
||||
if (crypt_maj >= 1 && crypt_min >= 2)
|
||||
if (_dm_satisfies_version(1, 2, crypt_maj, crypt_min))
|
||||
_dm_crypt_flags |= DM_KEY_WIPE_SUPPORTED;
|
||||
else
|
||||
log_dbg("Suspend and resume disabled, no wipe key support.");
|
||||
|
||||
if (crypt_maj >= 1 && crypt_min >= 10)
|
||||
if (_dm_satisfies_version(1, 10, crypt_maj, crypt_min))
|
||||
_dm_crypt_flags |= DM_LMK_SUPPORTED;
|
||||
|
||||
if (dm_maj >= 4 && dm_min >= 20)
|
||||
if (_dm_satisfies_version(4, 20, dm_maj, dm_min))
|
||||
_dm_crypt_flags |= DM_SECURE_SUPPORTED;
|
||||
|
||||
/* not perfect, 2.6.33 supports with 1.7.0 */
|
||||
if (crypt_maj >= 1 && crypt_min >= 8)
|
||||
if (_dm_satisfies_version(1, 8, crypt_maj, crypt_min))
|
||||
_dm_crypt_flags |= DM_PLAIN64_SUPPORTED;
|
||||
|
||||
if (crypt_maj >= 1 && crypt_min >= 11)
|
||||
if (_dm_satisfies_version(1, 11, crypt_maj, crypt_min))
|
||||
_dm_crypt_flags |= DM_DISCARDS_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 13, crypt_maj, crypt_min))
|
||||
_dm_crypt_flags |= DM_TCW_SUPPORTED;
|
||||
|
||||
/* Repeat test if dm-crypt is not present */
|
||||
if (crypt_maj > 0)
|
||||
_dm_crypt_checked = 1;
|
||||
@@ -137,28 +159,40 @@ static void _dm_set_verity_compat(const char *dm_version, unsigned verity_maj,
|
||||
verity_maj, verity_min, verity_patch);
|
||||
}
|
||||
|
||||
static void _dm_kernel_info(void)
|
||||
{
|
||||
struct utsname uts;
|
||||
|
||||
if (!uname(&uts))
|
||||
log_dbg("Detected kernel %s %s %s.",
|
||||
uts.sysname, uts.release, uts.machine);
|
||||
|
||||
}
|
||||
|
||||
static int _dm_check_versions(void)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
struct dm_versions *target, *last_target;
|
||||
char dm_version[16];
|
||||
int r = 0;
|
||||
|
||||
if (_dm_crypt_checked)
|
||||
return 1;
|
||||
|
||||
_dm_kernel_info();
|
||||
|
||||
/* Shut up DM while checking */
|
||||
_quiet_log = 1;
|
||||
|
||||
/* FIXME: add support to DM so it forces crypt target module load here */
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
if (!dm_task_run(dmt)) {
|
||||
dm_task_destroy(dmt);
|
||||
return 0;
|
||||
}
|
||||
if (!dm_task_run(dmt))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_get_driver_version(dmt, dm_version, sizeof(dm_version))) {
|
||||
dm_task_destroy(dmt);
|
||||
return 0;
|
||||
}
|
||||
if (!dm_task_get_driver_version(dmt, dm_version, sizeof(dm_version)))
|
||||
goto out;
|
||||
|
||||
target = dm_task_get_versions(dmt);
|
||||
do {
|
||||
@@ -177,52 +211,67 @@ static int _dm_check_versions(void)
|
||||
target = (struct dm_versions *)((char *) target + target->next);
|
||||
} while (last_target != target);
|
||||
|
||||
r = 1;
|
||||
log_dbg("Device-mapper backend running with UDEV support %sabled.",
|
||||
_dm_use_udev() ? "en" : "dis");
|
||||
out:
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
return 1;
|
||||
|
||||
_quiet_log = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t dm_flags(void)
|
||||
{
|
||||
if (!_dm_crypt_checked)
|
||||
_dm_check_versions();
|
||||
|
||||
return _dm_crypt_flags;
|
||||
}
|
||||
|
||||
int dm_init(struct crypt_device *context, int check_kernel)
|
||||
/* This doesn't run any kernel checks, just set up userspace libdevmapper */
|
||||
void dm_backend_init(void)
|
||||
{
|
||||
if (!_dm_use_count++) {
|
||||
log_dbg("Initialising device-mapper backend%s, UDEV is %sabled.",
|
||||
check_kernel ? "" : " (NO kernel check requested)",
|
||||
_dm_use_udev() ? "en" : "dis");
|
||||
if (check_kernel && !_dm_check_versions()) {
|
||||
log_err(context, _("Cannot initialize device-mapper. Is dm_mod kernel module loaded?\n"));
|
||||
return -1;
|
||||
}
|
||||
if (getuid() || geteuid())
|
||||
log_dbg(("WARNING: Running as a non-root user. Functionality may be unavailable."));
|
||||
log_dbg("Initialising device-mapper backend library.");
|
||||
dm_log_init(set_dm_error);
|
||||
dm_log_init_verbose(10);
|
||||
}
|
||||
|
||||
// FIXME: global context is not safe
|
||||
if (context)
|
||||
_context = context;
|
||||
|
||||
return 1; /* unsafe memory */
|
||||
}
|
||||
|
||||
void dm_exit(void)
|
||||
void dm_backend_exit(void)
|
||||
{
|
||||
if (_dm_use_count && (!--_dm_use_count)) {
|
||||
log_dbg("Releasing device-mapper backend.");
|
||||
dm_log_init_verbose(0);
|
||||
dm_log_init(NULL);
|
||||
dm_lib_release();
|
||||
_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* libdevmapper is not context friendly, switch context on every DM call.
|
||||
* FIXME: this is not safe if called in parallel but neither is DM lib.
|
||||
*/
|
||||
static int dm_init_context(struct crypt_device *cd)
|
||||
{
|
||||
_context = cd;
|
||||
if (!_dm_check_versions()) {
|
||||
if (getuid() || geteuid())
|
||||
log_err(cd, _("Cannot initialize device-mapper, "
|
||||
"running as non-root user.\n"));
|
||||
else
|
||||
log_err(cd, _("Cannot initialize device-mapper. "
|
||||
"Is dm_mod kernel module loaded?\n"));
|
||||
_context = NULL;
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static void dm_exit_context(void)
|
||||
{
|
||||
_context = NULL;
|
||||
}
|
||||
|
||||
/* Return path to DM device */
|
||||
char *dm_device_path(const char *prefix, int major, int minor)
|
||||
{
|
||||
@@ -287,14 +336,16 @@ static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
|
||||
hex_key(hexkey, dmd->u.crypt.vk->keylength, dmd->u.crypt.vk->key);
|
||||
|
||||
max_size = strlen(hexkey) + strlen(dmd->u.crypt.cipher) +
|
||||
strlen(dmd->data_device) + strlen(features) + 64;
|
||||
strlen(device_block_path(dmd->data_device)) +
|
||||
strlen(features) + 64;
|
||||
params = crypt_safe_alloc(max_size);
|
||||
if (!params)
|
||||
goto out;
|
||||
|
||||
r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
|
||||
dmd->u.crypt.cipher, hexkey, dmd->u.crypt.iv_offset,
|
||||
dmd->data_device, dmd->u.crypt.offset, features);
|
||||
device_block_path(dmd->data_device), dmd->u.crypt.offset,
|
||||
features);
|
||||
if (r < 0 || r >= max_size) {
|
||||
crypt_safe_free(params);
|
||||
params = NULL;
|
||||
@@ -328,8 +379,8 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
||||
strncpy(hexsalt, "-", 2);
|
||||
|
||||
max_size = strlen(hexroot) + strlen(hexsalt) +
|
||||
strlen(dmd->data_device) +
|
||||
strlen(dmd->u.verity.hash_device) +
|
||||
strlen(device_block_path(dmd->data_device)) +
|
||||
strlen(device_block_path(dmd->u.verity.hash_device)) +
|
||||
strlen(vp->hash_name) + 128;
|
||||
|
||||
params = crypt_safe_alloc(max_size);
|
||||
@@ -338,8 +389,8 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
||||
|
||||
r = snprintf(params, max_size,
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s",
|
||||
vp->hash_type, dmd->data_device,
|
||||
dmd->u.verity.hash_device,
|
||||
vp->hash_type, device_block_path(dmd->data_device),
|
||||
device_block_path(dmd->u.verity.hash_device),
|
||||
vp->data_block_size, vp->hash_block_size,
|
||||
vp->data_size, dmd->u.verity.hash_offset,
|
||||
vp->hash_name, hexroot, hexsalt);
|
||||
@@ -423,7 +474,8 @@ error:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dm_remove_device(const char *name, int force, uint64_t size)
|
||||
int dm_remove_device(struct crypt_device *cd, const char *name,
|
||||
int force, uint64_t size)
|
||||
{
|
||||
int r = -EINVAL;
|
||||
int retries = force ? RETRY_COUNT : 1;
|
||||
@@ -432,6 +484,9 @@ int dm_remove_device(const char *name, int force, uint64_t size)
|
||||
if (!name || (force && !size))
|
||||
return -EINVAL;
|
||||
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
|
||||
do {
|
||||
r = _dm_simple(DM_DEVICE_REMOVE, name, 1) ? 0 : -EINVAL;
|
||||
if (--retries && r) {
|
||||
@@ -454,6 +509,7 @@ int dm_remove_device(const char *name, int force, uint64_t size)
|
||||
} while (r == -EINVAL && retries);
|
||||
|
||||
dm_task_update_nodes();
|
||||
dm_exit_context();
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -465,14 +521,19 @@ int dm_remove_device(const char *name, int force, uint64_t size)
|
||||
* CRYPT-LUKS1-00000000000000000000000000000000-name
|
||||
* CRYPT-TEMP-name
|
||||
*/
|
||||
static void dm_prepare_uuid(const char *name, const char *type, const char *uuid, char *buf, size_t buflen)
|
||||
static int dm_prepare_uuid(const char *name, const char *type, const char *uuid, char *buf, size_t buflen)
|
||||
{
|
||||
char *ptr, uuid2[UUID_LEN] = {0};
|
||||
uuid_t uu;
|
||||
unsigned i = 0;
|
||||
|
||||
/* Remove '-' chars */
|
||||
if (uuid && !uuid_parse(uuid, uu)) {
|
||||
if (uuid) {
|
||||
if (uuid_parse(uuid, uu) < 0) {
|
||||
log_dbg("Requested UUID %s has invalid format.", uuid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
|
||||
if (uuid[i] != '-') {
|
||||
*ptr = uuid[i];
|
||||
@@ -488,10 +549,12 @@ static void dm_prepare_uuid(const char *name, const char *type, const char *uuid
|
||||
log_dbg("DM-UUID is %s", buf);
|
||||
if (i >= buflen)
|
||||
log_err(NULL, _("DM-UUID for device %s was truncated.\n"), name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _dm_create_device(const char *name, const char *type,
|
||||
const char *device, uint32_t flags,
|
||||
struct device *device, uint32_t flags,
|
||||
const char *uuid, uint64_t size,
|
||||
char *params, int reload)
|
||||
{
|
||||
@@ -514,7 +577,8 @@ static int _dm_create_device(const char *name, const char *type,
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out_no_removal;
|
||||
} else {
|
||||
dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));
|
||||
if (!dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid)))
|
||||
goto out_no_removal;
|
||||
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
|
||||
goto out_no_removal;
|
||||
@@ -572,7 +636,7 @@ out:
|
||||
}
|
||||
|
||||
if (r < 0 && !reload)
|
||||
dm_remove_device(name, 0, 0);
|
||||
_dm_simple(DM_DEVICE_REMOVE, name, 1);
|
||||
|
||||
out_no_removal:
|
||||
if (cookie && _dm_use_udev())
|
||||
@@ -587,23 +651,31 @@ out_no_removal:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dm_create_device(const char *name,
|
||||
int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
int reload)
|
||||
{
|
||||
char *table_params = NULL;
|
||||
int r = -EINVAL;
|
||||
|
||||
if (!type)
|
||||
return -EINVAL;
|
||||
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
|
||||
if (dmd->target == DM_CRYPT)
|
||||
table_params = get_dm_crypt_params(dmd);
|
||||
else if (dmd->target == DM_VERITY)
|
||||
table_params = get_dm_verity_params(dmd->u.verity.vp, dmd);
|
||||
|
||||
if (!table_params || !type)
|
||||
return -EINVAL;
|
||||
|
||||
return _dm_create_device(name, type, dmd->data_device, dmd->flags,
|
||||
dmd->uuid, dmd->size, table_params, reload);
|
||||
if (table_params)
|
||||
r = _dm_create_device(name, type, dmd->data_device,
|
||||
dmd->flags, dmd->uuid, dmd->size,
|
||||
table_params, reload);
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
|
||||
static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
||||
@@ -656,31 +728,45 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dm_status_device(const char *name)
|
||||
int dm_status_device(struct crypt_device *cd, const char *name)
|
||||
{
|
||||
int r;
|
||||
struct dm_info dmi;
|
||||
struct stat st;
|
||||
|
||||
/* libdevmapper is too clever and handles
|
||||
* path argument differenly with error.
|
||||
* Fail early here if parameter is non-existent path.
|
||||
*/
|
||||
if (strchr(name, '/') && stat(name, &st) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
r = dm_status_dmi(name, &dmi, NULL, NULL);
|
||||
dm_exit_context();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return (dmi.open_count > 0);
|
||||
}
|
||||
|
||||
int dm_status_suspended(const char *name)
|
||||
int dm_status_suspended(struct crypt_device *cd, const char *name)
|
||||
{
|
||||
int r;
|
||||
struct dm_info dmi;
|
||||
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
r = dm_status_dmi(name, &dmi, DM_CRYPT_TARGET, NULL);
|
||||
dm_exit_context();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dmi.suspended ? 1 : 0;
|
||||
}
|
||||
|
||||
int dm_status_verity_ok(const char *name)
|
||||
static int _dm_status_verity_ok(const char *name)
|
||||
{
|
||||
int r;
|
||||
struct dm_info dmi;
|
||||
@@ -699,6 +785,17 @@ int dm_status_verity_ok(const char *name)
|
||||
return r;
|
||||
}
|
||||
|
||||
int dm_status_verity_ok(struct crypt_device *cd, const char *name)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
r = _dm_status_verity_ok(name);
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
|
||||
/* FIXME use hex wrapper, user val wrappers for line parsing */
|
||||
static int _dm_query_crypt(uint32_t get_flags,
|
||||
struct dm_info *dmi,
|
||||
@@ -708,6 +805,7 @@ static int _dm_query_crypt(uint32_t get_flags,
|
||||
uint64_t val64;
|
||||
char *rcipher, *key_, *rdevice, *endp, buffer[3], *arg;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
memset(dmd, 0, sizeof(*dmd));
|
||||
dmd->target = DM_CRYPT;
|
||||
@@ -730,8 +828,13 @@ static int _dm_query_crypt(uint32_t get_flags,
|
||||
|
||||
/* device */
|
||||
rdevice = strsep(¶ms, " ");
|
||||
if (get_flags & DM_ACTIVE_DEVICE)
|
||||
dmd->data_device = crypt_lookup_dev(rdevice);
|
||||
if (get_flags & DM_ACTIVE_DEVICE) {
|
||||
arg = crypt_lookup_dev(rdevice);
|
||||
r = device_alloc(&dmd->data_device, arg);
|
||||
free(arg);
|
||||
if (r < 0 && r != -ENOTBLK)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*offset */
|
||||
if (!params)
|
||||
@@ -805,6 +908,7 @@ static int _dm_query_verity(uint32_t get_flags,
|
||||
uint64_t val64;
|
||||
ssize_t len;
|
||||
char *str, *str2;
|
||||
int r;
|
||||
|
||||
if (get_flags & DM_ACTIVE_VERITY_PARAMS)
|
||||
vp = dmd->u.verity.vp;
|
||||
@@ -826,15 +930,25 @@ static int _dm_query_verity(uint32_t get_flags,
|
||||
str = strsep(¶ms, " ");
|
||||
if (!params)
|
||||
return -EINVAL;
|
||||
if (get_flags & DM_ACTIVE_DEVICE)
|
||||
dmd->data_device = crypt_lookup_dev(str);
|
||||
if (get_flags & DM_ACTIVE_DEVICE) {
|
||||
str2 = crypt_lookup_dev(str);
|
||||
r = device_alloc(&dmd->data_device, str2);
|
||||
free(str2);
|
||||
if (r < 0 && r != -ENOTBLK)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* hash device */
|
||||
str = strsep(¶ms, " ");
|
||||
if (!params)
|
||||
return -EINVAL;
|
||||
if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE)
|
||||
dmd->u.verity.hash_device = crypt_lookup_dev(str);
|
||||
if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
|
||||
str2 = crypt_lookup_dev(str);
|
||||
r = device_alloc(&dmd->u.verity.hash_device, str2);
|
||||
free(str2);
|
||||
if (r < 0 && r != -ENOTBLK)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* data block size*/
|
||||
val32 = strtoul(params, ¶ms, 10);
|
||||
@@ -907,8 +1021,8 @@ static int _dm_query_verity(uint32_t get_flags,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_query_device(const char *name, uint32_t get_flags,
|
||||
struct crypt_dm_active_device *dmd)
|
||||
int dm_query_device(struct crypt_device *cd, const char *name,
|
||||
uint32_t get_flags, struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
struct dm_info dmi;
|
||||
@@ -918,6 +1032,8 @@ int dm_query_device(const char *name, uint32_t get_flags,
|
||||
void *next = NULL;
|
||||
int r = -EINVAL;
|
||||
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
|
||||
goto out;
|
||||
if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
|
||||
@@ -949,7 +1065,7 @@ int dm_query_device(const char *name, uint32_t get_flags,
|
||||
r = _dm_query_verity(get_flags, &dmi, params, dmd);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = dm_status_verity_ok(name);
|
||||
r = _dm_status_verity_ok(name);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
if (r == 0)
|
||||
@@ -979,6 +1095,7 @@ out:
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1009,52 +1126,63 @@ static int _dm_message(const char *name, const char *msg)
|
||||
return r;
|
||||
}
|
||||
|
||||
int dm_suspend_and_wipe_key(const char *name)
|
||||
int dm_suspend_and_wipe_key(struct crypt_device *cd, const char *name)
|
||||
{
|
||||
if (!_dm_check_versions())
|
||||
int r = -ENOTSUP;
|
||||
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
|
||||
if (!(_dm_crypt_flags & DM_KEY_WIPE_SUPPORTED))
|
||||
return -ENOTSUP;
|
||||
goto out;
|
||||
|
||||
if (!_dm_simple(DM_DEVICE_SUSPEND, name, 0))
|
||||
return -EINVAL;
|
||||
if (!_dm_simple(DM_DEVICE_SUSPEND, name, 0)) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!_dm_message(name, "key wipe")) {
|
||||
_dm_simple(DM_DEVICE_RESUME, name, 1);
|
||||
return -EINVAL;
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_resume_and_reinstate_key(const char *name,
|
||||
size_t key_size,
|
||||
const char *key)
|
||||
int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
size_t key_size, const char *key)
|
||||
{
|
||||
int msg_size = key_size * 2 + 10; // key set <key>
|
||||
char *msg;
|
||||
int r = 0;
|
||||
char *msg = NULL;
|
||||
int r = -ENOTSUP;
|
||||
|
||||
if (!_dm_check_versions())
|
||||
if (dm_init_context(cd))
|
||||
return -ENOTSUP;
|
||||
|
||||
if (!(_dm_crypt_flags & DM_KEY_WIPE_SUPPORTED))
|
||||
return -ENOTSUP;
|
||||
goto out;
|
||||
|
||||
msg = crypt_safe_alloc(msg_size);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
if (!msg) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(msg, 0, msg_size);
|
||||
strcpy(msg, "key set ");
|
||||
hex_key(&msg[8], key_size, key);
|
||||
|
||||
if (!_dm_message(name, msg) ||
|
||||
!_dm_simple(DM_DEVICE_RESUME, name, 1))
|
||||
!_dm_simple(DM_DEVICE_RESUME, name, 1)) {
|
||||
r = -EINVAL;
|
||||
|
||||
goto out;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
crypt_safe_free(msg);
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1072,27 +1200,3 @@ 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.u.crypt.offset + dmd.size) ||
|
||||
(offset + size) <= dmd.u.crypt.offset)
|
||||
r = 0;
|
||||
else
|
||||
r = -EBUSY;
|
||||
|
||||
log_dbg("seg: %" PRIu64 " - %" PRIu64 ", new %" PRIu64 " - %" PRIu64 "%s",
|
||||
dmd.u.crypt.offset, dmd.u.crypt.offset + dmd.size, offset, offset + size,
|
||||
r ? " (overlapping)" : " (ok)");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,13 @@ moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libloopaes.la
|
||||
|
||||
libloopaes_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
libloopaes_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
|
||||
|
||||
libloopaes_la_SOURCES = \
|
||||
loopaes.c \
|
||||
loopaes.h
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
AM_CPPFLAGS = -include config.h \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/lib/crypto_backend
|
||||
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2013, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -73,16 +75,16 @@ static int hash_keys(struct crypt_device *cd,
|
||||
const char *hash_override,
|
||||
const char **input_keys,
|
||||
unsigned int keys_count,
|
||||
unsigned int key_len_output)
|
||||
unsigned int key_len_output,
|
||||
unsigned int key_len_input)
|
||||
{
|
||||
const char *hash_name;
|
||||
char tweak, *key_ptr;
|
||||
unsigned i, key_len_input;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
hash_name = hash_override ?: get_hash(key_len_output);
|
||||
tweak = get_tweak(keys_count);
|
||||
key_len_input = strlen(input_keys[0]);
|
||||
|
||||
if (!keys_count || !key_len_output || !hash_name || !key_len_input) {
|
||||
log_err(cd, _("Key processing error (using hash %s).\n"),
|
||||
@@ -132,9 +134,10 @@ int LOOPAES_parse_keyfile(struct crypt_device *cd,
|
||||
size_t buffer_len)
|
||||
{
|
||||
const char *keys[LOOPAES_KEYS_MAX];
|
||||
unsigned i, key_index, key_len, offset;
|
||||
unsigned int key_lengths[LOOPAES_KEYS_MAX];
|
||||
unsigned int i, key_index, key_len, offset;
|
||||
|
||||
log_dbg("Parsing loop-AES keyfile of size %d.", buffer_len);
|
||||
log_dbg("Parsing loop-AES keyfile of size %zu.", buffer_len);
|
||||
|
||||
if (!buffer_len)
|
||||
return -EINVAL;
|
||||
@@ -152,33 +155,45 @@ int LOOPAES_parse_keyfile(struct crypt_device *cd,
|
||||
|
||||
offset = 0;
|
||||
key_index = 0;
|
||||
key_lengths[0] = 0;
|
||||
while (offset < buffer_len && key_index < LOOPAES_KEYS_MAX) {
|
||||
keys[key_index++] = &buffer[offset];
|
||||
while (offset < buffer_len && buffer[offset])
|
||||
keys[key_index] = &buffer[offset];
|
||||
key_lengths[key_index] = 0;;
|
||||
while (offset < buffer_len && buffer[offset]) {
|
||||
offset++;
|
||||
key_lengths[key_index]++;
|
||||
}
|
||||
if (offset == buffer_len) {
|
||||
log_dbg("Unterminated key #%d in keyfile.", key_index);
|
||||
log_err(cd, _("Incompatible loop-AES keyfile detected.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
while (offset < buffer_len && !buffer[offset])
|
||||
offset++;
|
||||
key_index++;
|
||||
}
|
||||
|
||||
/* All keys must be the same length */
|
||||
key_len = key_index ? strlen(keys[0]) : 0;
|
||||
key_len = key_lengths[0];
|
||||
for (i = 0; i < key_index; i++)
|
||||
if (key_len != strlen(keys[i])) {
|
||||
if (!key_lengths[i] || (key_lengths[i] != key_len)) {
|
||||
log_dbg("Unexpected length %d of key #%d (should be %d).",
|
||||
strlen(keys[i]), i, key_len);
|
||||
key_lengths[i], i, key_len);
|
||||
key_len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
log_dbg("Keyfile: %d keys of length %d.", key_index, key_len);
|
||||
if (offset != buffer_len || key_len == 0 ||
|
||||
(key_index != 1 && key_index !=64 && key_index != 65)) {
|
||||
log_err(cd, _("Incompatible loop-AES keyfile detected.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg("Keyfile: %d keys of length %d.", key_index, key_len);
|
||||
|
||||
*keys_count = key_index;
|
||||
return hash_keys(cd, vk, hash, keys, key_index, crypt_get_volume_key_size(cd));
|
||||
return hash_keys(cd, vk, hash, keys, key_index,
|
||||
crypt_get_volume_key_size(cd), key_len);
|
||||
}
|
||||
|
||||
int LOOPAES_activate(struct crypt_device *cd,
|
||||
@@ -193,10 +208,9 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
int r;
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.target = DM_CRYPT,
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
.size = 0,
|
||||
.flags = flags,
|
||||
.data_device = crypt_get_device_name(cd),
|
||||
.data_device = crypt_data_device(cd),
|
||||
.u.crypt = {
|
||||
.cipher = NULL,
|
||||
.vk = vk,
|
||||
@@ -205,9 +219,8 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
&dmd.size, &dmd.u.crypt.offset, &flags);
|
||||
r = device_block_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -225,9 +238,9 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
log_dbg("Trying to activate loop-AES device %s using cipher %s.",
|
||||
name, dmd.u.crypt.cipher);
|
||||
|
||||
r = dm_create_device(name, CRYPT_LOOPAES, &dmd, 0);
|
||||
r = dm_create_device(cd, name, CRYPT_LOOPAES, &dmd, 0);
|
||||
|
||||
if (!r && !(dm_flags() & req_flags)) {
|
||||
if (r < 0 && !(dm_flags() & req_flags)) {
|
||||
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping.\n"));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -2,18 +2,20 @@
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2013, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -21,7 +23,6 @@
|
||||
#define _LOOPAES_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
struct crypt_device;
|
||||
struct volume_key;
|
||||
|
||||
@@ -2,20 +2,16 @@ moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libluks1.la
|
||||
|
||||
libluks1_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
libluks1_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
|
||||
|
||||
libluks1_la_SOURCES = \
|
||||
af.c \
|
||||
pbkdf.c \
|
||||
keymanage.c \
|
||||
keyencryption.c \
|
||||
pbkdf.h \
|
||||
af.h \
|
||||
luks.h
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
AM_CPPFLAGS = -include config.h \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/lib/crypto_backend
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -66,9 +67,14 @@ out:
|
||||
|
||||
static int diffuse(char *src, char *dst, size_t size, const char *hash_name)
|
||||
{
|
||||
unsigned int digest_size = crypt_hash_size(hash_name);
|
||||
int hash_size = crypt_hash_size(hash_name);
|
||||
unsigned int digest_size;
|
||||
unsigned int i, blocks, padding;
|
||||
|
||||
if (hash_size <= 0)
|
||||
return 1;
|
||||
digest_size = hash_size;
|
||||
|
||||
blocks = size / digest_size;
|
||||
padding = size % digest_size;
|
||||
|
||||
@@ -141,3 +147,17 @@ out:
|
||||
free(bufblock);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Size of final split data including sector alignment */
|
||||
size_t AF_split_sectors(size_t blocksize, unsigned int blocknumbers)
|
||||
{
|
||||
size_t af_size;
|
||||
|
||||
/* data material * stripes */
|
||||
af_size = blocksize * blocknumbers;
|
||||
|
||||
/* round up to sector */
|
||||
af_size = (af_size + (SECTOR_SIZE - 1)) / SECTOR_SIZE;
|
||||
|
||||
return af_size;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -38,5 +39,6 @@
|
||||
|
||||
int AF_split(char *src, char *dst, size_t blocksize, unsigned int blocknumbers, const char *hash);
|
||||
int AF_merge(char *src, char *dst, size_t blocksize, unsigned int blocknumbers, const char *hash);
|
||||
size_t AF_split_sectors(size_t blocksize, unsigned int blocknumbers);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*
|
||||
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -18,189 +20,230 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "luks.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define div_round_up(a,b) ({ \
|
||||
typeof(a) __a = (a); \
|
||||
typeof(b) __b = (b); \
|
||||
(__a - 1) / __b + 1; \
|
||||
})
|
||||
static void _error_hint(struct crypt_device *ctx, const char *device,
|
||||
const char *cipher, const char *mode, size_t keyLength)
|
||||
{
|
||||
char cipher_spec[MAX_CIPHER_LEN * 3];
|
||||
|
||||
static inline int round_up_modulo(int x, int m) {
|
||||
return div_round_up(x, m) * m;
|
||||
if (snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", cipher, mode) < 0)
|
||||
return;
|
||||
|
||||
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"),
|
||||
device, cipher_spec);
|
||||
|
||||
if (!strncmp(mode, "xts", 3) && (keyLength != 256 && keyLength != 512))
|
||||
log_err(ctx, _("Key size in XTS mode must be 256 or 512 bits.\n"));
|
||||
}
|
||||
|
||||
static const char *cleaner_name=NULL;
|
||||
static uint64_t cleaner_size = 0;
|
||||
static int devfd=-1;
|
||||
|
||||
static int setup_mapping(const char *cipher, const char *name,
|
||||
const char *device,
|
||||
static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
const char *cipher, const char *cipher_mode,
|
||||
struct volume_key *vk,
|
||||
unsigned int sector, size_t srcLength,
|
||||
int mode, struct crypt_device *ctx)
|
||||
unsigned int sector,
|
||||
ssize_t (*func)(int, int, void *, size_t),
|
||||
int mode,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
int device_sector_size = sector_size_for_device(device);
|
||||
char name[PATH_MAX], path[PATH_MAX];
|
||||
char cipher_spec[MAX_CIPHER_LEN * 3];
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.target = DM_CRYPT,
|
||||
.uuid = NULL,
|
||||
.size = 0,
|
||||
.flags = 0,
|
||||
.data_device = device,
|
||||
.flags = CRYPT_ACTIVATE_PRIVATE,
|
||||
.data_device = crypt_metadata_device(ctx),
|
||||
.u.crypt = {
|
||||
.cipher = cipher,
|
||||
.cipher = cipher_spec,
|
||||
.vk = vk,
|
||||
.offset = sector,
|
||||
.iv_offset = 0,
|
||||
}
|
||||
};
|
||||
int r, bsize, devfd = -1;
|
||||
|
||||
log_dbg("Using dmcrypt to access keyslot area.");
|
||||
|
||||
bsize = device_block_size(dmd.data_device);
|
||||
if (bsize <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
dmd.size = size_round_up(srcLength, bsize) / SECTOR_SIZE;
|
||||
|
||||
dmd.flags = CRYPT_ACTIVATE_PRIVATE;
|
||||
if (mode == O_RDONLY)
|
||||
dmd.flags |= CRYPT_ACTIVATE_READONLY;
|
||||
/*
|
||||
* we need to round this to nearest multiple of the underlying
|
||||
* device's sector size, otherwise the mapping will be refused.
|
||||
*/
|
||||
if(device_sector_size < 0) {
|
||||
log_err(ctx, _("Unable to obtain sector size for %s"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dmd.size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
|
||||
cleaner_size = dmd.size;
|
||||
if (snprintf(name, sizeof(name), "temporary-cryptsetup-%d", getpid()) < 0)
|
||||
return -ENOMEM;
|
||||
if (snprintf(path, sizeof(path), "%s/%s", dm_get_dir(), name) < 0)
|
||||
return -ENOMEM;
|
||||
if (snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", cipher, cipher_mode) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
return dm_create_device(name, "TEMP", &dmd, 0);
|
||||
}
|
||||
|
||||
static void sigint_handler(int sig __attribute__((unused)))
|
||||
{
|
||||
if(devfd >= 0)
|
||||
close(devfd);
|
||||
devfd = -1;
|
||||
if(cleaner_name)
|
||||
dm_remove_device(cleaner_name, 1, cleaner_size);
|
||||
|
||||
signal(SIGINT, SIG_DFL);
|
||||
kill(getpid(), SIGINT);
|
||||
}
|
||||
|
||||
static const char *_error_hint(char *cipherMode, size_t keyLength)
|
||||
{
|
||||
const char *hint= "";
|
||||
|
||||
if (!strncmp(cipherMode, "xts", 3) && (keyLength != 256 && keyLength != 512))
|
||||
hint = _("Key size in XTS mode must be 256 or 512 bits.\n");
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
/* This function is not reentrant safe, as it installs a signal
|
||||
handler and global vars for cleaning */
|
||||
static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
ssize_t (*func)(int, void *, size_t),
|
||||
int mode,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
char *name = NULL;
|
||||
char *fullpath = NULL;
|
||||
char *dmCipherSpec = NULL;
|
||||
const char *dmDir = dm_get_dir();
|
||||
int r = -1;
|
||||
|
||||
if(dmDir == NULL) {
|
||||
log_err(ctx, _("Failed to obtain device mapper directory."));
|
||||
return -1;
|
||||
}
|
||||
if(asprintf(&name,"temporary-cryptsetup-%d",getpid()) == -1 ||
|
||||
asprintf(&fullpath,"%s/%s",dmDir,name) == -1 ||
|
||||
asprintf(&dmCipherSpec,"%s-%s",hdr->cipherName, hdr->cipherMode) == -1) {
|
||||
r = -ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
cleaner_name = name;
|
||||
|
||||
r = setup_mapping(dmCipherSpec, name, device,
|
||||
vk, sector, srcLength, mode, ctx);
|
||||
r = device_block_adjust(ctx, dmd.data_device, DEV_OK,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
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, vk->keylength * 8));
|
||||
r = -EIO;
|
||||
goto out1;
|
||||
log_err(ctx, _("Device %s doesn't exist or access denied.\n"),
|
||||
device_path(dmd.data_device));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
devfd = open(fullpath, mode | O_DIRECT | O_SYNC); /* devfd is a global var */
|
||||
if (mode != O_RDONLY && dmd.flags & CRYPT_ACTIVATE_READONLY) {
|
||||
log_err(ctx, _("Cannot write to device %s, permission denied.\n"),
|
||||
device_path(dmd.data_device));
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
r = dm_create_device(ctx, name, "TEMP", &dmd, 0);
|
||||
if (r < 0) {
|
||||
if (r != -EACCES && r != -ENOTSUP)
|
||||
_error_hint(ctx, device_path(dmd.data_device),
|
||||
cipher, cipher_mode, vk->keylength * 8);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
devfd = open(path, mode | O_DIRECT | O_SYNC);
|
||||
if (devfd == -1) {
|
||||
log_err(ctx, _("Failed to open temporary keystore device.\n"));
|
||||
r = -EIO;
|
||||
goto out2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = func(devfd,src,srcLength);
|
||||
r = func(devfd, bsize, src, srcLength);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Failed to access temporary keystore device.\n"));
|
||||
r = -EIO;
|
||||
goto out3;
|
||||
}
|
||||
|
||||
} else
|
||||
r = 0;
|
||||
out3:
|
||||
out:
|
||||
if(devfd != -1)
|
||||
close(devfd);
|
||||
devfd = -1;
|
||||
out2:
|
||||
dm_remove_device(cleaner_name, 1, cleaner_size);
|
||||
out1:
|
||||
signal(SIGINT, SIG_DFL);
|
||||
cleaner_name = NULL;
|
||||
cleaner_size = 0;
|
||||
free(dmCipherSpec);
|
||||
free(fullpath);
|
||||
free(name);
|
||||
dm_remove_device(ctx, name, 1, dmd.size);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
return LUKS_endec_template(src,srcLength,hdr,vk, device,
|
||||
sector, write_blockwise, O_RDWR, ctx);
|
||||
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
struct crypt_storage *s;
|
||||
int devfd, bsize, r = 0;
|
||||
|
||||
/* Only whole sector writes supported */
|
||||
if (srcLength % SECTOR_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
/* Encrypt buffer */
|
||||
r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
|
||||
if (r)
|
||||
log_dbg("Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
cipher, cipher_mode, r);
|
||||
|
||||
/* Fallback to old temporary dmcrypt device */
|
||||
if (r == -ENOTSUP || r == -ENOENT)
|
||||
return LUKS_endec_template(src, srcLength, cipher, cipher_mode,
|
||||
vk, sector, write_blockwise, O_RDWR, ctx);
|
||||
|
||||
if (r) {
|
||||
_error_hint(ctx, device_path(device), cipher, cipher_mode,
|
||||
vk->keylength * 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
log_dbg("Using userspace crypto wrapper to access keyslot area.");
|
||||
|
||||
r = crypt_storage_encrypt(s, 0, srcLength / SECTOR_SIZE, src);
|
||||
crypt_storage_destroy(s);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Write buffer to device */
|
||||
bsize = device_block_size(device);
|
||||
if (bsize <= 0)
|
||||
return -EIO;
|
||||
|
||||
devfd = open(device_path(device), O_RDWR | O_DIRECT);
|
||||
if (devfd == -1)
|
||||
return -EIO;
|
||||
|
||||
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
||||
write_blockwise(devfd, bsize, src, srcLength) == -1)
|
||||
r = -EIO;
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
return LUKS_endec_template(dst,dstLength,hdr,vk, device,
|
||||
sector, read_blockwise, O_RDONLY, ctx);
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
struct crypt_storage *s;
|
||||
int devfd, bsize, r = 0;
|
||||
|
||||
/* Only whole sector reads supported */
|
||||
if (dstLength % SECTOR_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
|
||||
if (r)
|
||||
log_dbg("Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
cipher, cipher_mode, r);
|
||||
|
||||
/* Fallback to old temporary dmcrypt device */
|
||||
if (r == -ENOTSUP || r == -ENOENT)
|
||||
return LUKS_endec_template(dst, dstLength, cipher, cipher_mode,
|
||||
vk, sector, read_blockwise, O_RDONLY, ctx);
|
||||
|
||||
if (r) {
|
||||
_error_hint(ctx, device_path(device), cipher, cipher_mode,
|
||||
vk->keylength * 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
log_dbg("Using userspace crypto wrapper to access keyslot area.");
|
||||
|
||||
/* Read buffer from device */
|
||||
bsize = device_block_size(device);
|
||||
if (bsize <= 0) {
|
||||
crypt_storage_destroy(s);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
devfd = open(device_path(device), O_RDONLY | O_DIRECT);
|
||||
if (devfd == -1) {
|
||||
crypt_storage_destroy(s);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
||||
read_blockwise(devfd, bsize, dst, dstLength) == -1) {
|
||||
crypt_storage_destroy(s);
|
||||
close(devfd);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
close(devfd);
|
||||
|
||||
/* Decrypt buffer */
|
||||
r = crypt_storage_decrypt(s, 0, dstLength / SECTOR_SIZE, dst);
|
||||
crypt_storage_destroy(s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*
|
||||
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2014, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -33,56 +35,60 @@
|
||||
|
||||
#include "luks.h"
|
||||
#include "af.h"
|
||||
#include "pbkdf.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define div_round_up(a,b) ({ \
|
||||
typeof(a) __a = (a); \
|
||||
typeof(b) __b = (b); \
|
||||
(__a - 1) / __b + 1; \
|
||||
})
|
||||
|
||||
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)
|
||||
/* Get size of struct luks_phdr with all keyslots material space */
|
||||
static size_t LUKS_device_sectors(size_t keyLen)
|
||||
{
|
||||
uint64_t keyslot_sectors, sector;
|
||||
size_t keyslot_sectors, sector;
|
||||
int i;
|
||||
|
||||
keyslot_sectors = div_round_up(keyLen * LUKS_STRIPES, SECTOR_SIZE);
|
||||
sector = round_up_modulo(LUKS_PHDR_SIZE, LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
keyslot_sectors = AF_split_sectors(keyLen, LUKS_STRIPES);
|
||||
sector = LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE;
|
||||
|
||||
for (i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
sector = round_up_modulo(sector, LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
sector = size_round_up(sector, LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
sector += keyslot_sectors;
|
||||
}
|
||||
|
||||
return sector;
|
||||
}
|
||||
|
||||
static int LUKS_check_device_size(struct crypt_device *ctx, const char *device,
|
||||
size_t keyLength)
|
||||
int LUKS_keyslot_area(struct luks_phdr *hdr,
|
||||
int keyslot,
|
||||
uint64_t *offset,
|
||||
uint64_t *length)
|
||||
{
|
||||
if(keyslot >= LUKS_NUMKEYS || keyslot < 0)
|
||||
return -EINVAL;
|
||||
|
||||
*offset = hdr->keyblock[keyslot].keyMaterialOffset * SECTOR_SIZE;
|
||||
*length = AF_split_sectors(hdr->keyBytes, LUKS_STRIPES) * SECTOR_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int LUKS_check_device_size(struct crypt_device *ctx, size_t keyLength)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
uint64_t dev_sectors, hdr_sectors;
|
||||
|
||||
if (!keyLength)
|
||||
return -EINVAL;
|
||||
|
||||
if(device_size(device, &dev_sectors)) {
|
||||
log_dbg("Cannot get device size for device %s.", device);
|
||||
log_dbg("Cannot get device size for device %s.", device_path(device));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dev_sectors >>= SECTOR_SHIFT;
|
||||
hdr_sectors = LUKS_device_sectors(keyLength);
|
||||
log_dbg("Key length %u, device size %" PRIu64 " sectors, header size %"
|
||||
log_dbg("Key length %zu, device size %" PRIu64 " sectors, header size %"
|
||||
PRIu64 " sectors.",keyLength, dev_sectors, hdr_sectors);
|
||||
|
||||
if (hdr_sectors > dev_sectors) {
|
||||
log_err(ctx, _("Device %s is too small.\n"), device);
|
||||
log_err(ctx, _("Device %s is too small. (LUKS requires at least %" PRIu64 " bytes.)\n"),
|
||||
device_path(device), hdr_sectors * SECTOR_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -112,7 +118,7 @@ static int LUKS_check_keyslot_size(const struct luks_phdr *phdr, unsigned int ke
|
||||
return 1;
|
||||
}
|
||||
|
||||
secs_per_stripes = div_round_up(phdr->keyBytes * phdr->keyblock[keyIndex].stripes, SECTOR_SIZE);
|
||||
secs_per_stripes = AF_split_sectors(phdr->keyBytes, phdr->keyblock[keyIndex].stripes);
|
||||
|
||||
if (phdr->payloadOffset < (phdr->keyblock[keyIndex].keyMaterialOffset + secs_per_stripes)) {
|
||||
log_dbg("Invalid keyslot size %u (offset %u, stripes %u) in "
|
||||
@@ -142,54 +148,56 @@ static const char *dbg_slot_state(crypt_keyslot_info ki)
|
||||
}
|
||||
}
|
||||
|
||||
int LUKS_hdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
struct luks_phdr hdr;
|
||||
int r = 0, devfd = -1;
|
||||
ssize_t hdr_size;
|
||||
ssize_t buffer_size;
|
||||
char *buffer = NULL;
|
||||
struct stat st;
|
||||
|
||||
if(stat(backup_file, &st) == 0) {
|
||||
log_err(ctx, _("Requested file %s already exist.\n"), backup_file);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(&hdr, 1, 0, ctx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
buffer_size = LUKS_device_sectors(hdr->keyBytes) << SECTOR_SHIFT;
|
||||
hdr_size = LUKS_device_sectors(hdr.keyBytes) << SECTOR_SHIFT;
|
||||
buffer_size = size_round_up(hdr_size, crypt_getpagesize());
|
||||
|
||||
buffer = crypt_safe_alloc(buffer_size);
|
||||
if (!buffer || buffer_size < LUKS_ALIGN_KEYSLOTS) {
|
||||
if (!buffer || hdr_size < LUKS_ALIGN_KEYSLOTS || hdr_size > buffer_size) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes).",
|
||||
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS);
|
||||
log_dbg("Storing backup of header (%zu bytes) and keyslot area (%zu bytes).",
|
||||
sizeof(hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);
|
||||
|
||||
devfd = open(device, O_RDONLY | O_DIRECT | O_SYNC);
|
||||
log_dbg("Output backup file size: %zu bytes.", buffer_size);
|
||||
|
||||
devfd = device_open(device, O_RDONLY);
|
||||
if(devfd == -1) {
|
||||
log_err(ctx, _("Device %s is not a valid LUKS device.\n"), device);
|
||||
log_err(ctx, _("Device %s is not a valid LUKS device.\n"), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(read_blockwise(devfd, buffer, buffer_size) < buffer_size) {
|
||||
if (read_blockwise(devfd, device_block_size(device), buffer, hdr_size) < hdr_size) {
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
/* Wipe unused area, so backup cannot contain old signatures */
|
||||
memset(buffer + sizeof(*hdr), 0, LUKS_ALIGN_KEYSLOTS - sizeof(*hdr));
|
||||
if (hdr.keyblock[0].keyMaterialOffset * SECTOR_SIZE == LUKS_ALIGN_KEYSLOTS)
|
||||
memset(buffer + sizeof(hdr), 0, LUKS_ALIGN_KEYSLOTS - sizeof(hdr));
|
||||
|
||||
devfd = creat(backup_file, S_IRUSR);
|
||||
devfd = open(backup_file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR);
|
||||
if (devfd == -1) {
|
||||
if (errno == EEXIST)
|
||||
log_err(ctx, _("Requested header backup file %s already exists.\n"), backup_file);
|
||||
else
|
||||
log_err(ctx, _("Cannot create header backup file %s.\n"), backup_file);
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -204,28 +212,26 @@ int LUKS_hdr_backup(
|
||||
out:
|
||||
if (devfd != -1)
|
||||
close(devfd);
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_hdr_restore(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
int r = 0, devfd = -1, diff_uuid = 0;
|
||||
ssize_t buffer_size = 0;
|
||||
char *buffer = NULL, msg[200];
|
||||
struct stat st;
|
||||
struct luks_phdr hdr_file;
|
||||
|
||||
if(stat(backup_file, &st) < 0) {
|
||||
log_err(ctx, _("Backup file %s doesn't exist.\n"), backup_file);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = LUKS_read_phdr_backup(backup_file, &hdr_file, 0, ctx);
|
||||
if (r == -ENOENT)
|
||||
return r;
|
||||
|
||||
r = LUKS_read_phdr_backup(backup_file, device, &hdr_file, 0, ctx);
|
||||
if (!r)
|
||||
buffer_size = LUKS_device_sectors(hdr_file.keyBytes) << SECTOR_SHIFT;
|
||||
|
||||
@@ -255,9 +261,9 @@ int LUKS_hdr_restore(
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
r = LUKS_read_phdr(device, hdr, 0, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 0, 0, ctx);
|
||||
if (r == 0) {
|
||||
log_dbg("Device %s already contains LUKS header, checking UUID and offset.", device);
|
||||
log_dbg("Device %s already contains LUKS header, checking UUID and offset.", device_path(device));
|
||||
if(hdr->payloadOffset != hdr_file.payloadOffset ||
|
||||
hdr->keyBytes != hdr_file.keyBytes) {
|
||||
log_err(ctx, _("Data offset or key size differs on device and backup, restore failed.\n"));
|
||||
@@ -268,7 +274,7 @@ int LUKS_hdr_restore(
|
||||
diff_uuid = 1;
|
||||
}
|
||||
|
||||
if (snprintf(msg, sizeof(msg), _("Device %s %s%s"), device,
|
||||
if (snprintf(msg, sizeof(msg), _("Device %s %s%s"), device_path(device),
|
||||
r ? _("does not contain LUKS header. Replacing header can destroy data on that device.") :
|
||||
_("already contains LUKS header. Replacing header will destroy existing keyslots."),
|
||||
diff_uuid ? _("\nWARNING: real device header has different UUID than backup!") : "") < 0) {
|
||||
@@ -281,24 +287,28 @@ int LUKS_hdr_restore(
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes) to device %s.",
|
||||
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS, device);
|
||||
log_dbg("Storing backup of header (%zu bytes) and keyslot area (%zu bytes) to device %s.",
|
||||
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS, device_path(device));
|
||||
|
||||
devfd = open(device, O_WRONLY | O_DIRECT | O_SYNC);
|
||||
devfd = device_open(device, O_RDWR);
|
||||
if (devfd == -1) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device);
|
||||
if (errno == EACCES)
|
||||
log_err(ctx, _("Cannot write to device %s, permission denied.\n"),
|
||||
device_path(device));
|
||||
else
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(write_blockwise(devfd, buffer, buffer_size) < buffer_size) {
|
||||
if (write_blockwise(devfd, device_block_size(device), buffer, buffer_size) < buffer_size) {
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
/* Be sure to reload new data */
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
out:
|
||||
if (devfd != -1)
|
||||
close(devfd);
|
||||
@@ -307,7 +317,7 @@ out:
|
||||
}
|
||||
|
||||
/* This routine should do some just basic recovery for known problems. */
|
||||
static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
{
|
||||
struct luks_phdr temp_phdr;
|
||||
const unsigned char *sector = (const unsigned char*)phdr;
|
||||
@@ -315,7 +325,7 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
|
||||
uint64_t PBKDF2_per_sec = 1;
|
||||
int i, bad, r, need_write = 0;
|
||||
|
||||
if (phdr->keyBytes != 16 && phdr->keyBytes != 32) {
|
||||
if (phdr->keyBytes != 16 && phdr->keyBytes != 32 && phdr->keyBytes != 64) {
|
||||
log_err(ctx, _("Non standard key size, manual repair required.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -336,7 +346,7 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
|
||||
phdr->hashSpec,phdr->uuid, LUKS_STRIPES,
|
||||
phdr->payloadOffset, 0,
|
||||
1, &PBKDF2_per_sec,
|
||||
"/dev/null", ctx);
|
||||
1, ctx);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Repair failed."));
|
||||
goto out;
|
||||
@@ -384,7 +394,7 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
|
||||
|
||||
if (need_write) {
|
||||
log_verbose(ctx, _("Writing LUKS header to disk.\n"));
|
||||
r = LUKS_write_phdr(device, phdr, ctx);
|
||||
r = LUKS_write_phdr(phdr, ctx);
|
||||
}
|
||||
out:
|
||||
crypt_free_volume_key(vk);
|
||||
@@ -413,7 +423,7 @@ static int _check_and_convert_hdr(const char *device,
|
||||
}
|
||||
|
||||
hdr->hashSpec[LUKS_HASHSPEC_L - 1] = '\0';
|
||||
if (PBKDF2_HMAC_ready(hdr->hashSpec) < 0) {
|
||||
if (crypt_hmac_size(hdr->hashSpec) < LUKS_DIGESTSIZE) {
|
||||
log_err(ctx, _("Requested LUKS hash %s is not supported.\n"), hdr->hashSpec);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -441,7 +451,7 @@ static int _check_and_convert_hdr(const char *device,
|
||||
|
||||
if (repair) {
|
||||
if (r == -EINVAL)
|
||||
r = _keyslot_repair(device, hdr, ctx);
|
||||
r = _keyslot_repair(hdr, ctx);
|
||||
else
|
||||
log_verbose(ctx, _("No known problems detected for LUKS header.\n"));
|
||||
}
|
||||
@@ -464,7 +474,6 @@ static void LUKS_fix_header_compatible(struct luks_phdr *header)
|
||||
}
|
||||
|
||||
int LUKS_read_phdr_backup(const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
struct crypt_device *ctx)
|
||||
@@ -477,8 +486,8 @@ int LUKS_read_phdr_backup(const char *backup_file,
|
||||
|
||||
devfd = open(backup_file, O_RDONLY);
|
||||
if(-1 == devfd) {
|
||||
log_err(ctx, _("Cannot open file %s.\n"), device);
|
||||
return -EINVAL;
|
||||
log_err(ctx, _("Cannot open header backup file %s.\n"), backup_file);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (read(devfd, hdr, hdr_size) < hdr_size)
|
||||
@@ -493,60 +502,70 @@ int LUKS_read_phdr_backup(const char *backup_file,
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_read_phdr(const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int LUKS_read_phdr(struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
int repair,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
ssize_t hdr_size = sizeof(struct luks_phdr);
|
||||
int devfd = 0, r = 0;
|
||||
|
||||
/* LUKS header starts at offset 0, first keyslot on LUKS_ALIGN_KEYSLOTS */
|
||||
assert(sizeof(struct luks_phdr) <= LUKS_ALIGN_KEYSLOTS);
|
||||
|
||||
/* Stripes count cannot be changed without additional code fixes yet */
|
||||
assert(LUKS_STRIPES == 4000);
|
||||
|
||||
if (repair && !require_luks_device)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg("Reading LUKS header of size %d from device %s",
|
||||
hdr_size, device);
|
||||
log_dbg("Reading LUKS header of size %zu from device %s",
|
||||
hdr_size, device_path(device));
|
||||
|
||||
devfd = open(device,O_RDONLY | O_DIRECT | O_SYNC);
|
||||
if(-1 == devfd) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device);
|
||||
devfd = device_open(device, O_RDONLY);
|
||||
if (devfd == -1) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (read_blockwise(devfd, hdr, hdr_size) < hdr_size)
|
||||
if (read_blockwise(devfd, device_block_size(device), hdr, hdr_size) < hdr_size)
|
||||
r = -EIO;
|
||||
else
|
||||
r = _check_and_convert_hdr(device, hdr, require_luks_device,
|
||||
r = _check_and_convert_hdr(device_path(device), hdr, require_luks_device,
|
||||
repair, ctx);
|
||||
|
||||
if (!r)
|
||||
r = LUKS_check_device_size(ctx, device, hdr->keyBytes);
|
||||
r = LUKS_check_device_size(ctx, hdr->keyBytes);
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_write_phdr(const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int LUKS_write_phdr(struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
ssize_t hdr_size = sizeof(struct luks_phdr);
|
||||
int devfd = 0;
|
||||
unsigned int i;
|
||||
struct luks_phdr convHdr;
|
||||
int r;
|
||||
|
||||
log_dbg("Updating LUKS header of size %d on device %s",
|
||||
sizeof(struct luks_phdr), device);
|
||||
log_dbg("Updating LUKS header of size %zu on device %s",
|
||||
sizeof(struct luks_phdr), device_path(device));
|
||||
|
||||
r = LUKS_check_device_size(ctx, device, hdr->keyBytes);
|
||||
r = LUKS_check_device_size(ctx, hdr->keyBytes);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
devfd = open(device,O_RDWR | O_DIRECT | O_SYNC);
|
||||
devfd = device_open(device, O_RDWR);
|
||||
if(-1 == devfd) {
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device);
|
||||
if (errno == EACCES)
|
||||
log_err(ctx, _("Cannot write to device %s, permission denied.\n"),
|
||||
device_path(device));
|
||||
else
|
||||
log_err(ctx, _("Cannot open device %s.\n"), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -565,34 +584,42 @@ int LUKS_write_phdr(const char *device,
|
||||
convHdr.keyblock[i].stripes = htonl(hdr->keyblock[i].stripes);
|
||||
}
|
||||
|
||||
r = write_blockwise(devfd, &convHdr, hdr_size) < hdr_size ? -EIO : 0;
|
||||
r = write_blockwise(devfd, device_block_size(device), &convHdr, hdr_size) < hdr_size ? -EIO : 0;
|
||||
if (r)
|
||||
log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device);
|
||||
log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device_path(device));
|
||||
close(devfd);
|
||||
|
||||
/* Re-read header from disk to be sure that in-memory and on-disk data are the same. */
|
||||
if (!r) {
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
if (r)
|
||||
log_err(ctx, _("Error re-reading LUKS header after update on device %s.\n"), device);
|
||||
log_err(ctx, _("Error re-reading LUKS header after update on device %s.\n"),
|
||||
device_path(device));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int LUKS_PBKDF2_performance_check(const char *hashSpec,
|
||||
uint64_t *PBKDF2_per_sec,
|
||||
struct crypt_device *ctx)
|
||||
/* Check that kernel supports requested cipher by decryption of one sector */
|
||||
static int LUKS_check_cipher(struct luks_phdr *hdr, struct crypt_device *ctx)
|
||||
{
|
||||
if (!*PBKDF2_per_sec) {
|
||||
if (PBKDF2_performance_check(hashSpec, PBKDF2_per_sec) < 0) {
|
||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"), hashSpec);
|
||||
return -EINVAL;
|
||||
}
|
||||
log_dbg("PBKDF2: %" PRIu64 " iterations per second using hash %s.", *PBKDF2_per_sec, hashSpec);
|
||||
}
|
||||
int r;
|
||||
struct volume_key *empty_key;
|
||||
char buf[SECTOR_SIZE];
|
||||
|
||||
return 0;
|
||||
log_dbg("Checking if cipher %s-%s is usable.", hdr->cipherName, hdr->cipherMode);
|
||||
|
||||
empty_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
if (!empty_key)
|
||||
return -ENOMEM;
|
||||
|
||||
r = LUKS_decrypt_from_storage(buf, sizeof(buf),
|
||||
hdr->cipherName, hdr->cipherMode,
|
||||
empty_key, 0, ctx);
|
||||
|
||||
crypt_free_volume_key(empty_key);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
@@ -603,21 +630,27 @@ 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,
|
||||
int detached_metadata_device,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
unsigned int i=0;
|
||||
unsigned int blocksPerStripeSet = div_round_up(vk->keylength*stripes,SECTOR_SIZE);
|
||||
unsigned int i = 0, hdr_sectors = LUKS_device_sectors(vk->keylength);
|
||||
size_t blocksPerStripeSet, currentSector;
|
||||
int r;
|
||||
uuid_t partitionUuid;
|
||||
int currentSector;
|
||||
char luksMagic[] = LUKS_MAGIC;
|
||||
|
||||
/* For separate metadata device allow zero alignment */
|
||||
if (alignPayload == 0 && !metadata_device)
|
||||
if (alignPayload == 0 && !detached_metadata_device)
|
||||
alignPayload = DEFAULT_DISK_ALIGNMENT / SECTOR_SIZE;
|
||||
|
||||
if (PBKDF2_HMAC_ready(hashSpec) < 0) {
|
||||
if (alignPayload && detached_metadata_device && alignPayload < hdr_sectors) {
|
||||
log_err(ctx, _("Data offset for detached LUKS header must be "
|
||||
"either 0 or higher than header size (%d sectors).\n"),
|
||||
hdr_sectors);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (crypt_hmac_size(hashSpec) < LUKS_DIGESTSIZE) {
|
||||
log_err(ctx, _("Requested LUKS hash %s is not supported.\n"), hashSpec);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -642,6 +675,10 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
|
||||
LUKS_fix_header_compatible(header);
|
||||
|
||||
r = LUKS_check_cipher(header, ctx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
log_dbg("Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes",
|
||||
header->version, header->hashSpec ,header->cipherName, header->cipherMode,
|
||||
header->keyBytes);
|
||||
@@ -652,39 +689,45 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
return r;
|
||||
}
|
||||
|
||||
if ((r = LUKS_PBKDF2_performance_check(header->hashSpec, PBKDF2_per_sec, ctx)))
|
||||
r = crypt_benchmark_kdf(ctx, "pbkdf2", header->hashSpec,
|
||||
"foo", 3, "bar", 3, PBKDF2_per_sec);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
||||
header->hashSpec);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Compute master key digest */
|
||||
iteration_time_ms /= 8;
|
||||
header->mkDigestIterations = at_least((uint32_t)(*PBKDF2_per_sec/1024) * iteration_time_ms,
|
||||
LUKS_MKD_ITERATIONS_MIN);
|
||||
|
||||
r = PBKDF2_HMAC(header->hashSpec,vk->key,vk->keylength,
|
||||
r = crypt_pbkdf("pbkdf2", header->hashSpec, vk->key,vk->keylength,
|
||||
header->mkDigestSalt, LUKS_SALTSIZE,
|
||||
header->mkDigestIterations,
|
||||
header->mkDigest,LUKS_DIGESTSIZE);
|
||||
header->mkDigest,LUKS_DIGESTSIZE,
|
||||
header->mkDigestIterations);
|
||||
if(r < 0) {
|
||||
log_err(ctx, _("Cannot create LUKS header: header digest failed (using hash %s).\n"),
|
||||
header->hashSpec);
|
||||
return r;
|
||||
}
|
||||
|
||||
currentSector = round_up_modulo(LUKS_PHDR_SIZE, LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
currentSector = LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE;
|
||||
blocksPerStripeSet = AF_split_sectors(vk->keylength, stripes);
|
||||
for(i = 0; i < LUKS_NUMKEYS; ++i) {
|
||||
header->keyblock[i].active = LUKS_KEY_DISABLED;
|
||||
header->keyblock[i].keyMaterialOffset = currentSector;
|
||||
header->keyblock[i].stripes = stripes;
|
||||
currentSector = round_up_modulo(currentSector + blocksPerStripeSet,
|
||||
currentSector = size_round_up(currentSector + blocksPerStripeSet,
|
||||
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
|
||||
}
|
||||
|
||||
if (metadata_device) {
|
||||
if (detached_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);
|
||||
currentSector = size_round_up(currentSector, alignPayload);
|
||||
header->payloadOffset = currentSector + alignOffset;
|
||||
}
|
||||
|
||||
@@ -697,7 +740,6 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
}
|
||||
|
||||
int LUKS_hdr_uuid_set(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
const char *uuid,
|
||||
struct crypt_device *ctx)
|
||||
@@ -713,10 +755,10 @@ int LUKS_hdr_uuid_set(
|
||||
|
||||
uuid_unparse(partitionUuid, hdr->uuid);
|
||||
|
||||
return LUKS_write_phdr(device, hdr, ctx);
|
||||
return LUKS_write_phdr(hdr, ctx);
|
||||
}
|
||||
|
||||
int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
int LUKS_set_key(unsigned int keyIndex,
|
||||
const char *password, size_t passwordLen,
|
||||
struct luks_phdr *hdr, struct volume_key *vk,
|
||||
uint32_t iteration_time_ms,
|
||||
@@ -725,7 +767,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
{
|
||||
struct volume_key *derived_key;
|
||||
char *AfKey = NULL;
|
||||
unsigned int AFEKSize;
|
||||
size_t AFEKSize;
|
||||
uint64_t PBKDF2_temp;
|
||||
int r;
|
||||
|
||||
@@ -734,7 +776,8 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(hdr->keyblock[keyIndex].stripes < LUKS_STRIPES) {
|
||||
/* LUKS keyslot has always at least 4000 stripes accoding to specification */
|
||||
if(hdr->keyblock[keyIndex].stripes < 4000) {
|
||||
log_err(ctx, _("Key slot %d material includes too few stripes. Header manipulation?\n"),
|
||||
keyIndex);
|
||||
return -EINVAL;
|
||||
@@ -742,8 +785,13 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
|
||||
log_dbg("Calculating data for key slot %d", keyIndex);
|
||||
|
||||
if ((r = LUKS_PBKDF2_performance_check(hdr->hashSpec, PBKDF2_per_sec, ctx)))
|
||||
r = crypt_benchmark_kdf(ctx, "pbkdf2", hdr->hashSpec,
|
||||
"foo", 3, "bar", 3, PBKDF2_per_sec);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
||||
hdr->hashSpec);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid floating point operation
|
||||
@@ -765,12 +813,12 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt,
|
||||
LUKS_SALTSIZE, CRYPT_RND_SALT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto out;
|
||||
|
||||
r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen,
|
||||
r = crypt_pbkdf("pbkdf2", hdr->hashSpec, password, passwordLen,
|
||||
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
|
||||
hdr->keyblock[keyIndex].passwordIterations,
|
||||
derived_key->key, hdr->keyBytes);
|
||||
derived_key->key, hdr->keyBytes,
|
||||
hdr->keyblock[keyIndex].passwordIterations);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -778,7 +826,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
* AF splitting, the masterkey stored in vk->key is split to AfKey
|
||||
*/
|
||||
assert(vk->keylength == hdr->keyBytes);
|
||||
AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength;
|
||||
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
AfKey = crypt_safe_alloc(AFEKSize);
|
||||
if (!AfKey) {
|
||||
r = -ENOMEM;
|
||||
@@ -791,27 +839,24 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
log_dbg("Updating key slot %d [0x%04x] area on device %s.", keyIndex,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset << 9, device);
|
||||
log_dbg("Updating key slot %d [0x%04x] area.", keyIndex,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset << 9);
|
||||
/* Encryption via dm */
|
||||
r = LUKS_encrypt_to_storage(AfKey,
|
||||
AFEKSize,
|
||||
hdr,
|
||||
hdr->cipherName, hdr->cipherMode,
|
||||
derived_key,
|
||||
device,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
ctx);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Failed to write to key storage.\n"));
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Mark the key as active in phdr */
|
||||
r = LUKS_keyslot_set(hdr, (int)keyIndex, 1);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_write_phdr(device, hdr, ctx);
|
||||
r = LUKS_write_phdr(hdr, ctx);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -828,10 +873,10 @@ int LUKS_verify_volume_key(const struct luks_phdr *hdr,
|
||||
{
|
||||
char checkHashBuf[LUKS_DIGESTSIZE];
|
||||
|
||||
if (PBKDF2_HMAC(hdr->hashSpec, vk->key, vk->keylength,
|
||||
if (crypt_pbkdf("pbkdf2", hdr->hashSpec, vk->key, vk->keylength,
|
||||
hdr->mkDigestSalt, LUKS_SALTSIZE,
|
||||
hdr->mkDigestIterations, checkHashBuf,
|
||||
LUKS_DIGESTSIZE) < 0)
|
||||
checkHashBuf, LUKS_DIGESTSIZE,
|
||||
hdr->mkDigestIterations) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (memcmp(checkHashBuf, hdr->mkDigest, LUKS_DIGESTSIZE))
|
||||
@@ -841,8 +886,7 @@ int LUKS_verify_volume_key(const struct luks_phdr *hdr,
|
||||
}
|
||||
|
||||
/* Try to open a particular key slot */
|
||||
static int LUKS_open_key(const char *device,
|
||||
unsigned int keyIndex,
|
||||
static int LUKS_open_key(unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
@@ -866,30 +910,29 @@ static int LUKS_open_key(const char *device,
|
||||
return -ENOMEM;
|
||||
|
||||
assert(vk->keylength == hdr->keyBytes);
|
||||
AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength;
|
||||
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
AfKey = crypt_safe_alloc(AFEKSize);
|
||||
if (!AfKey)
|
||||
return -ENOMEM;
|
||||
if (!AfKey) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen,
|
||||
r = crypt_pbkdf("pbkdf2", hdr->hashSpec, password, passwordLen,
|
||||
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
|
||||
hdr->keyblock[keyIndex].passwordIterations,
|
||||
derived_key->key, hdr->keyBytes);
|
||||
derived_key->key, hdr->keyBytes,
|
||||
hdr->keyblock[keyIndex].passwordIterations);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
log_dbg("Reading key slot %d area.", keyIndex);
|
||||
r = LUKS_decrypt_from_storage(AfKey,
|
||||
AFEKSize,
|
||||
hdr,
|
||||
hdr->cipherName, hdr->cipherMode,
|
||||
derived_key,
|
||||
device,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
ctx);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Failed to read from key storage.\n"));
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = AF_merge(AfKey,vk->key,vk->keylength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec);
|
||||
if (r < 0)
|
||||
@@ -904,8 +947,7 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_open_key_with_hdr(const char *device,
|
||||
int keyIndex,
|
||||
int LUKS_open_key_with_hdr(int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
@@ -918,12 +960,12 @@ int LUKS_open_key_with_hdr(const char *device,
|
||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
|
||||
if (keyIndex >= 0) {
|
||||
r = LUKS_open_key(device, keyIndex, password, passwordLen, hdr, *vk, ctx);
|
||||
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, *vk, ctx);
|
||||
return (r < 0) ? r : keyIndex;
|
||||
}
|
||||
|
||||
for(i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
r = LUKS_open_key(device, i, password, passwordLen, hdr, *vk, ctx);
|
||||
r = LUKS_open_key(i, password, passwordLen, hdr, *vk, ctx);
|
||||
if(r == 0)
|
||||
return i;
|
||||
|
||||
@@ -937,15 +979,15 @@ int LUKS_open_key_with_hdr(const char *device,
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int LUKS_del_key(const char *device,
|
||||
unsigned int keyIndex,
|
||||
int LUKS_del_key(unsigned int keyIndex,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
unsigned int startOffset, endOffset, stripesLen;
|
||||
struct device *device = crypt_metadata_device(ctx);
|
||||
unsigned int startOffset, endOffset;
|
||||
int r;
|
||||
|
||||
r = LUKS_read_phdr(device, hdr, 1, 0, ctx);
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -958,14 +1000,19 @@ int LUKS_del_key(const char *device,
|
||||
|
||||
/* secure deletion of key material */
|
||||
startOffset = hdr->keyblock[keyIndex].keyMaterialOffset;
|
||||
stripesLen = hdr->keyBytes * hdr->keyblock[keyIndex].stripes;
|
||||
endOffset = startOffset + div_round_up(stripesLen, SECTOR_SIZE);
|
||||
endOffset = startOffset + AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes);
|
||||
|
||||
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);
|
||||
if (r == -EACCES) {
|
||||
log_err(ctx, _("Cannot write to device %s, permission denied.\n"),
|
||||
device_path(device));
|
||||
r = -EINVAL;
|
||||
} else
|
||||
log_err(ctx, _("Cannot wipe device %s.\n"),
|
||||
device_path(device));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -973,7 +1020,7 @@ int LUKS_del_key(const char *device,
|
||||
memset(&hdr->keyblock[keyIndex].passwordSalt, 0, LUKS_SALTSIZE);
|
||||
hdr->keyblock[keyIndex].passwordIterations = 0;
|
||||
|
||||
r = LUKS_write_phdr(device, hdr, ctx);
|
||||
r = LUKS_write_phdr(hdr, ctx);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1048,7 +1095,7 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
.flags = flags,
|
||||
.size = 0,
|
||||
.data_device = crypt_get_device_name(cd),
|
||||
.data_device = crypt_data_device(cd),
|
||||
.u.crypt = {
|
||||
.cipher = NULL,
|
||||
.vk = vk,
|
||||
@@ -1062,9 +1109,8 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
else
|
||||
device_check = DEV_EXCL;
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, device_check,
|
||||
&dmd.size, &dmd.u.crypt.offset,
|
||||
&dmd.flags);
|
||||
r = device_block_adjust(cd, dmd.data_device, device_check,
|
||||
dmd.u.crypt.offset, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -1073,7 +1119,7 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
return -ENOMEM;
|
||||
|
||||
dmd.u.crypt.cipher = dm_cipher;
|
||||
r = dm_create_device(name, CRYPT_LUKS1, &dmd, 0);
|
||||
r = dm_create_device(cd, name, CRYPT_LUKS1, &dmd, 0);
|
||||
|
||||
free(dm_cipher);
|
||||
return r;
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -51,8 +52,6 @@
|
||||
#define LUKS_MAGIC {'L','U','K','S', 0xba, 0xbe};
|
||||
#define LUKS_MAGIC_L 6
|
||||
|
||||
#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1)
|
||||
|
||||
/* Actually we need only 37, but we don't want struct autoaligning to kick in */
|
||||
#define UUID_STRING_L 40
|
||||
|
||||
@@ -63,6 +62,7 @@
|
||||
converted */
|
||||
|
||||
struct volume_key;
|
||||
struct device_backend;
|
||||
|
||||
struct luks_phdr {
|
||||
char magic[LUKS_MAGIC_L];
|
||||
@@ -108,11 +108,10 @@ int LUKS_generate_phdr(
|
||||
unsigned int alignOffset,
|
||||
uint32_t iteration_time_ms,
|
||||
uint64_t *PBKDF2_per_sec,
|
||||
const char *metadata_device,
|
||||
int detached_metadata_device,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_read_phdr(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
int repair,
|
||||
@@ -120,36 +119,29 @@ int LUKS_read_phdr(
|
||||
|
||||
int LUKS_read_phdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_uuid_set(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
const char *uuid,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_restore(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_write_phdr(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_set_key(
|
||||
const char *device,
|
||||
unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
@@ -160,7 +152,6 @@ int LUKS_set_key(
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_open_key_with_hdr(
|
||||
const char *device,
|
||||
int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
@@ -169,7 +160,6 @@ int LUKS_open_key_with_hdr(
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_del_key(
|
||||
const char *device,
|
||||
unsigned int keyIndex,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
@@ -178,20 +168,24 @@ crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot);
|
||||
int LUKS_keyslot_find_empty(struct luks_phdr *hdr);
|
||||
int LUKS_keyslot_active_count(struct luks_phdr *hdr);
|
||||
int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable);
|
||||
int LUKS_keyslot_area(struct luks_phdr *hdr,
|
||||
int keyslot,
|
||||
uint64_t *offset,
|
||||
uint64_t *length);
|
||||
|
||||
int LUKS_encrypt_to_storage(
|
||||
char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_decrypt_from_storage(
|
||||
char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
* Implementation of Password-Based Cryptography as per PKCS#5
|
||||
* Copyright (C) 2002,2003 Simon Josefsson
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* LUKS code
|
||||
* Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <alloca.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "crypto_backend.h"
|
||||
#include "pbkdf.h"
|
||||
|
||||
static volatile uint64_t __PBKDF2_global_j = 0;
|
||||
static volatile uint64_t __PBKDF2_performance = 0;
|
||||
|
||||
/*
|
||||
* 5.2 PBKDF2
|
||||
*
|
||||
* PBKDF2 applies a pseudorandom function (see Appendix B.1 for an
|
||||
* example) to derive keys. The length of the derived key is essentially
|
||||
* unbounded. (However, the maximum effective search space for the
|
||||
* derived key may be limited by the structure of the underlying
|
||||
* pseudorandom function. See Appendix B.1 for further discussion.)
|
||||
* PBKDF2 is recommended for new applications.
|
||||
*
|
||||
* PBKDF2 (P, S, c, dkLen)
|
||||
*
|
||||
* Options: PRF underlying pseudorandom function (hLen
|
||||
* denotes the length in octets of the
|
||||
* pseudorandom function output)
|
||||
*
|
||||
* Input: P password, an octet string (ASCII or UTF-8)
|
||||
* S salt, an octet string
|
||||
* c iteration count, a positive integer
|
||||
* dkLen intended length in octets of the derived
|
||||
* key, a positive integer, at most
|
||||
* (2^32 - 1) * hLen
|
||||
*
|
||||
* Output: DK derived key, a dkLen-octet string
|
||||
*/
|
||||
|
||||
#define MAX_PRF_BLOCK_LEN 80
|
||||
|
||||
static int pkcs5_pbkdf2(const char *hash,
|
||||
const char *P, size_t Plen,
|
||||
const char *S, size_t Slen,
|
||||
unsigned int c, unsigned int dkLen,
|
||||
char *DK, int perfcheck)
|
||||
{
|
||||
struct crypt_hmac *hmac;
|
||||
char U[MAX_PRF_BLOCK_LEN];
|
||||
char T[MAX_PRF_BLOCK_LEN];
|
||||
int i, k, rc = -EINVAL;
|
||||
unsigned int u, hLen, l, r;
|
||||
size_t tmplen = Slen + 4;
|
||||
char *tmp;
|
||||
|
||||
tmp = alloca(tmplen);
|
||||
if (tmp == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
hLen = crypt_hmac_size(hash);
|
||||
if (hLen == 0 || hLen > MAX_PRF_BLOCK_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (c == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (dkLen == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
*
|
||||
* Steps:
|
||||
*
|
||||
* 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
|
||||
* stop.
|
||||
*/
|
||||
|
||||
if (dkLen > 4294967295U)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* 2. Let l be the number of hLen-octet blocks in the derived key,
|
||||
* rounding up, and let r be the number of octets in the last
|
||||
* block:
|
||||
*
|
||||
* l = CEIL (dkLen / hLen) ,
|
||||
* r = dkLen - (l - 1) * hLen .
|
||||
*
|
||||
* Here, CEIL (x) is the "ceiling" function, i.e. the smallest
|
||||
* integer greater than, or equal to, x.
|
||||
*/
|
||||
|
||||
l = dkLen / hLen;
|
||||
if (dkLen % hLen)
|
||||
l++;
|
||||
r = dkLen - (l - 1) * hLen;
|
||||
|
||||
/*
|
||||
* 3. For each block of the derived key apply the function F defined
|
||||
* below to the password P, the salt S, the iteration count c, and
|
||||
* the block index to compute the block:
|
||||
*
|
||||
* T_1 = F (P, S, c, 1) ,
|
||||
* T_2 = F (P, S, c, 2) ,
|
||||
* ...
|
||||
* T_l = F (P, S, c, l) ,
|
||||
*
|
||||
* where the function F is defined as the exclusive-or sum of the
|
||||
* first c iterates of the underlying pseudorandom function PRF
|
||||
* applied to the password P and the concatenation of the salt S
|
||||
* and the block index i:
|
||||
*
|
||||
* F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
|
||||
*
|
||||
* where
|
||||
*
|
||||
* U_1 = PRF (P, S || INT (i)) ,
|
||||
* U_2 = PRF (P, U_1) ,
|
||||
* ...
|
||||
* U_c = PRF (P, U_{c-1}) .
|
||||
*
|
||||
* Here, INT (i) is a four-octet encoding of the integer i, most
|
||||
* significant octet first.
|
||||
*
|
||||
* 4. Concatenate the blocks and extract the first dkLen octets to
|
||||
* produce a derived key DK:
|
||||
*
|
||||
* DK = T_1 || T_2 || ... || T_l<0..r-1>
|
||||
*
|
||||
* 5. Output the derived key DK.
|
||||
*
|
||||
* Note. The construction of the function F follows a "belt-and-
|
||||
* suspenders" approach. The iterates U_i are computed recursively to
|
||||
* remove a degree of parallelism from an opponent; they are exclusive-
|
||||
* ored together to reduce concerns about the recursion degenerating
|
||||
* into a small set of values.
|
||||
*
|
||||
*/
|
||||
|
||||
if (crypt_hmac_init(&hmac, hash, P, Plen))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 1; (uint) i <= l; i++) {
|
||||
memset(T, 0, hLen);
|
||||
|
||||
for (u = 1; u <= c ; u++) {
|
||||
if (u == 1) {
|
||||
memcpy(tmp, S, Slen);
|
||||
tmp[Slen + 0] = (i & 0xff000000) >> 24;
|
||||
tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
|
||||
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
|
||||
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
|
||||
|
||||
if (crypt_hmac_write(hmac, tmp, tmplen))
|
||||
goto out;
|
||||
} else {
|
||||
if (crypt_hmac_write(hmac, U, hLen))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (crypt_hmac_final(hmac, U, hLen))
|
||||
goto out;
|
||||
|
||||
for (k = 0; (uint) k < hLen; k++)
|
||||
T[k] ^= U[k];
|
||||
|
||||
if (perfcheck && __PBKDF2_performance) {
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (perfcheck)
|
||||
__PBKDF2_global_j++;
|
||||
}
|
||||
|
||||
memcpy(DK + (i - 1) * hLen, T, (uint) i == l ? r : hLen);
|
||||
}
|
||||
rc = 0;
|
||||
out:
|
||||
crypt_hmac_destroy(hmac);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int PBKDF2_HMAC(const char *hash,
|
||||
const char *password, size_t passwordLen,
|
||||
const char *salt, size_t saltLen, unsigned int iterations,
|
||||
char *dKey, size_t dKeyLen)
|
||||
{
|
||||
return pkcs5_pbkdf2(hash, password, passwordLen, salt, saltLen,
|
||||
iterations, (unsigned int)dKeyLen, dKey, 0);
|
||||
}
|
||||
|
||||
int PBKDF2_HMAC_ready(const char *hash)
|
||||
{
|
||||
if (crypt_hmac_size(hash) < 20)
|
||||
return -EINVAL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sigvtalarm(int foo __attribute__((unused)))
|
||||
{
|
||||
__PBKDF2_performance = __PBKDF2_global_j;
|
||||
}
|
||||
|
||||
/* This code benchmarks PBKDF2 and returns iterations/second using wth specified hash */
|
||||
int PBKDF2_performance_check(const char *hash, uint64_t *iter)
|
||||
{
|
||||
int timer_type, r;
|
||||
char buf;
|
||||
struct itimerval it;
|
||||
|
||||
if (__PBKDF2_global_j)
|
||||
return -EBUSY;
|
||||
|
||||
if (PBKDF2_HMAC_ready(hash) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* If crypto backend is not implemented in userspace,
|
||||
* but uses some kernel part, we must measure also time
|
||||
* spent in kernel. */
|
||||
if (crypt_backend_flags() & CRYPT_BACKEND_KERNEL) {
|
||||
timer_type = ITIMER_PROF;
|
||||
signal(SIGPROF,sigvtalarm);
|
||||
} else {
|
||||
timer_type = ITIMER_VIRTUAL;
|
||||
signal(SIGVTALRM,sigvtalarm);
|
||||
}
|
||||
|
||||
it.it_interval.tv_usec = 0;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_value.tv_usec = 0;
|
||||
it.it_value.tv_sec = 1;
|
||||
if (setitimer(timer_type, &it, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = pkcs5_pbkdf2(hash, "foo", 3, "bar", 3, ~(0U), 1, &buf, 1);
|
||||
|
||||
*iter = __PBKDF2_performance;
|
||||
__PBKDF2_global_j = 0;
|
||||
__PBKDF2_performance = 0;
|
||||
return r;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Implementation of Password-Based Cryptography as per PKCS#5
|
||||
* Copyright (C) 2002,2003 Simon Josefsson
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* LUKS code
|
||||
* Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_PBKDF_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_PBKDF_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int PBKDF2_HMAC(const char *hash,
|
||||
const char *password, size_t passwordLen,
|
||||
const char *salt, size_t saltLen, unsigned int iterations,
|
||||
char *dKey, size_t dKeyLen);
|
||||
|
||||
|
||||
int PBKDF2_performance_check(const char *hash, uint64_t *iter);
|
||||
int PBKDF2_HMAC_ready(const char *hash);
|
||||
|
||||
#endif
|
||||
@@ -5,7 +5,8 @@
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -22,6 +23,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
1128
lib/setup.c
1128
lib/setup.c
File diff suppressed because it is too large
Load Diff
14
lib/tcrypt/Makefile.am
Normal file
14
lib/tcrypt/Makefile.am
Normal file
@@ -0,0 +1,14 @@
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libtcrypt.la
|
||||
|
||||
libtcrypt_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
|
||||
|
||||
libtcrypt_la_SOURCES = \
|
||||
tcrypt.c \
|
||||
tcrypt.h
|
||||
|
||||
AM_CPPFLAGS = -include config.h \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/lib/crypto_backend
|
||||
|
||||
1043
lib/tcrypt/tcrypt.c
Normal file
1043
lib/tcrypt/tcrypt.c
Normal file
File diff suppressed because it is too large
Load Diff
114
lib/tcrypt/tcrypt.h
Normal file
114
lib/tcrypt/tcrypt.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) header defitinion
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
#ifndef _CRYPTSETUP_TCRYPT_H
|
||||
#define _CRYPTSETUP_TCRYPT_H
|
||||
|
||||
#define TCRYPT_HDR_SALT_LEN 64
|
||||
#define TCRYPT_HDR_IV_LEN 16
|
||||
#define TCRYPT_HDR_LEN 448
|
||||
#define TCRYPT_HDR_KEY_LEN 192
|
||||
#define TCRYPT_HDR_MAGIC "TRUE"
|
||||
#define TCRYPT_HDR_MAGIC_LEN 4
|
||||
|
||||
#define TCRYPT_HDR_HIDDEN_OFFSET_OLD -1536
|
||||
#define TCRYPT_HDR_HIDDEN_OFFSET 65536
|
||||
|
||||
#define TCRYPT_HDR_HIDDEN_OFFSET_BCK -65536
|
||||
#define TCRYPT_HDR_OFFSET_BCK -131072
|
||||
|
||||
#define TCRYPT_HDR_SYSTEM_OFFSET 31744
|
||||
|
||||
#define TCRYPT_LRW_IKEY_LEN 16
|
||||
#define TCRYPT_KEY_POOL_LEN 64
|
||||
#define TCRYPT_KEYFILE_LEN 1048576
|
||||
|
||||
#define TCRYPT_HDR_FLAG_SYSTEM (1 << 0)
|
||||
#define TCRYPT_HDR_FLAG_NONSYSTEM (1 << 1)
|
||||
|
||||
struct tcrypt_phdr {
|
||||
char salt[TCRYPT_HDR_SALT_LEN];
|
||||
|
||||
/* encrypted part, TCRYPT_HDR_LEN bytes */
|
||||
union {
|
||||
struct __attribute__((__packed__)) {
|
||||
char magic[TCRYPT_HDR_MAGIC_LEN];
|
||||
uint16_t version;
|
||||
uint16_t version_tc;
|
||||
uint32_t keys_crc32;
|
||||
uint64_t _reserved1[2]; /* data/header ctime */
|
||||
uint64_t hidden_volume_size;
|
||||
uint64_t volume_size;
|
||||
uint64_t mk_offset;
|
||||
uint64_t mk_size;
|
||||
uint32_t flags;
|
||||
uint32_t sector_size;
|
||||
uint8_t _reserved2[120];
|
||||
uint32_t header_crc32;
|
||||
char keys[256];
|
||||
} d;
|
||||
char e[TCRYPT_HDR_LEN];
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct crypt_dm_active_device;
|
||||
struct volume_key;
|
||||
struct device;
|
||||
|
||||
int TCRYPT_read_phdr(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params);
|
||||
|
||||
int TCRYPT_init_by_name(struct crypt_device *cd, const char *name,
|
||||
const struct crypt_dm_active_device *dmd,
|
||||
struct device **device,
|
||||
struct crypt_params_tcrypt *tcrypt_params,
|
||||
struct tcrypt_phdr *tcrypt_hdr);
|
||||
|
||||
int TCRYPT_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params,
|
||||
uint32_t flags);
|
||||
|
||||
int TCRYPT_deactivate(struct crypt_device *cd,
|
||||
const char *name);
|
||||
|
||||
uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params);
|
||||
|
||||
uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params);
|
||||
|
||||
int TCRYPT_get_volume_key(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params,
|
||||
struct volume_key **vk);
|
||||
|
||||
int TCRYPT_dump(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params);
|
||||
|
||||
#endif
|
||||
319
lib/utils.c
319
lib/utils.c
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* utils - miscellaneous device utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -22,25 +24,16 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
unsigned crypt_getpagesize(void)
|
||||
{
|
||||
return (unsigned)sysconf(_SC_PAGESIZE);
|
||||
long r = sysconf(_SC_PAGESIZE);
|
||||
return r < 0 ? DEFAULT_MEM_ALIGNMENT : r;
|
||||
}
|
||||
|
||||
static int get_alignment(int fd)
|
||||
@@ -74,52 +67,15 @@ static void *aligned_malloc(void **base, int size, int alignment)
|
||||
#endif
|
||||
}
|
||||
|
||||
int device_read_ahead(const char *dev, uint32_t *read_ahead)
|
||||
{
|
||||
int fd, r = 0;
|
||||
long read_ahead_long;
|
||||
|
||||
if ((fd = open(dev, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
r = ioctl(fd, BLKRAGET, &read_ahead_long) ? 0 : 1;
|
||||
close(fd);
|
||||
|
||||
if (r)
|
||||
*read_ahead = (uint32_t) read_ahead_long;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int sector_size(int fd)
|
||||
{
|
||||
int bsize;
|
||||
if (ioctl(fd,BLKSSZGET, &bsize) < 0)
|
||||
return -EINVAL;
|
||||
else
|
||||
return bsize;
|
||||
}
|
||||
|
||||
int sector_size_for_device(const char *device)
|
||||
{
|
||||
int fd = open(device, O_RDONLY);
|
||||
int r;
|
||||
if(fd < 0)
|
||||
return -EINVAL;
|
||||
r = sector_size(fd);
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t write_blockwise(int fd, void *orig_buf, size_t count)
|
||||
ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count)
|
||||
{
|
||||
void *hangover_buf, *hangover_buf_base = NULL;
|
||||
void *buf, *buf_base = NULL;
|
||||
int r, hangover, solid, bsize, alignment;
|
||||
int r, hangover, solid, alignment;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
if (fd == -1 || !orig_buf || bsize <= 0)
|
||||
return -1;
|
||||
|
||||
hangover = count % bsize;
|
||||
solid = count - hangover;
|
||||
@@ -143,16 +99,19 @@ ssize_t write_blockwise(int fd, void *orig_buf, size_t count)
|
||||
goto out;
|
||||
|
||||
r = read(fd, hangover_buf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
if (r < 0 || r < hangover)
|
||||
goto out;
|
||||
|
||||
if (r < bsize)
|
||||
bsize = r;
|
||||
|
||||
r = lseek(fd, -bsize, SEEK_CUR);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
memcpy(hangover_buf, (char*)buf + solid, hangover);
|
||||
|
||||
r = write(fd, hangover_buf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
if (r < 0 || r < hangover)
|
||||
goto out;
|
||||
}
|
||||
ret = count;
|
||||
@@ -163,14 +122,14 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
|
||||
ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count) {
|
||||
void *hangover_buf, *hangover_buf_base = NULL;
|
||||
void *buf, *buf_base = NULL;
|
||||
int r, hangover, solid, bsize, alignment;
|
||||
int r, hangover, solid, alignment;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
if (fd == -1 || !orig_buf || bsize <= 0)
|
||||
return -1;
|
||||
|
||||
hangover = count % bsize;
|
||||
solid = count - hangover;
|
||||
@@ -192,7 +151,7 @@ ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
|
||||
if (!hangover_buf)
|
||||
goto out;
|
||||
r = read(fd, hangover_buf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
if (r < 0 || r < hangover)
|
||||
goto out;
|
||||
|
||||
memcpy((char *)buf + solid, hangover_buf, hangover);
|
||||
@@ -213,15 +172,15 @@ out:
|
||||
* is implicitly included in the read/write offset, which can not be set to non-aligned
|
||||
* boundaries. Hence, we combine llseek with write.
|
||||
*/
|
||||
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset) {
|
||||
ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset) {
|
||||
char *frontPadBuf;
|
||||
void *frontPadBuf_base = NULL;
|
||||
int r, bsize, frontHang;
|
||||
int r, frontHang;
|
||||
size_t innerCount = 0;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
if (fd == -1 || !buf || bsize <= 0)
|
||||
return -1;
|
||||
|
||||
frontHang = offset % bsize;
|
||||
|
||||
@@ -255,7 +214,7 @@ ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset) {
|
||||
count -= innerCount;
|
||||
}
|
||||
|
||||
ret = count ? write_blockwise(fd, buf, count) : 0;
|
||||
ret = count ? write_blockwise(fd, bsize, buf, count) : 0;
|
||||
if (ret >= 0)
|
||||
ret += innerCount;
|
||||
out:
|
||||
@@ -264,171 +223,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int device_ready(struct crypt_device *cd, const char *device, int mode)
|
||||
{
|
||||
int devfd, r = 0;
|
||||
ssize_t s;
|
||||
struct stat st;
|
||||
char buf[512];
|
||||
|
||||
if(stat(device, &st) < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
|
||||
log_dbg("Trying to open and read device %s.", device);
|
||||
devfd = open(device, mode | O_DIRECT | O_SYNC);
|
||||
if(devfd < 0) {
|
||||
log_err(cd, _("Cannot open device %s for %s%s access.\n"), device,
|
||||
(mode & O_EXCL) ? _("exclusive ") : "",
|
||||
(mode & O_RDWR) ? _("writable") : _("read-only"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Try to read first sector */
|
||||
s = read_blockwise(devfd, buf, sizeof(buf));
|
||||
if (s < 0 || s != sizeof(buf)) {
|
||||
log_verbose(cd, _("Cannot read device %s.\n"), device);
|
||||
r = -EIO;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
close(devfd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
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;
|
||||
int fd, r = -1;
|
||||
int flags = 0;
|
||||
|
||||
*readonly = 0;
|
||||
*size = 0;
|
||||
|
||||
if (stat(device, &st) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* never wipe header on mounted device */
|
||||
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 */
|
||||
fd = open(device, O_RDWR | flags);
|
||||
if (fd == -1 && errno == EROFS) {
|
||||
*readonly = 1;
|
||||
fd = open(device, O_RDONLY | flags);
|
||||
}
|
||||
|
||||
if (fd == -1 && device_check == DEV_EXCL && errno == EBUSY)
|
||||
return -EBUSY;
|
||||
|
||||
if (fd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the device can be opened read-write, i.e. readonly is still 0, then
|
||||
* check whether BKROGET says that it is read-only. E.g. read-only loop
|
||||
* devices may be openend read-write but are read-only according to BLKROGET
|
||||
*/
|
||||
if (*readonly == 0 && (r = ioctl(fd, BLKROGET, readonly)) < 0)
|
||||
goto out;
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, size) >= 0) {
|
||||
*size >>= SECTOR_SHIFT;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE, &size_small) >= 0) {
|
||||
*size = (uint64_t)size_small;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = -EINVAL;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int device_check_and_adjust(struct crypt_device *cd,
|
||||
const char *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t *size,
|
||||
uint64_t *offset,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int r, real_readonly;
|
||||
uint64_t real_size;
|
||||
|
||||
if (!device)
|
||||
return -ENOTBLK;
|
||||
|
||||
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 "
|
||||
"(already mapped or mounted).\n"),
|
||||
device);
|
||||
else
|
||||
log_err(cd, _("Cannot get info about device %s.\n"),
|
||||
device);
|
||||
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;
|
||||
}
|
||||
*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 (real_readonly)
|
||||
*flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
log_dbg("Calculated device size is %" PRIu64 " sectors (%s), offset %" PRIu64 ".",
|
||||
*size, real_readonly ? "RO" : "RW", *offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MEMLOCK */
|
||||
#define DEFAULT_PROCESS_PRIORITY -18
|
||||
|
||||
@@ -441,7 +235,7 @@ int crypt_memlock_inc(struct crypt_device *ctx)
|
||||
if (!_memlock_count++) {
|
||||
log_dbg("Locking memory.");
|
||||
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
|
||||
log_err(ctx, _("WARNING!!! Possibly insecure memory. Are you root?\n"));
|
||||
log_dbg("Cannot lock memory with mlockall.");
|
||||
_memlock_count--;
|
||||
return 0;
|
||||
}
|
||||
@@ -450,7 +244,7 @@ int crypt_memlock_inc(struct crypt_device *ctx)
|
||||
log_err(ctx, _("Cannot get process priority.\n"));
|
||||
else
|
||||
if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY))
|
||||
log_err(ctx, _("setpriority %d failed: %s\n"),
|
||||
log_dbg("setpriority %d failed: %s",
|
||||
DEFAULT_PROCESS_PRIORITY, strerror(errno));
|
||||
}
|
||||
return _memlock_count ? 1 : 0;
|
||||
@@ -463,64 +257,7 @@ int crypt_memlock_dec(struct crypt_device *ctx)
|
||||
if (munlockall() == -1)
|
||||
log_err(ctx, _("Cannot unlock memory.\n"));
|
||||
if (setpriority(PRIO_PROCESS, 0, _priority))
|
||||
log_err(ctx, _("setpriority %d failed: %s\n"), _priority, strerror(errno));
|
||||
log_dbg("setpriority %d failed: %s", _priority, strerror(errno));
|
||||
}
|
||||
return _memlock_count ? 1 : 0;
|
||||
}
|
||||
|
||||
/* DEVICE TOPOLOGY */
|
||||
|
||||
/* block device topology ioctls, introduced in 2.6.32 */
|
||||
#ifndef BLKIOMIN
|
||||
#define BLKIOMIN _IO(0x12,120)
|
||||
#define BLKIOOPT _IO(0x12,121)
|
||||
#define BLKALIGNOFF _IO(0x12,122)
|
||||
#endif
|
||||
|
||||
void get_topology_alignment(const char *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment)
|
||||
{
|
||||
int dev_alignment_offset = 0;
|
||||
unsigned int min_io_size = 0, opt_io_size = 0;
|
||||
unsigned long temp_alignment = 0;
|
||||
int fd;
|
||||
|
||||
*required_alignment = default_alignment;
|
||||
*alignment_offset = 0;
|
||||
|
||||
fd = open(device, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
/* minimum io size */
|
||||
if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) {
|
||||
log_dbg("Topology info for %s not supported, using default offset %lu bytes.",
|
||||
device, default_alignment);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* optimal io size */
|
||||
if (ioctl(fd, BLKIOOPT, &opt_io_size) == -1)
|
||||
opt_io_size = min_io_size;
|
||||
|
||||
/* alignment offset, bogus -1 means misaligned/unknown */
|
||||
if (ioctl(fd, BLKALIGNOFF, &dev_alignment_offset) == -1 || dev_alignment_offset < 0)
|
||||
dev_alignment_offset = 0;
|
||||
*alignment_offset = (unsigned long)dev_alignment_offset;
|
||||
|
||||
temp_alignment = (unsigned long)min_io_size;
|
||||
|
||||
if (temp_alignment < (unsigned long)opt_io_size)
|
||||
temp_alignment = (unsigned long)opt_io_size;
|
||||
|
||||
/* If calculated alignment is multiple of default, keep default */
|
||||
if (temp_alignment && (default_alignment % temp_alignment))
|
||||
*required_alignment = temp_alignment;
|
||||
|
||||
log_dbg("Topology: IO (%u/%u), offset = %lu; Required alignment is %lu bytes.",
|
||||
min_io_size, opt_io_size, *alignment_offset, *required_alignment);
|
||||
out:
|
||||
(void)close(fd);
|
||||
}
|
||||
|
||||
262
lib/utils_benchmark.c
Normal file
262
lib/utils_benchmark.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library, cipher bechmark
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2013, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
* This is not simulating storage, so using disk block causes extreme overhead.
|
||||
* Let's use some fixed block size where results are more reliable...
|
||||
*/
|
||||
#define CIPHER_BLOCK_BYTES 65536
|
||||
|
||||
/*
|
||||
* If the measured value is lower, encrypted buffer is probably too small
|
||||
* and calculated values are not reliable.
|
||||
*/
|
||||
#define CIPHER_TIME_MIN_MS 0.001
|
||||
|
||||
/*
|
||||
* The whole test depends on Linux kernel usermode crypto API for now.
|
||||
* (The same implementations are used in dm-crypt though.)
|
||||
*/
|
||||
|
||||
struct cipher_perf {
|
||||
char name[32];
|
||||
char mode[32];
|
||||
char *key;
|
||||
size_t key_length;
|
||||
char *iv;
|
||||
size_t iv_length;
|
||||
size_t buffer_size;
|
||||
};
|
||||
|
||||
static int time_ms(struct timespec *start, struct timespec *end, double *ms)
|
||||
{
|
||||
double start_ms, end_ms;
|
||||
|
||||
start_ms = start->tv_sec * 1000.0 + start->tv_nsec / (1000.0 * 1000);
|
||||
end_ms = end->tv_sec * 1000.0 + end->tv_nsec / (1000.0 * 1000);
|
||||
|
||||
*ms = end_ms - start_ms;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cipher_perf_one(struct cipher_perf *cp, char *buf,
|
||||
size_t buf_size, int enc)
|
||||
{
|
||||
struct crypt_cipher *cipher = NULL;
|
||||
size_t done = 0, block = CIPHER_BLOCK_BYTES;
|
||||
int r;
|
||||
|
||||
if (buf_size < block)
|
||||
block = buf_size;
|
||||
|
||||
r = crypt_cipher_init(&cipher, cp->name, cp->mode, cp->key, cp->key_length);
|
||||
if (r < 0) {
|
||||
log_dbg("Cannot initialise cipher %s, mode %s.", cp->name, cp->mode);
|
||||
return r;
|
||||
}
|
||||
|
||||
while (done < buf_size) {
|
||||
if ((done + block) > buf_size)
|
||||
block = buf_size - done;
|
||||
|
||||
if (enc)
|
||||
r = crypt_cipher_encrypt(cipher, &buf[done], &buf[done],
|
||||
block, cp->iv, cp->iv_length);
|
||||
else
|
||||
r = crypt_cipher_decrypt(cipher, &buf[done], &buf[done],
|
||||
block, cp->iv, cp->iv_length);
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
done += block;
|
||||
}
|
||||
|
||||
crypt_cipher_destroy(cipher);
|
||||
|
||||
return r;
|
||||
}
|
||||
static int cipher_measure(struct cipher_perf *cp, char *buf,
|
||||
size_t buf_size, int encrypt, double *ms)
|
||||
{
|
||||
struct timespec start, end;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Using getrusage would be better here but the precision
|
||||
* is not adequate, so better stick with CLOCK_MONOTONIC
|
||||
*/
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = cipher_perf_one(cp, buf, buf_size, encrypt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = time_ms(&start, &end, ms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (*ms < CIPHER_TIME_MIN_MS) {
|
||||
log_dbg("Measured cipher runtime (%1.6f) is too low.", *ms);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double speed_mbs(unsigned long bytes, double ms)
|
||||
{
|
||||
double speed = bytes, s = ms / 1000.;
|
||||
|
||||
return speed / (1024 * 1024) / s;
|
||||
}
|
||||
|
||||
static int cipher_perf(struct cipher_perf *cp,
|
||||
double *encryption_mbs, double *decryption_mbs)
|
||||
{
|
||||
double ms_enc, ms_dec, ms;
|
||||
int r, repeat_enc, repeat_dec;
|
||||
void *buf = NULL;
|
||||
|
||||
if (posix_memalign(&buf, crypt_getpagesize(), cp->buffer_size))
|
||||
return -ENOMEM;
|
||||
|
||||
ms_enc = 0.0;
|
||||
repeat_enc = 1;
|
||||
while (ms_enc < 1000.0) {
|
||||
r = cipher_measure(cp, buf, cp->buffer_size, 1, &ms);
|
||||
if (r < 0) {
|
||||
free(buf);
|
||||
return r;
|
||||
}
|
||||
ms_enc += ms;
|
||||
repeat_enc++;
|
||||
}
|
||||
|
||||
ms_dec = 0.0;
|
||||
repeat_dec = 1;
|
||||
while (ms_dec < 1000.0) {
|
||||
r = cipher_measure(cp, buf, cp->buffer_size, 0, &ms);
|
||||
if (r < 0) {
|
||||
free(buf);
|
||||
return r;
|
||||
}
|
||||
ms_dec += ms;
|
||||
repeat_dec++;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
*encryption_mbs = speed_mbs(cp->buffer_size * repeat_enc, ms_enc);
|
||||
*decryption_mbs = speed_mbs(cp->buffer_size * repeat_dec, ms_dec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_benchmark(struct crypt_device *cd,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
size_t volume_key_size,
|
||||
size_t iv_size,
|
||||
size_t buffer_size,
|
||||
double *encryption_mbs,
|
||||
double *decryption_mbs)
|
||||
{
|
||||
struct cipher_perf cp = {
|
||||
.key_length = volume_key_size,
|
||||
.iv_length = iv_size,
|
||||
.buffer_size = buffer_size,
|
||||
};
|
||||
char *c;
|
||||
int r;
|
||||
|
||||
if (!cipher || !cipher_mode || !volume_key_size)
|
||||
return -EINVAL;
|
||||
|
||||
r = init_crypto(cd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = -ENOMEM;
|
||||
if (iv_size) {
|
||||
cp.iv = malloc(iv_size);
|
||||
if (!cp.iv)
|
||||
goto out;
|
||||
crypt_random_get(cd, cp.iv, iv_size, CRYPT_RND_NORMAL);
|
||||
}
|
||||
|
||||
cp.key = malloc(volume_key_size);
|
||||
if (!cp.key)
|
||||
goto out;
|
||||
|
||||
crypt_random_get(cd, cp.key, volume_key_size, CRYPT_RND_NORMAL);
|
||||
strncpy(cp.name, cipher, sizeof(cp.name)-1);
|
||||
strncpy(cp.mode, cipher_mode, sizeof(cp.mode)-1);
|
||||
|
||||
/* Ignore IV generator */
|
||||
if ((c = strchr(cp.mode, '-')))
|
||||
*c = '\0';
|
||||
|
||||
r = cipher_perf(&cp, encryption_mbs, decryption_mbs);
|
||||
out:
|
||||
free(cp.key);
|
||||
free(cp.iv);
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_benchmark_kdf(struct crypt_device *cd,
|
||||
const char *kdf,
|
||||
const char *hash,
|
||||
const char *password,
|
||||
size_t password_size,
|
||||
const char *salt,
|
||||
size_t salt_size,
|
||||
uint64_t *iterations_sec)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!iterations_sec)
|
||||
return -EINVAL;
|
||||
|
||||
r = init_crypto(cd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!strncmp(kdf, "pbkdf2", 6))
|
||||
r = crypt_pbkdf_check(kdf, hash, password, password_size,
|
||||
salt, salt_size, iterations_sec);
|
||||
else
|
||||
r = -EINVAL;
|
||||
|
||||
if (!r)
|
||||
log_dbg("KDF %s, hash %s: %" PRIu64 " iterations per second.",
|
||||
kdf, hash, *iterations_sec);
|
||||
return r;
|
||||
}
|
||||
@@ -3,10 +3,12 @@
|
||||
*
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -92,7 +94,9 @@ void *crypt_safe_alloc(size_t size)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
memset(&alloc->data, 0, size);
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
@@ -261,6 +265,49 @@ out_err:
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple call to lseek(3) might not be possible for some inputs (e.g.
|
||||
* reading from a pipe), so this function instead reads of up to BUFSIZ bytes
|
||||
* at a time until the specified number of bytes. It returns -1 on read error
|
||||
* or when it reaches EOF before the requested number of bytes have been
|
||||
* discarded.
|
||||
*/
|
||||
static int keyfile_seek(int fd, size_t bytes)
|
||||
{
|
||||
char tmp[BUFSIZ];
|
||||
size_t next_read;
|
||||
ssize_t bytes_r;
|
||||
off_t r;
|
||||
|
||||
r = lseek(fd, bytes, SEEK_CUR);
|
||||
if (r > 0)
|
||||
return 0;
|
||||
if (r < 0 && errno != ESPIPE)
|
||||
return -1;
|
||||
|
||||
while (bytes > 0) {
|
||||
/* figure out how much to read */
|
||||
next_read = bytes > sizeof(tmp) ? sizeof(tmp) : bytes;
|
||||
|
||||
bytes_r = read(fd, tmp, next_read);
|
||||
if (bytes_r < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
/* read error */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bytes_r == 0)
|
||||
/* EOF */
|
||||
break;
|
||||
|
||||
bytes -= bytes_r;
|
||||
}
|
||||
|
||||
return bytes == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: --key-file=- is interpreted as a read from a binary file (stdin)
|
||||
* key_size_max == 0 means detect maximum according to input type (tty/file)
|
||||
@@ -274,7 +321,7 @@ int crypt_get_key(const char *prompt,
|
||||
{
|
||||
int fd, regular_file, read_stdin, char_read, unlimited_read = 0;
|
||||
int r = -EINVAL;
|
||||
char *pass = NULL, tmp;
|
||||
char *pass = NULL;
|
||||
size_t buflen, i, file_read_size;
|
||||
struct stat st;
|
||||
|
||||
@@ -342,8 +389,7 @@ int crypt_get_key(const char *prompt,
|
||||
}
|
||||
|
||||
/* Discard keyfile_offset bytes on input */
|
||||
for(i = 0; i < keyfile_offset; i++)
|
||||
if (read(fd, &tmp, 1) != 1) {
|
||||
if (keyfile_offset && keyfile_seek(fd, keyfile_offset) < 0) {
|
||||
log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
@@ -467,10 +513,13 @@ int crypt_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size)
|
||||
break;
|
||||
case 't':
|
||||
case 'T': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'g':
|
||||
case 'G': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'm':
|
||||
case 'M': mult *= mult_base;
|
||||
/* Fall through */
|
||||
case 'k':
|
||||
case 'K': mult *= mult_base;
|
||||
break;
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -22,10 +24,10 @@
|
||||
#define _UTILS_CRYPT_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
#define MAX_CIPHER_LEN 32
|
||||
#define MAX_CIPHER_LEN_STR "32"
|
||||
#define MAX_CIPHER_LEN_STR "31"
|
||||
#define MAX_KEYFILES 32
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
|
||||
442
lib/utils_device.c
Normal file
442
lib/utils_device.c
Normal file
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* device backend utilities
|
||||
*
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <unistd.h>
|
||||
#include "internal.h"
|
||||
|
||||
struct device {
|
||||
char *path;
|
||||
|
||||
char *file_path;
|
||||
int loop_fd;
|
||||
|
||||
int init_done:1;
|
||||
};
|
||||
|
||||
static int device_ready(const char *device)
|
||||
{
|
||||
int devfd, r = 0;
|
||||
struct stat st;
|
||||
|
||||
log_dbg("Trying to open and read device %s.", device);
|
||||
devfd = open(device, O_RDONLY);
|
||||
if (devfd < 0) {
|
||||
log_err(NULL, _("Device %s doesn't exist or access denied.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fstat(devfd, &st) < 0)
|
||||
r = -EINVAL;
|
||||
else if (!S_ISBLK(st.st_mode))
|
||||
r = S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int device_open(struct device *device, int flags)
|
||||
{
|
||||
int devfd;
|
||||
|
||||
devfd = open(device_path(device), flags | O_DIRECT | O_SYNC);
|
||||
if (devfd < 0 && errno == EINVAL) {
|
||||
log_dbg("Trying to open device %s without direct-io.",
|
||||
device_path(device));
|
||||
devfd = open(device_path(device), flags | O_SYNC);
|
||||
}
|
||||
|
||||
return devfd;
|
||||
}
|
||||
|
||||
int device_alloc(struct device **device, const char *path)
|
||||
{
|
||||
struct device *dev;
|
||||
int r;
|
||||
|
||||
if (!path) {
|
||||
*device = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev = malloc(sizeof(struct device));
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(dev, 0, sizeof(struct device));
|
||||
dev->loop_fd = -1;
|
||||
|
||||
r = device_ready(path);
|
||||
if (!r) {
|
||||
dev->init_done = 1;
|
||||
} else if (r == -ENOTBLK) {
|
||||
/* alloc loop later */
|
||||
} else if (r < 0) {
|
||||
free(dev);
|
||||
return -ENOTBLK;
|
||||
}
|
||||
|
||||
dev->path = strdup(path);
|
||||
if (!dev->path) {
|
||||
free(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*device = dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void device_free(struct device *device)
|
||||
{
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
if (device->loop_fd != -1) {
|
||||
log_dbg("Closed loop %s (%s).", device->path, device->file_path);
|
||||
close(device->loop_fd);
|
||||
}
|
||||
|
||||
free(device->file_path);
|
||||
free(device->path);
|
||||
free(device);
|
||||
}
|
||||
|
||||
/* Get block device path */
|
||||
const char *device_block_path(const struct device *device)
|
||||
{
|
||||
if (!device || !device->init_done)
|
||||
return NULL;
|
||||
|
||||
return device->path;
|
||||
}
|
||||
|
||||
/* Get path to device / file */
|
||||
const char *device_path(const struct device *device)
|
||||
{
|
||||
if (!device)
|
||||
return NULL;
|
||||
|
||||
if (device->file_path)
|
||||
return device->file_path;
|
||||
|
||||
return device->path;
|
||||
}
|
||||
|
||||
/* block device topology ioctls, introduced in 2.6.32 */
|
||||
#ifndef BLKIOMIN
|
||||
#define BLKIOMIN _IO(0x12,120)
|
||||
#define BLKIOOPT _IO(0x12,121)
|
||||
#define BLKALIGNOFF _IO(0x12,122)
|
||||
#endif
|
||||
|
||||
void device_topology_alignment(struct device *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment)
|
||||
{
|
||||
int dev_alignment_offset = 0;
|
||||
unsigned int min_io_size = 0, opt_io_size = 0;
|
||||
unsigned long temp_alignment = 0;
|
||||
int fd;
|
||||
|
||||
*required_alignment = default_alignment;
|
||||
*alignment_offset = 0;
|
||||
|
||||
if (!device || !device->path) //FIXME
|
||||
return;
|
||||
|
||||
fd = open(device->path, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
/* minimum io size */
|
||||
if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) {
|
||||
log_dbg("Topology info for %s not supported, using default offset %lu bytes.",
|
||||
device->path, default_alignment);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* optimal io size */
|
||||
if (ioctl(fd, BLKIOOPT, &opt_io_size) == -1)
|
||||
opt_io_size = min_io_size;
|
||||
|
||||
/* alignment offset, bogus -1 means misaligned/unknown */
|
||||
if (ioctl(fd, BLKALIGNOFF, &dev_alignment_offset) == -1 || dev_alignment_offset < 0)
|
||||
dev_alignment_offset = 0;
|
||||
*alignment_offset = (unsigned long)dev_alignment_offset;
|
||||
|
||||
temp_alignment = (unsigned long)min_io_size;
|
||||
|
||||
if (temp_alignment < (unsigned long)opt_io_size)
|
||||
temp_alignment = (unsigned long)opt_io_size;
|
||||
|
||||
/* If calculated alignment is multiple of default, keep default */
|
||||
if (temp_alignment && (default_alignment % temp_alignment))
|
||||
*required_alignment = temp_alignment;
|
||||
|
||||
log_dbg("Topology: IO (%u/%u), offset = %lu; Required alignment is %lu bytes.",
|
||||
min_io_size, opt_io_size, *alignment_offset, *required_alignment);
|
||||
out:
|
||||
(void)close(fd);
|
||||
}
|
||||
|
||||
int device_block_size(struct device *device)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, bsize = 0, r = -EINVAL;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
fd = open(device->path, O_RDONLY);
|
||||
if(fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
goto out;
|
||||
|
||||
if (S_ISREG(st.st_mode) || device->file_path) {
|
||||
r = (int)crypt_getpagesize();
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
|
||||
r = bsize;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int device_read_ahead(struct device *device, uint32_t *read_ahead)
|
||||
{
|
||||
int fd, r = 0;
|
||||
long read_ahead_long;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(device->path, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
r = ioctl(fd, BLKRAGET, &read_ahead_long) ? 0 : 1;
|
||||
close(fd);
|
||||
|
||||
if (r)
|
||||
*read_ahead = (uint32_t) read_ahead_long;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Get data size in bytes */
|
||||
int device_size(struct device *device, uint64_t *size)
|
||||
{
|
||||
struct stat st;
|
||||
int devfd, r = -EINVAL;
|
||||
|
||||
devfd = open(device->path, O_RDONLY);
|
||||
if(devfd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (fstat(devfd, &st) < 0)
|
||||
goto out;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
*size = (uint64_t)st.st_size;
|
||||
r = 0;
|
||||
} else if (ioctl(devfd, BLKGETSIZE64, size) >= 0)
|
||||
r = 0;
|
||||
out:
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int device_info(struct device *device,
|
||||
enum devcheck device_check,
|
||||
int *readonly, uint64_t *size)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, r = -EINVAL, flags = 0;
|
||||
|
||||
*readonly = 0;
|
||||
*size = 0;
|
||||
|
||||
if (stat(device->path, &st) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* never wipe header on mounted device */
|
||||
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 */
|
||||
/* coverity[toctou] */
|
||||
fd = open(device->path, O_RDWR | flags);
|
||||
if (fd == -1 && errno == EROFS) {
|
||||
*readonly = 1;
|
||||
fd = open(device->path, O_RDONLY | flags);
|
||||
}
|
||||
|
||||
if (fd == -1 && device_check == DEV_EXCL && errno == EBUSY)
|
||||
return -EBUSY;
|
||||
|
||||
if (fd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
//FIXME: add readonly check
|
||||
*size = (uint64_t)st.st_size;
|
||||
*size >>= SECTOR_SHIFT;
|
||||
} else {
|
||||
/* If the device can be opened read-write, i.e. readonly is still 0, then
|
||||
* check whether BKROGET says that it is read-only. E.g. read-only loop
|
||||
* devices may be openend read-write but are read-only according to BLKROGET
|
||||
*/
|
||||
if (*readonly == 0 && (r = ioctl(fd, BLKROGET, readonly)) < 0)
|
||||
goto out;
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, size) >= 0) {
|
||||
*size >>= SECTOR_SHIFT;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
r = -EINVAL;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int device_internal_prepare(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
char *loop_device;
|
||||
int r, loop_fd, readonly = 0;
|
||||
|
||||
if (device->init_done)
|
||||
return 0;
|
||||
|
||||
log_dbg("Allocating a free loop device.");
|
||||
loop_device = crypt_loop_get_device();
|
||||
if (!loop_device) {
|
||||
if (getuid() || geteuid())
|
||||
log_err(cd, _("Cannot use a loopback device, "
|
||||
"running as non-root user.\n"));
|
||||
else
|
||||
log_err(cd, _("Cannot find a free loopback device.\n"));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Keep the loop open, dettached on last close. */
|
||||
loop_fd = crypt_loop_attach(loop_device, device->path, 0, 1, &readonly);
|
||||
if (loop_fd == -1) {
|
||||
log_err(cd, _("Attaching loopback device failed "
|
||||
"(loop device with autoclear flag is required).\n"));
|
||||
free(loop_device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = device_ready(loop_device);
|
||||
if (r < 0) {
|
||||
free(loop_device);
|
||||
return r;
|
||||
}
|
||||
|
||||
device->loop_fd = loop_fd;
|
||||
device->file_path = device->path;
|
||||
device->path = loop_device;
|
||||
device->init_done = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_block_adjust(struct crypt_device *cd,
|
||||
struct device *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t device_offset,
|
||||
uint64_t *size,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int r, real_readonly;
|
||||
uint64_t real_size;
|
||||
|
||||
if (!device)
|
||||
return -ENOTBLK;
|
||||
|
||||
r = device_internal_prepare(cd, device);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = device_info(device, device_check, &real_readonly, &real_size);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Cannot use device %s which is in use "
|
||||
"(already mapped or mounted).\n"),
|
||||
device->path);
|
||||
else
|
||||
log_err(cd, _("Cannot get info about device %s.\n"),
|
||||
device->path);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (device_offset >= real_size) {
|
||||
log_err(cd, _("Requested offset is beyond real size of device %s.\n"),
|
||||
device->path);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (size && !*size) {
|
||||
*size = real_size;
|
||||
if (!*size) {
|
||||
log_err(cd, _("Device %s has zero size.\n"), device->path);
|
||||
return -ENOTBLK;
|
||||
}
|
||||
*size -= device_offset;
|
||||
}
|
||||
|
||||
/* in case of size is set by parameter */
|
||||
if (size && ((real_size - device_offset) < *size)) {
|
||||
log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64
|
||||
", backing device size = %" PRIu64,
|
||||
device->path, device_offset, *size, real_size);
|
||||
log_err(cd, _("Device %s is too small.\n"), device->path);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (flags && real_readonly)
|
||||
*flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (size)
|
||||
log_dbg("Calculated device size is %" PRIu64" sectors (%s), offset %" PRIu64 ".",
|
||||
*size, real_readonly ? "RO" : "RW", device_offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t size_round_up(size_t size, unsigned int block)
|
||||
{
|
||||
size_t s = (size + (block - 1)) / block;
|
||||
return s * block;
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* devname - search for device name
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2013, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -26,13 +28,10 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "utils_dm.h"
|
||||
|
||||
char *crypt_lookup_dev(const char *dev_id);
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
|
||||
#include "internal.h"
|
||||
|
||||
static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_level)
|
||||
{
|
||||
@@ -135,7 +134,7 @@ char *crypt_lookup_dev(const char *dev_id)
|
||||
if (snprintf(path, sizeof(path), "/sys/dev/block/%s", dev_id) < 0)
|
||||
return NULL;
|
||||
|
||||
len = readlink(path, link, sizeof(link));
|
||||
len = readlink(path, link, sizeof(link) - 1);
|
||||
if (len < 0) {
|
||||
/* Without /sys use old scan */
|
||||
if (stat("/sys/dev/block", &st) < 0)
|
||||
@@ -168,15 +167,12 @@ char *crypt_lookup_dev(const char *dev_id)
|
||||
return devpath;
|
||||
}
|
||||
|
||||
static int crypt_sysfs_get_major_minor(const char *kname, int *major, int *minor)
|
||||
static int _read_uint64(const char *sysfs_path, uint64_t *value)
|
||||
{
|
||||
char path[PATH_MAX], tmp[64] = {0};
|
||||
int fd, r = 0;
|
||||
char tmp[64] = {0};
|
||||
int fd, r;
|
||||
|
||||
if (snprintf(path, sizeof(path), "/sys/block/%s/dev", kname) < 0)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) < 0)
|
||||
if ((fd = open(sysfs_path, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
r = read(fd, tmp, sizeof(tmp));
|
||||
close(fd);
|
||||
@@ -184,85 +180,185 @@ static int crypt_sysfs_get_major_minor(const char *kname, int *major, int *minor
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
tmp[63] = '\0';
|
||||
if (sscanf(tmp, "%d:%d", major, minor) != 2)
|
||||
if (sscanf(tmp, "%" PRIu64, value) != 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int crypt_sysfs_get_holders_dir(const char *device, char *path, int size)
|
||||
static int _sysfs_get_uint64(int major, int minor, uint64_t *value, const char *attr)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/%s",
|
||||
major, minor, attr) < 0)
|
||||
return 0;
|
||||
|
||||
return _read_uint64(path, value);
|
||||
}
|
||||
|
||||
static int _path_get_uint64(const char *sysfs_path, uint64_t *value, const char *attr)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (snprintf(path, sizeof(path), "%s/%s",
|
||||
sysfs_path, attr) < 0)
|
||||
return 0;
|
||||
|
||||
return _read_uint64(path, value);
|
||||
}
|
||||
|
||||
int crypt_dev_is_rotational(int major, int minor)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
if (!_sysfs_get_uint64(major, minor, &val, "queue/rotational"))
|
||||
return 1; /* if failed, expect rotational disk */
|
||||
|
||||
return val ? 1 : 0;
|
||||
}
|
||||
|
||||
int crypt_dev_is_partition(const char *dev_path)
|
||||
{
|
||||
uint64_t val;
|
||||
struct stat st;
|
||||
|
||||
if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
|
||||
if (stat(dev_path, &st) < 0)
|
||||
return 0;
|
||||
|
||||
if (snprintf(path, size, "/sys/dev/block/%d:%d/holders",
|
||||
major(st.st_rdev), minor(st.st_rdev)) < 0)
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
if (!_sysfs_get_uint64(major(st.st_rdev), minor(st.st_rdev),
|
||||
&val, "partition"))
|
||||
return 0;
|
||||
|
||||
return val ? 1 : 0;
|
||||
}
|
||||
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size)
|
||||
uint64_t crypt_dev_partition_offset(const char *dev_path)
|
||||
{
|
||||
uint64_t val;
|
||||
struct stat st;
|
||||
|
||||
if (!crypt_dev_is_partition(dev_path))
|
||||
return 0;
|
||||
|
||||
if (stat(dev_path, &st) < 0)
|
||||
return 0;
|
||||
|
||||
if (!_sysfs_get_uint64(major(st.st_rdev), minor(st.st_rdev),
|
||||
&val, "start"))
|
||||
return 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Try to find partition which match offset and size on top level device */
|
||||
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size)
|
||||
{
|
||||
char link[PATH_MAX], path[PATH_MAX], part_path[PATH_MAX], *devname;
|
||||
char *result = NULL;
|
||||
struct stat st;
|
||||
size_t devname_len;
|
||||
ssize_t len;
|
||||
struct dirent *entry;
|
||||
DIR *dir;
|
||||
struct dirent *d;
|
||||
char path[PATH_MAX], *dmname;
|
||||
int major, minor, r = 0;
|
||||
uint64_t part_offset, part_size;
|
||||
|
||||
if (!crypt_sysfs_get_holders_dir(device, path, sizeof(path)))
|
||||
return -EINVAL;
|
||||
if (stat(dev_path, &st) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!(dir = opendir(path)))
|
||||
return -EINVAL;
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return NULL;
|
||||
|
||||
while (!r && (d = readdir(dir))) {
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d",
|
||||
major(st.st_rdev), minor(st.st_rdev)) < 0)
|
||||
return NULL;
|
||||
|
||||
len = readlink(path, link, sizeof(link) - 1);
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
|
||||
/* Get top level disk name for sysfs search */
|
||||
link[len] = '\0';
|
||||
devname = strrchr(link, '/');
|
||||
if (!devname)
|
||||
return NULL;
|
||||
devname++;
|
||||
|
||||
/* DM devices do not use kernel partitions. */
|
||||
if (dm_is_dm_kernel_name(devname))
|
||||
return NULL;
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir)
|
||||
return NULL;
|
||||
|
||||
devname_len = strlen(devname);
|
||||
while((entry = readdir(dir))) {
|
||||
if (strncmp(entry->d_name, devname, devname_len))
|
||||
continue;
|
||||
|
||||
if (!dm_is_dm_kernel_name(d->d_name)) {
|
||||
r = -EBUSY;
|
||||
break;
|
||||
}
|
||||
if (snprintf(part_path, sizeof(part_path), "%s/%s",
|
||||
path, entry->d_name) < 0)
|
||||
continue;
|
||||
|
||||
if (!crypt_sysfs_get_major_minor(d->d_name, &major, &minor)) {
|
||||
r = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (stat(part_path, &st) < 0)
|
||||
continue;
|
||||
|
||||
if (!(dmname = dm_device_path(NULL, major, minor))) {
|
||||
r = -EINVAL;
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (!_path_get_uint64(part_path, &part_offset, "start") ||
|
||||
!_path_get_uint64(part_path, &part_size, "size"))
|
||||
continue;
|
||||
if (part_offset == offset && part_size == size &&
|
||||
snprintf(part_path, sizeof(part_path), "/dev/%s",
|
||||
entry->d_name) > 0) {
|
||||
result = strdup(part_path);
|
||||
break;
|
||||
}
|
||||
r = dm_check_segment(dmname, offset, size);
|
||||
free(dmname);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
return r;
|
||||
return result;
|
||||
}
|
||||
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational)
|
||||
/* Try to find base device from partition */
|
||||
char *crypt_get_base_device(const char *dev_path)
|
||||
{
|
||||
char path[PATH_MAX], tmp[64] = {0};
|
||||
int fd, r;
|
||||
char link[PATH_MAX], path[PATH_MAX], part_path[PATH_MAX], *devname;
|
||||
struct stat st;
|
||||
ssize_t len;
|
||||
|
||||
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/queue/rotational",
|
||||
major, minor) < 0)
|
||||
return 0;
|
||||
if (!crypt_dev_is_partition(dev_path))
|
||||
return NULL;
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
r = read(fd, tmp, sizeof(tmp));
|
||||
close(fd);
|
||||
if (stat(dev_path, &st) < 0)
|
||||
return NULL;
|
||||
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d",
|
||||
major(st.st_rdev), minor(st.st_rdev)) < 0)
|
||||
return NULL;
|
||||
|
||||
if (sscanf(tmp, "%d", rotational) != 1)
|
||||
return 0;
|
||||
len = readlink(path, link, sizeof(link) - 1);
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
|
||||
return 1;
|
||||
/* Get top level disk name for sysfs search */
|
||||
link[len] = '\0';
|
||||
devname = strrchr(link, '/');
|
||||
if (!devname)
|
||||
return NULL;
|
||||
*devname = '\0';
|
||||
devname = strrchr(link, '/');
|
||||
if (!devname)
|
||||
return NULL;
|
||||
devname++;
|
||||
|
||||
if (dm_is_dm_kernel_name(devname))
|
||||
return NULL;
|
||||
|
||||
snprintf(part_path, sizeof(part_path), "/dev/%s", devname);
|
||||
return strdup(part_path);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* libdevmapper - device-mapper backend for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004, Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -28,6 +30,7 @@
|
||||
struct crypt_device;
|
||||
struct volume_key;
|
||||
struct crypt_params_verity;
|
||||
struct device;
|
||||
|
||||
/* Device mapper backend - kernel support flags */
|
||||
#define DM_KEY_WIPE_SUPPORTED (1 << 0) /* key wipe message */
|
||||
@@ -36,6 +39,7 @@ struct crypt_params_verity;
|
||||
#define DM_PLAIN64_SUPPORTED (1 << 3) /* plain64 IV */
|
||||
#define DM_DISCARDS_SUPPORTED (1 << 4) /* discards/TRIM option is supported */
|
||||
#define DM_VERITY_SUPPORTED (1 << 5) /* dm-verity target supported */
|
||||
#define DM_TCW_SUPPORTED (1 << 6) /* tcw (TCRYPT CBC with whitening) */
|
||||
uint32_t dm_flags(void);
|
||||
|
||||
#define DM_ACTIVE_DEVICE (1 << 0)
|
||||
@@ -54,7 +58,7 @@ struct crypt_dm_active_device {
|
||||
uint64_t size; /* active device size */
|
||||
uint32_t flags; /* activation flags */
|
||||
const char *uuid;
|
||||
const char *data_device;
|
||||
struct device *data_device;
|
||||
union {
|
||||
struct {
|
||||
const char *cipher;
|
||||
@@ -67,7 +71,7 @@ struct crypt_dm_active_device {
|
||||
uint64_t iv_offset; /* IV initilisation sector */
|
||||
} crypt;
|
||||
struct {
|
||||
const char *hash_device;
|
||||
struct device *hash_device;
|
||||
|
||||
const char *root_hash;
|
||||
uint32_t root_hash_size;
|
||||
@@ -78,26 +82,28 @@ struct crypt_dm_active_device {
|
||||
} u;
|
||||
};
|
||||
|
||||
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_status_suspended(const char *name);
|
||||
int dm_status_verity_ok(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,
|
||||
void dm_backend_init(void);
|
||||
void dm_backend_exit(void);
|
||||
|
||||
int dm_remove_device(struct crypt_device *cd, const char *name,
|
||||
int force, uint64_t size);
|
||||
int dm_status_device(struct crypt_device *cd, const char *name);
|
||||
int dm_status_suspended(struct crypt_device *cd, const char *name);
|
||||
int dm_status_verity_ok(struct crypt_device *cd, const char *name);
|
||||
int dm_query_device(struct crypt_device *cd, const char *name,
|
||||
uint32_t get_flags, struct crypt_dm_active_device *dmd);
|
||||
int dm_create_device(struct crypt_device *cd, 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(const char *prefix, int major, int minor);
|
||||
int dm_suspend_and_wipe_key(struct crypt_device *cd, const char *name);
|
||||
int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
size_t key_size, const char *key);
|
||||
|
||||
const char *dm_get_dir(void);
|
||||
|
||||
/* These are DM helpers used only by utils_devpath file */
|
||||
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);
|
||||
char *dm_device_path(const char *prefix, int major, int minor);
|
||||
|
||||
#endif /* _UTILS_DM_H */
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2013, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -18,45 +19,36 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "libcryptsetup.h"
|
||||
#include "nls.h"
|
||||
#include "utils_fips.h"
|
||||
#include "config.h"
|
||||
|
||||
#if !ENABLE_FIPS
|
||||
int crypt_fips_mode(void) { return 0; }
|
||||
void crypt_fips_libcryptsetup_check(struct crypt_device *cd) {}
|
||||
void crypt_fips_self_check(struct crypt_device *cd) {}
|
||||
void crypt_fips_libcryptsetup_check(void) {}
|
||||
#else
|
||||
#include <fipscheck.h>
|
||||
|
||||
int crypt_fips_mode(void)
|
||||
{
|
||||
return FIPSCHECK_kernel_fips_mode();
|
||||
return FIPSCHECK_kernel_fips_mode() && !access(FIPS_MODULE_FILE, F_OK);
|
||||
}
|
||||
|
||||
static void crypt_fips_verify(struct crypt_device *cd,
|
||||
const char *name, const char *function)
|
||||
static void crypt_fips_verify(const char *name, const char *function)
|
||||
{
|
||||
if (!crypt_fips_mode())
|
||||
if (access(FIPS_MODULE_FILE, F_OK))
|
||||
return;
|
||||
|
||||
if (!FIPSCHECK_verify(name, function)) {
|
||||
crypt_log(cd, CRYPT_LOG_ERROR, _("FIPS checksum verification failed.\n"));
|
||||
fputs(_("FIPS checksum verification failed.\n"), stderr);
|
||||
if (FIPSCHECK_kernel_fips_mode())
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
crypt_log(cd, CRYPT_LOG_VERBOSE, _("Running in FIPS mode.\n"));
|
||||
}
|
||||
|
||||
void crypt_fips_libcryptsetup_check(struct crypt_device *cd)
|
||||
void crypt_fips_libcryptsetup_check(void)
|
||||
{
|
||||
crypt_fips_verify(cd, LIBCRYPTSETUP_VERSION_FIPS, "crypt_init");
|
||||
}
|
||||
|
||||
void crypt_fips_self_check(struct crypt_device *cd)
|
||||
{
|
||||
crypt_fips_verify(cd, NULL, NULL);
|
||||
crypt_fips_verify(LIBCRYPTSETUP_VERSION_FIPS, "crypt_init");
|
||||
}
|
||||
#endif /* ENABLE_FIPS */
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2013, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -23,7 +24,6 @@
|
||||
struct crypt_device;
|
||||
|
||||
int crypt_fips_mode(void);
|
||||
void crypt_fips_libcryptsetup_check(struct crypt_device *cd);
|
||||
void crypt_fips_self_check(struct crypt_device *cd);
|
||||
void crypt_fips_libcryptsetup_check(void);
|
||||
|
||||
#endif /* _UTILS_FIPS_H */
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -25,6 +27,7 @@
|
||||
#include <limits.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/loop.h>
|
||||
|
||||
#include "utils_loop.h"
|
||||
@@ -43,13 +46,10 @@ static char *crypt_loop_get_device_old(void)
|
||||
{
|
||||
char dev[20];
|
||||
int i, loop_fd;
|
||||
struct stat st;
|
||||
struct loop_info64 lo64 = {0};
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
sprintf(dev, "/dev/loop%d", i);
|
||||
if (stat(dev, &st) || !S_ISBLK(st.st_mode))
|
||||
return NULL;
|
||||
|
||||
loop_fd = open(dev, O_RDONLY);
|
||||
if (loop_fd < 0)
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -34,18 +36,20 @@
|
||||
|
||||
#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)
|
||||
static ssize_t _crypt_wipe_zero(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
memset(buffer, 0, size);
|
||||
return write_lseek_blockwise(fd, buffer, size, offset);
|
||||
return write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_random(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
static ssize_t _crypt_wipe_random(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
if (crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return write_lseek_blockwise(fd, buffer, size, offset);
|
||||
return write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -74,7 +78,8 @@ static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn)
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_disk(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
static ssize_t _crypt_wipe_disk(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
int r;
|
||||
unsigned int i;
|
||||
@@ -95,22 +100,23 @@ static ssize_t _crypt_wipe_disk(int fd, char *buffer, uint64_t offset, uint64_t
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
written = write_lseek_blockwise(fd, buffer, size, offset);
|
||||
written = write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
||||
if (written < 0 || written != (ssize_t)size)
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Rewrite it finally with random */
|
||||
return _crypt_wipe_random(fd, buffer, offset, size);
|
||||
return _crypt_wipe_random(fd, bsize, buffer, offset, size);
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_ssd(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
static ssize_t _crypt_wipe_ssd(int fd, int bsize, char *buffer,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
// FIXME: for now just rewrite it by random
|
||||
return _crypt_wipe_random(fd, buffer, offset, size);
|
||||
return _crypt_wipe_random(fd, bsize, buffer, offset, size);
|
||||
}
|
||||
|
||||
int crypt_wipe(const char *device,
|
||||
int crypt_wipe(struct device *device,
|
||||
uint64_t offset,
|
||||
uint64_t size,
|
||||
crypt_wipe_type type,
|
||||
@@ -118,59 +124,63 @@ int crypt_wipe(const char *device,
|
||||
{
|
||||
struct stat st;
|
||||
char *buffer;
|
||||
int devfd, flags, rotational;
|
||||
int devfd, flags, bsize;
|
||||
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);
|
||||
device_path(device), (unsigned long)size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stat(device, &st) < 0) {
|
||||
log_dbg("Device %s not found.", device);
|
||||
if (stat(device_path(device), &st) < 0) {
|
||||
log_dbg("Device %s not found.", device_path(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)
|
||||
if (type == CRYPT_WIPE_DISK && S_ISBLK(st.st_mode)) {
|
||||
if (!crypt_dev_is_rotational(major(st.st_rdev),
|
||||
minor(st.st_rdev))) {
|
||||
type = CRYPT_WIPE_SSD;
|
||||
log_dbg("Non-rotational device, using SSD wipe mode.");
|
||||
} else
|
||||
log_dbg("Rotational device, using normal wipe mode.");
|
||||
}
|
||||
|
||||
bsize = device_block_size(device);
|
||||
if (bsize <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
buffer = malloc(size);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
flags = O_RDWR | O_DIRECT | O_SYNC;
|
||||
flags = O_RDWR;
|
||||
|
||||
/* use O_EXCL only for block devices */
|
||||
if (exclusive && S_ISBLK(st.st_mode))
|
||||
flags |= O_EXCL;
|
||||
|
||||
devfd = open(device, flags);
|
||||
/* coverity[toctou] */
|
||||
devfd = device_open(device, flags);
|
||||
if (devfd == -1) {
|
||||
free(buffer);
|
||||
return errno == EBUSY ? -EBUSY : -EINVAL;
|
||||
return errno ? -errno : -EINVAL;
|
||||
}
|
||||
|
||||
// FIXME: use fixed block size and loop here
|
||||
switch (type) {
|
||||
case CRYPT_WIPE_ZERO:
|
||||
written = _crypt_wipe_zero(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_zero(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_DISK:
|
||||
written = _crypt_wipe_disk(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_disk(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_SSD:
|
||||
written = _crypt_wipe_ssd(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_ssd(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_RANDOM:
|
||||
written = _crypt_wipe_random(devfd, buffer, offset, size);
|
||||
written = _crypt_wipe_random(devfd, bsize, buffer, offset, size);
|
||||
break;
|
||||
default:
|
||||
log_dbg("Unsuported wipe type requested: (%d)", type);
|
||||
|
||||
@@ -2,15 +2,13 @@ moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libverity.la
|
||||
|
||||
libverity_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
libverity_la_CFLAGS = -Wall $(AM_CFLAGS) @CRYPTO_CFLAGS@
|
||||
|
||||
libverity_la_SOURCES = \
|
||||
verity_hash.c \
|
||||
verity.c \
|
||||
verity.h
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
AM_CPPFLAGS = -include config.h \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/lib/crypto_backend
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
*
|
||||
* Copyright (C) 2012, 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 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -52,20 +53,22 @@ struct verity_sb {
|
||||
|
||||
/* Read verity superblock from disk */
|
||||
int VERITY_read_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
char **uuid_string,
|
||||
struct crypt_params_verity *params)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(cd);
|
||||
int bsize = device_block_size(device);
|
||||
struct verity_sb sb = {};
|
||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||
int devfd = 0, sb_version;
|
||||
|
||||
log_dbg("Reading VERITY header of size %u on device %s, offset %" PRIu64 ".",
|
||||
sizeof(struct verity_sb), device, sb_offset);
|
||||
log_dbg("Reading VERITY header of size %zu on device %s, offset %" PRIu64 ".",
|
||||
sizeof(struct verity_sb), device_path(device), sb_offset);
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device doesn't use on-disk header.\n"), device);
|
||||
log_err(cd, _("Verity device %s doesn't use on-disk header.\n"),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -74,21 +77,22 @@ int VERITY_read_sb(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
devfd = open(device ,O_RDONLY | O_DIRECT);
|
||||
devfd = device_open(device, O_RDONLY);
|
||||
if(devfd == -1) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), device);
|
||||
log_err(cd, _("Cannot open device %s.\n"), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(lseek(devfd, sb_offset, SEEK_SET) < 0 ||
|
||||
read_blockwise(devfd, &sb, hdr_size) < hdr_size) {
|
||||
read_blockwise(devfd, bsize, &sb, hdr_size) < hdr_size) {
|
||||
close(devfd);
|
||||
return -EIO;
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
if (memcmp(sb.signature, VERITY_SIGNATURE, sizeof(sb.signature))) {
|
||||
log_err(cd, _("Device %s is not a valid VERITY device.\n"), device);
|
||||
log_err(cd, _("Device %s is not a valid VERITY device.\n"),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -144,32 +148,35 @@ int VERITY_read_sb(struct crypt_device *cd,
|
||||
|
||||
/* Write verity superblock to disk */
|
||||
int VERITY_write_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
const char *uuid_string,
|
||||
struct crypt_params_verity *params)
|
||||
{
|
||||
struct device *device = crypt_metadata_device(cd);
|
||||
int bsize = device_block_size(device);
|
||||
struct verity_sb sb = {};
|
||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||
uuid_t uuid;
|
||||
int r, devfd = 0;
|
||||
|
||||
log_dbg("Updating VERITY header of size %u on device %s, offset %" PRIu64 ".",
|
||||
sizeof(struct verity_sb), device, sb_offset);
|
||||
log_dbg("Updating VERITY header of size %zu on device %s, offset %" PRIu64 ".",
|
||||
sizeof(struct verity_sb), device_path(device), sb_offset);
|
||||
|
||||
if (!uuid_string || uuid_parse(uuid_string, uuid) == -1) {
|
||||
log_err(cd, _("Wrong VERITY UUID format provided.\n"), device);
|
||||
log_err(cd, _("Wrong VERITY UUID format provided on device %s.\n"),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device doesn't use on-disk header.\n"), device);
|
||||
log_err(cd, _("Verity device %s doesn't use on-disk header.\n"),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
devfd = open(device, O_RDWR | O_DIRECT);
|
||||
devfd = device_open(device, O_RDWR);
|
||||
if(devfd == -1) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), device);
|
||||
log_err(cd, _("Cannot open device %s.\n"), device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -184,9 +191,10 @@ int VERITY_write_sb(struct crypt_device *cd,
|
||||
memcpy(sb.salt, params->salt, params->salt_size);
|
||||
memcpy(sb.uuid, uuid, sizeof(sb.uuid));
|
||||
|
||||
r = write_lseek_blockwise(devfd, (char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0;
|
||||
r = write_lseek_blockwise(devfd, bsize, (char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0;
|
||||
if (r)
|
||||
log_err(cd, _("Error during update of verity header on device %s.\n"), device);
|
||||
log_err(cd, _("Error during update of verity header on device %s.\n"),
|
||||
device_path(device));
|
||||
close(devfd);
|
||||
|
||||
return r;
|
||||
@@ -220,14 +228,12 @@ int VERITY_UUID_generate(struct crypt_device *cd, char **uuid_string)
|
||||
/* Activate verity device in kernel device-mapper */
|
||||
int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags)
|
||||
{
|
||||
struct crypt_dm_active_device dmd;
|
||||
uint64_t offset = 0;
|
||||
int r;
|
||||
|
||||
log_dbg("Trying to activate VERITY device %s using hash %s.",
|
||||
@@ -236,7 +242,6 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
if (verity_hdr->flags & CRYPT_VERITY_CHECK_HASH) {
|
||||
log_dbg("Verification of data in userspace required.");
|
||||
r = VERITY_verify(cd, verity_hdr,
|
||||
crypt_get_device_name(cd), hash_device,
|
||||
root_hash, root_hash_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -246,8 +251,8 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
return 0;
|
||||
|
||||
dmd.target = DM_VERITY;
|
||||
dmd.data_device = crypt_get_device_name(cd);
|
||||
dmd.u.verity.hash_device = hash_device;
|
||||
dmd.data_device = crypt_data_device(cd);
|
||||
dmd.u.verity.hash_device = crypt_metadata_device(cd);
|
||||
dmd.u.verity.root_hash = root_hash;
|
||||
dmd.u.verity.root_hash_size = root_hash_size;
|
||||
dmd.u.verity.hash_offset = VERITY_hash_offset_block(verity_hdr),
|
||||
@@ -256,20 +261,25 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
dmd.uuid = crypt_get_uuid(cd);
|
||||
dmd.u.verity.vp = verity_hdr;
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
&dmd.size, &offset, &dmd.flags);
|
||||
r = device_block_adjust(cd, dmd.u.verity.hash_device, DEV_OK,
|
||||
0, NULL, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dm_create_device(name, CRYPT_VERITY, &dmd, 0);
|
||||
if (!r && !(dm_flags() & DM_VERITY_SUPPORTED)) {
|
||||
r = device_block_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
0, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd, 0);
|
||||
if (r < 0 && !(dm_flags() & DM_VERITY_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel doesn't support dm-verity mapping.\n"));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_status_verity_ok(name);
|
||||
r = dm_status_verity_ok(cd, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
*
|
||||
* Copyright (C) 2012, 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 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -21,7 +22,6 @@
|
||||
#define _VERITY_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
#define VERITY_MAX_HASH_TYPE 1
|
||||
#define VERITY_BLOCK_SIZE_OK(x) ((x) % 512 || (x) < 512 || \
|
||||
@@ -31,20 +31,17 @@ struct crypt_device;
|
||||
struct crypt_params_verity;
|
||||
|
||||
int VERITY_read_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
char **uuid,
|
||||
struct crypt_params_verity *params);
|
||||
|
||||
int VERITY_write_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
const char *uuid_string,
|
||||
struct crypt_params_verity *params);
|
||||
|
||||
int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
@@ -52,15 +49,11 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
|
||||
int VERITY_verify(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
*
|
||||
* Copyright (C) 2012, 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 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 program is distributed in the hope that it will be useful,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
@@ -202,8 +203,8 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
int verify,
|
||||
int version,
|
||||
const char *hash_name,
|
||||
const char *hash_device,
|
||||
const char *data_device,
|
||||
struct device *hash_device,
|
||||
struct device *data_device,
|
||||
size_t hash_block_size,
|
||||
size_t data_block_size,
|
||||
off_t data_blocks,
|
||||
@@ -219,7 +220,7 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
off_t hash_level_block[VERITY_MAX_LEVELS];
|
||||
off_t hash_level_size[VERITY_MAX_LEVELS];
|
||||
off_t data_file_blocks, s;
|
||||
size_t hash_per_block, hash_per_block_bits;
|
||||
size_t hash_per_block_bits;
|
||||
off_t data_device_size = 0, hash_device_size = 0;
|
||||
uint64_t dev_size;
|
||||
int levels, i, r;
|
||||
@@ -227,7 +228,8 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
log_dbg("Hash %s %s, data device %s, data blocks %" PRIu64
|
||||
", hash_device %s, offset %" PRIu64 ".",
|
||||
verify ? "verification" : "creation", hash_name,
|
||||
data_device, data_blocks, hash_device, hash_position);
|
||||
device_path(data_device), data_blocks,
|
||||
device_path(hash_device), hash_position);
|
||||
|
||||
if (data_blocks < 0 || hash_position < 0) {
|
||||
log_err(cd, _("Invalid size parameters for verity device.\n"));
|
||||
@@ -249,7 +251,6 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
hash_per_block_bits = get_bits_down(hash_block_size / digest_size);
|
||||
hash_per_block = 1 << hash_per_block_bits;
|
||||
if (!hash_per_block_bits)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -269,12 +270,10 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
for (i = levels - 1; i >= 0; i--) {
|
||||
hash_level_block[i] = hash_position;
|
||||
// verity position of block data_file_blocks at level i
|
||||
s = data_file_blocks >> (i * hash_per_block_bits);
|
||||
s = (s + hash_per_block - 1) / hash_per_block;
|
||||
s = (data_file_blocks + ((off_t)1 << ((i + 1) * hash_per_block_bits)) - 1) >> ((i + 1) * hash_per_block_bits);
|
||||
hash_level_size[i] = s;
|
||||
if (hash_position + s < hash_position ||
|
||||
(hash_position + s) < 0 ||
|
||||
(hash_position + s) != hash_position + s) {
|
||||
if ((hash_position + s) < hash_position ||
|
||||
(hash_position + s) < 0) {
|
||||
log_err(cd, _("Device offset overflow.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -288,18 +287,21 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
|
||||
log_dbg("Data device size required: %" PRIu64 " bytes.",
|
||||
data_device_size);
|
||||
data_file = fopen(data_device, "r");
|
||||
data_file = fopen(device_path(data_device), "r");
|
||||
if (!data_file) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), data_device);
|
||||
log_err(cd, _("Cannot open device %s.\n"),
|
||||
device_path(data_device)
|
||||
);
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg("Hash device size required: %" PRIu64 " bytes.",
|
||||
hash_device_size);
|
||||
hash_file = fopen(hash_device, verify ? "r" : "r+");
|
||||
hash_file = fopen(device_path(hash_device), verify ? "r" : "r+");
|
||||
if (!hash_file) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), hash_device);
|
||||
log_err(cd, _("Cannot open device %s.\n"),
|
||||
device_path(hash_device));
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -316,9 +318,10 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
if (r)
|
||||
goto out;
|
||||
} else {
|
||||
hash_file_2 = fopen(hash_device, "r");
|
||||
hash_file_2 = fopen(device_path(hash_device), "r");
|
||||
if (!hash_file_2) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), hash_device);
|
||||
log_err(cd, _("Cannot open device %s.\n"),
|
||||
device_path(hash_device));
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -378,16 +381,14 @@ out:
|
||||
/* Verify verity device using userspace crypto backend */
|
||||
int VERITY_verify(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
return VERITY_create_or_verify_hash(cd, 1,
|
||||
verity_hdr->hash_type,
|
||||
verity_hdr->hash_name,
|
||||
hash_device,
|
||||
data_device,
|
||||
crypt_metadata_device(cd),
|
||||
crypt_data_device(cd),
|
||||
verity_hdr->hash_block_size,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
@@ -401,8 +402,6 @@ int VERITY_verify(struct crypt_device *cd,
|
||||
/* Create verity hash */
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
@@ -418,8 +417,8 @@ int VERITY_create(struct crypt_device *cd,
|
||||
return VERITY_create_or_verify_hash(cd, 0,
|
||||
verity_hdr->hash_type,
|
||||
verity_hdr->hash_name,
|
||||
hash_device,
|
||||
data_device,
|
||||
crypt_metadata_device(cd),
|
||||
crypt_data_device(cd),
|
||||
verity_hdr->hash_block_size,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
*
|
||||
* 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.
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH CRYPTSETUP-REENCRYPT "8" "June 2012" "cryptsetup-reencrypt" "Maintenance Commands"
|
||||
.TH CRYPTSETUP-REENCRYPT "8" "December 2013" "cryptsetup-reencrypt" "Maintenance Commands"
|
||||
.SH NAME
|
||||
cryptsetup-reencrypt - tool for offline LUKS device re-encryption
|
||||
.SH SYNOPSIS
|
||||
@@ -67,6 +67,9 @@ you can destructively shrink device with \-\-reduce-device-size option.
|
||||
.TP
|
||||
.B "\-\-hash, \-h \fI<hash-spec>\fR"
|
||||
Specifies the hash used in the LUKS key setup scheme and volume key digest.
|
||||
|
||||
NOTE: if this parameter is not specified, default hash algorithm is always used
|
||||
for new device header.
|
||||
.TP
|
||||
.B "\-\-iter-time, \-i \fI<milliseconds>\fR"
|
||||
The number of milliseconds to spend with PBKDF2 passphrase processing for the
|
||||
@@ -100,6 +103,12 @@ Read a maximum of \fIvalue\fR bytes from the key file.
|
||||
Default is to read the whole file up to the compiled-in
|
||||
maximum.
|
||||
.TP
|
||||
.B "\-\-keep-key"
|
||||
Do not change encryption key, just reencrypt the LUKS header and keyslots.
|
||||
|
||||
This option can be combined only with \fI\-\-hash\fR or \fI\-\-iter-time\fR
|
||||
options.
|
||||
.TP
|
||||
.B "\-\-tries, \-T"
|
||||
Number of retries for invalid passphrase entry.
|
||||
.TP
|
||||
@@ -130,7 +139,7 @@ This means that last sectors on the original device will be lost,
|
||||
ciphertext data will be effectively shifted by specified
|
||||
number of sectors.
|
||||
|
||||
It can be usefull if you e.g. added some space to underlying
|
||||
It can be useful if you e.g. added some space to underlying
|
||||
partition (so last sectors contains no data).
|
||||
|
||||
For units suffix see \-\-device-size parameter description.
|
||||
@@ -151,7 +160,7 @@ WARNING: This is destructive operation and cannot be reverted.
|
||||
.B "\-\-use-directio"
|
||||
Use direct-io (O_DIRECT) for all read/write data operations.
|
||||
|
||||
Usefull if direct-io operations perform better than normal buffered
|
||||
Useful if direct-io operations perform better than normal buffered
|
||||
operations (e.g. in virtual environments).
|
||||
.TP
|
||||
.B "\-\-use-fsync"
|
||||
@@ -178,18 +187,20 @@ Reencrypt /dev/sdb1 (change volume key)
|
||||
cryptsetup-reencrypt /dev/sdb1
|
||||
.TP
|
||||
Reencrypt and also change cipher and cipher mode
|
||||
cryptsetup-reencrypt /dev/sdb1 -c aes-xts-plain64
|
||||
cryptsetup-reencrypt /dev/sdb1 \-c aes-xts-plain64
|
||||
.TP
|
||||
Add LUKS encryption to not yet encrypted device
|
||||
|
||||
First, be sure you have space added to disk.
|
||||
|
||||
Or alternatively shrink filesystem in advance.
|
||||
.br
|
||||
Here we need 4096 512-bytes sectors (enough for 2x128 bit key).
|
||||
|
||||
fdisk -u /dev/sdb # move sdb1 partition end + 4096 sectors
|
||||
fdisk \-u /dev/sdb # move sdb1 partition end + 4096 sectors
|
||||
(or use resize2fs or tool for your filesystem and shrink it)
|
||||
|
||||
cryptsetup-reencrypt /dev/sdb1 --new --reduce-device-size 4096
|
||||
cryptsetup-reencrypt /dev/sdb1 \-\-new \-\-reduce-device-size 4096S
|
||||
|
||||
.SH REPORTING BUGS
|
||||
Report bugs, including ones in the documentation, on
|
||||
@@ -200,9 +211,9 @@ Please attach the output of the failed command with the
|
||||
.SH AUTHORS
|
||||
Cryptsetup-reencrypt was written by Milan Broz <gmazyland@gmail.com>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012 Milan Broz
|
||||
Copyright \(co 2012-2014 Milan Broz
|
||||
.br
|
||||
Copyright \(co 2012 Red Hat, Inc.
|
||||
Copyright \(co 2012-2013 Red Hat, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
499
man/cryptsetup.8
499
man/cryptsetup.8
@@ -1,4 +1,4 @@
|
||||
.TH CRYPTSETUP "8" "May 2012" "cryptsetup" "Maintenance Commands"
|
||||
.TH CRYPTSETUP "8" "December 2013" "cryptsetup" "Maintenance Commands"
|
||||
.SH NAME
|
||||
cryptsetup - manage plain dm-crypt and LUKS encrypted volumes
|
||||
.SH SYNOPSIS
|
||||
@@ -10,6 +10,16 @@ device-mapper mappings. These include plain dm-crypt volumes and
|
||||
LUKS volumes. The difference is that LUKS uses a metadata header
|
||||
and can hence offer more features than plain dm-crypt. On the other
|
||||
hand, the header is visible and vulnerable to damage.
|
||||
|
||||
In addition, cryptsetup provides limited support for the use of
|
||||
historic loopaes volumes and for TruerCrypt compatible volumes.
|
||||
|
||||
.SH PLAIN DM-CRYPT OR LUKS?
|
||||
.PP
|
||||
Unless you understand the cryptographic background well, use LUKS.
|
||||
With plain dm-crypt there are a number of possible user errors
|
||||
that massively decrease security. While LUKS cannot fix them
|
||||
all, it can lessen the impact for many of them.
|
||||
.SH WARNINGS
|
||||
.PP
|
||||
A lot of good information on the risks of using encrypted storage,
|
||||
@@ -43,32 +53,51 @@ surprising frequency. This risk is the result of a trade-off
|
||||
between security and safety, as LUKS is designed for fast and
|
||||
secure wiping by just overwriting header and key-slot area.
|
||||
|
||||
.SH PLAIN MODE
|
||||
Plain dm-crypt encrypts the device sector-by-sector with a
|
||||
single, non-salted hash of the passphrase. No checks
|
||||
are performed, no metadata is used. There is no formatting operation.
|
||||
When the raw device is mapped (created), the usual device operations
|
||||
can be used on the mapped device, including filesystem creation.
|
||||
Mapped devices usually reside in /dev/mapper/<name>.
|
||||
\fBPreviously used partitions:\fR If a partition was previously used,
|
||||
it is a very good idea to wipe filesystem signatures, data, etc. before
|
||||
creating a LUKS or plain dm-crypt container on it.
|
||||
For a quick removal of filesystem signatures, use "wipefs". Take care
|
||||
though that this may not remove everything. In particular md (RAID)
|
||||
signatures at the end of a device may survive. It also does not
|
||||
remove data. For a full wipe, overwrite the whole partition before
|
||||
container creation. If you do not know how to to that, the
|
||||
cryptsetup FAQ describes several options.
|
||||
|
||||
There are four operations:
|
||||
.SH BASIC COMMANDS
|
||||
The following are valid actions for all supported device types.
|
||||
|
||||
\fIcreate\fR <name> <device>
|
||||
\fIopen\fR <device> <name> \-\-type <device_type>
|
||||
.IP
|
||||
Creates a mapping with <name> backed by device <device>.
|
||||
Opens (creates a mapping with) <name> backed by device <device>.
|
||||
|
||||
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify-passphrase,
|
||||
\-\-key-file, \-\-keyfile-offset, \-\-key-size, \-\-offset, \-\-skip, \-\-size,
|
||||
\-\-readonly, \-\-shared, \-\-allow-discards]
|
||||
Device type can be \fIplain\fR, \fIluks\fR (default), \fIloopaes\fR
|
||||
or \fItcrypt\fR.
|
||||
|
||||
Example: 'cryptsetup create e1 /dev/sda10' maps the raw
|
||||
encrypted device /dev/sda10 to the mapped (decrypted) device
|
||||
/dev/mapper/e1, which can then be mounted, fsck-ed or have a
|
||||
filesystem created on it.
|
||||
For backward compatibility there are \fBopen\fR command aliases:
|
||||
|
||||
\fBcreate\fR (argument-order <name> <device>): open \-\-type plain
|
||||
.br
|
||||
\fBplainOpen\fR: open \-\-type plain
|
||||
.br
|
||||
\fBluksOpen\fR: open \-\-type luks
|
||||
.br
|
||||
\fBloopaesOpen\fR: open \-\-type loopaes
|
||||
.br
|
||||
\fBtcryptOpen\fR: open \-\-type tcrypt
|
||||
|
||||
\fB<options>\fR are type specific and are described below
|
||||
for individual device types. For \fBcreate\fR, the order of the <name>
|
||||
and <device> options is inverted for historical reasons, all other
|
||||
aliases use the standard \fB<device> <name>\fR order.
|
||||
.PP
|
||||
\fIremove\fR <name>
|
||||
\fIclose\fR <name>
|
||||
.IP
|
||||
Removes the existing mapping <name> and wipes the key from kernel memory.
|
||||
|
||||
For backward compatibility there are \fBclose\fR command aliases:
|
||||
\fBremove\fR, \fBplainClose\fR, \fBluksClose\fR, \fBloopaesClose\fR,
|
||||
\fBtcryptClose\fR (all behaves exactly the same, device type is
|
||||
determined automatically from active device).
|
||||
.PP
|
||||
\fIstatus\fR <name>
|
||||
.IP
|
||||
@@ -82,6 +111,30 @@ If \-\-size (in sectors) is not specified, the size of the
|
||||
underlying block device is used. Note that this does not
|
||||
change the raw device geometry, it just changes how many
|
||||
sectors of the raw device are represented in the mapped device.
|
||||
.SH PLAIN MODE
|
||||
Plain dm-crypt encrypts the device sector-by-sector with a
|
||||
single, non-salted hash of the passphrase. No checks
|
||||
are performed, no metadata is used. There is no formatting operation.
|
||||
When the raw device is mapped (opened), the usual device operations
|
||||
can be used on the mapped device, including filesystem creation.
|
||||
Mapped devices usually reside in /dev/mapper/<name>.
|
||||
|
||||
The following are valid plain device type actions:
|
||||
|
||||
\fIopen\fR \-\-type plain <device> <name>
|
||||
.br
|
||||
\fIcreate\fR <name> <device> (\fBOBSOLETE syntax\fR)
|
||||
.IP
|
||||
Opens (creates a mapping with) <name> backed by device <device>.
|
||||
|
||||
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify-passphrase,
|
||||
\-\-key-file, \-\-keyfile-offset, \-\-key-size, \-\-offset, \-\-skip, \-\-size,
|
||||
\-\-readonly, \-\-shared, \-\-allow-discards]
|
||||
|
||||
Example: 'cryptsetup open \-\-type plain /dev/sda10 e1' maps the raw
|
||||
encrypted device /dev/sda10 to the mapped (decrypted) device
|
||||
/dev/mapper/e1, which can then be mounted, fsck-ed or have a
|
||||
filesystem created on it.
|
||||
.SH LUKS EXTENSION
|
||||
LUKS, the Linux Unified Key Setup, is a standard for disk encryption.
|
||||
It adds a standardized header at the start of the device,
|
||||
@@ -123,17 +176,20 @@ from stdin and the safety-question being skipped.
|
||||
|
||||
You can only call luksFormat on a LUKS device that is not mapped.
|
||||
|
||||
\fB<options>\fR can be [\-\-cipher, \-\-verify-passphrase, \-\-key-size,
|
||||
\-\-key-slot, \-\-key-file (takes precedence over optional second argument),
|
||||
\-\-keyfile-offset, \-\-keyfile-size, \-\-use-random | \-\-use-urandom,
|
||||
\-\-uuid,
|
||||
\-\-master-key-file].
|
||||
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify\-passphrase,
|
||||
\-\-key\-size, \-\-key\-slot,
|
||||
\-\-key\-file (takes precedence over optional second argument),
|
||||
\-\-keyfile\-offset, \-\-keyfile\-size, \-\-use\-random | \-\-use\-urandom,
|
||||
\-\-uuid, \-\-master\-key\-file, \-\-iter\-time, \-\-header,
|
||||
\-\-force\-password].
|
||||
|
||||
\fBWARNING:\fR Doing a luksFormat on an existing LUKS container will
|
||||
make all data the old container permanently irretrievable, unless
|
||||
you have a header backup.
|
||||
.PP
|
||||
\fIluksOpen\fR <device> <name>
|
||||
\fIopen\fR \-\-type luks <device> <name>
|
||||
.br
|
||||
\fIluksOpen\fR <device> <name> (\fBold syntax\fR)
|
||||
.IP
|
||||
Opens the LUKS device <device> and sets up a mapping <name> after
|
||||
successful verification of the supplied passphrase.
|
||||
@@ -143,13 +199,9 @@ prompts for it interactively.
|
||||
The <device> parameter can be also specified by LUKS UUID in the
|
||||
format UUID=<uuid>, which uses the symlinks in /dev/disk/by-uuid.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-readonly, \-\-test-passphrase,
|
||||
\-\-allow-discards, \-\-header, \-\-key-slot, \-\-master-key-file].
|
||||
.PP
|
||||
\fIluksClose\fR <name>
|
||||
.IP
|
||||
identical to \fIremove\fR.
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size, \-\-readonly, \-\-test\-passphrase,
|
||||
\-\-allow\-discards, \-\-header, \-\-key-slot, \-\-master\-key\-file].
|
||||
.PP
|
||||
\fIluksSuspend\fR <name>
|
||||
.IP
|
||||
@@ -159,7 +211,7 @@ and wipes the encryption
|
||||
key from kernel memory. Needs kernel 2.6.19 or later.
|
||||
|
||||
After this operation you have to use \fIluksResume\fR to reinstate
|
||||
the encryption key and unblock the device or \fIluksClose\fR to remove
|
||||
the encryption key and unblock the device or \fIclose\fR to remove
|
||||
the mapped device.
|
||||
|
||||
\fBWARNING:\fR never suspend the device on which the cryptsetup binary resides.
|
||||
@@ -171,7 +223,7 @@ the mapped device.
|
||||
Resumes a suspended device and reinstates the encryption key.
|
||||
Prompts interactively for a passphrase if \-\-key-file is not given.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-header]
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-size, \-\-header]
|
||||
.PP
|
||||
\fIluksAddKey\fR <device> [<key file with new key>]
|
||||
.IP
|
||||
@@ -180,9 +232,10 @@ interactively or via \-\-key-file.
|
||||
The new passphrase to be added can be specified interactively
|
||||
or read from the file given as positional argument.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-new-keyfile-offset,
|
||||
\-\-new-keyfile-size, \-\-key-slot, \-\-master-key-file].
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size, \-\-new\-keyfile\-offset,
|
||||
\-\-new\-keyfile\-size, \-\-key\-slot, \-\-master\-key\-file,
|
||||
\-\-iter\-time, \-\-force\-password].
|
||||
.PP
|
||||
\fIluksRemoveKey\fR <device> [<key file with passphrase to be removed>]
|
||||
.IP
|
||||
@@ -190,12 +243,12 @@ Removes the supplied passphrase from the LUKS device. The
|
||||
passphrase to be removed can be specified interactively,
|
||||
as positional argument or via \-\-key-file.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size]
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size]
|
||||
|
||||
\fBWARNING:\fR If you read the passphrase from stdin
|
||||
(without further argument or with '-' as argument
|
||||
to \-\-key-file), batch-mode (-q) will be implicitely
|
||||
to \-\-key\-file), batch-mode (\-q) will be implicitely
|
||||
switched on and no warning will be given when you remove the
|
||||
last remaining passphrase from a LUKS container. Removing
|
||||
the last passphrase makes the LUKS container permanently
|
||||
@@ -204,7 +257,7 @@ inaccessible.
|
||||
\fIluksChangeKey\fR <device> [<new key file>]
|
||||
.IP
|
||||
Changes an existing passphrase. The passphrase
|
||||
to be changed must be supplied interactively or via \-\-key-file.
|
||||
to be changed must be supplied interactively or via \-\-key\-file.
|
||||
The new passphrase can be supplied interactively or in
|
||||
a file given as positional argument.
|
||||
|
||||
@@ -222,9 +275,9 @@ during this operation can cause the overwrite to fail after
|
||||
the old passphrase has been wiped and make the LUKS container
|
||||
inaccessible.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-new-keyfile-offset,
|
||||
\-\-new-keyfile-size, \-\-key-slot].
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size, \-\-new\-keyfile\-offset,
|
||||
\-\-new\-keyfile\-size, \-\-key\-slot, \-\-force\-password].
|
||||
.PP
|
||||
\fIluksKillSlot\fR <device> <key slot number>
|
||||
.IP
|
||||
@@ -234,16 +287,26 @@ This command can remove the last remaining key-slot, but requires
|
||||
an interactive confirmation when doing so. Removing the last
|
||||
passphrase makes a LUKS container permanently inaccessible.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset, \-\-keyfile-size].
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
|
||||
\-\-keyfile\-size].
|
||||
|
||||
\fBWARNING:\fR If you read the passphrase from stdin
|
||||
(without further argument or with '-' as argument
|
||||
to \-\-key-file), batch-mode (-q) will be implicitely
|
||||
to \-\-key-file), batch-mode (\-q) will be implicitely
|
||||
switched on and no warning will be given when you remove the
|
||||
last remaining passphrase from a LUKS container. Removing
|
||||
the last passphrase makes the LUKS container permanently
|
||||
inaccessible.
|
||||
.PP
|
||||
\fIerase\fR <device>
|
||||
.br
|
||||
\fIluksErase\fR <device>
|
||||
.IP
|
||||
Erase all keyslots and make the LUKS container permanently inaccessible.
|
||||
You do not need to provide any password for this operation.
|
||||
|
||||
\fBWARNING:\fR This operation is irreversible.
|
||||
.PP
|
||||
\fIluksUUID\fR <device>
|
||||
.IP
|
||||
Print the UUID of a LUKS device.
|
||||
@@ -260,7 +323,7 @@ means the device is a LUKS device.
|
||||
.IP
|
||||
Dump the header information of a LUKS device.
|
||||
|
||||
If the \-\-dump-master-key option is used, the LUKS device master key is
|
||||
If the \-\-dump\-master\-key option is used, the LUKS device master key is
|
||||
dumped instead of the keyslot info. Beware that the master key cannot be
|
||||
changed and can be used to decrypt the data stored in the LUKS container
|
||||
without a passphrase and even without the LUKS header. This means
|
||||
@@ -268,16 +331,16 @@ that if the master key is compromised, the whole device has to be
|
||||
erased to prevent further access. Use this option carefully.
|
||||
|
||||
In order to dump the master key, a passphrase has to be supplied,
|
||||
either interactively or via \-\-key-file.
|
||||
either interactively or via \-\-key\-file.
|
||||
|
||||
\fB<options>\fR can be [\-\-dump-master-key, \-\-key-file,
|
||||
\-\-keyfile-offset, \-\-keyfile-size].
|
||||
\fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
|
||||
\-\-keyfile\-offset, \-\-keyfile\-size].
|
||||
|
||||
\fBWARNING:\fR If \-\-dump-master-key is used with \-\-key-file
|
||||
and the argument to \-\-key-file is '-', no validation question
|
||||
\fBWARNING:\fR If \-\-dump\-master\-key is used with \-\-key\-file
|
||||
and the argument to \-\-key\-file is '-', no validation question
|
||||
will be asked and no warning given.
|
||||
.PP
|
||||
\fIluksHeaderBackup\fR <device> \-\-header-backup-file <file>
|
||||
\fIluksHeaderBackup\fR <device> \-\-header\-backup\-file <file>
|
||||
.IP
|
||||
Stores a binary backup of the LUKS header and keyslot area.
|
||||
.br
|
||||
@@ -294,7 +357,7 @@ addition or overwrite the encrypted data area as well.
|
||||
The second option is less secure, as some sectors
|
||||
can survive, e.g. due to defect management.
|
||||
.PP
|
||||
\fIluksHeaderRestore\fR <device> \-\-header-backup-file <file>
|
||||
\fIluksHeaderRestore\fR <device> \-\-header\-backup\-file <file>
|
||||
.IP
|
||||
Restores a binary backup of the LUKS header and keyslot area
|
||||
from the specified file.
|
||||
@@ -308,32 +371,23 @@ This command requires that the master key size and data offset
|
||||
of the LUKS header already on the device and of the header backup
|
||||
match. Alternatively, if there is no LUKS header on the device,
|
||||
the backup will also be written to it.
|
||||
.PP
|
||||
\fIrepair\fR <device>
|
||||
.IP
|
||||
Tries to repair the LUKS device metadata if possible.
|
||||
|
||||
This command is useful to fix some known benign LUKS metadata
|
||||
header corruptions. Only basic corruptions of unused keyslot
|
||||
are fixable. This command will only change the LUKS header, not
|
||||
any key-slot data.
|
||||
|
||||
\fBWARNING:\fR Always create a binary backup of the original
|
||||
header before calling this command.
|
||||
.SH loop-AES EXTENSION
|
||||
cryptsetup supports mapping loop-AES encrypted partition using
|
||||
a compatibility mode.
|
||||
.PP
|
||||
\fIloopaesOpen\fR <device> <name> \-\-key-file <keyfile>
|
||||
\fIopen\fR \-\-type loopaes <device> <name> \-\-key\-file <keyfile>
|
||||
.br
|
||||
\fIloopaesOpen\fR <device> <name> \-\-key\-file <keyfile> (\fBold syntax\fR)
|
||||
.IP
|
||||
Opens the loop-AES <device> and sets up a mapping <name>.
|
||||
|
||||
If the key file is encrypted with GnuPG, then you have to use
|
||||
\-\-key-file=- and decrypt it before use, e.g. like this:
|
||||
\-\-key\-file=\- and decrypt it before use, e.g. like this:
|
||||
.br
|
||||
gpg \-\-decrypt <keyfile> | cryptsetup loopaesOpen \-\-key-file=- <device> <name>
|
||||
gpg \-\-decrypt <keyfile> | cryptsetup loopaesOpen \-\-key\-file=\-
|
||||
<device> <name>
|
||||
|
||||
Use \fB\-\-key-file-size\fR to specify the proper key length if needed.
|
||||
Use \fB\-\-keyfile\-size\fR to specify the proper key length if needed.
|
||||
|
||||
Use \fB\-\-offset\fR to specify device offset. Note that the units
|
||||
need to be specified in number of 512 byte sectors.
|
||||
@@ -347,15 +401,141 @@ Use \fB\-\-hash\fR to override the default hash function for
|
||||
passphrase hashing (otherwise it is detected according to key
|
||||
size).
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-key-size, \-\-offset, \-\-skip,
|
||||
\-\-hash, \-\-readonly, \-\-allow-discards].
|
||||
.PP
|
||||
\fIloopaesClose\fR <name>
|
||||
.IP
|
||||
Identical to \fIremove\fR.
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-key\-size, \-\-offset, \-\-skip,
|
||||
\-\-hash, \-\-readonly, \-\-allow\-discards].
|
||||
.PP
|
||||
See also section 7 of the FAQ and \fBhttp://loop-aes.sourceforge.net\fR
|
||||
for more information regarding loop-AES.
|
||||
.SH TCRYPT (TrueCrypt-compatible) EXTENSION
|
||||
cryptsetup supports mapping of TrueCrypt or tcplay encrypted partition
|
||||
using a native Linux kernel API.
|
||||
Header formatting and TCRYPT header change is not supported, cryptsetup
|
||||
never changes TCRYPT header on-device.
|
||||
|
||||
TCRYPT extension requires kernel userspace
|
||||
crypto API to be available (introduced in Linux kernel 2.6.38).
|
||||
If you are configuring kernel yourself, enable
|
||||
"User-space interface for symmetric key cipher algorithms" in
|
||||
"Cryptographic API" section (CRYPTO_USER_API_SKCIPHER .config option).
|
||||
|
||||
Because TCRYPT header is encrypted, you have to always provide valid
|
||||
passphrase and keyfiles.
|
||||
|
||||
Cryptsetup should recognize all header variants, except legacy cipher chains
|
||||
using LRW encryption mode with 64 bits encryption block (namely Blowfish
|
||||
in LRW mode is not recognized, this is limitation of kernel crypto API).
|
||||
|
||||
\fBNOTE:\fR Activation with \fBtcryptOpen\fR is supported only for cipher chains
|
||||
using LRW or XTS encryption modes.
|
||||
|
||||
The \fBtcryptDump\fR command should work for all recognized TCRYPT devices
|
||||
and doesn't require superuser privilege.
|
||||
|
||||
To map system device (device with boot loader where the whole encrypted
|
||||
system resides) use \fB\-\-tcrypt\-system\fR option.
|
||||
You can use partition device as the parameter (parameter must be real partition
|
||||
device, not image in file), then only this partition is mapped.
|
||||
|
||||
If you have whole TCRYPT device as a file image and you want to map multiple
|
||||
partition encrypted with system encryption, please create loopback mapping
|
||||
with partitions first (\fBlosetup \-P\fR, see \fPlosetup(8)\fR man page for more info),
|
||||
and use loop partition as the device parameter.
|
||||
|
||||
If you use whole base device as parameter, one device for the whole system
|
||||
encryption is mapped. This mode is available only for backward compatibility
|
||||
with older cryptsetup versions which mapped TCRYPT system encryption
|
||||
using whole device.
|
||||
|
||||
To use hidden header (and map hidden device, if available),
|
||||
use \fB\-\-tcrypt\-hidden\fR option.
|
||||
|
||||
To explicitly use backup (secondary) header, use \fB\-\-tcrypt\-backup\fR
|
||||
option.
|
||||
|
||||
\fBNOTE:\fR There is no protection for a hidden volume if
|
||||
the outer volume is mounted. The reason is that if there
|
||||
were any protection, it would require some metadata describing
|
||||
what to protect in the outer volume and the hidden volume would
|
||||
become detectable.
|
||||
|
||||
.PP
|
||||
\fIopen\fR \-\-type tcrypt <device> <name>
|
||||
.br
|
||||
\fItcryptOpen\fR <device> <name> (\fBold syntax\fR)
|
||||
.IP
|
||||
Opens the TCRYPT (a TrueCrypt-compatible) <device> and sets up
|
||||
a mapping <name>.
|
||||
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-tcrypt\-hidden,
|
||||
\-\-tcrypt\-system, \-\-tcrypt\-backup, \-\-readonly, \-\-test\-passphrase,
|
||||
\-\-allow-discards].
|
||||
|
||||
The keyfile parameter allows combination of file content with the
|
||||
passphrase and can be repeated. Note that using keyfiles is compatible
|
||||
with TCRYPT and is different from LUKS keyfile logic.
|
||||
|
||||
\fBWARNING:\fR Option \fB\-\-allow\-discards\fR cannot be combined with
|
||||
option \fB\-\-tcrypt\-hidden\fR. For normal mapping it can cause
|
||||
\fBdestruction of hidden volume\fR (hidden volume appears as unused space
|
||||
for outer volume so this space can be discarded).
|
||||
|
||||
.PP
|
||||
\fItcryptDump\fR <device>
|
||||
.IP
|
||||
Dump the header information of a TCRYPT device.
|
||||
|
||||
If the \-\-dump\-master\-key option is used, the TCRYPT device master key
|
||||
is dumped instead of TCRYPT header info. Beware that the master key
|
||||
(or concatenated master keys if cipher chain is used)
|
||||
can be used to decrypt the data stored in the TCRYPT container without
|
||||
a passphrase.
|
||||
This means that if the master key is compromised, the whole device has
|
||||
to be erased to prevent further access. Use this option carefully.
|
||||
|
||||
\fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
|
||||
\-\-tcrypt\-hidden, \-\-tcrypt\-system, \-\-tcrypt\-backup].
|
||||
|
||||
The keyfile parameter allows combination of file content with the
|
||||
passphrase and can be repeated.
|
||||
.PP
|
||||
See also \fBhttp://www.truecrypt.org\fR for more information regarding
|
||||
TrueCrypt.
|
||||
|
||||
Please note that cryptsetup does not use TrueCrypt code, please report
|
||||
all problems related to this compatibility extension to cryptsetup project.
|
||||
.SH MISCELLANEOUS
|
||||
.PP
|
||||
\fIrepair\fR <device>
|
||||
.IP
|
||||
Tries to repair the device metadata if possible. Currently supported only
|
||||
for LUKS device type.
|
||||
|
||||
This command is useful to fix some known benign LUKS metadata
|
||||
header corruptions. Only basic corruptions of unused keyslot
|
||||
are fixable. This command will only change the LUKS header, not
|
||||
any key-slot data.
|
||||
|
||||
\fBWARNING:\fR Always create a binary backup of the original
|
||||
header before calling this command.
|
||||
.PP
|
||||
\fIbenchmark\fR <options>
|
||||
.IP
|
||||
Benchmarks ciphers and KDF (key derivation function).
|
||||
Without parameters it tries to measure few common configurations.
|
||||
|
||||
To benchmark other ciphers or modes, you need to specify \fB\-\-cipher\fR
|
||||
and \fB\-\-key\-size\fR options or \fB\-\-hash\fR for KDF test.
|
||||
|
||||
\fBNOTE:\fR This benchmark is using memory only and is only informative.
|
||||
You cannot directly predict real storage encryption speed from it.
|
||||
|
||||
For testing block ciphers, this benchmark requires kernel userspace
|
||||
crypto API to be available (introduced in Linux kernel 2.6.38).
|
||||
If you are configuring kernel yourself, enable
|
||||
"User-space interface for symmetric key cipher algorithms" in
|
||||
"Cryptographic API" section (CRYPTO_USER_API_SKCIPHER .config option).
|
||||
|
||||
\fB<options>\fR can be [\-\-cipher, \-\-key\-size, \-\-hash].
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B "\-\-verbose, \-v"
|
||||
@@ -365,11 +545,13 @@ Print more information on command execution.
|
||||
Run in debug mode with full diagnostic logs. Debug output
|
||||
lines are always prefixed by '#'.
|
||||
.TP
|
||||
.B "\-\-hash, \-h \fI<hash-spec>\fR"
|
||||
Specifies the passphrase hash for \fIcreate\fR and \fIloopaesOpen\fR.
|
||||
.B "\-\-hash, \-h \fI<hash\-spec>\fR"
|
||||
Specifies the passphrase hash for \fIopen\fR (for plain and
|
||||
loopaes device types).
|
||||
|
||||
Specifies the hash used in the LUKS key setup scheme and volume key digest
|
||||
for \fIluksFormat\fR.
|
||||
for \fIluksFormat\fR. The specified hash is used as hash-parameter
|
||||
for PBKDF2 and for the AF splitter.
|
||||
|
||||
The specified hash name is passed to the compiled-in crypto backend.
|
||||
Different backends may support different hashes.
|
||||
@@ -379,21 +561,25 @@ excludes, e.g., MD5. Do not use a non-crypto hash like
|
||||
\fB"crc32"\fR as this breaks security.
|
||||
|
||||
Values compatible with old version of cryptsetup are
|
||||
\fB"ripemd160"\fR for \fIcreate\fR and
|
||||
\fB"ripemd160"\fR for \fIopen \-\-type plain\fR and
|
||||
\fB"sha1"\fR for \fIluksFormat\fR.
|
||||
|
||||
Use \fIcryptsetup \-\-help\fR to show the defaults.
|
||||
.TP
|
||||
.B "\-\-cipher, \-c \fI<cipher-spec>\fR"
|
||||
.B "\-\-cipher, \-c \fI<cipher\-spec>\fR"
|
||||
Set the cipher specification string.
|
||||
|
||||
\fIcryptsetup \-\-help\fR shows the compiled-in defaults.
|
||||
The current default in the distributed sources is
|
||||
"aes-cbc-essiv:sha256" for both plain dm-crypt and LUKS.
|
||||
"aes-cbc-essiv:sha256" for plain dm-crypt and
|
||||
"aes-xts-plain64" for LUKS.
|
||||
|
||||
For XTS mode (a possible future default), use "aes-xts-plain"
|
||||
or better "aes-xts-plain64"
|
||||
as cipher specification and optionally set a key size of
|
||||
If a hash is part of the cipher spefification, then it is
|
||||
used as part of the IV generation. For example, ESSIV
|
||||
needs a hash function, while "plain64" does not and
|
||||
hence none is specified.
|
||||
|
||||
For XTS mode you can optionally set a key size of
|
||||
512 bits with the \-s option. Key size for XTS
|
||||
mode is twice that for other modes for the same
|
||||
security level.
|
||||
@@ -405,7 +591,7 @@ kernel 2.6.33 or later. More information can be found in the FAQ.
|
||||
When interactively asking for a passphrase, ask for it twice
|
||||
and complain if both inputs do not match. Advised when creating
|
||||
a regular mapping for the first time, or when running
|
||||
\fIluksFormat\fR. Ignores on input from file or stdin.
|
||||
\fIluksFormat\fR. Ignored on input from file or stdin.
|
||||
.TP
|
||||
.B "\-\-key-file, \-d \fIname\fR"
|
||||
Read the passphrase from file.
|
||||
@@ -413,9 +599,9 @@ Read the passphrase from file.
|
||||
If the name given is "-", then the passphrase will be read from stdin.
|
||||
In this case, reading will not stop at newline characters.
|
||||
|
||||
With LUKS, passphrases supplied via \-\-key-file are always
|
||||
With LUKS, passphrases supplied via \-\-key\-file are always
|
||||
the existing passphrases requested by a command, except in
|
||||
the case of \fIluksFormat\fR where \-\-key-file is equivalent
|
||||
the case of \fIluksFormat\fR where \-\-key\-file is equivalent
|
||||
to the positional key file argument.
|
||||
|
||||
If you want to set a new passphrase via key file, you have to
|
||||
@@ -423,37 +609,37 @@ use a positional argument to \fIluksAddKey\fR.
|
||||
|
||||
See section \fBNOTES ON PASSPHRASE PROCESSING\fR for more information.
|
||||
.TP
|
||||
.B "\-\-keyfile-offset \fIvalue\fR"
|
||||
.B "\-\-keyfile\-offset \fIvalue\fR"
|
||||
Skip \fIvalue\fR bytes at the beginning of the key file.
|
||||
Works with all commands that accepts key files.
|
||||
.TP
|
||||
.B "\-\-keyfile-size, \-l \fIvalue\fR"
|
||||
.B "\-\-keyfile\-size, \-l \fIvalue\fR"
|
||||
Read a maximum of \fIvalue\fR bytes from the key file.
|
||||
Default is to read the whole file up to the compiled-in
|
||||
maximum that can be queried with \-\-help. Supplying more
|
||||
data than the compiled-in maximum aborts the operation.
|
||||
|
||||
This option is useful
|
||||
to cut trailing newlines, for example. If \-\-keyfile-offset
|
||||
to cut trailing newlines, for example. If \-\-keyfile\-offset
|
||||
is also given, the size count starts after the offset.
|
||||
Works with all commands that accepts key files.
|
||||
.TP
|
||||
.B "\-\-new-keyfile-offset \fIvalue\fR"
|
||||
.B "\-\-new\-keyfile\-offset \fIvalue\fR"
|
||||
Skip \fIvalue\fR bytes at the start when
|
||||
adding a new passphrase from key file with
|
||||
\fIluksAddKey\fR.
|
||||
.TP
|
||||
.B "\-\-new-keyfile-size \fIvalue\fR"
|
||||
.B "\-\-new\-keyfile\-size \fIvalue\fR"
|
||||
Read a maximum of \fIvalue\fR bytes when adding
|
||||
a new passphrase from key file with \fIluksAddKey\fR.
|
||||
Default is to read the whole file up to the compiled-in
|
||||
maximum length that can be queried with \-\-help.
|
||||
Supplying more than the compiled in maximum aborts the
|
||||
operation.
|
||||
When \-\-new-keyfile-offset is also given, reading starts
|
||||
When \-\-new\-keyfile\-offset is also given, reading starts
|
||||
after the offset.
|
||||
.TP
|
||||
.B "\-\-master-key-file"
|
||||
.B "\-\-master\-key\-file"
|
||||
Use a master key stored in a file.
|
||||
|
||||
For \fIluksFormat\fR this
|
||||
@@ -463,20 +649,25 @@ LUKS header and all other parameters are the same,
|
||||
then the new header decrypts the data encrypted with the
|
||||
header the master key was taken from.
|
||||
|
||||
\fBWARNING:\fR If you create your own master key, you
|
||||
need to make sure to do it right. Otherwise you can end
|
||||
up with a low-entropy or otherwise partially predictable
|
||||
master key which will compromise security.
|
||||
|
||||
For \fIluksAddKey\fR this allows adding a new passphrase
|
||||
without having to know an exiting one.
|
||||
|
||||
For \fIluksOpen\fR this allows to open the LUKS device
|
||||
For \fIopen\fR this allows one to open the LUKS device
|
||||
without giving a passphrase.
|
||||
.TP
|
||||
.B "\-\-dump-master-key"
|
||||
.B "\-\-dump\-master\-key"
|
||||
For \fIluksDump\fR this option includes the master key in the displayed
|
||||
information. Use with care, as the master key can be used to
|
||||
bypass the passphrases, see also option \-\-master-key-file.
|
||||
bypass the passphrases, see also option \-\-master\-key\-file.
|
||||
.TP
|
||||
.B "\-\-use-random"
|
||||
.B "\-\-use\-random"
|
||||
.TP
|
||||
.B "\-\-use-urandom"
|
||||
.B "\-\-use\-urandom"
|
||||
For \fIluksFormat\fR these options define which kernel random number
|
||||
generator will be used to create the master key (which is a
|
||||
long-term key).
|
||||
@@ -492,18 +683,18 @@ Using /dev/random can block a long time, potentially
|
||||
forever, if not enough entropy can be harvested by
|
||||
the kernel.
|
||||
.TP
|
||||
.B "\-\-key-slot, \-S <0-7>"
|
||||
.B "\-\-key\-slot, \-S <0\-7>"
|
||||
For LUKS operations that add key material, this options allows you
|
||||
to specify which key slot is selected for the new key.
|
||||
This option can be used for \fIluksFormat\fR,
|
||||
and \fIluksAddKey\fR.
|
||||
.br
|
||||
In addition, for \fIluksOpen\fR, this option selects a
|
||||
In addition, for \fIopen\fR, this option selects a
|
||||
specific key-slot to compare the passphrase against.
|
||||
If the given passphrase would only match a different key-slot,
|
||||
the operation fails.
|
||||
.TP
|
||||
.B "\-\-key-size, \-s <bits>"
|
||||
.B "\-\-key\-size, \-s <bits>"
|
||||
Sets key size in bits. The argument has to be a multiple of
|
||||
8. The possible key-sizes are limited by the cipher and
|
||||
mode used.
|
||||
@@ -511,31 +702,29 @@ mode used.
|
||||
See /proc/crypto for more information. Note that key-size
|
||||
in /proc/crypto is stated in bytes.
|
||||
|
||||
This option can be used for \fIcreate\fR or \fIluksFormat\fR. All
|
||||
other LUKS actions will use the key-size specified in the LUKS header.
|
||||
This option can be used for \fIopen \-\-type plain\fR or \fIluksFormat\fR.
|
||||
All other LUKS actions will use the key-size specified in the LUKS header.
|
||||
Use \fIcryptsetup \-\-help\fR to show the compiled-in defaults.
|
||||
.TP
|
||||
.B "\-\-size, \-b <number of 512 byte sectors>"
|
||||
Force the size of the underlying device in sectors of 512 bytes.
|
||||
This option is only relevant for the \fIcreate\fR and \fIresize\fR
|
||||
This option is only relevant for the \fIopen\fR and \fIresize\fR
|
||||
actions.
|
||||
.TP
|
||||
.B "\-\-offset, \-o <number of 512 byte sectors>"
|
||||
Start offset in the backend device in 512-byte sectors.
|
||||
This option is only relevant for the \fIcreate\fR and \fIloopaesOpen\fR
|
||||
actions.
|
||||
This option is only relevant for the \fIopen\fR action with plain
|
||||
or loopaes device types.
|
||||
.TP
|
||||
.B "\-\-skip, \-p <number of 512 byte sectors>"
|
||||
How many sectors of the encrypted data to skip at the beginning.
|
||||
This option is only relevant for \fIcreate\fR and \fIloopaesOpen\fR action.
|
||||
Start offset used in IV calculation in 512-byte sectors
|
||||
(how many sectors of the encrypted data to skip at the beginning).
|
||||
This option is only relevant for the \fIopen\fR action with plain
|
||||
or loopaes device types.
|
||||
|
||||
This is different from the \-\-offset options with respect to
|
||||
the sector numbers used in IV calculation.
|
||||
Using \-\-offset will shift the IV calculation by the same negative amount.
|
||||
Hence, if \-\-offset \fIn\fR, sector \fIn\fR will get a sector
|
||||
number of \fI0\fR for the IV calculation.
|
||||
Using \-\-skip causes sector \fIn\fR to also be the first sector
|
||||
of the mapped device, but with its number for IV generation is \fIn\fR.
|
||||
Hence, if \-\-offset \fIn\fR, and \-\-skip \fIs\fR, sector \fIn\fR
|
||||
(the first sector of encrypted device) will get a sector number
|
||||
of \fIs\fR for the IV calculation.
|
||||
.TP
|
||||
.B "\-\-readonly, \-r"
|
||||
set up a read-only mapping.
|
||||
@@ -544,16 +733,16 @@ set up a read-only mapping.
|
||||
Creates an additional mapping for one common
|
||||
ciphertext device. Arbitrary mappings are supported.
|
||||
This option is only relevant for the
|
||||
\fIcreate\fR action. Use \-\-offset, \-\-size and \-\-skip to
|
||||
\fIopen \-\-type plain\fR action. Use \-\-offset, \-\-size and \-\-skip to
|
||||
specify the mapped area.
|
||||
.TP
|
||||
.B "\-\-iter-time, \-i <number of milliseconds>"
|
||||
.B "\-\-iter\-time, \-i <number of milliseconds>"
|
||||
The number of milliseconds to spend with PBKDF2 passphrase processing.
|
||||
This option is only relevant for LUKS operations that set or change
|
||||
passphrases, such as \fIluksFormat\fR or \fIluksAddKey\fR.
|
||||
Specifying 0 as parameter selects the compiled-in default.
|
||||
.TP
|
||||
.B "\-\-batch-mode, \-q"
|
||||
.B "\-\-batch\-mode, \-q"
|
||||
Suppresses all confirmation questions. Use with care!
|
||||
|
||||
If the \-y option is not specified, this option also switches off
|
||||
@@ -562,9 +751,8 @@ the passphrase verification for \fIluksFormat\fR.
|
||||
.B "\-\-timeout, \-t <number of seconds>"
|
||||
The number of seconds to wait before timeout on passphrase input
|
||||
via terminal. It is relevant every time a passphrase is asked,
|
||||
for example for \fIcreate\fR, \fIluksOpen\fR, \fIluksFormat\fR
|
||||
or \fIluksAddKey\fR. It has no effect if used in conjunction
|
||||
with \-\-key-file.
|
||||
for example for \fIopen\fR, \fIluksFormat\fR or \fIluksAddKey\fR.
|
||||
It has no effect if used in conjunction with \-\-key-file.
|
||||
.br
|
||||
This option is useful when the system
|
||||
should not stall if the user does not input a passphrase,
|
||||
@@ -575,10 +763,10 @@ which means to wait forever.
|
||||
How often the input of the passphrase shall be retried.
|
||||
This option is relevant
|
||||
every time a passphrase is asked, for example for
|
||||
\fIcreate\fR, \fIluksOpen\fR, \fIluksFormat\fR
|
||||
or \fIluksAddKey\fR. The default is 3 tries.
|
||||
\fIopen\fR, \fIluksFormat\fR or \fIluksAddKey\fR.
|
||||
The default is 3 tries.
|
||||
.TP
|
||||
.B "\-\-align-payload <number of 512 byte sectors>"
|
||||
.B "\-\-align\-payload <number of 512 byte sectors>"
|
||||
Align payload at a boundary of \fIvalue\fR 512-byte sectors.
|
||||
This option is relevant for \fIluksFormat\fR.
|
||||
|
||||
@@ -598,10 +786,9 @@ used with the \fIluksUUID\fR command.
|
||||
The UUID must be provided in the standard UUID format,
|
||||
e.g. 12345678-1234-1234-1234-123456789abc.
|
||||
.TP
|
||||
.B "\-\-allow-discards\fR"
|
||||
.B "\-\-allow\-discards\fR"
|
||||
Allow the use of discard (TRIM) requests for device.
|
||||
This option is only relevant for \fIcreate\fR, \fIluksOpen\fR
|
||||
and \fIloopaesOpen\fR.
|
||||
This option is only relevant for \fIopen\fR action.
|
||||
|
||||
\fBWARNING:\fR This command can have a negative security impact
|
||||
because it can make filesystem-level operations visible on
|
||||
@@ -613,17 +800,18 @@ later. If in doubt, do no use it.
|
||||
A kernel version of 3.1 or later is needed. For earlier kernels
|
||||
this option is ignored.
|
||||
.TP
|
||||
.B "\-\-test-passphrase\fR"
|
||||
.B "\-\-test\-passphrase\fR"
|
||||
Do not activate device, just verify passphrase.
|
||||
This option is only relevant for \fIluksOpen\fR.
|
||||
This option is only relevant for \fIopen\fR action (the device
|
||||
mapping name is not mandatory if this option is used).
|
||||
.TP
|
||||
.B "\-\-header\fR <device or file storing the LUKS header>"
|
||||
Use a detached (separated) metadata device or file where the
|
||||
LUKS header is stored. This options allows to store ciphertext
|
||||
LUKS header is stored. This options allows one to store ciphertext
|
||||
and LUKS header on different devices.
|
||||
|
||||
This option is only relevant for LUKS devices and can be
|
||||
used with the \fIluksFormat\fR, \fIluksOpen\fR, \fIluksSuspend\fR,
|
||||
used with the \fIluksFormat\fR, \fIopen\fR, \fIluksSuspend\fR,
|
||||
\fIluksResume\fR, \fIstatus\fR and \fIresize\fR commands.
|
||||
|
||||
For \fIluksFormat\fR with a file name as argument to \-\-header,
|
||||
@@ -634,16 +822,32 @@ For other commands that change the LUKS header (e.g. \fIluksAddKey\fR),
|
||||
specify the device or file with the LUKS header directly as the
|
||||
LUKS device.
|
||||
|
||||
If used with \fIluksFormat\fR, the \-\-align-payload option is taken
|
||||
If used with \fIluksFormat\fR, the \-\-align\-payload option is taken
|
||||
as absolute sector alignment on ciphertext device and can be zero.
|
||||
|
||||
\fBWARNING:\fR There is no check whether the ciphertext device specified
|
||||
actually belongs to the header given. In fact you can specify an
|
||||
arbitrary device as the ciphertext device for \fIluksOpen\fR
|
||||
arbitrary device as the ciphertext device for \fIopen\fR
|
||||
with the \-\-header option. Use with care.
|
||||
.TP
|
||||
.B "\-\-force\-password\fR"
|
||||
Do not use password quality checking for new LUKS passwords.
|
||||
|
||||
This option applies only to \fIluksFormat\fR, \fIluksAddKey\fR and
|
||||
\fIluksChangeKey\fR and is ignored if cryptsetup is built without
|
||||
password quality checking support.
|
||||
|
||||
For more info about password quality check, see manual page
|
||||
for \fBpwquality.conf(5)\fR.
|
||||
.TP
|
||||
.B "\-\-version"
|
||||
Show the program version.
|
||||
.TP
|
||||
.B "\-\-usage"
|
||||
Show short option help.
|
||||
.TP
|
||||
.B "\-\-help, \-?"
|
||||
Show help text and default parameters.
|
||||
.SH RETURN CODES
|
||||
Cryptsetup returns 0 on success and a non-zero value on error.
|
||||
|
||||
@@ -659,7 +863,7 @@ low-entropy passphrases are easy to attack in plain mode.
|
||||
first newline, i.e. '\\n'.
|
||||
The input without the newline character is processed with
|
||||
the default hash or the hash specified with \-\-hash.
|
||||
The has result will be truncated to the key size
|
||||
The hash result will be truncated to the key size
|
||||
of the used cipher, or the size specified with \-s.
|
||||
|
||||
\fBFrom stdin\fR: Reading will continue until a newline (or until
|
||||
@@ -702,13 +906,13 @@ the newline character.
|
||||
\fBFrom stdin\fR:
|
||||
LUKS will read passphrases from stdin up to the
|
||||
first newline character or the compiled-in
|
||||
maximum key file length. If \-\-keyfile-size is
|
||||
maximum key file length. If \-\-keyfile\-size is
|
||||
given, it is ignored.
|
||||
|
||||
\fBFrom key file\fR:
|
||||
The complete keyfile is read up to the compiled-in
|
||||
maximum size. Newline characters do not terminate the
|
||||
input. The \-\-keyfile-size option can be used to limit
|
||||
input. The \-\-keyfile\-size option can be used to limit
|
||||
what is read.
|
||||
|
||||
\fBPassphrase processing\fR:
|
||||
@@ -716,13 +920,18 @@ Whenever a passphrase is added to a LUKS header (luksAddKey, luksFormat),
|
||||
the user may specify how much the time the passphrase processing
|
||||
should consume. The time is used to determine the iteration count
|
||||
for PBKDF2 and higher times will offer better protection for
|
||||
low-entropy passphrases, but luksOpen will take longer to
|
||||
low-entropy passphrases, but open will take longer to
|
||||
complete. For passphrases that have entropy higher than the
|
||||
used key length, higher iteration times will not increase security.
|
||||
|
||||
The default setting of one second is sufficient for most
|
||||
practical cases. The only exception is a low-entropy
|
||||
passphrase used on a slow device.
|
||||
passphrase used on a device with a slow CPU, as this will
|
||||
result in a low iteration count. On a slow device it may
|
||||
be advisable to increase the iteration time using the
|
||||
\-\-iter\-time option in order to obtain a higher
|
||||
iteration count. This does slow down all later luksOpen
|
||||
operations accordingly.
|
||||
.SH INCOHERENT BEHAVIOR FOR INVALID PASSPHRASES/KEYS
|
||||
LUKS checks for a valid passphrase when an encrypted partition
|
||||
is unlocked. The behavior of plain dm-crypt is different.
|
||||
@@ -758,7 +967,7 @@ and for wiping deleted keyslots.
|
||||
|
||||
The second type is used for the volume (master) key. You can switch
|
||||
between using /dev/random and /dev/urandom here, see
|
||||
\fP\-\-use-random\fR and \fP\-\-use-urandom\fR
|
||||
\fP\-\-use\-random\fR and \fP\-\-use\-urandom\fR
|
||||
options. Using /dev/random on a system without enough entropy sources
|
||||
can cause \fPluksFormat\fR to block until the requested amount of
|
||||
random data is gathered. In a low-entropy situation (embedded system),
|
||||
@@ -794,7 +1003,7 @@ or in the 'Issues' section on LUKS website.
|
||||
Please attach the output of the failed command with the
|
||||
\-\-debug option added.
|
||||
.SH AUTHORS
|
||||
cryptsetup originally written by Christophe Saout <christophe@saout.de>
|
||||
cryptsetup originally written by Jana Saout <jana@saout.de>
|
||||
.br
|
||||
The LUKS extensions and original man page were written by
|
||||
Clemens Fruhwirth <clemens@endorphin.org>.
|
||||
@@ -803,13 +1012,15 @@ Man page extensions by Milan Broz <gmazyland@gmail.com>.
|
||||
.br
|
||||
Man page rewrite and extension by Arno Wagner <arno@wagner.name>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004 Christophe Saout
|
||||
Copyright \(co 2004 Jana Saout
|
||||
.br
|
||||
Copyright \(co 2004-2006 Clemens Fruhwirth
|
||||
.br
|
||||
Copyright \(co 2009-2012 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2012 Arno Wagner
|
||||
Copyright \(co 2009-2014 Milan Broz
|
||||
.br
|
||||
Copyright \(co 2012-2014 Arno Wagner
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH VERITYSETUP "8" "June 2012" "veritysetup" "Maintenance Commands"
|
||||
.TH VERITYSETUP "8" "December 2013" "veritysetup" "Maintenance Commands"
|
||||
.SH NAME
|
||||
veritysetup - manage dm-verity (block level verification) volumes
|
||||
.SH SYNOPSIS
|
||||
@@ -23,9 +23,8 @@ by \-\-hash\-offset option.
|
||||
Note you need to provide root hash string for device verification
|
||||
or activation. Root hash must be trusted.
|
||||
|
||||
If data or hash device argument points to regular file, veritysetup
|
||||
allocates loopback device. In this case, hash file size must be enough
|
||||
to store the hash area.
|
||||
The data or hash device argument can be block device or file image.
|
||||
If hash device path doesn't exist, it will be created as file.
|
||||
|
||||
\fB<options>\fR can be [\-\-hash, \-\-no-superblock, \-\-format,
|
||||
\-\-data-block-size, \-\-hash-block-size, \-\-data-blocks, \-\-hash-offset,
|
||||
@@ -131,7 +130,9 @@ The first implementation of veritysetup was written by Chrome OS authors.
|
||||
This version is based on verification code written by Mikulas Patocka <mpatocka@redhat.com>
|
||||
and rewritten for libcryptsetup by Milan Broz <gmazyland@gmail.com>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012 Red Hat, Inc.
|
||||
Copyright \(co 2012-2013 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2012-2014 Milan Broz
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
17
misc/11-dm-crypt.rules
Normal file
17
misc/11-dm-crypt.rules
Normal file
@@ -0,0 +1,17 @@
|
||||
# Old udev rules historically used in device-mapper.
|
||||
# No need to install these until you have some weird configuration.
|
||||
# (Code internally set the same flags.)
|
||||
|
||||
ACTION!="add|change", GOTO="crypt_end"
|
||||
ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="crypt_end"
|
||||
|
||||
ENV{DM_UUID}=="CRYPT-TEMP-?*", GOTO="crypt_disable"
|
||||
ENV{DM_UUID}!="?*", ENV{DM_NAME}=="temporary-cryptsetup-?*", GOTO="crypt_disable"
|
||||
GOTO="crypt_end"
|
||||
|
||||
LABEL="crypt_disable"
|
||||
ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}="1"
|
||||
ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}="1"
|
||||
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
||||
|
||||
LABEL="crypt_end"
|
||||
17
misc/dict_search/Makefile
Normal file
17
misc/dict_search/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
TARGET=crypt_dict
|
||||
CFLAGS=-O2 -g -Wall -D_GNU_SOURCE
|
||||
LDLIBS=-lcryptsetup
|
||||
CC=gcc
|
||||
|
||||
SOURCES=$(wildcard *.c)
|
||||
OBJECTS=$(SOURCES:.c=.o)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) -o $@ $^ $(LDLIBS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core $(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
22
misc/dict_search/README
Normal file
22
misc/dict_search/README
Normal file
@@ -0,0 +1,22 @@
|
||||
Simple example how to use libcryptsetup
|
||||
for password search.
|
||||
|
||||
Run: crypt_dict luks|tcrypt <device|image> <dictionary> [cpus]
|
||||
|
||||
luks|tcrypt specified device type (LUKS or TrueCrypt)
|
||||
|
||||
<device|image> is LUKS or TrueCrypt device or image
|
||||
|
||||
<dictionary> is list of passphrases to try
|
||||
(note trailing EOL is stripped)
|
||||
|
||||
cpus - number of processes to start in parallel
|
||||
|
||||
Format of dictionary file is simple one password per line,
|
||||
if first char on line s # it is skiped as comment.
|
||||
|
||||
For LUKS, you have it run as root (device-mapper cannot
|
||||
create dmcrypt devices as nrmal user. Code need
|
||||
to map keyslots as temporary dmcrypt device.)
|
||||
|
||||
For TrueCrypt devices root privilege is not required.
|
||||
158
misc/dict_search/crypt_dict.c
Normal file
158
misc/dict_search/crypt_dict.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Example of LUKS/TrueCrypt password dictionary search
|
||||
*
|
||||
* Copyright (C) 2012 Milan Broz <gmazyland@gmail.com>
|
||||
*
|
||||
* Run this (for LUKS as root),
|
||||
* e.g. ./crypt_dict test.img /usr/share/john/password.lst 4
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <libcryptsetup.h>
|
||||
|
||||
#define MAX_LEN 512
|
||||
|
||||
static enum { LUKS, TCRYPT } device_type;
|
||||
|
||||
static void check(struct crypt_device *cd, const char *pwd_file, unsigned my_id, unsigned max_id)
|
||||
{
|
||||
FILE *f;
|
||||
int len, r = -1;
|
||||
unsigned long line = 0;
|
||||
char pwd[MAX_LEN];
|
||||
|
||||
if (fork())
|
||||
return;
|
||||
|
||||
/* open password file, now in separate process */
|
||||
f = fopen(pwd_file, "r");
|
||||
if (!f) {
|
||||
printf("Cannot open %s.\n", pwd_file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while (fgets(pwd, MAX_LEN, f)) {
|
||||
|
||||
/* every process tries N-th line, skip others */
|
||||
if (line++ % max_id != my_id)
|
||||
continue;
|
||||
|
||||
len = strlen(pwd);
|
||||
|
||||
/* strip EOL - this is like a input from tty */
|
||||
if (len && pwd[len - 1] == '\n') {
|
||||
pwd[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
|
||||
/* lines starting "#!comment" are comments */
|
||||
if (len >= 9 && !strncmp(pwd, "#!comment", 9)) {
|
||||
/* printf("skipping %s\n", pwd); */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* printf("%d: checking %s\n", my_id, pwd); */
|
||||
if (device_type == LUKS)
|
||||
r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, pwd, len, 0);
|
||||
else if (device_type == TCRYPT) {
|
||||
struct crypt_params_tcrypt params = {
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES,
|
||||
.passphrase = pwd,
|
||||
.passphrase_size = len,
|
||||
};
|
||||
r = crypt_load(cd, CRYPT_TCRYPT, ¶ms);
|
||||
}
|
||||
if (r >= 0) {
|
||||
printf("Found passphrase for slot %d: \"%s\"\n", r, pwd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
crypt_free(cd);
|
||||
exit(r >= 0 ? 2 : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, status, procs = 4;
|
||||
struct crypt_device *cd;
|
||||
|
||||
if (argc < 4 || argc > 5) {
|
||||
printf("Use: %s luks|tcrypt <device|file> <password file> [#processes] %d\n", argv[0], argc);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (argc == 5 && (sscanf(argv[4], "%i", &procs) != 1 || procs < 1)) {
|
||||
printf("Wrong number of processes.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "luks"))
|
||||
device_type = LUKS;
|
||||
else if (!strcmp(argv[1], "tcrypt"))
|
||||
device_type = TCRYPT;
|
||||
else {
|
||||
printf("Wrong device type %s.\n", argv[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* crypt_set_debug_level(CRYPT_DEBUG_ALL); */
|
||||
|
||||
/*
|
||||
* Need to create temporary keyslot device-mapper devices and allocate loop if needed,
|
||||
* so root is requried here.
|
||||
*/
|
||||
if (getuid() != 0) {
|
||||
printf("You must be root to run this program.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* signal all children if anything happens */
|
||||
prctl(PR_SET_PDEATHSIG, SIGHUP);
|
||||
setpriority(PRIO_PROCESS, 0, -5);
|
||||
|
||||
/* we are not going to modify anything, so common init is ok */
|
||||
if (crypt_init(&cd, argv[2]) ||
|
||||
(device_type == LUKS && crypt_load(cd, CRYPT_LUKS1, NULL))) {
|
||||
printf("Cannot open %s.\n", argv[2]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* run scan in separate processes, it is up to scheduler to assign CPUs inteligently */
|
||||
for (i = 0; i < procs; i++)
|
||||
check(cd, argv[3], i, procs);
|
||||
|
||||
/* wait until at least one finishes with error or status 2 (key found) */
|
||||
while (wait(&status) != -1 && WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) == EXIT_SUCCESS)
|
||||
continue;
|
||||
/* kill rest of processes */
|
||||
kill(0, SIGHUP);
|
||||
/* not reached */
|
||||
break;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
@@ -2,17 +2,32 @@ Example of simple dracut module for reencryption of system
|
||||
LUKS drive on-the-fly.
|
||||
|
||||
Install in /usr/[share|lib]/dracut/modules.d/90reencrypt, then
|
||||
rebuild intramfs "with dracut -f -a reencrypt".
|
||||
build special intramfs "with dracut -a reencrypt -o crypt".
|
||||
Reencrypt module doesn't work (has a conflict) with crypt module as
|
||||
of now. After successfull reencryption reboot using original initramfs.
|
||||
|
||||
Dracut then recognize argument rd_REENCRYPT=name:size,
|
||||
e.g. rd_REENCRYPT=sda2:52G means only 52G of device
|
||||
Dracut then recognize argument rd.luks.reencrypt=name:size,
|
||||
e.g. rd.luks.reencrypt=sda2:52G means only 52G of device
|
||||
will be reencrypted (default is whole device).
|
||||
(Name is kernel name of device.)
|
||||
|
||||
Also, you may specify keyslot which you want to use for reencryption,
|
||||
rd.luks.reencrypt_keyslot=<keyslot_number>. Bear in mind that if you
|
||||
use this option, all other keyslots will be deactivated.
|
||||
|
||||
Another argument, rd.luks.reencrypt_key=/dev/sda:/path/to/keyfile
|
||||
can be used to read password for specific keyslot from device containing
|
||||
filesystem with a keyfile (file with a password). If you omit reencrypt_key
|
||||
argument, reencryption would work only in case a LUKS container has
|
||||
exactly one keyslot activated.
|
||||
|
||||
Arguments rd.luks.reencrypt_keyslot and rd.luks.reencrypt_key are not
|
||||
mandatory.
|
||||
|
||||
Note that reencryption context is stored in ramdisk, any
|
||||
fail can mean complete lost of data!
|
||||
|
||||
Copyright (C) 2012 Milan Broz <asi@ucw.cz>
|
||||
Copyright (C) 2012 Milan Broz <gmazyland@gmail.com>
|
||||
|
||||
This copyrighted material is made available to anyone wishing to use,
|
||||
modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -7,14 +7,21 @@ check() {
|
||||
|
||||
depends() {
|
||||
echo dm rootfs-block
|
||||
return 0
|
||||
}
|
||||
|
||||
installkernel() {
|
||||
instmods dm_crypt =crypto
|
||||
# requires hostonly='' override so that loop module is pulled in initramfs
|
||||
# even if not loaded in actual kernel. dracut bug?
|
||||
hostonly='' instmods dm_crypt =crypto loop
|
||||
}
|
||||
|
||||
install() {
|
||||
if dracut_module_included crypt; then
|
||||
derror "'reencrypt' can't be installed together with 'crypt'."
|
||||
derror "Add '-o crypt' option to install reencrypt module."
|
||||
return 1
|
||||
fi
|
||||
|
||||
dracut_install cryptsetup-reencrypt
|
||||
|
||||
inst_hook cmdline 30 "$moddir/parse-reencrypt.sh"
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
REENC=$(getargs rd_REENCRYPT=)
|
||||
REENC=$(getargs rd.luks.reencrypt=)
|
||||
REENC_DEV=$(echo $REENC | sed 's/:.*//')
|
||||
REENC_SIZE=$(echo $REENC | sed -n 's/.*://p')
|
||||
|
||||
REENC_KEY=$(getargs rd.luks.reencrypt_key=)
|
||||
if [ -z "$REENC_KEY" ] ; then
|
||||
REENC_KEY=none
|
||||
fi
|
||||
|
||||
REENC_SLOT=$(getargs rd.luks.reencrypt_keyslot=)
|
||||
if [ -z "$REENC_SLOT" ] ; then
|
||||
REENC_SLOT=any
|
||||
fi
|
||||
|
||||
if [ -n "$REENC_DEV" ] ; then
|
||||
{
|
||||
printf 'SUBSYSTEM!="block", GOTO="reenc_end"\n'
|
||||
@@ -11,7 +21,7 @@ if [ -n "$REENC_DEV" ] ; then
|
||||
printf 'KERNEL!="%s", GOTO="reenc_end"\n' $REENC_DEV
|
||||
printf 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue \
|
||||
--unique --onetime --name crypt-reencrypt-%%k \
|
||||
/sbin/reencrypt $env{DEVNAME} %s"\n' "$REENC_SIZE"
|
||||
/sbin/reencrypt $env{DEVNAME} %s"\n' "$REENC_KEY $REENC_SLOT $REENC_SIZE"
|
||||
printf 'LABEL="reenc_end"\n'
|
||||
} > /etc/udev/rules.d/69-reencryption.rules
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $1=$device [$2=keyfile|none [$3=keyslot|any [$4=size]]]
|
||||
#
|
||||
|
||||
[ -d /sys/module/dm_crypt ] || modprobe dm_crypt
|
||||
|
||||
[ -d /sys/module/loop ] || modprobe loop
|
||||
|
||||
[ -f /tmp/reencrypted ] && exit 0
|
||||
|
||||
. /lib/dracut-lib.sh
|
||||
@@ -14,21 +19,61 @@ else
|
||||
fi
|
||||
|
||||
PARAMS="$device -T 1 --use-fsync -B 32"
|
||||
if [ -n "$2" ]; then
|
||||
PARAMS="$PARAMS --device-size $2"
|
||||
if [ "$3" != "any" ]; then
|
||||
PARAMS="$PARAMS -S $3"
|
||||
fi
|
||||
|
||||
if [ -n "$4" ]; then
|
||||
PARAMS="$PARAMS --device-size $4"
|
||||
fi
|
||||
|
||||
reenc_readkey() {
|
||||
local keypath="${1#*:}"
|
||||
local keydev="${1%%:*}"
|
||||
|
||||
local mntp="/tmp/reencrypted-mount-tmp"
|
||||
mkdir "$mntp"
|
||||
mount -r "$keydev" "$mntp" && cat "$mntp/$keypath"
|
||||
umount "$mntp"
|
||||
rm -r "$mntp"
|
||||
}
|
||||
|
||||
reenc_run() {
|
||||
local cwd=$(pwd)
|
||||
local _prompt="LUKS password for REENCRYPTING $device"
|
||||
cd /tmp
|
||||
if [ "$1" = "none" ] ; then
|
||||
if [ "$2" != "any" ]; then
|
||||
_prompt="$_prompt, using keyslot $2"
|
||||
fi
|
||||
/bin/plymouth ask-for-password \
|
||||
--prompt "$_prompt" \
|
||||
--command="/sbin/cryptsetup-reencrypt $PARAMS"
|
||||
else
|
||||
info "REENCRYPT using key $1"
|
||||
reenc_readkey "$1" | /sbin/cryptsetup-reencrypt -d - $PARAMS
|
||||
fi
|
||||
_ret=$?
|
||||
cd $cwd
|
||||
}
|
||||
|
||||
info "REENCRYPT $device requested"
|
||||
# flock against other interactive activities
|
||||
{ flock -s 9;
|
||||
CURR=$(pwd)
|
||||
cd /tmp
|
||||
/bin/plymouth ask-for-password --prompt "LUKS password for REENCRYPTING $device" \
|
||||
--command="/sbin/cryptsetup-reencrypt $PARAMS"
|
||||
cd $CURR
|
||||
} 9>/.console.lock
|
||||
reenc_run $2 $3
|
||||
} 9>/.console_lock
|
||||
|
||||
if [ $_ret -eq 0 ]; then
|
||||
# do not ask again
|
||||
>> /tmp/reencrypted
|
||||
warn "Reencryption of device $device has finished successfully. Use previous"
|
||||
warn "initramfs image (without reencrypt module) to boot the system. When"
|
||||
warn "you leave the emergency shell, the system will reboot."
|
||||
|
||||
exit 0
|
||||
emergency_shell -n "(reboot)"
|
||||
[ -x /usr/bin/systemctl ] && /usr/bin/systemctl reboot
|
||||
[ -x /sbin/shutdown ] && /sbin/shutdown -r now
|
||||
fi
|
||||
|
||||
# panic the kernel otherwise
|
||||
exit 1
|
||||
|
||||
14
misc/keyslot_checker/Makefile
Normal file
14
misc/keyslot_checker/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
TARGETS=chk_luks_keyslots
|
||||
CFLAGS=-O0 -g -Wall -D_GNU_SOURCE
|
||||
LDLIBS=-lcryptsetup -lm
|
||||
CC=gcc
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
chk_luks_keyslots: chk_luks_keyslots.o
|
||||
$(CC) -o $@ $^ $(LDLIBS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core $(TARGETS)
|
||||
|
||||
.PHONY: clean
|
||||
120
misc/keyslot_checker/README
Normal file
120
misc/keyslot_checker/README
Normal file
@@ -0,0 +1,120 @@
|
||||
Purpose
|
||||
=======
|
||||
|
||||
chk_luks_keyslots is a tool that searches the keyslot area of a
|
||||
LUKS container for positions where entropy is low and hence
|
||||
there is a high probability of damage from overwrites of parts
|
||||
of the key-slot with data such as a RAID superblock or a partition
|
||||
table.
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
1. Install the version of cryptsetup the tool came with.
|
||||
2. Compile with "make"
|
||||
|
||||
Manual compile can be done with
|
||||
gcc -lm -lcryptsetup chk_luks_keyslots.c -o chk_luks_keyslots
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Call chk_luks_keyslots without arguments for an option summary.
|
||||
|
||||
|
||||
Example of a good keyslot area with keys 0 and 2 in use:
|
||||
--------------------------------------------------------
|
||||
|
||||
root> ./chk_luks_keyslots /dev/loop0
|
||||
|
||||
parameters (commandline and LUKS header):
|
||||
sector size: 512
|
||||
threshold: 0.900000
|
||||
|
||||
- processing keyslot 0: start: 0x001000 end: 0x020400
|
||||
- processing keyslot 1: keyslot not in use
|
||||
- processing keyslot 2: start: 0x041000 end: 0x060400
|
||||
- processing keyslot 3: keyslot not in use
|
||||
- processing keyslot 4: keyslot not in use
|
||||
- processing keyslot 5: keyslot not in use
|
||||
- processing keyslot 6: keyslot not in use
|
||||
- processing keyslot 7: keyslot not in use
|
||||
|
||||
|
||||
Same example of a fault in slot 2 at offset 0x50000:
|
||||
----------------------------------------------------
|
||||
|
||||
root>./chk_luks_keyslots /dev/loop2
|
||||
|
||||
parameters (commandline and LUKS header):
|
||||
sector size: 512
|
||||
threshold: 0.900000
|
||||
|
||||
- processing keyslot 0: start: 0x001000 end: 0x020400
|
||||
- processing keyslot 1: keyslot not in use
|
||||
- processing keyslot 2: start: 0x041000 end: 0x060400
|
||||
low entropy at: 0x050000 entropy: 0.549165
|
||||
- processing keyslot 3: keyslot not in use
|
||||
- processing keyslot 4: keyslot not in use
|
||||
- processing keyslot 5: keyslot not in use
|
||||
- processing keyslot 6: keyslot not in use
|
||||
- processing keyslot 7: keyslot not in use
|
||||
|
||||
|
||||
Same as last, but verbose:
|
||||
--------------------------
|
||||
root>./chk_luks_keyslots -v /dev/loop2
|
||||
|
||||
parameters (commandline and LUKS header):
|
||||
sector size: 512
|
||||
threshold: 0.900000
|
||||
|
||||
- processing keyslot 0: start: 0x001000 end: 0x020400
|
||||
- processing keyslot 1: keyslot not in use
|
||||
- processing keyslot 2: start: 0x041000 end: 0x060400
|
||||
low entropy at: 0x050000 entropy: 0.549165
|
||||
Binary dump:
|
||||
0x050000 54 68 69 73 20 69 73 20 61 20 74 65 73 74 2D 73 This is a test-s
|
||||
0x050010 65 63 74 6F 72 20 66 6F 72 20 63 68 6B 5F 6C 75 ector for chk_lu
|
||||
0x050020 6B 73 5F 6B 65 79 73 6C 6F 74 73 20 74 68 65 20 ks_keyslots the
|
||||
0x050030 71 75 69 63 6B 20 62 72 6F 77 6E 20 66 6F 78 20 quick brown fox
|
||||
0x050040 6A 75 6D 70 73 20 6F 76 65 72 20 74 68 65 20 6C jumps over the l
|
||||
0x050050 61 7A 79 20 64 6F 67 20 74 68 65 20 71 75 69 63 azy dog the quic
|
||||
0x050060 6B 20 62 72 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 k brown fox jump
|
||||
0x050070 73 20 6F 76 65 72 20 74 68 65 20 6C 61 7A 79 20 s over the lazy
|
||||
0x050080 64 6F 67 20 74 68 65 20 71 75 69 63 6B 20 62 72 dog the quick br
|
||||
0x050090 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 73 20 6F 76 own fox jumps ov
|
||||
0x0500a0 65 72 20 74 68 65 20 6C 61 7A 79 20 64 6F 67 20 er the lazy dog
|
||||
0x0500b0 74 68 65 20 71 75 69 63 6B 20 62 72 6F 77 6E 20 the quick brown
|
||||
0x0500c0 66 6F 78 20 6A 75 6D 70 73 20 6F 76 65 72 20 74 fox jumps over t
|
||||
0x0500d0 68 65 20 6C 61 7A 79 20 64 6F 67 20 74 68 65 20 he lazy dog the
|
||||
0x0500e0 71 75 69 63 6B 20 62 72 6F 77 6E 20 66 6F 78 20 quick brown fox
|
||||
0x0500f0 6A 75 6D 70 73 20 6F 76 65 72 20 74 68 65 20 6C jumps over the l
|
||||
0x050100 61 7A 79 20 64 6F 67 20 74 68 65 20 71 75 69 63 azy dog the quic
|
||||
0x050110 6B 20 62 72 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 k brown fox jump
|
||||
0x050120 73 20 6F 76 65 72 20 74 68 65 20 6C 61 7A 79 20 s over the lazy
|
||||
0x050130 64 6F 67 20 74 68 65 20 71 75 69 63 6B 20 62 72 dog the quick br
|
||||
0x050140 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 73 20 6F 76 own fox jumps ov
|
||||
0x050150 65 72 20 74 68 65 20 6C 61 7A 79 20 64 6F 67 20 er the lazy dog
|
||||
0x050160 74 68 65 20 71 75 69 63 6B 20 62 72 6F 77 6E 20 the quick brown
|
||||
0x050170 66 6F 78 20 6A 75 6D 70 73 20 6F 76 65 72 20 74 fox jumps over t
|
||||
0x050180 68 65 20 6C 61 7A 79 20 64 6F 67 20 74 68 65 20 he lazy dog the
|
||||
0x050190 71 75 69 63 6B 20 62 72 6F 77 6E 20 66 6F 78 20 quick brown fox
|
||||
0x0501a0 6A 75 6D 70 73 20 6F 76 65 72 20 74 68 65 20 6C jumps over the l
|
||||
0x0501b0 61 7A 79 20 64 6F 67 20 74 68 65 20 71 75 69 63 azy dog the quic
|
||||
0x0501c0 6B 20 62 72 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 k brown fox jump
|
||||
0x0501d0 73 20 6F 76 65 72 20 74 68 65 20 6C 61 7A 79 20 s over the lazy
|
||||
0x0501e0 64 6F 67 20 74 68 65 20 71 75 69 63 6B 20 62 72 dog the quick br
|
||||
0x0501f0 6F 77 6E 20 66 6F 78 20 6A 75 6D 70 73 20 6F 76 own fox jumps ov
|
||||
|
||||
- processing keyslot 3: keyslot not in use
|
||||
- processing keyslot 4: keyslot not in use
|
||||
- processing keyslot 5: keyslot not in use
|
||||
- processing keyslot 6: keyslot not in use
|
||||
- processing keyslot 7: keyslot not in use
|
||||
|
||||
----
|
||||
Copyright (C) 2012, Arno Wagner <arno@wagner.name>
|
||||
This file is free documentation; the author gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
371
misc/keyslot_checker/chk_luks_keyslots.c
Normal file
371
misc/keyslot_checker/chk_luks_keyslots.c
Normal file
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* LUKS keyslot entropy tester. Works only for header version 1.
|
||||
*
|
||||
* Functionality: Determines sample entropy (symbols: bytes) for
|
||||
* each (by default) 512B sector in each used keyslot. If it
|
||||
* is lower than a threshold, the sector address is printed
|
||||
* as it is suspected of having non-"random" data in it, indicating
|
||||
* damage by overwriting. This can obviously not find overwriting
|
||||
* with random or random-like data (encrypted, compressed).
|
||||
*
|
||||
* Version history:
|
||||
* v0.1: 09.09.2012 Initial release
|
||||
* v0.2: 08.10.2012 Converted to use libcryptsetup
|
||||
*
|
||||
* Copyright (C) 2012, Arno Wagner <arno@wagner.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <libcryptsetup.h>
|
||||
|
||||
const char *help =
|
||||
"Version 0.2 [8.10.2012]\n"
|
||||
"\n"
|
||||
" chk_luks_keyslots [options] luks-device \n"
|
||||
"\n"
|
||||
"This tool checks all keyslots of a LUKS device for \n"
|
||||
"low entropy sections. If any are found, they are reported. \n"
|
||||
"This allows to find areas damaged by things like filesystem \n"
|
||||
"creation or RAID superblocks. \n"
|
||||
"\n"
|
||||
"Options: \n"
|
||||
" -t <num> Entropy threshold. Possible values 0.0 ... 1.0 \n"
|
||||
" Default: 0.90, which works well for 512B sectors.\n"
|
||||
" For 512B sectors, you will get frequent misdetections\n"
|
||||
" at thresholds around 0.94\n"
|
||||
" Higher value: more sensitive but more false detections.\n"
|
||||
" -s <num> Sector size. Must divide keyslot-size.\n"
|
||||
" Default: 512 Bytes.\n"
|
||||
" Values smaller than 128 are generally not very useful.\n"
|
||||
" For values smaller than the default, you need to adjust\n"
|
||||
" the threshold down to reduce misdetection. For values\n"
|
||||
" larger than the default you need to adjust the threshold\n"
|
||||
" up to retain sensitivity.\n"
|
||||
" -v Print found suspicuous sectors verbosely. \n"
|
||||
" -d Print decimal addresses instead of hex ones.\n"
|
||||
"\n";
|
||||
|
||||
|
||||
/* Config defaults */
|
||||
|
||||
static int sector_size = 512;
|
||||
static double threshold = 0.90;
|
||||
static int print_decimal = 0;
|
||||
static int verbose = 0;
|
||||
|
||||
/* tools */
|
||||
|
||||
/* Calculates and returns sample entropy on byte level for
|
||||
* The argument.
|
||||
*/
|
||||
static double ent_samp(unsigned char * buf, int len)
|
||||
{
|
||||
int freq[256]; /* stores symbol frequencies */
|
||||
int i;
|
||||
double e, f;
|
||||
|
||||
/* 0. Plausibility checks */
|
||||
if (len <= 0)
|
||||
return 0.0;
|
||||
|
||||
/* 1. count all frequencies */
|
||||
for (i = 0; i < 256; i++) {
|
||||
freq[i] = 0.0;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i ++)
|
||||
freq[buf[i]]++;
|
||||
|
||||
/* 2. calculate sample entropy */
|
||||
e = 0.0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
f = freq[i];
|
||||
if (f > 0) {
|
||||
f = f / (double)len;
|
||||
e += f * log2(f);
|
||||
}
|
||||
}
|
||||
|
||||
if (e != 0.0)
|
||||
e = -1.0 * e;
|
||||
|
||||
e = e / 8.0;
|
||||
return e;
|
||||
}
|
||||
|
||||
static void print_address(FILE *out, uint64_t value)
|
||||
{
|
||||
if (print_decimal) {
|
||||
fprintf(out,"%08" PRIu64 " ", value);
|
||||
} else {
|
||||
fprintf(out,"%#08" PRIx64 " ", value);
|
||||
}
|
||||
}
|
||||
|
||||
/* uses default "hd" style, i.e. 16 bytes followed by ASCII */
|
||||
static void hexdump_line(FILE *out, uint64_t address, unsigned char *buf) {
|
||||
int i;
|
||||
static char tbl[16] = "0123456789ABCDEF";
|
||||
|
||||
fprintf(out," ");
|
||||
print_address(out, address);
|
||||
fprintf(out," ");
|
||||
|
||||
/* hex */
|
||||
for (i = 0; i < 16; i++) {
|
||||
fprintf(out, "%c%c",
|
||||
tbl[(unsigned char)buf[i]>> 4],
|
||||
tbl[(unsigned char)buf[i] & 0x0f]);
|
||||
fprintf(out," ");
|
||||
if (i == 7)
|
||||
fprintf(out," ");
|
||||
}
|
||||
|
||||
fprintf(out," ");
|
||||
|
||||
/* ascii */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (isprint(buf[i])) {
|
||||
fprintf(out, "%c", buf[i]);
|
||||
} else {
|
||||
fprintf(out, ".");
|
||||
}
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
static void hexdump_sector(FILE *out, unsigned char *buf, uint64_t address, int len)
|
||||
{
|
||||
int done;
|
||||
|
||||
done = 0;
|
||||
while (len - done >= 16) {
|
||||
hexdump_line(out, address + done, buf + done);
|
||||
done += 16;
|
||||
}
|
||||
}
|
||||
|
||||
static int check_keyslots(FILE *out, struct crypt_device *cd, int f_luks)
|
||||
{
|
||||
int i;
|
||||
double ent;
|
||||
off_t ofs;
|
||||
uint64_t start, length, end;
|
||||
crypt_keyslot_info ki;
|
||||
unsigned char buffer[sector_size];
|
||||
|
||||
for (i = 0; i < crypt_keyslot_max(CRYPT_LUKS1) ; i++) {
|
||||
fprintf(out, "- processing keyslot %d:", i);
|
||||
ki = crypt_keyslot_status(cd, i);
|
||||
if (ki == CRYPT_SLOT_INACTIVE) {
|
||||
fprintf(out, " keyslot not in use\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ki == CRYPT_SLOT_INVALID) {
|
||||
fprintf(out, "\nError: keyslot invalid.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (crypt_keyslot_area(cd, i, &start, &length) < 0) {
|
||||
fprintf(stderr,"\nError: querying keyslot area failed for slot %d\n", i);
|
||||
perror(NULL);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
end = start + length;
|
||||
|
||||
fprintf(out, " start: ");
|
||||
print_address(out, start);
|
||||
fprintf(out, " end: ");
|
||||
print_address(out, end);
|
||||
fprintf(out, "\n");
|
||||
|
||||
/* check whether sector-size divides size */
|
||||
if (length % sector_size != 0) {
|
||||
fprintf(stderr,"\nError: Argument to -s does not divide keyslot size\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (ofs = start; (uint64_t)ofs < end; ofs += sector_size) {
|
||||
if (lseek(f_luks, ofs, SEEK_SET) != ofs) {
|
||||
fprintf(stderr,"\nCannot seek to keyslot area.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (read(f_luks, buffer, sector_size) != sector_size) {
|
||||
fprintf(stderr,"\nCannot read keyslot area.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
ent = ent_samp(buffer, sector_size);
|
||||
if (ent < threshold) {
|
||||
fprintf(out, " low entropy at: ");
|
||||
print_address(out, ofs);
|
||||
fprintf(out, " entropy: %f\n", ent);
|
||||
if (verbose) {
|
||||
fprintf(out, " Binary dump:\n");
|
||||
hexdump_sector(out, buffer, (uint64_t)ofs, sector_size);
|
||||
fprintf(out,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* Main */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* for option processing */
|
||||
int c, r;
|
||||
char *device;
|
||||
|
||||
/* for use of libcryptsetup */
|
||||
struct crypt_device *cd;
|
||||
|
||||
/* Other vars */
|
||||
int f_luks; /* device file for the luks device */
|
||||
FILE *out;
|
||||
|
||||
/* temporary helper vars */
|
||||
int res;
|
||||
|
||||
/* getopt values */
|
||||
char *s, *end;
|
||||
double tvalue;
|
||||
int svalue;
|
||||
|
||||
/* global initializations */
|
||||
out = stdout;
|
||||
|
||||
/* get commandline parameters */
|
||||
while ((c = getopt (argc, argv, "t:s:vd")) != -1) {
|
||||
switch (c) {
|
||||
case 't':
|
||||
s = optarg;
|
||||
tvalue = strtod(s, &end);
|
||||
if (s == end) {
|
||||
fprintf(stderr, "\nError: Parsing of argument to -t failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (tvalue < 0.0 || tvalue > 1.0) {
|
||||
fprintf(stderr,"\nError: Argument to -t must be in 0.0 ... 1.0\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
threshold = tvalue;
|
||||
break;
|
||||
case 's':
|
||||
s = optarg;
|
||||
svalue = strtol(s, &end, 10);
|
||||
if (s == end) {
|
||||
fprintf(stderr, "\nError: Parsing of argument to -s failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (svalue < 1) {
|
||||
fprintf(stderr,"\nError: Argument to -s must be >= 1 \n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sector_size = svalue;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'd':
|
||||
print_decimal = 1;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 't' || optopt == 's')
|
||||
fprintf (stderr,"\nError: Option -%c requires an argument.\n",
|
||||
optopt);
|
||||
else if (isprint (optopt)) {
|
||||
fprintf(stderr,"\nError: Unknown option `-%c'.\n", optopt);
|
||||
fprintf(stderr,"\n\n%s", help);
|
||||
} else {
|
||||
fprintf (stderr, "\nError: Unknown option character `\\x%x'.\n",
|
||||
optopt);
|
||||
fprintf(stderr,"\n\n%s", help);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse non-option stuff. Should be exactly one, the device. */
|
||||
if (optind+1 != argc) {
|
||||
fprintf(stderr,"\nError: exactly one non-option argument expected!\n");
|
||||
fprintf(stderr,"\n\n%s", help);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
device = argv[optind];
|
||||
|
||||
/* test whether we can open and read device */
|
||||
/* This is neded as we are reading the actual data
|
||||
* in the keyslots dirtectly from the LUKS container.
|
||||
*/
|
||||
f_luks = open(device, O_RDONLY);
|
||||
if (f_luks == -1) {
|
||||
fprintf(stderr,"\nError: Opening of device %s failed:\n", device);
|
||||
perror(NULL);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* now get the parameters we need via libcryptsetup */
|
||||
/* Basically we need all active keyslots and their placement on disk */
|
||||
|
||||
/* first init. This does the following:
|
||||
* - gets us a crypt_device struct with some values filled in
|
||||
* Note: This does some init stuff we do not need, but that
|
||||
* should not cause trouble.
|
||||
*/
|
||||
|
||||
res = crypt_init(&cd, device);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "crypt_init() failed. Maybe not running as root?\n");
|
||||
close(f_luks);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* now load LUKS header into the crypt_device
|
||||
* This should also make sure a valid LUKS1 header is on disk
|
||||
* and hence we should be able to skip magic and version checks.
|
||||
*/
|
||||
res = crypt_load(cd, CRYPT_LUKS1, NULL);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "crypt_load() failed. LUKS header too broken/absent?\n");
|
||||
crypt_free(cd);
|
||||
close(f_luks);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fprintf(out, "\nparameters (commandline and LUKS header):\n");
|
||||
fprintf(out, " sector size: %d\n", sector_size);
|
||||
fprintf(out, " threshold: %0f\n\n", threshold);
|
||||
|
||||
r = check_keyslots(out, cd, f_luks);
|
||||
|
||||
crypt_free(cd);
|
||||
close(f_luks);
|
||||
return r;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Try to get LUKS info and master key from active mapping and prepare parameters for cryptsetup.
|
||||
#
|
||||
# Copyright (C) 2010,2011,2012 Milan Broz <asi@ucw.cz>
|
||||
# Copyright (C) 2010,2011,2012 Milan Broz <gmazyland@gmail.com>
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
cs
|
||||
de
|
||||
es
|
||||
fi
|
||||
fr
|
||||
id
|
||||
|
||||
@@ -6,13 +6,16 @@ lib/crypt_plain.c
|
||||
lib/utils_crypt.c
|
||||
lib/utils_loop.c
|
||||
lib/utils_fips.c
|
||||
lib/utils_device.c
|
||||
lib/luks1/af.c
|
||||
lib/luks1/keyencryption.c
|
||||
lib/luks1/keymanage.c
|
||||
lib/luks1/pbkdf.c
|
||||
lib/loopaes/loopaes.c
|
||||
lib/tcrypt/tcrypt.c
|
||||
lib/verity/verity.c
|
||||
lib/verity/verity_hash.c
|
||||
src/cryptsetup.c
|
||||
src/veritysetup.c
|
||||
src/cryptsetup_reencrypt.c
|
||||
src/utils_tools.c
|
||||
src/utils_password.c
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
INCLUDES = -I$(top_srcdir)/lib $(PYTHON_INCLUDES)
|
||||
AM_CPPFLAGS = -include $(top_srcdir)/config.h -I$(top_srcdir)/lib $(PYTHON_INCLUDES)
|
||||
EXTRA_DIST = pycryptsetup-test.py
|
||||
CLEANFILES = *.img
|
||||
|
||||
@@ -9,8 +9,8 @@ pyexec_LTLIBRARIES = pycryptsetup.la
|
||||
|
||||
pycryptsetup_la_SOURCES = pycryptsetup.c
|
||||
pycryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) -fno-strict-aliasing
|
||||
pycryptsetup_la_LDFLAGS = -avoid-version -module
|
||||
pycryptsetup_la_LIBADD = $(top_builddir)/lib/libcryptsetup.la -lpython$(PYTHON_VERSION)
|
||||
pycryptsetup_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||
pycryptsetup_la_LIBADD = $(top_builddir)/lib/libcryptsetup.la $(PYTHON_LIBS)
|
||||
else
|
||||
all:
|
||||
endif
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Python bindings to libcryptsetup test
|
||||
#
|
||||
# Copyright (C) 2011, Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2011-2014, 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
|
||||
@@ -18,6 +18,8 @@
|
||||
# License along with this file; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
@@ -31,11 +33,11 @@ DEVICE = "pycryptsetup_test_dev"
|
||||
|
||||
def log(level, txt):
|
||||
if level == pycryptsetup.CRYPT_LOG_ERROR:
|
||||
print txt,
|
||||
print(txt,end="")
|
||||
return
|
||||
|
||||
def askyes(txt):
|
||||
print "Question:", txt
|
||||
print("Question:", txt)
|
||||
return 1
|
||||
|
||||
def askpassword(txt):
|
||||
@@ -43,17 +45,17 @@ def askpassword(txt):
|
||||
|
||||
def print_status(c):
|
||||
r = c.status()
|
||||
print "status :",
|
||||
print("status :",end="")
|
||||
if r == pycryptsetup.CRYPT_ACTIVE:
|
||||
print "ACTIVE"
|
||||
print("ACTIVE")
|
||||
elif r == pycryptsetup.CRYPT_INACTIVE:
|
||||
print "INACTIVE"
|
||||
print("INACTIVE")
|
||||
else:
|
||||
print "ERROR"
|
||||
print("ERROR")
|
||||
return
|
||||
|
||||
if os.geteuid() != 0:
|
||||
print "WARNING: You must be root to run this test, test skipped."
|
||||
print("WARNING: You must be root to run this test, test skipped.")
|
||||
sys.exit(0)
|
||||
|
||||
os.system("dd if=/dev/zero of=" + IMG + " bs=1M count=32 >/dev/null 2>&1")
|
||||
@@ -69,36 +71,36 @@ c = pycryptsetup.CryptSetup(
|
||||
c.debugLevel(pycryptsetup.CRYPT_DEBUG_NONE);
|
||||
c.iterationTime(1)
|
||||
r = c.isLuks()
|
||||
print "isLuks :", r
|
||||
print("isLuks :", r)
|
||||
c.askyes(message = "Is there anybody out there?")
|
||||
c.log(priority = pycryptsetup.CRYPT_LOG_ERROR, message = "Nobody there...\n")
|
||||
c.luksFormat(cipher = "aes", cipherMode= "xts-plain64", keysize = 512)
|
||||
print "isLuks :", c.isLuks()
|
||||
print "luksUUID:", c.luksUUID()
|
||||
print "addKeyVK:", c.addKeyByVolumeKey(newPassphrase = PASSWORD, slot = 2)
|
||||
print "addKeyP :", c.addKeyByPassphrase(passphrase = PASSWORD,
|
||||
newPassphrase = PASSWORD2, slot = 3)
|
||||
print "removeP :", c.removePassphrase(passphrase = PASSWORD2)
|
||||
print "addKeyP :", c.addKeyByPassphrase(PASSWORD, PASSWORD2)
|
||||
print("isLuks :", c.isLuks())
|
||||
print("luksUUID:", c.luksUUID())
|
||||
print("addKeyVK:", c.addKeyByVolumeKey(newPassphrase = PASSWORD, slot = 2))
|
||||
print("addKeyP :", c.addKeyByPassphrase(passphrase = PASSWORD,
|
||||
newPassphrase = PASSWORD2, slot = 3))
|
||||
print("removeP :", c.removePassphrase(passphrase = PASSWORD2))
|
||||
print("addKeyP :", c.addKeyByPassphrase(PASSWORD, PASSWORD2))
|
||||
# original api required wrong passphrase parameter here
|
||||
# print "killSlot:", c.killSlot(passphrase = "xxx", slot = 0)
|
||||
print "killSlot:", c.killSlot(slot = 0)
|
||||
print "activate:", c.activate(name = DEVICE, passphrase = PASSWORD)
|
||||
print "suspend :", c.suspend()
|
||||
print("killSlot:", c.killSlot(slot = 0))
|
||||
print("activate:", c.activate(name = DEVICE, passphrase = PASSWORD))
|
||||
print("suspend :", c.suspend())
|
||||
# os.system("dmsetup info -c " + DEVICE)
|
||||
print "resume :", c.resume(passphrase = PASSWORD)
|
||||
print("resume :", c.resume(passphrase = PASSWORD))
|
||||
print_status(c)
|
||||
info = c.info()
|
||||
print "cipher :", info["cipher"]
|
||||
print "cmode :", info["cipher_mode"]
|
||||
print "keysize :", info["keysize"]
|
||||
print "dir :", info["dir"]
|
||||
print "device :", info["device"]
|
||||
print "offset :", info["offset"]
|
||||
print "name :", info["name"]
|
||||
print "uuid :", info["uuid"]
|
||||
print("cipher :", info["cipher"])
|
||||
print("cmode :", info["cipher_mode"])
|
||||
print("keysize :", info["keysize"])
|
||||
print("dir :", info["dir"])
|
||||
print("device :", info["device"])
|
||||
print("offset :", info["offset"])
|
||||
print("name :", info["name"])
|
||||
print("uuid :", info["uuid"])
|
||||
# os.system("cryptsetup luksDump " + info["device"])
|
||||
print "deact. :", c.deactivate()
|
||||
print("deact. :", c.deactivate())
|
||||
|
||||
del c
|
||||
|
||||
@@ -109,7 +111,7 @@ c = pycryptsetup.CryptSetup(
|
||||
logFunc = log,
|
||||
passwordDialog = askpassword)
|
||||
|
||||
print "activate:", c.activate(name = DEVICE, passphrase = PASSWORD)
|
||||
print("activate:", c.activate(name = DEVICE, passphrase = PASSWORD))
|
||||
|
||||
c2 = pycryptsetup.CryptSetup(
|
||||
name = DEVICE,
|
||||
@@ -118,13 +120,13 @@ c2 = pycryptsetup.CryptSetup(
|
||||
passwordDialog = askpassword)
|
||||
|
||||
info = c2.info()
|
||||
print "cipher :", info["cipher"]
|
||||
print "cmode :", info["cipher_mode"]
|
||||
print "keysize :", info["keysize"]
|
||||
print("cipher :", info["cipher"])
|
||||
print("cmode :", info["cipher_mode"])
|
||||
print("keysize :", info["keysize"])
|
||||
|
||||
print "deact. :", c.deactivate()
|
||||
print("deact. :", c.deactivate())
|
||||
r = c2.deactivate()
|
||||
print "deact. :", r
|
||||
print("deact. :", r)
|
||||
del c
|
||||
del c2
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Python bindings to libcryptsetup
|
||||
*
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2014, Red Hat, Inc. All rights reserved.
|
||||
* Written by Martin Sivak
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
@@ -25,6 +25,24 @@
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
#define MOD_ERROR_VAL
|
||||
#define MOD_SUCCESS_VAL(val)
|
||||
#define MOD_INIT(name) void init##name(void)
|
||||
#define MOD_DEF(ob, name, doc, methods) \
|
||||
ob = Py_InitModule3(name, methods, doc);
|
||||
#else
|
||||
#define PyInt_AsLong PyLong_AsLong
|
||||
#define PyInt_Check PyLong_Check
|
||||
#define MOD_ERROR_VAL NULL
|
||||
#define MOD_SUCCESS_VAL(val) val
|
||||
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
|
||||
#define MOD_DEF(ob, name, doc, methods) \
|
||||
static struct PyModuleDef moduledef = { \
|
||||
PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
|
||||
ob = PyModule_Create(&moduledef);
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
@@ -128,7 +146,7 @@ static void CryptSetup_dealloc(CryptSetupObject* self)
|
||||
crypt_free(self->device);
|
||||
|
||||
/* free self */
|
||||
self->ob_type->tp_free((PyObject*)self);
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject *CryptSetup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
@@ -155,13 +173,15 @@ static PyObject *PyObjectResult(int is)
|
||||
return result;
|
||||
}
|
||||
|
||||
#define CryptSetup_HELP "CryptSetup object\n\n\
|
||||
static char
|
||||
CryptSetup_HELP[] =
|
||||
"CryptSetup object\n\n\
|
||||
constructor takes one to five arguments:\n\
|
||||
__init__(device, name, yesDialog, passwordDialog, logFunc)\n\n\
|
||||
yesDialog - python function with func(text) signature, \n\
|
||||
which asks the user question text and returns 1\n\
|
||||
of the answer was positive or 0 if not\n\
|
||||
logFunc - python function with func(level, text) signature to log stuff somewhere"
|
||||
logFunc - python function with func(level, text) signature to log stuff somewhere";
|
||||
|
||||
static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -229,8 +249,10 @@ static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwd
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CryptSetup_activate_HELP "Activate LUKS device\n\n\
|
||||
activate(name)"
|
||||
static char
|
||||
CryptSetup_activate_HELP[] =
|
||||
"Activate LUKS device\n\n\
|
||||
activate(name)";
|
||||
|
||||
static PyObject *CryptSetup_activate(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -241,6 +263,7 @@ static PyObject *CryptSetup_activate(CryptSetupObject* self, PyObject *args, PyO
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &name, &passphrase))
|
||||
return NULL;
|
||||
|
||||
|
||||
// FIXME: allow keyfile and \0 in passphrase
|
||||
is = crypt_activate_by_passphrase(self->device, name, CRYPT_ANY_SLOT,
|
||||
passphrase, passphrase ? strlen(passphrase) : 0, 0);
|
||||
@@ -253,8 +276,10 @@ static PyObject *CryptSetup_activate(CryptSetupObject* self, PyObject *args, PyO
|
||||
return PyObjectResult(is);
|
||||
}
|
||||
|
||||
#define CryptSetup_deactivate_HELP "Dectivate LUKS device\n\n\
|
||||
deactivate()"
|
||||
static char
|
||||
CryptSetup_deactivate_HELP[] =
|
||||
"Dectivate LUKS device\n\n\
|
||||
deactivate()";
|
||||
|
||||
static PyObject *CryptSetup_deactivate(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -268,8 +293,10 @@ static PyObject *CryptSetup_deactivate(CryptSetupObject* self, PyObject *args, P
|
||||
return PyObjectResult(is);
|
||||
}
|
||||
|
||||
#define CryptSetup_askyes_HELP "Asks a question using the configured dialog CB\n\n\
|
||||
int askyes(message)"
|
||||
static char
|
||||
CryptSetup_askyes_HELP[] =
|
||||
"Asks a question using the configured dialog CB\n\n\
|
||||
int askyes(message)";
|
||||
|
||||
static PyObject *CryptSetup_askyes(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -294,8 +321,10 @@ static PyObject *CryptSetup_askyes(CryptSetupObject* self, PyObject *args, PyObj
|
||||
return result;
|
||||
}
|
||||
|
||||
#define CryptSetup_log_HELP "Logs a string using the configured log CB\n\n\
|
||||
log(int level, message)"
|
||||
static char
|
||||
CryptSetup_log_HELP[] =
|
||||
"Logs a string using the configured log CB\n\n\
|
||||
log(int level, message)";
|
||||
|
||||
static PyObject *CryptSetup_log(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -322,8 +351,10 @@ static PyObject *CryptSetup_log(CryptSetupObject* self, PyObject *args, PyObject
|
||||
return result;
|
||||
}
|
||||
|
||||
#define CryptSetup_luksUUID_HELP "Get UUID of the LUKS device\n\n\
|
||||
luksUUID()"
|
||||
static char
|
||||
CryptSetup_luksUUID_HELP[] =
|
||||
"Get UUID of the LUKS device\n\n\
|
||||
luksUUID()";
|
||||
|
||||
static PyObject *CryptSetup_luksUUID(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -336,17 +367,21 @@ static PyObject *CryptSetup_luksUUID(CryptSetupObject* self, PyObject *args, PyO
|
||||
return result;
|
||||
}
|
||||
|
||||
#define CryptSetup_isLuks_HELP "Is the device LUKS?\n\n\
|
||||
isLuks()"
|
||||
static char
|
||||
CryptSetup_isLuks_HELP[] =
|
||||
"Is the device LUKS?\n\n\
|
||||
isLuks()";
|
||||
|
||||
static PyObject *CryptSetup_isLuks(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
return PyObjectResult(crypt_load(self->device, CRYPT_LUKS1, NULL));
|
||||
}
|
||||
|
||||
#define CryptSetup_Info_HELP "Returns dictionary with info about opened device\nKeys:\n\
|
||||
static char
|
||||
CryptSetup_Info_HELP[] =
|
||||
"Returns dictionary with info about opened device\nKeys:\n\
|
||||
dir\n name\n uuid\n cipher\n cipher_mode\n keysize\n device\n\
|
||||
offset\n size\n skip\n mode\n"
|
||||
offset\n size\n skip\n mode\n";
|
||||
|
||||
static PyObject *CryptSetup_Info(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -371,11 +406,13 @@ static PyObject *CryptSetup_Info(CryptSetupObject* self, PyObject *args, PyObjec
|
||||
return result;
|
||||
}
|
||||
|
||||
#define CryptSetup_luksFormat_HELP "Format device to enable LUKS\n\n\
|
||||
static char
|
||||
CryptSetup_luksFormat_HELP[] =
|
||||
"Format device to enable LUKS\n\n\
|
||||
luksFormat(cipher = 'aes', cipherMode = 'cbc-essiv:sha256', keysize = 256)\n\n\
|
||||
cipher - cipher specification, e.g. aes, serpent\n\
|
||||
cipherMode - cipher mode specification, e.g. cbc-essiv:sha256, xts-plain64\n\
|
||||
keysize - key size in bits"
|
||||
keysize - key size in bits";
|
||||
|
||||
static PyObject *CryptSetup_luksFormat(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -408,11 +445,13 @@ static PyObject *CryptSetup_luksFormat(CryptSetupObject* self, PyObject *args, P
|
||||
NULL, NULL, keysize / 8, NULL));
|
||||
}
|
||||
|
||||
#define CryptSetup_addKeyByPassphrase_HELP "Initialize keyslot using passphrase\n\n\
|
||||
static char
|
||||
CryptSetup_addKeyByPassphrase_HELP[] =
|
||||
"Initialize keyslot using passphrase\n\n\
|
||||
addKeyByPassphrase(passphrase, newPassphrase, slot)\n\n\
|
||||
passphrase - string or none to ask the user\n\
|
||||
newPassphrase - passphrase to add\n\
|
||||
slot - which slot to use (optional)"
|
||||
slot - which slot to use (optional)";
|
||||
|
||||
static PyObject *CryptSetup_addKeyByPassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -435,10 +474,12 @@ static PyObject *CryptSetup_addKeyByPassphrase(CryptSetupObject* self, PyObject
|
||||
newpassphrase, newpassphrase_len));
|
||||
}
|
||||
|
||||
#define CryptSetup_addKeyByVolumeKey_HELP "Initialize keyslot using cached volume key\n\n\
|
||||
static char
|
||||
CryptSetup_addKeyByVolumeKey_HELP[] =
|
||||
"Initialize keyslot using cached volume key\n\n\
|
||||
addKeyByVolumeKey(passphrase, newPassphrase, slot)\n\n\
|
||||
newPassphrase - passphrase to add\n\
|
||||
slot - which slot to use (optional)"
|
||||
slot - which slot to use (optional)";
|
||||
|
||||
static PyObject *CryptSetup_addKeyByVolumeKey(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -457,9 +498,11 @@ static PyObject *CryptSetup_addKeyByVolumeKey(CryptSetupObject* self, PyObject *
|
||||
NULL, 0, newpassphrase, newpassphrase_len));
|
||||
}
|
||||
|
||||
#define CryptSetup_removePassphrase_HELP "Destroy keyslot using passphrase\n\n\
|
||||
static char
|
||||
CryptSetup_removePassphrase_HELP[] =
|
||||
"Destroy keyslot using passphrase\n\n\
|
||||
removePassphrase(passphrase)\n\n\
|
||||
passphrase - string or none to ask the user"
|
||||
passphrase - string or none to ask the user";
|
||||
|
||||
static PyObject *CryptSetup_removePassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -482,9 +525,11 @@ static PyObject *CryptSetup_removePassphrase(CryptSetupObject* self, PyObject *a
|
||||
return PyObjectResult(crypt_keyslot_destroy(self->device, is));
|
||||
}
|
||||
|
||||
#define CryptSetup_killSlot_HELP "Destroy keyslot\n\n\
|
||||
static char
|
||||
CryptSetup_killSlot_HELP[] =
|
||||
"Destroy keyslot\n\n\
|
||||
killSlot(slot)\n\n\
|
||||
slot - the slot to remove"
|
||||
slot - the slot to remove";
|
||||
|
||||
static PyObject *CryptSetup_killSlot(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -511,8 +556,10 @@ static PyObject *CryptSetup_killSlot(CryptSetupObject* self, PyObject *args, PyO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define CryptSetup_Status_HELP "Status of LUKS device\n\n\
|
||||
luksStatus()"
|
||||
static char
|
||||
CryptSetup_Status_HELP[] =
|
||||
"Status of LUKS device\n\n\
|
||||
luksStatus()";
|
||||
|
||||
static PyObject *CryptSetup_Status(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -524,9 +571,11 @@ static PyObject *CryptSetup_Status(CryptSetupObject* self, PyObject *args, PyObj
|
||||
return PyObjectResult(crypt_status(self->device, self->activated_as));
|
||||
}
|
||||
|
||||
#define CryptSetup_Resume_HELP "Resume LUKS device\n\n\
|
||||
static char
|
||||
CryptSetup_Resume_HELP[] =
|
||||
"Resume LUKS device\n\n\
|
||||
luksOpen(passphrase)\n\n\
|
||||
passphrase - string or none to ask the user"
|
||||
passphrase - string or none to ask the user";
|
||||
|
||||
static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -542,6 +591,7 @@ static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObj
|
||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &passphrase))
|
||||
return NULL;
|
||||
|
||||
|
||||
if (passphrase)
|
||||
passphrase_len = strlen(passphrase);
|
||||
|
||||
@@ -549,8 +599,10 @@ static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObj
|
||||
CRYPT_ANY_SLOT, passphrase, passphrase_len));
|
||||
}
|
||||
|
||||
#define CryptSetup_Suspend_HELP "Suspend LUKS device\n\n\
|
||||
luksSupsend()"
|
||||
static char
|
||||
CryptSetup_Suspend_HELP[] =
|
||||
"Suspend LUKS device\n\n\
|
||||
luksSupsend()";
|
||||
|
||||
static PyObject *CryptSetup_Suspend(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -562,9 +614,11 @@ static PyObject *CryptSetup_Suspend(CryptSetupObject* self, PyObject *args, PyOb
|
||||
return PyObjectResult(crypt_suspend(self->device, self->activated_as));
|
||||
}
|
||||
|
||||
#define CryptSetup_debugLevel_HELP "Set debug level\n\n\
|
||||
static char
|
||||
CryptSetup_debugLevel_HELP[] =
|
||||
"Set debug level\n\n\
|
||||
debugLevel(level)\n\n\
|
||||
level - debug level"
|
||||
level - debug level";
|
||||
|
||||
static PyObject *CryptSetup_debugLevel(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -579,9 +633,11 @@ static PyObject *CryptSetup_debugLevel(CryptSetupObject* self, PyObject *args, P
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#define CryptSetup_iterationTime_HELP "Set iteration time\n\n\
|
||||
static char
|
||||
CryptSetup_iterationTime_HELP[] =
|
||||
"Set iteration time\n\n\
|
||||
iterationTime(time_ms)\n\n\
|
||||
time_ms - time in miliseconds"
|
||||
time_ms - time in miliseconds";
|
||||
|
||||
static PyObject *CryptSetup_iterationTime(CryptSetupObject* self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
@@ -637,8 +693,7 @@ static PyMethodDef CryptSetup_methods[] = {
|
||||
};
|
||||
|
||||
static PyTypeObject CryptSetupType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /*ob_size*/
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"pycryptsetup.CryptSetup", /*tp_name*/
|
||||
sizeof(CryptSetupObject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
@@ -682,15 +737,14 @@ static PyMethodDef pycryptsetup_methods[] = {
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC initpycryptsetup(void);
|
||||
PyMODINIT_FUNC initpycryptsetup(void)
|
||||
MOD_INIT(pycryptsetup)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
if (PyType_Ready(&CryptSetupType) < 0)
|
||||
return;
|
||||
return MOD_ERROR_VAL;
|
||||
|
||||
m = Py_InitModule3("pycryptsetup", pycryptsetup_methods, "CryptSetup pythonized API.");
|
||||
MOD_DEF(m, "pycryptsetup", "CryptSetup pythonized API.", pycryptsetup_methods);
|
||||
Py_INCREF(&CryptSetupType);
|
||||
|
||||
PyModule_AddObject(m, "CryptSetup", (PyObject *)&CryptSetupType);
|
||||
@@ -710,4 +764,6 @@ PyMODINIT_FUNC initpycryptsetup(void)
|
||||
PyModule_AddIntConstant(m, "CRYPT_INACTIVE", CRYPT_INACTIVE);
|
||||
PyModule_AddIntConstant(m, "CRYPT_ACTIVE", CRYPT_ACTIVE);
|
||||
PyModule_AddIntConstant(m, "CRYPT_BUSY", CRYPT_BUSY);
|
||||
|
||||
return MOD_SUCCESS_VAL(m);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
INCLUDES = \
|
||||
AM_CPPFLAGS = -include config.h \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/lib \
|
||||
-DDATADIR=\""$(datadir)"\" \
|
||||
@@ -6,23 +6,25 @@ INCLUDES = \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DSYSCONFDIR=\""$(sysconfdir)"\" \
|
||||
-DVERSION=\""$(VERSION)"\" \
|
||||
-D_GNU_SOURCE
|
||||
-DVERSION=\""$(VERSION)"\"
|
||||
|
||||
# cryptsetup
|
||||
cryptsetup_SOURCES = \
|
||||
$(top_builddir)/lib/utils_crypt.c \
|
||||
$(top_builddir)/lib/utils_loop.c \
|
||||
$(top_builddir)/lib/utils_fips.c \
|
||||
utils_tools.c \
|
||||
utils_password.c \
|
||||
cryptsetup.c \
|
||||
cryptsetup.h
|
||||
|
||||
cryptsetup_LDADD = \
|
||||
$(top_builddir)/lib/libcryptsetup.la \
|
||||
@POPT_LIBS@ \
|
||||
@FIPSCHECK_LIBS@
|
||||
@FIPSCHECK_LIBS@ \
|
||||
@PWQUALITY_LIBS@
|
||||
|
||||
cryptsetup_CFLAGS = -Wall
|
||||
cryptsetup_CFLAGS = $(AM_CFLAGS) -Wall
|
||||
|
||||
sbin_PROGRAMS=cryptsetup
|
||||
|
||||
@@ -30,9 +32,10 @@ if STATIC_TOOLS
|
||||
sbin_PROGRAMS += cryptsetup.static
|
||||
cryptsetup_static_SOURCES = $(cryptsetup_SOURCES)
|
||||
cryptsetup_static_CFLAGS = $(cryptsetup_CFLAGS)
|
||||
cryptsetup_static_LDFLAGS = -all-static
|
||||
cryptsetup_static_LDFLAGS = $(AM_LDFLAGS) -all-static
|
||||
cryptsetup_static_LDADD = $(cryptsetup_LDADD) \
|
||||
@CRYPTO_STATIC_LIBS@ \
|
||||
@PWQUALITY_STATIC_LIBS@ \
|
||||
@DEVMAPPER_STATIC_LIBS@ \
|
||||
@UUID_LIBS@
|
||||
endif
|
||||
@@ -43,6 +46,7 @@ if VERITYSETUP
|
||||
veritysetup_SOURCES = \
|
||||
$(top_builddir)/lib/utils_crypt.c \
|
||||
$(top_builddir)/lib/utils_loop.c \
|
||||
utils_tools.c \
|
||||
veritysetup.c \
|
||||
cryptsetup.h
|
||||
|
||||
@@ -58,7 +62,7 @@ if STATIC_TOOLS
|
||||
sbin_PROGRAMS += veritysetup.static
|
||||
veritysetup_static_SOURCES = $(veritysetup_SOURCES)
|
||||
veritysetup_static_CFLAGS = $(veritysetup_CFLAGS)
|
||||
veritysetup_static_LDFLAGS = -all-static
|
||||
veritysetup_static_LDFLAGS = $(AM_LDFLAGS) -all-static
|
||||
veritysetup_static_LDADD = $(veritysetup_LDADD) \
|
||||
@CRYPTO_STATIC_LIBS@ \
|
||||
@DEVMAPPER_STATIC_LIBS@ \
|
||||
@@ -70,6 +74,7 @@ endif
|
||||
if REENCRYPT
|
||||
cryptsetup_reencrypt_SOURCES = \
|
||||
$(top_builddir)/lib/utils_crypt.c \
|
||||
utils_tools.c \
|
||||
cryptsetup_reencrypt.c \
|
||||
cryptsetup.h
|
||||
|
||||
@@ -82,7 +87,7 @@ if STATIC_TOOLS
|
||||
sbin_PROGRAMS += cryptsetup-reencrypt.static
|
||||
cryptsetup_reencrypt_static_SOURCES = $(cryptsetup_reencrypt_SOURCES)
|
||||
cryptsetup_reencrypt_static_CFLAGS = $(cryptsetup_reencrypt_CFLAGS)
|
||||
cryptsetup_reencrypt_static_LDFLAGS = -all-static
|
||||
cryptsetup_reencrypt_static_LDFLAGS = $(AM_LDFLAGS) -all-static
|
||||
cryptsetup_reencrypt_static_LDADD = $(cryptsetup_reencrypt_LDADD) \
|
||||
@CRYPTO_STATIC_LIBS@ \
|
||||
@DEVMAPPER_STATIC_LIBS@ \
|
||||
|
||||
1024
src/cryptsetup.c
1024
src/cryptsetup.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user