Compare commits

...

70 Commits

Author SHA1 Message Date
Milan Broz
64d6b339a0 Prepare version 1.6.6. 2014-08-16 11:15:46 +02:00
Milan Broz
4f5f1b78c4 Update po files. 2014-08-16 11:00:18 +02:00
Milan Broz
3e886ecf57 Update po files. 2014-08-13 17:50:00 +02:00
Milan Broz
210ea612b3 Avoid compilation warnings in Python wrapper.
All these are Python interface misconceptions,
the strings (or string arrays) in parameters should be const
parameters.

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

Better try to activate volume with dicard flags and if it is not possible,
try to activate device without the discard flag.
2014-07-24 22:11:58 +02:00
Milan Broz
3640eaa726 Re-check flags after DM device creations. 2014-07-24 11:52:58 +02:00
Milan Broz
2250d5f71f Move safe table params wipe into function which allocates it. 2014-07-24 11:37:24 +02:00
Milan Broz
d9678325a2 Update LUKS1 test images. 2014-07-12 21:16:19 +02:00
Milan Broz
dc8c47d936 Fallback to old temporary device mapping method if hash is not supported. 2014-07-12 20:30:24 +02:00
Milan Broz
5b7100ff87 Update po files. 2014-07-10 19:06:11 +02:00
Milan Broz
4afa592160 Set devel version. 2014-06-29 14:36:10 +02:00
Milan Broz
54c7a2b0aa Fix signed/unsigned compiler warnings. 2014-06-29 11:55:11 +02:00
Milan Broz
9cabc9bf05 Bump library version.
There are new use case but it is still backwards compatible.
2014-06-29 10:53:59 +02:00
Milan Broz
dfd46df8a5 Properly fail for unsupported IVs. 2014-06-29 10:38:50 +02:00
Milan Broz
25cd4f3a1d Add debug info for crypto wrapper in LUKS keyslot encryption. 2014-06-28 21:50:05 +02:00
Milan Broz
d5b594dd12 Remove uneeded check in luksFormat to allow operation as normal user. 2014-06-28 15:23:04 +02:00
Milan Broz
803686ea4b Prepare version 1.6.5. 2014-06-28 13:57:32 +02:00
Milan Broz
3add769b51 Add deprecation warning about internal terminal password query. 2014-06-28 13:49:26 +02:00
Milan Broz
d5a72cd65a Fix typo in kernel backend. 2014-06-26 15:38:51 +02:00
Milan Broz
d63163e46c Add notes about Whirlpool hash fail to tests. 2014-06-26 14:47:02 +02:00
Milan Broz
62d690492c Fix unit in reencrypt man page. 2014-06-26 14:44:15 +02:00
Ondrej Kozina
54d81a6258 fix memory leak on error path 2014-06-25 18:03:42 +02:00
Milan Broz
56679a6e4a Update es.po. 2014-06-25 17:57:12 +02:00
Milan Broz
e0788d9d61 Update es.po. 2014-06-24 17:56:05 +02:00
wagner
833e066853 sync with wiki, updated to "toned down" item 2.2 2014-06-24 03:06:36 +02:00
Milan Broz
02f860140d Fix trailing space. 2014-06-23 23:30:11 +02:00
Milan Broz
027cebade3 Update po files. 2014-06-23 21:40:54 +02:00
Milan Broz
bb8dbfdf5b Update author name. 2014-06-23 21:40:12 +02:00
Milan Broz
8e380183f8 Print minimal device size if LUKS header space is too small. 2014-06-22 17:51:31 +02:00
Ondrej Kozina
4f89028c67 modify FIPS checks
- we need a way to notify an user about running misconfigured system which
will turn to be unusable in real FIPS mode. For more details look at:
http://bugzilla.redhat.com/show_bug.cgi?id=1009707#c25

- also fixes invisble verbose log about running in FIPS mode due to its misplacement
2014-06-22 17:24:10 +02:00
Milan Broz
6b4c33d3a5 Enable to specify Python version in configure. 2014-06-18 23:06:04 +02:00
Robert Kuska
7a2e6990ca Port pycryptsetup-test.py to Python3. 2014-06-18 09:19:03 +02:00
Robert Kuska
98ba2f2333 Port pycryptsetup.c to Python3. 2014-06-18 09:09:40 +02:00
Ondrej Kozina
4e4d933d7b fix reencryption tests failure with older grep 2014-06-18 08:56:23 +02:00
Milan Broz
91c739958c Allow ECB mode in cryptsetup benchmark. 2014-06-17 23:09:13 +02:00
Milan Broz
1a6e1ae918 Always remove temporary active device name on load and format. 2014-06-17 22:28:51 +02:00
Milan Broz
aedf39a9ca Remove unused static declaration. 2014-06-17 22:01:59 +02:00
Milan Broz
a274cd3a74 Update TODO. 2014-06-17 21:55:42 +02:00
Milan Broz
6be21469fb Use internel PBKDF2 in Nettle library for Nettle crypto backend.
This also requires Nettle >= 2.6.
2014-06-17 21:54:14 +02:00
Milan Broz
e0d3ff8aeb Fix non-header context init for device in use. 2014-06-14 23:04:43 +02:00
Milan Broz
0614ab6b07 Allow simple status of crypt device without providing metadata header.
If device is activated, we can provide some information from
active kernel parameters instead of header.
2014-06-14 17:42:57 +02:00
Milan Broz
49e55c0f42 Fix keyfile offset parameter for loopaes.
Fixes Issue#216.
2014-06-14 14:35:27 +02:00
Milan Broz
be4edbb460 Update es.po. 2014-06-13 16:51:59 +02:00
Milan Broz
4d30237f7a Handle error better in storage wrapper. 2014-06-01 22:02:32 +02:00
Milan Broz
a3c0f6784b Process LUKS keyslots in userspace through kernel crypto wrapper.
This allow LUKS handling without requiring root privilege.

The dmcrypt device-mapper is used only for device activation now.
2014-06-01 21:34:21 +02:00
Milan Broz
6d4c2db3b1 Fix mode test for nonexisting table. 2014-06-01 20:57:45 +02:00
Milan Broz
1436f2a0a0 Add wrapper for cipher block size query.
There is no better way for now without loading crypto modules.
2014-06-01 20:56:17 +02:00
wagner
e6a46bf827 sync with Wiki version 2014-05-02 08:30:22 +02:00
Milan Broz
9563aa33c8 Fix PBKDF2 for crypto backens which does not support long HMAC keys.
(Or it rehases key in every iteration.)

- Kernel backens seems not to support >20480 HMAC key
- NSS is slow (without proper key reset)

Add some test vectors (commented out by default).
2014-04-13 19:34:50 +02:00
Milan Broz
6225c901fe Use proper images with mentioned hashes in luks test. 2014-04-13 19:34:06 +02:00
Milan Broz
cad0cbf0c8 Fix integer type warnings in debug log. 2014-04-13 16:41:29 +02:00
Milan Broz
1fc441f091 Include images in tarball ans use xz format. 2014-04-13 16:29:21 +02:00
Milan Broz
22849ccd11 Add luks1 compat image testing.
This test use long keyfile to test proper KDF functionality.
2014-04-13 16:21:11 +02:00
Cristian Rodríguez
a809224ec7 Fix all format string issues found by the attribute format patch 2014-04-12 08:52:20 +02:00
Cristian Rodríguez
ae23ecb9b2 annotate two function with __attribute__ ((format (printf...
Helps to find format strings bugs..
2014-04-12 08:52:06 +02:00
Milan Broz
0db77f3ace Update po files. 2014-04-06 18:58:35 +02:00
Milan Broz
779c80c581 Fix some spelling error found by lintian.
Thanks to Jonas Meurer.
2014-03-04 20:27:15 +01:00
wagner
00ced59c1a Sync with Wiki 2014-03-01 14:55:15 +01:00
wagner
20595f4b14 Sync with latest WIKI version of the FAQ 2014-03-01 14:42:12 +01:00
66 changed files with 4559 additions and 2949 deletions

View File

@@ -1,3 +1,3 @@
Christophe Saout <christophe@saout.de>
Jana Saout <jana@saout.de>
Clemens Fruhwirth <clemens@endorphin.org>
Milan Broz <gmazyland@gmail.com>

327
FAQ
View File

@@ -41,7 +41,7 @@ A. Contributors
SSDs/FLASH DRIVES: SSDs and Flash are different. Currently it is
unclear how to get LUKS or plain dm-crypt to run on them with the
full set of security features intact. This may or may not be a
problem, depending on the attacher model. See Section 5.19.
problem, depending on the attacker model. See Section 5.19.
BACKUP: Yes, encrypted disks die, just as normal ones do. A full
backup is mandatory, see Section "6. Backup and Data Recovery" on
@@ -268,6 +268,9 @@ A. Contributors
Note that automatic wiping is on the TODO list for cryptsetup, so
at some time in the future this will become unnecessary.
Alternatively, plain cm-crypt can be used for a very fast wipe with
crypto-grade randomness, see Item 2.19
04) Create the LUKS container:
cryptsetup luksFormat <target device>
@@ -322,7 +325,85 @@ A. Contributors
easy to make, but will compromise your security.
* 2.2 How do I set up encrypted swap?
* 2.2 LUKS on partitions or raw disks?
This is a complicated question, and made more so by the availability
of RAID and LVM. I will try to give some scenarios and discuss
advantages and disadvantages. Note that I say LUKS for simplicity,
but you can do all the things described with plain dm-crypt as well.
Also note that your specific scenario may be so special that most
or even all things I say below do not apply.
Be aware that if you add LVM into the mix, things can get very
complicated. Same with RAID but less so. In particular, data
recovery can get exceedingly difficult. Only do so if you have a
really good reason and always remember KISS is what separates an
engineer from an amateur. Of course, if you really need the added
complexity, KISS is satisfied. But be very sure as there is a price
to pay for it. In engineering, complexity is always the enemy and
needs to be fought without mercy when encountered.
Also consider using RAID instead of LVM, as at least with the old
superblock format 0.90, the RAID superblock is in the place (end
of disk) where the risk of it permanently damaging the LUKS header
is smallest and you can have your array assembled by the RAID
controller (i.e. the kernel), as it should be. Use partition type
0xfd for that. I recommend staying away from superblock formats
1.0, 1.1 and 1.2 unless you really need them. Be aware that you
lose autodetection with them and have to fall back to some
user-space script to do it.
Scenarios:
(1) Encrypted partition: Just make a partition to your liking,
and put LUKS on top of it and a filesystem into the LUKS container.
This gives you isolation of differently-tasked data areas, just as
ordinary partitioning does. You can have confidential data,
non-confidential data, data for some specific applications,
user-homes, root, etc. Advantages are simplicity as there is a 1:1
mapping between partitions and filesystems, clear security
functionality and the ability to separate data into different,
independent (!) containers.
Note that you cannot do this for encrypted root, that requires an
initrd. On the other hand, an initrd is about as vulnerable to a
competent attacker as a non-encrypted root, so there really is no
security advantage to doing it that way. An attacker that wants to
compromise your system will just compromise the initrd or the
kernel itself. The better way to deal with this is to make sure the
root partition does not store any critical data and move that to
additional encrypted partitions. If you really are concerned your
root partition may be sabotaged by somebody with physical access
(that would however strangely not, say, sabotage your BIOS,
keyboard, etc.), protect it in some other way. The PC is just not
set-up for a really secure boot-chain (whatever some people may
claim).
(2) Fully encrypted raw block device: For this, put LUKS on the
raw device (e.g. /dev/sdb) and put a filesystem into the LUKS
container, no partitioning whatsoever involved. This is very
suitable for things like external USB disks used for backups or
offline data-storage.
(3) Encrypted RAID: Create your RAID from partitions and/or full
devices. Put LUKS on top of the RAID device, just if it were an
ordinary block device. Applications are just the same as above, but
you get redundancy. (Side note as many people seem to be unaware of
it: You can do RAID1 with an arbitrary number of components in
Linux.) See also Item 2.8.
(4) Now, some people advocate doing the encryption below the RAID
layer. That has several serious problems. One is that suddenly
debugging RAID issues becomes much harder. You cannot do automatic
RAID assembly anymore. You need to keep the encryption keys for the
components in sync or manage them somehow. The only possible
advantage is that things may run a little faster as more CPUs do
the encryption, but if speed is a priority over security and
simplicity, you are doing this wrong anyways. A good way to
mitigate a speed issue is to get a CPU that does hardware AES.
* 2.3 How do I set up encrypted swap?
As things that are confidential can end up in swap (keys,
passphrases, etc. are usually protected against being swapped to
@@ -378,7 +459,7 @@ A. Contributors
swapon /dev/mapper/swap
* 2.3 What is the difference between "plain" and LUKS format?
* 2.4 What is the difference between "plain" and LUKS format?
First, unless you happen to understand the cryptographic background
well, you should use LUKS. It does protect the user from a lot of
@@ -443,7 +524,7 @@ A. Contributors
non-default XTS mode).
* 2.4 Can I encrypt an already existing, non-empty partition to use
* 2.5 Can I encrypt an already existing, non-empty partition to use
LUKS?
There is no converter, and it is not really needed. The way to do
@@ -458,7 +539,7 @@ A. Contributors
to be in a filesystem.
* 2.5 How do I use LUKS with a loop-device?
* 2.6 How do I use LUKS with a loop-device?
This can be very handy for experiments. Setup is just the same as
with any block device. If you want, for example, to use a 100MiB
@@ -472,7 +553,7 @@ A. Contributors
To unmap the file when done, use "losetup -d /dev/loop0".
* 2.6 When I add a new key-slot to LUKS, it asks for a passphrase but
* 2.7 When I add a new key-slot to LUKS, it asks for a passphrase but
then complains about there not being a key-slot with that
passphrase?
@@ -484,7 +565,7 @@ A. Contributors
new key-slot.
* 2.7 Encryption on top of RAID or the other way round?
* 2.8 Encryption on top of RAID or the other way round?
Unless you have special needs, place encryption between RAID and
filesystem, i.e. encryption on top of RAID. You can do it the other
@@ -510,7 +591,7 @@ A. Contributors
encrypted.
* 2.8 How do I read a dm-crypt key from file?
* 2.9 How do I read a dm-crypt key from file?
Use the --key-file option, like this:
@@ -525,7 +606,7 @@ A. Contributors
detail.
* 2.9 How do I read a LUKS slot key from file?
* 2.10 How do I read a LUKS slot key from file?
What you really do here is to read a passphrase from file, just as
you would with manual entry of a passphrase for a key-slot. You can
@@ -551,7 +632,7 @@ A. Contributors
cryptsetup luksOpen --key-file keyfile /dev/loop0 e1
* 2.10 How do I read the LUKS master key from file?
* 2.11 How do I read the LUKS master key from file?
The question you should ask yourself first is why you would want to
do this. The only legitimate reason I can think of is if you want
@@ -562,7 +643,7 @@ A. Contributors
do this here.
* 2.11 What are the security requirements for a key read from file?
* 2.12 What are the security requirements for a key read from file?
A file-stored key or passphrase has the same security requirements
as one entered interactively, however you can use random bytes and
@@ -574,7 +655,7 @@ A. Contributors
head -c 256 /dev/random > keyfile
* 2.12 If I map a journaled file system using dm-crypt/LUKS, does it
* 2.13 If I map a journaled file system using dm-crypt/LUKS, does it
still provide its usual transactional guarantees?
Yes, it does, unless a very old kernel is used. The required flags
@@ -602,7 +683,7 @@ A. Contributors
should improve further and eventually the problem should go away.
* 2.13 Can I use LUKS or cryptsetup with a more secure (external)
* 2.14 Can I use LUKS or cryptsetup with a more secure (external)
medium for key storage, e.g. TPM or a smartcard?
Yes, see the answers on using a file-supplied key. You do have to
@@ -616,7 +697,7 @@ A. Contributors
related to the cryptsetup project.
* 2.14 Can I resize a dm-crypt or LUKS partition?
* 2.15 Can I resize a dm-crypt or LUKS partition?
Yes, you can, as neither dm-crypt nor LUKS stores partition size.
Whether you should is a different question. Personally I recommend
@@ -636,7 +717,7 @@ A. Contributors
for that.
* 2.15 How do I Benchmark the Ciphers, Hashes and Modes?
* 2.16 How do I Benchmark the Ciphers, Hashes and Modes?
Since version 1.60 cryptsetup supports the "benchmark" command.
Simply run as root:
@@ -652,7 +733,7 @@ A. Contributors
and half of it is the cipher key, the other half is the XTS key.
* 2.16 How do I Verify I have an Authentic cryptsetup Source Package?
* 2.17 How do I Verify I have an Authentic cryptsetup Source Package?
Current maintainer is Milan Broz and he signs the release packages
with his PGP key. The key he currently uses is the "RSA key ID
@@ -677,7 +758,7 @@ A. Contributors
longer as an FAQ can sustain. If in doubt, ask on the mailing list.
* 2.17 Is there a concern with 4k Sectors?
* 2.18 Is there a concern with 4k Sectors?
Not from dm-crypt itself. Encryption will be done in 512B blocks,
but if the partition and filesystem are aligned correctly and the
@@ -689,6 +770,39 @@ A. Contributors
misaligned, dm-crypt can make the effect worse though.
* 2.19 How can I wipe a device with crypto-grade randomness?
The conventional recommendation if you want to not just do a
zero-wipe is to use something like
cat /dev/urandom > <taget-device>
That is very slow and painful at 10-20MB/s on a fast computer.
Using cryptsetup and a plain dm-crypt device with a random key, it
is much faster and gives you the same level of security. The
defaults are quite enough.
For device set-up, do the following:
cryptsetup open --type plain -d /dev/urandom /dev/<block-device> to_be_wiped
Then you have several options. Simple wipe without
progress-indicator:
cat /dev/zero > /dev/mapper/to_be_wiped
Progress-indicator by dd_rescue:
dd_rescue -w /dev/zero /dev/mapper/to_be_wiped
Progress-indicator by my "wcs" stream meter (available from
http://www.tansi.org/tools/index.html ):
cat /dev/zero | wcs > /dev/mapper/to_be_wiped
Remove the mapping at the end and you are done.
3. Common Problems
@@ -1124,9 +1238,9 @@ A. Contributors
new filesystem on the raw LUKS partition, making the raw partition
part of a raid array and just writing to the raw partition.
The LUKS header contains a 256 bit "salt" value and without that no
decryption is possible. While the salt is not secret, it is
key-grade material and cannot be reconstructed. This is a
The LUKS header contains a 256 bit "salt" per key-slot and without
that no decryption is possible. While the salts are not secret,
they are key-grade material and cannot be reconstructed. This is a
cryptographically strong "cannot". From observations on the
cryptsetup mailing-list, people typically go though the usual
stages of grief (Denial, Anger, Bargaining, Depression, Acceptance)
@@ -1135,12 +1249,13 @@ A. Contributors
fine. Even if we usually cannot help with getting back your data,
most people found the feedback comforting.
If your header does not contain an intact salt, best go directly
to the last stage ("Acceptance") and think about what to do now.
There is one exception that I know of: If your LUKS container is
still open, then it may be possible to extract the master key from
the running system. See Item "How do I recover the master key from
a mapped LUKS container?" in Section "Backup and Data Recovery".
If your header does not contain an intact key-slot salt, best go
directly to the last stage ("Acceptance") and think about what to
do now. There is one exception that I know of: If your LUKS
container is still open, then it may be possible to extract the
master key from the running system. See Item "How do I recover the
master key from a mapped LUKS container?" in Section "Backup and
Data Recovery".
* 5.8 What is a "salt"?
@@ -1669,6 +1784,16 @@ A. Contributors
cryptsetup luksHeaderRestore --header-backup-file <file> <device>
If you are unsure about a header to be restored, make a backup of
the current one first! You can also test the header-file without
restoring it by using the --header option for a detached header
like this:
cryptsetup --header <file> luksOpen <device> </dev/mapper/ -name>
If that unlocks your keys-lot, you are good. Do not forget to close
the device again.
* 6.3 How do I test a LUKS header?
@@ -1719,7 +1844,16 @@ A. Contributors
cat backup.tbz2.gpg | gpg - | tar djf -
Note: Always verify backups, especially encrypted ones.
Note: Always verify backups, especially encrypted ones!
There is one problem with verifying like this: The kernel may still
have some files cached and in fact verify them against RAM or may
even verify RAM against RAM, which defeats the purpose of the
exercise. The following command empties the kernel caches:
echo 3 > /proc/sys/vm/drop_caches
Run it after backup and before verify.
In both cases GnuPG will ask you interactively for your symmetric
key. The verify will only output errors. Use "tar dvjf -" to get
@@ -1727,6 +1861,13 @@ A. Contributors
unencrypted, turn off swap if it is not encrypted before doing the
backup.
Restore works like certification with the 'd' ('difference')
replaced by 'x' ('eXtract'). Refer to the man-page of tar for more
explanations and instructions. Note that with default options tar
will overwrite already existing files without warning. If you are
unsure about how to use tar, experiment with it in a location
where you cannot do damage.
You can of course use different or no compression and you can use
an asymmetric key if you have one and have a backup of the secret
key that belongs to it.
@@ -1810,14 +1951,15 @@ A. Contributors
damage the LUKS header or key-slots?
There are two critical components for decryption: The salt values
in the header itself and the key-slots. If the salt values are
overwritten or changed, nothing (in the cryptographically strong
sense) can be done to access the data, unless there is a backup
of the LUKS header. If a key-slot is damaged, the data can still
be read with a different key-slot, if there is a remaining
undamaged and used key-slot. Note that in order to make a key-slot
unrecoverable in a cryptographically strong sense, changing about
4-6 bits in random locations of its 128kiB size is quite enough.
in the key-slot descriptors of the header and the key-slots. If the
salt values are overwritten or changed, nothing (in the
cryptographically strong sense) can be done to access the data,
unless there is a backup of the LUKS header. If a key-slot is
damaged, the data can still be read with a different key-slot, if
there is a remaining undamaged and used key-slot. Note that in
order to make a key-slot unrecoverable in a cryptographically
strong sense, changing about 4-6 bits in random locations of its
128kiB size is quite enough.
* 6.9 What happens if I (quick) format a LUKS partition?
@@ -1951,6 +2093,67 @@ http://code.google.com/p/cryptsetup/source/browse/misc/luks-header-from-active
The exact specification of the format is here:
http://code.google.com/p/cryptsetup/wiki/Specification
For your convenience, here is the LUKS header with hex offsets.
NOTE: The spec counts key-slots from 1 to 8, but the cryptsetup
tool counts from 0 to 7. The numbers here refer to the cryptsetup
numbers.
Refers to LUKS On-Disk Format Specification Version 1.2.1
LUKS header:
offset length name data type description
-----------------------------------------------------------------------
0x0000 0x06 magic byte[] 'L','U','K','S', 0xba, 0xbe
0 6
0x0006 0x02 version uint16_t LUKS version
6 3
0x0008 0x20 cipher-name char[] cipher name spec.
8 32
0x0028 0x20 cipher-mode char[] cipher mode spec.
40 32
0x0048 0x20 hash-spec char[] hash spec.
72 32
0x0068 0x04 payload-offset uint32_t bulk data offset in sectors
104 4 (512 bytes per sector)
0x006c 0x04 key-bytes uint32_t number of bytes in key
108 4
0x0070 0x14 mk-digest byte[] master key checksum
112 20 calculated with PBKDF2
0x0084 0x20 mk-digest-salt byte[] salt for PBKDF2 when
132 32 calculating mk-digest
0x00a4 0x04 mk-digest-iter uint32_t iteration count for PBKDF2
164 4 when calculating mk-digest
0x00a8 0x28 uuid char[] partition UUID
168 40
0x00d0 0x30 key-slot-0 key slot key slot 0
208 48
0x0100 0x30 key-slot-1 key slot key slot 1
256 48
0x0130 0x30 key-slot-2 key slot key slot 2
304 48
0x0160 0x30 key-slot-3 key slot key slot 3
352 48
0x0190 0x30 key-slot-4 key slot key slot 4
400 48
0x01c0 0x30 key-slot-5 key slot key slot 5
448 48
0x01f0 0x30 key-slot-6 key slot key slot 6
496 48
0x0220 0x30 key-slot-7 key slot key slot 7
544 48
Key slot:
offset length name data type description
-------------------------------------------------------------------------
0x0000 0x04 active uint32_t key slot enabled/disabled
0 4
0x0004 0x04 iterations uint32_t PBKDF2 iteration count
4 4
0x0008 0x20 salt byte[] PBKDF2 salt
8 32
0x0028 0x04 key-material-offset uint32_t key start sector
40 4 (512 bytes/sector)
0x002c 0x04 stripes uint32_t number of anti-forensic
44 4 stripes
* 6.13 What is the smallest possible LUKS container?
@@ -2157,10 +2360,10 @@ http://code.google.com/p/cryptsetup/source/browse/misc/luks-header-from-active
accessible anymore!
With cryptsetup 1.1.x, the distro maintainer can define different
default encryption modes for LUKS and plain devices. You can check
these compiled-in defaults using "cryptsetup --help". Moreover, the
plain device default changed because the old IV mode was
vulnerable to a watermarking attack.
default encryption modes. You can check the compiled-in defaults
using "cryptsetup --help". Moreover, the plain device default
changed because the old IV mode was vulnerable to a watermarking
attack.
If you are using a plain device and you need a compatible mode, just
specify cipher, key size and hash algorithm explicitly. For
@@ -2186,9 +2389,49 @@ http://code.google.com/p/cryptsetup/source/browse/misc/luks-header-from-active
It is the other way round: In gcrypt 1.5.3 and before Whirlpool is
broken and it was fixed in the next version. If you selected
whirlpool as hash on creation of a LUKS container, it does not work
anymore with the fixed library. Currently, the only work-around is
to decrypt with the old version. This also shows one risk of using
rarely used settings.
anymore with the fixed library. This shows one serious risk of
using rarely used settings.
The only two ways to deal with this are either to decrypt with an
old gcrypt version that has the flaw or to use a compatibility
feature introduced in cryptsetup 1.6.4 and gcrypt 1.6.1 or later.
Versions of gcrypt between 1.5.4 and 1.6.0 cannot be used.
Steps:
- Make a least a header backup or better, refresh your full
backup. (You have a full backup, right? See Item 6.1 and
following.)
- Make sure you have cryptsetup 1.6.4 or later and check the gcrypt
version:
cryptsetup luksDump <your luks device> --debug | grep backend
If gcrypt is at version 1.5.3 or before:
- Reencrypt the LUKS header with a different hash. (Requires
entering all keyslot passphrases. If you do not have all, remove
the ones you do not have before.):
cryptsetup-reencrypt --keep-key --hash sha256 <your luks device>
If gcrypt is at version 1.6.1 or later:
- Patch the hash name in the LUKS header from "whirlpool" to
"whirlpool_gcryptbug". This activates the broken implementation.
The detailed header layout is in Item 6.12 of this FAQ and in the
LUKS on-disk format specification. One way to change the hash is
with the following command:
echo -n -e 'whirlpool_gcryptbug\0' | dd of=<luks device> bs=1 seek=72 conv=notrunc
- You can now open the device again. It is highly advisable to
change the hash now with cryptsetup-reencrypt as described above.
While you can reencrypt to use the fixed whirlpool, that may not
be a good idea as almost nobody seems to use it and hence the long
time until the bug was discovered.
9. References and Further Reading

8
TODO
View File

@@ -4,13 +4,5 @@ Version 1.7:
- TRIM for keyslots
- Do we need crypt_data_path() - path to data device (if differs)?
- Resync ETA time is not accurate, calculate it better (last minute window?).
- Crypt benchmark cannot test ECB mode.
- crypto backend should initialise itself only once (debug log)
- Some crypt backends are inefective fo PBKDF2 (missing fast key reset)
Add optimisation to internal PBKDF2 (hash HMAC key in advance).
- Kernel backend doesn't allow PBKDF2 key size > 20480 bytes
(should be fixed with optimisation above).
- Add test vectors to internal PBKDF2 code.
- Add support for Nettle PBKDF2.
- Extend existing LUKS header to use another KDF? (https://password-hashing.net/)
- Fix all crazy automake warnings (or switch to Cmake).

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[1.6.4])
AC_INIT([cryptsetup],[1.6.6])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=9:0:5
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"
@@ -17,8 +17,8 @@ AC_CONFIG_HEADERS([config.h:config.h.in])
# http://lists.gnu.org/archive/html/automake/2013-01/msg00060.html
# For old automake use this
#AM_INIT_AUTOMAKE(dist-bzip2)
AM_INIT_AUTOMAKE([dist-bzip2 1.12 serial-tests])
#AM_INIT_AUTOMAKE(dist-xz)
AM_INIT_AUTOMAKE([dist-xz 1.12 serial-tests])
if test "x$prefix" = "xNONE"; then
sysconfdir=/etc
@@ -210,13 +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=1
use_internal_pbkdf2=0
NO_FIPS([])
])
@@ -386,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])
@@ -395,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"])

View File

@@ -834,16 +834,16 @@
* 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>
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 Christophe Saout <christophe@saout.de>
2004-03-10 Wednesday 17:50 Jana Saout <jana@saout.de>
* lib/: libcryptsetup.h, libdevmapper.c: Small fixes.
2004-03-09 Tuesday 21:41 Christophe Saout <christophe@saout.de>
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
@@ -851,7 +851,7 @@
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>
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,
@@ -859,7 +859,7 @@
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>
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,
@@ -867,19 +867,19 @@
src/Makefile.am: BLKGETSIZE64 fixes and started modularity
enhancements
2004-03-04 Thursday 21:06 Christophe Saout <christophe@saout.de>
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 Christophe Saout <christophe@saout.de>
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 Christophe Saout <christophe@saout.de>
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,

54
docs/v1.6.5-ReleaseNotes Normal file
View 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.

29
docs/v1.6.6-ReleaseNotes Normal file
View File

@@ -0,0 +1,29 @@
Cryptsetup 1.6.6 Release Notes
==============================
Changes since version 1.6.5
* LUKS: Fix keyslot device access for devices which
do not support direct IO operations. (Regression in 1.6.5.)
* LUKS: Fallback to old temporary keyslot device mapping method
if hash (for ESSIV) is not supported by userspace crypto
library. (Regression in 1.6.5.)
* Properly activate device with discard (TRIM for SSDs)
if requested even if dm_crypt module is not yet loaded.
Only if discard is not supported by the old kernel then
the discard option is ignored.
* Fix some static analysis build warnings (scan-build).
* Report crypto lib version only once (and always add kernel
version) in debug output.
Cryptsetup API NOTE:
The direct terminal handling for passphrase entry will be removed from
libcryptsetup in next major version (application should handle it itself).
It means that you have to always either provide password in buffer or set
your own password callback function through crypt_set_password_callback().
See API documentation (or libcryptsetup.h) for more info.

View File

@@ -1,7 +1,7 @@
/*
* cryptsetup plain device helper functions
*
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
* Copyright (C) 2004, Jana Saout <jana@saout.de>
* Copyright (C) 2010-2012 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2012, Milan Broz
*

View File

@@ -5,7 +5,7 @@ noinst_LTLIBRARIES = libcrypto_backend.la
libcrypto_backend_la_CFLAGS = $(AM_CFLAGS) -Wall @CRYPTO_CFLAGS@
libcrypto_backend_la_SOURCES = crypto_backend.h \
crypto_cipher_kernel.c pbkdf_check.c crc32.c
crypto_cipher_kernel.c crypto_storage.c pbkdf_check.c crc32.c
if CRYPTO_BACKEND_GCRYPT
libcrypto_backend_la_SOURCES += crypto_gcrypt.c

View File

@@ -2,7 +2,7 @@
* crypto backend implementation
*
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2012, Milan Broz
* Copyright (C) 2010-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
@@ -28,6 +28,7 @@ struct crypt_device;
struct crypt_hash;
struct crypt_hmac;
struct crypt_cipher;
struct crypt_storage;
int crypt_backend_init(struct crypt_device *ctx);
@@ -72,13 +73,15 @@ 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 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);
@@ -89,4 +92,14 @@ 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 */

View File

@@ -2,7 +2,7 @@
* Linux kernel userspace API crypto backend implementation (skcipher)
*
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012, Milan Broz
* Copyright (C) 2012-2014, Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -44,6 +44,50 @@ struct crypt_cipher {
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);
@@ -99,7 +143,8 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
return r;
}
if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, buffer, length) == -1) {
if (length && strcmp(name, "cipher_null") &&
setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, buffer, length) == -1) {
crypt_cipher_destroy(h);
return -EINVAL;
}
@@ -142,6 +187,9 @@ static int crypt_cipher_crypt(struct crypt_cipher *ctx,
/* Set encrypt/decrypt operation */
header = CMSG_FIRSTHDR(&msg);
if (!header)
return -EINVAL;
header->cmsg_level = SOL_ALG;
header->cmsg_type = ALG_SET_OP;
header->cmsg_len = CMSG_LEN(sizeof(*type));
@@ -202,6 +250,11 @@ int crypt_cipher_destroy(struct crypt_cipher *ctx)
#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)
{

View File

@@ -2,7 +2,7 @@
* GCRYPT crypto backend implementation
*
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2012, Milan Broz
* Copyright (C) 2010-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
@@ -331,7 +331,7 @@ int crypt_pbkdf(const char *kdf, const char *hash,
return -EINVAL;
return pkcs5_pbkdf2(hash_name, password, password_length, salt, salt_length,
iterations, key_length, key);
iterations, key_length, key, 0);
#else /* USE_INTERNAL_PBKDF2 */
int hash_id = gcry_md_map_name(hash_name);

View File

@@ -2,7 +2,7 @@
* Linux kernel userspace API crypto backend implementation
*
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2012, Milan Broz
* Copyright (C) 2010-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
@@ -44,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, 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 {
@@ -289,9 +290,11 @@ int crypt_pbkdf(const char *kdf, const char *hash,
char *key, size_t key_length,
unsigned int iterations)
{
if (!kdf || strncmp(kdf, "pbkdf2", 6))
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);
iterations, key_length, key, ha->block_length);
}

View File

@@ -2,7 +2,7 @@
* Nettle crypto backend implementation
*
* Copyright (C) 2011-2012 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2012, Milan Broz
* Copyright (C) 2011-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
@@ -24,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";
@@ -284,10 +285,21 @@ int crypt_pbkdf(const char *kdf, const char *hash,
char *key, size_t key_length,
unsigned int iterations)
{
struct crypt_hmac *h;
int r;
if (!kdf || strncmp(kdf, "pbkdf2", 6))
return -EINVAL;
/* FIXME: switch to internal implementation in Nettle 2.6 */
return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
iterations, key_length, key);
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;
}

View File

@@ -2,7 +2,7 @@
* NSS crypto backend implementation
*
* Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2012, Milan Broz
* Copyright (C) 2010-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
@@ -35,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 }
};
@@ -308,9 +309,11 @@ int crypt_pbkdf(const char *kdf, const char *hash,
char *key, size_t key_length,
unsigned int iterations)
{
if (!kdf || strncmp(kdf, "pbkdf2", 6))
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);
iterations, key_length, key, ha->block_length);
}

View File

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

View File

@@ -0,0 +1,291 @@
/*
* 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 -ENOENT;
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)
return -ENOENT;
if ((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;
}

View File

@@ -5,6 +5,7 @@
*
* 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
@@ -26,6 +27,25 @@
#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
*
@@ -52,17 +72,26 @@
* 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)
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;
@@ -152,8 +181,18 @@ int pkcs5_pbkdf2(const char *hash,
*
*/
if (crypt_hmac_init(&hmac, hash, P, Plen))
return -EINVAL;
/* 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);
@@ -185,5 +224,203 @@ int pkcs5_pbkdf2(const char *hash,
rc = 0;
out:
crypt_hmac_destroy(hmac);
memset(U, 0, sizeof(U));
memset(T, 0, sizeof(T));
memset(tmp, 0, tmplen);
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

View File

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

View File

@@ -1,7 +1,7 @@
/*
* 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
@@ -105,7 +105,7 @@ ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t
unsigned crypt_getpagesize(void);
int init_crypto(struct crypt_device *ctx);
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)

View File

@@ -1,7 +1,7 @@
/*
* 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
@@ -176,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
@@ -530,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,
@@ -548,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,
@@ -594,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,
@@ -620,6 +630,9 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
* @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_change_by_passphrase(struct crypt_device *cd,
int keyslot_old,
@@ -646,7 +659,6 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
* @return allocated key slot number or negative errno otherwise.
*
* @note Note that @e keyfile can be "-" for STDIN
*
*/
int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
int keyslot,
@@ -680,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,
@@ -763,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,

View File

@@ -1,7 +1,7 @@
/*
* 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
@@ -28,7 +28,6 @@
#include <fcntl.h>
#include <linux/fs.h>
#include <uuid/uuid.h>
#include <sys/utsname.h>
#include "internal.h"
@@ -86,12 +85,12 @@ static void set_dm_error(int level,
va_start(va, f);
if (vasprintf(&msg, f, va) > 0) {
if (level < 4 && !_quiet_log) {
log_err(_context, msg);
log_err(_context, "%s", msg);
log_err(_context, "\n");
} else {
/* We do not use DM visual stack backtrace here */
if (strncmp(msg, "<backtrace>", 11))
log_dbg(msg);
log_dbg("%s", msg);
}
}
free(msg);
@@ -159,16 +158,6 @@ static void _dm_set_verity_compat(const char *dm_version, unsigned verity_maj,
verity_maj, verity_min, verity_patch);
}
static void _dm_kernel_info(void)
{
struct utsname uts;
if (!uname(&uts))
log_dbg("Detected kernel %s %s %s.",
uts.sysname, uts.release, uts.machine);
}
static int _dm_check_versions(void)
{
struct dm_task *dmt;
@@ -179,8 +168,6 @@ static int _dm_check_versions(void)
if (_dm_crypt_checked)
return 1;
_dm_kernel_info();
/* Shut up DM while checking */
_quiet_log = 1;
@@ -306,22 +293,19 @@ static void hex_key(char *hexkey, size_t key_size, const char *key)
}
/* http://code.google.com/p/cryptsetup/wiki/DMCrypt */
static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd)
static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd, uint32_t flags)
{
int r, max_size, null_cipher = 0;
char *params, *hexkey;
const char *features = "";
const char *features;
if (!dmd)
return NULL;
if (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
if (dm_flags() & DM_DISCARDS_SUPPORTED) {
features = " 1 allow_discards";
log_dbg("Discard/TRIM is allowed.");
} else
log_dbg("Discard/TRIM is not supported by the kernel.");
}
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
features = " 1 allow_discards";
else
features = "";
if (!strncmp(dmd->u.crypt.cipher, "cipher_null-", 12))
null_cipher = 1;
@@ -566,6 +550,9 @@ static int _dm_create_device(const char *name, const char *type,
uint32_t cookie = 0;
uint16_t udev_flags = 0;
if (!params)
return -EINVAL;
if (flags & CRYPT_ACTIVATE_PRIVATE)
udev_flags = CRYPT_TEMP_UDEV_FLAGS;
@@ -642,12 +629,14 @@ out_no_removal:
if (cookie && _dm_use_udev())
(void)_dm_udev_wait(cookie);
if (params)
crypt_safe_free(params);
if (dmt)
dm_task_destroy(dmt);
dm_task_update_nodes();
/* If code just loaded target module, update versions */
_dm_check_versions();
return r;
}
@@ -657,7 +646,8 @@ int dm_create_device(struct crypt_device *cd, const char *name,
int reload)
{
char *table_params = NULL;
int r = -EINVAL;
uint32_t dmd_flags;
int r;
if (!type)
return -EINVAL;
@@ -665,15 +655,29 @@ int dm_create_device(struct crypt_device *cd, const char *name,
if (dm_init_context(cd))
return -ENOTSUP;
dmd_flags = dmd->flags;
if (dmd->target == DM_CRYPT)
table_params = get_dm_crypt_params(dmd);
table_params = get_dm_crypt_params(dmd, dmd_flags);
else if (dmd->target == DM_VERITY)
table_params = get_dm_verity_params(dmd->u.verity.vp, dmd);
if (table_params)
r = _dm_create_device(name, type, dmd->data_device,
dmd->flags, dmd->uuid, dmd->size,
table_params, reload);
r = _dm_create_device(name, type, dmd->data_device, dmd_flags,
dmd->uuid, dmd->size, table_params, reload);
/* If discard not supported try to load without discard */
if (!reload && r && dmd->target == DM_CRYPT &&
(dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!(dm_flags() & DM_DISCARDS_SUPPORTED)) {
log_dbg("Discard/TRIM is not supported, retrying activation.");
dmd_flags = dmd_flags & ~CRYPT_ACTIVATE_ALLOW_DISCARDS;
crypt_safe_free(table_params);
table_params = get_dm_crypt_params(dmd, dmd_flags);
r = _dm_create_device(name, type, dmd->data_device, dmd_flags,
dmd->uuid, dmd->size, table_params, reload);
}
crypt_safe_free(table_params);
dm_exit_context();
return r;
}

View File

@@ -137,7 +137,7 @@ int LOOPAES_parse_keyfile(struct crypt_device *cd,
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;

View File

@@ -3,6 +3,7 @@
*
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 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
@@ -26,8 +27,13 @@
#include "internal.h"
static void _error_hint(struct crypt_device *ctx, const char *device,
const char *cipher_spec, const char *mode, size_t keyLength)
const char *cipher, const char *mode, size_t keyLength)
{
char cipher_spec[MAX_CIPHER_LEN * 3];
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);
@@ -60,6 +66,8 @@ static int LUKS_endec_template(char *src, size_t srcLength,
};
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;
@@ -94,7 +102,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
if (r < 0) {
if (r != -EACCES && r != -ENOTSUP)
_error_hint(ctx, device_path(dmd.data_device),
cipher_spec, cipher_mode, vk->keylength * 8);
cipher, cipher_mode, vk->keylength * 8);
return -EIO;
}
@@ -125,8 +133,64 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
unsigned int sector,
struct crypt_device *ctx)
{
return LUKS_endec_template(src, srcLength, cipher, cipher_mode,
vk, sector, write_blockwise, O_RDWR, ctx);
struct device *device = crypt_metadata_device(ctx);
struct crypt_storage *s;
int devfd = -1, 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;
r = -EIO;
/* Write buffer to device */
bsize = device_block_size(device);
if (bsize <= 0)
goto out;
devfd = device_open(device, O_RDWR);
if (devfd == -1)
goto out;
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
write_blockwise(devfd, bsize, src, srcLength) == -1)
goto out;
r = 0;
out:
if(devfd != -1)
close(devfd);
if (r)
log_err(ctx, _("IO error while encrypting keyslot.\n"));
return r;
}
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
@@ -136,6 +200,61 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
unsigned int sector,
struct crypt_device *ctx)
{
return LUKS_endec_template(dst, dstLength, cipher, cipher_mode,
vk, sector, read_blockwise, O_RDONLY, ctx);
struct device *device = crypt_metadata_device(ctx);
struct crypt_storage *s;
int devfd = -1, 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.");
r = -EIO;
/* Read buffer from device */
bsize = device_block_size(device);
if (bsize <= 0)
goto bad;
devfd = device_open(device, O_RDONLY);
if (devfd == -1)
goto bad;
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
read_blockwise(devfd, bsize, dst, dstLength) == -1)
goto bad;
close(devfd);
/* Decrypt buffer */
r = crypt_storage_decrypt(s, 0, dstLength / SECTOR_SIZE, dst);
crypt_storage_destroy(s);
return r;
bad:
if(devfd != -1)
close(devfd);
log_err(ctx, _("IO error while decrypting keyslot.\n"));
crypt_storage_destroy(s);
return r;
}

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2013, Milan Broz
* 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
@@ -83,11 +83,12 @@ static int LUKS_check_device_size(struct crypt_device *ctx, size_t keyLength)
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_path(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;
}
@@ -147,22 +148,20 @@ static const char *dbg_slot_state(crypt_keyslot_info ki)
}
}
int LUKS_hdr_backup(
const char *backup_file,
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;
r = LUKS_read_phdr(hdr, 1, 0, ctx);
r = LUKS_read_phdr(&hdr, 1, 0, ctx);
if (r)
return r;
hdr_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);
@@ -171,10 +170,10 @@ int LUKS_hdr_backup(
goto out;
}
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes).",
sizeof(*hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);
log_dbg("Storing backup of header (%zu bytes) and keyslot area (%zu bytes).",
sizeof(hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);
log_dbg("Output backup file size: %u bytes.", buffer_size);
log_dbg("Output backup file size: %zu bytes.", buffer_size);
devfd = device_open(device, O_RDONLY);
if(devfd == -1) {
@@ -190,8 +189,8 @@ int LUKS_hdr_backup(
close(devfd);
/* Wipe unused area, so backup cannot contain old signatures */
if (hdr->keyblock[0].keyMaterialOffset * SECTOR_SIZE == LUKS_ALIGN_KEYSLOTS)
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 = open(backup_file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR);
if (devfd == -1) {
@@ -213,6 +212,7 @@ int LUKS_hdr_backup(
out:
if (devfd != -1)
close(devfd);
memset(&hdr, 0, sizeof(hdr));
crypt_safe_free(buffer);
return r;
}
@@ -287,7 +287,7 @@ int LUKS_hdr_restore(
goto out;
}
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes) to device %s.",
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 = device_open(device, O_RDWR);
@@ -520,7 +520,7 @@ int LUKS_read_phdr(struct luks_phdr *hdr,
if (repair && !require_luks_device)
return -EINVAL;
log_dbg("Reading LUKS header of size %d from device %s",
log_dbg("Reading LUKS header of size %zu from device %s",
hdr_size, device_path(device));
devfd = device_open(device, O_RDONLY);
@@ -552,7 +552,7 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
struct luks_phdr convHdr;
int r;
log_dbg("Updating LUKS header of size %d on device %s",
log_dbg("Updating LUKS header of size %zu on device %s",
sizeof(struct luks_phdr), device_path(device));
r = LUKS_check_device_size(ctx, hdr->keyBytes);

View File

@@ -130,7 +130,6 @@ int LUKS_hdr_uuid_set(
int LUKS_hdr_backup(
const char *backup_file,
struct luks_phdr *hdr,
struct crypt_device *ctx);
int LUKS_hdr_restore(

View File

@@ -1,7 +1,7 @@
/*
* 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
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/utsname.h>
#include <fcntl.h>
#include <errno.h>
@@ -78,6 +79,13 @@ struct crypt_device {
struct crypt_params_tcrypt params;
struct tcrypt_phdr hdr;
} tcrypt;
struct { /* used if initialized without header by name */
char *active_name;
/* buffers, must refresh from kernel on every query */
char cipher[MAX_CIPHER_LEN];
char cipher_mode[MAX_CIPHER_LEN];
unsigned int key_size;
} none;
} u;
/* callbacks definitions */
@@ -92,6 +100,9 @@ struct crypt_device {
char error[MAX_ERROR_LENGTH];
};
/* Just to suppress redundant messages about crypto backend */
static int _crypto_logged = 0;
/* Global error */
/* FIXME: not thread safe, remove this later */
static char global_error[MAX_ERROR_LENGTH] = {0};
@@ -181,6 +192,7 @@ struct device *crypt_data_device(struct crypt_device *cd)
int init_crypto(struct crypt_device *ctx)
{
struct utsname uts;
int r;
r = crypt_random_init(ctx);
@@ -193,7 +205,14 @@ int init_crypto(struct crypt_device *ctx)
if (r < 0)
log_err(ctx, _("Cannot initialize crypto backend.\n"));
log_dbg("Crypto backend (%s) initialized.", crypt_backend_version());
if (!r && !_crypto_logged) {
log_dbg("Crypto backend (%s) initialized.", crypt_backend_version());
if (!uname(&uts))
log_dbg("Detected kernel %s %s %s.",
uts.sysname, uts.release, uts.machine);
_crypto_logged = 1;
}
return r;
}
@@ -273,6 +292,24 @@ static int onlyLUKS(struct crypt_device *cd)
return r;
}
static void crypt_set_null_type(struct crypt_device *cd)
{
if (!cd->type)
return;
free(cd->type);
cd->type = NULL;
cd->u.none.active_name = NULL;
}
static void crypt_reset_null_type(struct crypt_device *cd)
{
if (cd->type)
return;
free(cd->u.none.active_name);
cd->u.none.active_name = NULL;
}
/* keyslot helpers */
static int keyslot_verify_or_find_empty(struct crypt_device *cd, int *keyslot)
@@ -753,8 +790,7 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
r = _crypt_load_luks1(cd, 0, 0);
if (r < 0) {
log_dbg("LUKS device header does not match active device.");
free(cd->type);
cd->type = NULL;
crypt_set_null_type(cd);
r = 0;
goto out;
}
@@ -763,14 +799,12 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
if (r < 0) {
log_dbg("LUKS device header uuid: %s mismatches DM returned uuid %s",
cd->u.luks1.hdr.uuid, dmd.uuid);
free(cd->type);
cd->type = NULL;
crypt_set_null_type(cd);
r = 0;
}
} else {
log_dbg("LUKS device header not available.");
free(cd->type);
cd->type = NULL;
crypt_set_null_type(cd);
r = 0;
}
} else if (isTCRYPT(cd->type)) {
@@ -904,7 +938,11 @@ out:
if (r < 0) {
crypt_free(*cd);
*cd = NULL;
} else if (!(*cd)->type && name) {
/* For anonymous device (no header found) remember initialized name */
(*cd)->u.none.active_name = strdup(name);
}
device_free(dmd.data_device);
free(CONST_CAST(void*)dmd.uuid);
return r;
@@ -1004,11 +1042,6 @@ static int _crypt_format_luks1(struct crypt_device *cd,
&required_alignment,
&alignment_offset, DEFAULT_DISK_ALIGNMENT);
/* Check early if we cannot allocate block device for key slot access */
r = device_block_adjust(cd, cd->device, DEV_OK, 0, NULL, NULL);
if(r < 0)
return r;
r = LUKS_generate_phdr(&cd->u.luks1.hdr, cd->volume_key, cipher, cipher_mode,
(params && params->hash) ? params->hash : "sha1",
uuid, LUKS_STRIPES,
@@ -1202,6 +1235,8 @@ int crypt_format(struct crypt_device *cd,
log_dbg("Formatting device %s as type %s.", mdata_device_path(cd) ?: "(none)", type);
crypt_reset_null_type(cd);
r = init_crypto(cd);
if (r < 0)
return r;
@@ -1222,8 +1257,7 @@ int crypt_format(struct crypt_device *cd,
}
if (r < 0) {
free(cd->type);
cd->type = NULL;
crypt_set_null_type(cd);
crypt_free_volume_key(cd->volume_key);
cd->volume_key = NULL;
}
@@ -1243,6 +1277,8 @@ int crypt_load(struct crypt_device *cd,
if (!crypt_metadata_device(cd))
return -EINVAL;
crypt_reset_null_type(cd);
if (!requested_type || isLUKS(requested_type)) {
if (cd->type && !isLUKS(cd->type)) {
log_dbg("Context is already initialised to type %s", cd->type);
@@ -1291,10 +1327,8 @@ int crypt_repair(struct crypt_device *cd,
/* cd->type and header must be set in context */
r = crypt_check_data_device_size(cd);
if (r < 0) {
free(cd->type);
cd->type = NULL;
}
if (r < 0)
crypt_set_null_type(cd);
return r;
}
@@ -1383,6 +1417,9 @@ int crypt_header_backup(struct crypt_device *cd,
if ((requested_type && !isLUKS(requested_type)) || !backup_file)
return -EINVAL;
if (cd->type && !isLUKS(cd->type))
return -EINVAL;
r = init_crypto(cd);
if (r < 0)
return r;
@@ -1390,13 +1427,15 @@ int crypt_header_backup(struct crypt_device *cd,
log_dbg("Requested header backup of device %s (%s) to "
"file %s.", mdata_device_path(cd), requested_type, backup_file);
return LUKS_hdr_backup(backup_file, &cd->u.luks1.hdr, cd);
r = LUKS_hdr_backup(backup_file, cd);
return r;
}
int crypt_header_restore(struct crypt_device *cd,
const char *requested_type,
const char *backup_file)
{
struct luks_phdr hdr;
int r;
if (requested_type && !isLUKS(requested_type))
@@ -1412,7 +1451,10 @@ int crypt_header_restore(struct crypt_device *cd,
log_dbg("Requested header restore to device %s (%s) from "
"file %s.", mdata_device_path(cd), requested_type, backup_file);
return LUKS_hdr_restore(backup_file, &cd->u.luks1.hdr, cd);
r = LUKS_hdr_restore(backup_file, isLUKS(cd->type) ? &cd->u.luks1.hdr : &hdr, cd);
memset(&hdr, 0, sizeof(hdr));
return r;
}
void crypt_free(struct crypt_device *cd)
@@ -1438,6 +1480,8 @@ void crypt_free(struct crypt_device *cd)
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
free(cd->u.verity.root_hash);
free(cd->u.verity.uuid);
} else if (!cd->type) {
free(cd->u.none.active_name);
}
free(cd->type);
@@ -2426,6 +2470,31 @@ int crypt_dump(struct crypt_device *cd)
return -EINVAL;
}
static int _init_by_name_crypt_none(struct crypt_device *cd)
{
struct crypt_dm_active_device dmd = {};
int r;
if (cd->type || !cd->u.none.active_name)
return -EINVAL;
r = dm_query_device(cd, cd->u.none.active_name,
DM_ACTIVE_CRYPT_CIPHER |
DM_ACTIVE_CRYPT_KEYSIZE, &dmd);
if (r >= 0)
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher,
cd->u.none.cipher, NULL,
cd->u.none.cipher_mode);
if (!r)
cd->u.none.key_size = dmd.u.crypt.vk->keylength;
crypt_free_volume_key(dmd.u.crypt.vk);
free(CONST_CAST(void*)dmd.u.crypt.cipher);
return r;
}
const char *crypt_get_cipher(struct crypt_device *cd)
{
if (isPLAIN(cd->type))
@@ -2440,6 +2509,9 @@ const char *crypt_get_cipher(struct crypt_device *cd)
if (isTCRYPT(cd->type))
return cd->u.tcrypt.params.cipher;
if (!cd->type && !_init_by_name_crypt_none(cd))
return cd->u.none.cipher;
return NULL;
}
@@ -2457,6 +2529,9 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd)
if (isTCRYPT(cd->type))
return cd->u.tcrypt.params.mode;
if (!cd->type && !_init_by_name_crypt_none(cd))
return cd->u.none.cipher_mode;
return NULL;
}
@@ -2498,6 +2573,9 @@ int crypt_get_volume_key_size(struct crypt_device *cd)
if (isTCRYPT(cd->type))
return cd->u.tcrypt.params.key_size;
if (!cd->type && !_init_by_name_crypt_none(cd))
return cd->u.none.key_size;
return 0;
}

View File

@@ -485,7 +485,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
size_t passphrase_size;
char *key;
unsigned int i, skipped = 0;
int r = -EINVAL, legacy_modes;
int r = -EPERM, legacy_modes;
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
return -ENOMEM;
@@ -498,7 +498,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded.\n"),
TCRYPT_KEY_POOL_LEN);
return -EPERM;
goto out;
}
/* Calculate pool content from keyfiles */
@@ -558,7 +558,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
", volume size %" PRIu64, (int)hdr->d.version,
(int)hdr->d.version_tc, (int)hdr->d.sector_size,
hdr->d.mk_offset, hdr->d.hidden_volume_size, hdr->d.volume_size);
log_dbg("TCRYPT: Header cipher %s-%s, key size %d",
log_dbg("TCRYPT: Header cipher %s-%s, key size %zu",
params->cipher, params->mode, params->key_size);
}
out:
@@ -580,7 +580,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
assert(sizeof(struct tcrypt_phdr) == 512);
log_dbg("Reading TCRYPT header of size %d bytes from device %s.",
log_dbg("Reading TCRYPT header of size %zu bytes from device %s.",
hdr_size, device_path(device));
bs = device_block_size(device);
@@ -1038,6 +1038,6 @@ int TCRYPT_dump(struct crypt_device *cd,
}
log_std(cd, "Cipher chain:\t%s\n", params->cipher);
log_std(cd, "Cipher mode:\t%s\n", params->mode);
log_std(cd, "MK bits: \t%d\n", params->key_size * 8);
log_std(cd, "MK bits: \t%zu\n", params->key_size * 8);
return 0;
}

View File

@@ -1,7 +1,7 @@
/*
* 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

View File

@@ -157,7 +157,7 @@ static int untimed_read(int fd, char *pass, size_t maxlen)
static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
{
struct timeval t;
fd_set fds;
fd_set fds = {}; /* Just to avoid scan-build false report for FD_SET */
int failed = -1;
FD_ZERO(&fds);
@@ -176,16 +176,18 @@ static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
{
struct termios orig, tmp;
int failed = -1;
int infd = STDIN_FILENO, outfd;
int infd, outfd;
if (maxlen < 1)
goto out_err;
/* Read and write to /dev/tty if available */
if ((infd = outfd = open("/dev/tty", O_RDWR)) == -1) {
infd = open("/dev/tty", O_RDWR);
if (infd == -1) {
infd = STDIN_FILENO;
outfd = STDERR_FILENO;
}
} else
outfd = infd;
if (tcgetattr(infd, &orig))
goto out_err;

View File

@@ -1,7 +1,7 @@
/*
* device backend utilities
*
* 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
@@ -72,6 +72,9 @@ int device_open(struct device *device, int flags)
devfd = open(device_path(device), flags | O_SYNC);
}
if (devfd < 0)
log_dbg("Cannot open device %s.", device_path(device));
return devfd;
}
@@ -229,6 +232,9 @@ int device_block_size(struct device *device)
if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
r = bsize;
out:
if (r <= 0)
log_dbg("Cannot get block size for device %s.", device_path(device));
close(fd);
return r;
}

View File

@@ -1,7 +1,7 @@
/*
* 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

View File

@@ -1,7 +1,7 @@
/*
* 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

View File

@@ -37,12 +37,13 @@ int crypt_fips_mode(void)
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)) {
fputs(_("FIPS checksum verification failed.\n"), stderr);
_exit(EXIT_FAILURE);
if (FIPSCHECK_kernel_fips_mode())
_exit(EXIT_FAILURE);
}
}

View File

@@ -63,11 +63,11 @@ int VERITY_read_sb(struct crypt_device *cd,
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 ".",
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"),
log_err(cd, _("Verity device %s doesn't use on-disk header.\n"),
device_path(device));
return -EINVAL;
}
@@ -159,17 +159,17 @@ int VERITY_write_sb(struct crypt_device *cd,
uuid_t uuid;
int r, devfd = 0;
log_dbg("Updating VERITY header of size %u on device %s, offset %" PRIu64 ".",
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"),
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"),
log_err(cd, _("Verity device %s doesn't use on-disk header.\n"),
device_path(device));
return -EINVAL;
}

View File

@@ -139,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.
@@ -160,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"
@@ -187,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

View File

@@ -131,7 +131,7 @@ Opens (creates a mapping with) <name> backed by device <device>.
\-\-key-file, \-\-keyfile-offset, \-\-key-size, \-\-offset, \-\-skip, \-\-size,
\-\-readonly, \-\-shared, \-\-allow-discards]
Example: 'cryptsetup open --type plain /dev/sda10 e1' maps the raw
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.
@@ -248,7 +248,7 @@ as positional argument or via \-\-key-file.
\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
@@ -292,7 +292,7 @@ passphrase makes a LUKS container permanently inaccessible.
\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
@@ -438,7 +438,7 @@ 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),
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
@@ -657,7 +657,7 @@ master key which will compromise security.
For \fIluksAddKey\fR this allows adding a new passphrase
without having to know an exiting one.
For \fIopen\fR this allows to open the LUKS device
For \fIopen\fR this allows one to open the LUKS device
without giving a passphrase.
.TP
.B "\-\-dump\-master\-key"
@@ -807,7 +807,7 @@ 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
@@ -1003,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>.
@@ -1012,7 +1012,7 @@ 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

View File

@@ -132,7 +132,7 @@ and rewritten for libcryptsetup by Milan Broz <gmazyland@gmail.com>.
.SH COPYRIGHT
Copyright \(co 2012-2013 Red Hat, Inc.
.br
Copyright \(co 2012-2013 Milan Broz
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.

455
po/cs.po

File diff suppressed because it is too large Load Diff

501
po/de.po

File diff suppressed because it is too large Load Diff

678
po/es.po

File diff suppressed because it is too large Load Diff

644
po/fi.po

File diff suppressed because it is too large Load Diff

427
po/fr.po

File diff suppressed because it is too large Load Diff

679
po/it.po

File diff suppressed because it is too large Load Diff

678
po/nl.po

File diff suppressed because it is too large Load Diff

427
po/pl.po

File diff suppressed because it is too large Load Diff

455
po/uk.po

File diff suppressed because it is too large Load Diff

467
po/vi.po

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ pyexec_LTLIBRARIES = pycryptsetup.la
pycryptsetup_la_SOURCES = pycryptsetup.c
pycryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) -fno-strict-aliasing
pycryptsetup_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
pycryptsetup_la_LIBADD = $(top_builddir)/lib/libcryptsetup.la -lpython$(PYTHON_VERSION)
pycryptsetup_la_LIBADD = $(top_builddir)/lib/libcryptsetup.la $(PYTHON_LIBS)
else
all:
endif

View File

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

View File

@@ -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,29 @@
#include "libcryptsetup.h"
/* Python API use char* where const char* should be used... */
#define CONST_CAST(x) (x)(uintptr_t)
#if PY_MAJOR_VERSION < 3
#define MOD_ERROR_VAL
#define MOD_SUCCESS_VAL(val)
#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
MOD_INIT(pycryptsetup);
typedef struct {
PyObject_HEAD
@@ -128,7 +151,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,17 +178,19 @@ 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)
{
static char *kwlist[] = {"device", "name", "yesDialog", "passwordDialog", "logFunc", NULL};
static const char *kwlist[] = {"device", "name", "yesDialog", "passwordDialog", "logFunc", NULL};
PyObject *yesDialogCB = NULL,
*passwordDialogCB = NULL,
*cmdLineLogCB = NULL,
@@ -173,7 +198,7 @@ static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwd
char *device = NULL, *deviceName = NULL;
int r;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOOO", kwlist, &device, &deviceName,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOOO", CONST_CAST(char**)kwlist, &device, &deviceName,
&yesDialogCB, &passwordDialogCB, &cmdLineLogCB))
return -1;
@@ -229,16 +254,18 @@ 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)
{
static char *kwlist[] = {"name", "passphrase", NULL};
static const char *kwlist[] = {"name", "passphrase", NULL};
char *name = NULL, *passphrase = NULL;
int is;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &name, &passphrase))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", CONST_CAST(char**)kwlist, &name, &passphrase))
return NULL;
// FIXME: allow keyfile and \0 in passphrase
@@ -253,8 +280,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,15 +297,17 @@ 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)
{
static char *kwlist[] = {"message", NULL};
static const char *kwlist[] = {"message", NULL};
PyObject *message = NULL, *result, *arglist;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &message))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", CONST_CAST(char**)kwlist, &message))
return NULL;
Py_INCREF(message);
@@ -294,15 +325,17 @@ 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)
{
static char *kwlist[] = {"priority", "message", NULL};
static const char *kwlist[] = {"priority", "message", NULL};
PyObject *message = NULL, *priority = NULL, *result, *arglist;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &message, &priority))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", CONST_CAST(char**)kwlist, &message, &priority))
return NULL;
Py_INCREF(message);
@@ -322,8 +355,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 +371,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,20 +410,22 @@ 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)
{
static char *kwlist[] = {"cipher", "cipherMode", "keysize", NULL};
static const char *kwlist[] = {"cipher", "cipherMode", "keysize", NULL};
char *cipher_mode = NULL, *cipher = NULL;
int keysize = 256;
PyObject *keysize_object = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzO", kwlist,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzO", CONST_CAST(char**)kwlist,
&cipher, &cipher_mode, &keysize_object))
return NULL;
@@ -408,20 +449,22 @@ 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)
{
static char *kwlist[] = {"passphrase", "newPassphrase", "slot", NULL};
static const char *kwlist[] = {"passphrase", "newPassphrase", "slot", NULL};
char *passphrase = NULL, *newpassphrase = NULL;
size_t passphrase_len = 0, newpassphrase_len = 0;
int slot = CRYPT_ANY_SLOT;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|i", kwlist, &passphrase, &newpassphrase, &slot))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|i", CONST_CAST(char**)kwlist, &passphrase, &newpassphrase, &slot))
return NULL;
if(passphrase)
@@ -435,19 +478,21 @@ 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)
{
static char *kwlist[] = {"newPassphrase", "slot", NULL};
static const char *kwlist[] = {"newPassphrase", "slot", NULL};
char *newpassphrase = NULL;
size_t newpassphrase_len = 0;
int slot = CRYPT_ANY_SLOT;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &newpassphrase, &slot))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", CONST_CAST(char**)kwlist, &newpassphrase, &slot))
return NULL;
if (newpassphrase)
@@ -457,18 +502,20 @@ 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)
{
static char *kwlist[] = {"passphrase", NULL};
static const char *kwlist[] = {"passphrase", NULL};
char *passphrase = NULL;
size_t passphrase_len = 0;
int is;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &passphrase))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", CONST_CAST(char**)kwlist, &passphrase))
return NULL;
if (passphrase)
@@ -482,16 +529,18 @@ 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)
{
static char *kwlist[] = {"slot", NULL};
static const char *kwlist[] = {"slot", NULL};
int slot = CRYPT_ANY_SLOT;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &slot))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", CONST_CAST(char**)kwlist, &slot))
return NULL;
switch (crypt_keyslot_status(self->device, slot)) {
@@ -511,8 +560,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,13 +575,15 @@ 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)
{
static char *kwlist[] = {"passphrase", NULL};
static const char *kwlist[] = {"passphrase", NULL};
char* passphrase = NULL;
size_t passphrase_len = 0;
@@ -539,7 +592,7 @@ static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObj
return NULL;
}
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &passphrase))
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", CONST_CAST(char**)kwlist, &passphrase))
return NULL;
if (passphrase)
@@ -549,8 +602,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,16 +617,18 @@ 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)
{
static char *kwlist[] = {"level", NULL};
static const char *kwlist[] = {"level", NULL};
int level = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &level))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", CONST_CAST(char**)kwlist, &level))
return NULL;
crypt_set_debug_level(level);
@@ -579,16 +636,18 @@ 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)
{
static char *kwlist[] = {"time_ms", NULL};
static const char *kwlist[] = {"time_ms", NULL};
uint64_t time_ms = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "K", kwlist, &time_ms))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "K", CONST_CAST(char**)kwlist, &time_ms))
return NULL;
crypt_set_iteration_time(self->device, time_ms);
@@ -597,9 +656,9 @@ static PyObject *CryptSetup_iterationTime(CryptSetupObject* self, PyObject *args
}
static PyMemberDef CryptSetup_members[] = {
{"yesDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, yesDialogCB), 0, "confirmation dialog callback"},
{"cmdLineLogCB", T_OBJECT_EX, offsetof(CryptSetupObject, cmdLineLogCB), 0, "logging callback"},
{"passwordDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, passwordDialogCB), 0, "password dialog callback"},
{CONST_CAST(char*)"yesDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, yesDialogCB), 0, CONST_CAST(char*)"confirmation dialog callback"},
{CONST_CAST(char*)"cmdLineLogCB", T_OBJECT_EX, offsetof(CryptSetupObject, cmdLineLogCB), 0, CONST_CAST(char*)"logging callback"},
{CONST_CAST(char*)"passwordDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, passwordDialogCB), 0, CONST_CAST(char*)"password dialog callback"},
{NULL}
};
@@ -615,7 +674,7 @@ static PyMethodDef CryptSetup_methods[] = {
/* cryptsetup info entrypoints */
{"luksUUID", (PyCFunction)CryptSetup_luksUUID, METH_NOARGS, CryptSetup_luksUUID_HELP},
{"isLuks", (PyCFunction)CryptSetup_isLuks, METH_NOARGS, CryptSetup_isLuks_HELP},
{"info", (PyCFunction)CryptSetup_Info, METH_NOARGS, CryptSetup_Info_HELP},
{"info", (PyCFunction)CryptSetup_Info, METH_NOARGS, CryptSetup_Info_HELP},
{"status", (PyCFunction)CryptSetup_Status, METH_NOARGS, CryptSetup_Status_HELP},
/* cryptsetup mgmt entrypoints */
@@ -637,8 +696,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 +740,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 +767,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);
}

View File

@@ -1,7 +1,7 @@
/*
* cryptsetup - setup cryptographic volumes for dm-crypt
*
* 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
@@ -202,7 +202,7 @@ static int action_open_loopaes(void)
r = crypt_activate_by_keyfile_offset(cd, action_argv[1], CRYPT_ANY_SLOT,
opt_key_file, opt_keyfile_size,
opt_keyfile_size, activate_flags);
opt_keyfile_offset, activate_flags);
out:
crypt_free(cd);
@@ -418,10 +418,10 @@ static int action_status(void)
ci == CRYPT_BUSY ? " and is in use" : "");
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
if (r < 0 || !crypt_get_type(cd))
if (r < 0)
goto out;
log_std(" type: %s\n", crypt_get_type(cd));
log_std(" type: %s\n", crypt_get_type(cd) ?: "n/a");
r = crypt_get_active_device(cd, action_argv[0], &cad);
if (r < 0)
@@ -540,6 +540,9 @@ static int action_benchmark(void)
strstr(cipher, "cast5"))
iv_size = 8;
if (!strcmp(cipher_mode, "ecb"))
iv_size = 0;
r = benchmark_cipher_loop(cipher, cipher_mode,
key_size / 8, iv_size,
&enc_mbr, &dec_mbr);
@@ -571,10 +574,10 @@ static int action_benchmark(void)
snprintf(cipher, MAX_CIPHER_LEN, "%s-%s",
bciphers[i].cipher, bciphers[i].mode);
if (!r)
log_std("%12s %4db %6.1f MiB/s %6.1f MiB/s\n",
log_std("%12s %4zub %6.1f MiB/s %6.1f MiB/s\n",
cipher, bciphers[i].key_size*8, enc_mbr, dec_mbr);
else
log_std("%12s %4db %13s %13s\n", cipher,
log_std("%12s %4zub %13s %13s\n", cipher,
bciphers[i].key_size*8, _("N/A"), _("N/A"));
}
if (skipped && skipped == i)
@@ -1484,9 +1487,6 @@ int main(int argc, const char **argv)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
if (crypt_fips_mode())
crypt_log(NULL, CRYPT_LOG_VERBOSE, _("Running in FIPS mode.\n"));
popt_context = poptGetContext(PACKAGE, argc, argv, popt_options, 0);
poptSetOtherOptionHelp(popt_context,
_("[OPTION...] <action> <action-specific>"));
@@ -1528,6 +1528,10 @@ int main(int argc, const char **argv)
if (r < -1)
usage(popt_context, EXIT_FAILURE, poptStrerror(r),
poptBadOption(popt_context, POPT_BADOPTION_NOALIAS));
if (crypt_fips_mode())
crypt_log(NULL, CRYPT_LOG_VERBOSE, _("Running in FIPS mode.\n"));
if (opt_version_mode) {
log_std("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
poptFreeContext(popt_context);

View File

@@ -1,7 +1,7 @@
/*
* cryptsetup - setup cryptographic volumes for dm-crypt
*
* 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
@@ -57,7 +57,7 @@ extern int opt_force_password;
/* Common tools */
void clogger(struct crypt_device *cd, int level, const char *file, int line,
const char *format, ...);
const char *format, ...) __attribute__ ((format (printf, 5, 6)));
void tool_log(int level, const char *msg, void *usrptr __attribute__((unused)));
void quiet_log(int level, const char *msg, void *usrptr);

View File

@@ -161,7 +161,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
}
s = read(devfd, buf, buf_size);
if (s < 0 || s != buf_size) {
if (s < 0 || s != (ssize_t)buf_size) {
log_err(_("Cannot read device %s.\n"), rc->device);
r = -EIO;
goto out;
@@ -193,7 +193,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
if (lseek(devfd, 0, SEEK_SET) == -1)
goto out;
s = write(devfd, buf, buf_size);
if (s < 0 || s != buf_size) {
if (s < 0 || s != (ssize_t)buf_size) {
log_err(_("Cannot write device %s.\n"), rc->device);
r = -EIO;
}
@@ -1086,7 +1086,7 @@ static void destroy_context(struct reenc_ctx *rc)
static int run_reencrypt(const char *device)
{
int r = -EINVAL;
struct reenc_ctx rc = {};
static struct reenc_ctx rc = {};
if (initialize_context(&rc, device))
goto out;
@@ -1161,7 +1161,7 @@ int main(int argc, const char **argv)
{ "tries", 'T', POPT_ARG_INT, &opt_tries, 0, N_("How often the input of the passphrase can be retried"), NULL },
{ "use-random", '\0', POPT_ARG_NONE, &opt_random, 0, N_("Use /dev/random for generating volume key."), NULL },
{ "use-urandom", '\0', POPT_ARG_NONE, &opt_urandom, 0, N_("Use /dev/urandom for generating volume key."), NULL },
{ "use-directio", '\0', POPT_ARG_NONE, &opt_directio, 0, N_("Use direct-io when accesing devices."), NULL },
{ "use-directio", '\0', POPT_ARG_NONE, &opt_directio, 0, N_("Use direct-io when accessing devices."), NULL },
{ "use-fsync", '\0', POPT_ARG_NONE, &opt_fsync, 0, N_("Use fsync after each block."), NULL },
{ "write-log", '\0', POPT_ARG_NONE, &opt_write_log, 0, N_("Update log file after every block."), NULL },
{ "key-slot", 'S', POPT_ARG_INT, &opt_key_slot, 0, N_("Use only this slot (others will be disabled)."), NULL },

View File

@@ -1,7 +1,7 @@
/*
* cryptsetup - setup cryptographic volumes for dm-crypt
*
* 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

View File

@@ -5,7 +5,9 @@ TESTS = api-test \
discards-test \
mode-test \
password-hash-test \
tcrypt-compat-test
tcrypt-compat-test \
luks1-compat-test \
device-test
if VERITYSETUP
TESTS += verity-compat-test
@@ -23,15 +25,18 @@ EXTRA_DIST = compatimage.img.bz2 compatv10image.img.bz2 \
evil_hdr-luks_hdr_damage.bz2 \
evil_hdr-small_luks_device.bz2 \
tcrypt-images.tar.bz2 \
luks1-images.tar.bz2 \
compat-test loopaes-test align-test discards-test mode-test password-hash-test \
verity-compat-test \
reencryption-compat-test \
tcrypt-compat-test \
luks1-compat-test \
device-test \
cryptsetup-valg-supps valg.sh valg-api.sh
CLEANFILES = cryptsetup-tst* valglog*
clean-local:
-rm -rf tcrypt-images
-rm -rf tcrypt-images luks1-images
differ_SOURCES = differ.c
differ_CFLAGS = $(AM_CFLAGS) -Wall -O2

View File

@@ -40,7 +40,7 @@ add_device() {
fi
sleep 2
DEV=$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
if [ ! -e /sys/block/$DEV/alignment_offset ] ; then
echo "This kernel seems to not support topology info, test skipped."

View File

@@ -2,7 +2,7 @@
* cryptsetup library API check functions
*
* Copyright (C) 2009-2013 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2013, Milan Broz
* Copyright (C) 2009-2014, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -1095,6 +1095,14 @@ static void AddDeviceLuks(void)
OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE));
FAIL_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params), "Context is already formated");
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
crypt_free(cd);
// check active status without header
OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, NULL));
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(!!crypt_get_type(cd));
OK_(strcmp(cipher, crypt_get_cipher(cd)));
OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd)));
EQ_((int)key_size, crypt_get_volume_key_size(cd));
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);

View File

@@ -533,6 +533,8 @@ echo $PWD1 | $CRYPTSETUP luksFormat -i1 $LOOPDEV --header $HEADER_IMG --align-pa
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail
$CRYPTSETUP -q resize $DEV_NAME --size 100 --header $HEADER_IMG || fail
$CRYPTSETUP -q status $DEV_NAME --header $HEADER_IMG | grep "size:" | grep -q "100 sectors" || fail
$CRYPTSETUP -q status $DEV_NAME | grep "type:" | grep -q "n/a" || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail
$CRYPTSETUP luksSuspend $DEV_NAME --header $HEADER_IMG || fail
echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail
$CRYPTSETUP luksClose $DEV_NAME || fail

58
tests/device-test Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
CRYPTSETUP="../src/cryptsetup"
MNT_DIR="./mnt_luks"
PWD1="93R4P4pIqAH8"
PWD2="mymJeD8ivEhE"
cleanup() {
udevadm settle >/dev/null 2>&1
if [ -d "$MNT_DIR" ] ; then
umount -f $MNT_DIR 2>/dev/null
rmdir $MNT_DIR 2>/dev/null
fi
sleep 2
}
fail()
{
if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi
cleanup
exit 100
}
skip()
{
echo "TEST SKIPPED: $1"
cleanup
exit 0
}
format() # key_bits expected [forced]
{
dd if=/dev/zero of=$DEV bs=1M count=5 >/dev/null 2>&1
echo $PWD1 | $CRYPTSETUP luksFormat $DEV -q -i1 -c aes-cbc-essiv:sha256
[ $? -ne 0 ] && fail "Format failed."
# test some operation, just in case
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV -i1 --key-slot 1
[ $? -ne 0 ] && fail "Keyslot add failed."
$CRYPTSETUP -q luksKillSlot $DEV 1
[ $? -ne 0 ] && fail "Keyslot removal failed."
}
if [ $(id -u) != 0 ]; then
echo "WARNING: You must be root to run this test, test skipped."
exit 0
fi
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
echo "[1] Using tmpfs for image"
DEV="$MNT_DIR/test.img"
mount -t tmpfs none $MNT_DIR || skip "Mounting tmpfs not available."
format
cleanup

View File

@@ -27,7 +27,7 @@ add_device() {
fi
sleep 2
DEV=$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV="/dev/$DEV"
[ -b $DEV ] || fail "Cannot find $DEV."

80
tests/luks1-compat-test Executable file
View File

@@ -0,0 +1,80 @@
#!/bin/bash
# check luks1 images parsing
# NOTE: if image with whirlpool hash fails, check
# that you are not using old gcrypt with flawed whirlpool
# (see cryptsetup debug output)
CRYPTSETUP=../src/cryptsetup
TST_DIR=luks1-images
MAP=luks1tst
KEYFILE=keyfile1
function remove_mapping()
{
[ -b /dev/mapper/$MAP ] && dmsetup remove $MAP
}
function fail()
{
[ -n "$1" ] && echo "$1"
echo " [FAILED]"
remove_mapping
exit 2
}
function skip()
{
[ -n "$1" ] && echo "$1"
echo "Test skipped."
exit 0
}
function test_one()
{
$CRYPTSETUP benchmark -c "$1" -s "$2" | grep -v "#" || skip
}
function test_required()
{
which lsblk >/dev/null 2>&1 || skip "WARNING: lsblk tool required."
echo "REQUIRED KDF TEST"
$CRYPTSETUP benchmark -h whirlpool | grep "N/A" && skip
echo "REQUIRED CIPHERS TEST"
echo "# Algorithm | Key | Encryption | Decryption"
test_one aes-xts 256
test_one twofish-xts 256
test_one serpent-xts 256
test_one aes-cbc 256
test_one aes-lrw 256
}
export LANG=C
if [ $(id -u) != 0 ]; then
echo "WARNING: You must be root to run activation part of test, test skipped."
exit 0
fi
test_required
[ ! -d $TST_DIR ] && tar xjf luks1-images.tar.bz2
echo "ACTIVATION FS UUID CHECK"
for file in $(ls $TST_DIR/luks1_*) ; do
echo -n " $file"
$CRYPTSETUP luksOpen -d $TST_DIR/$KEYFILE $file $MAP 2>/dev/null
ret=$?
# ignore missing whirlpool (pwd failed is exit code 2)
[ $ret -eq 1 ] && (echo $file | grep -q -e "whirlpool") && echo " [N/A]" && continue
[ $ret -ne 0 ] && fail
$CRYPTSETUP status $MAP >/dev/null || fail
$CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
$CRYPTSETUP remove $MAP || fail
[ "$UUID" != "DEAD-BABE" ] && fail "UUID check failed."
echo " [OK]"
done

BIN
tests/luks1-images.tar.bz2 Normal file

Binary file not shown.

View File

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

View File

@@ -52,7 +52,7 @@ function add_scsi_device() {
fi
sleep 2
SCSI_DEV="/dev/"$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
SCSI_DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
[ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV."
}

View File

@@ -99,8 +99,11 @@ fi
echo "ACTIVATION FS UUID CHECK"
for file in $(ls $TST_DIR/tc_*) ; do
echo -n " $file"
out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen -r $file $MAP 2>/dev/null)
[ $? -ne 0 ] && ( echo "$out" | grep -q -v "TCRYPT legacy mode" ) && echo " [N/A]" && continue
out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen -r $file $MAP 2>&1)
ret=$?
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue
[ $ret -ne 0 ] && fail
$CRYPTSETUP status $MAP >/dev/null || fail
$CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
@@ -112,8 +115,11 @@ done
echo "ACTIVATION FS UUID (HIDDEN) CHECK"
for file in $(ls $TST_DIR/tc_*-hidden) ; do
echo -n " $file"
out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen -r $file $MAP --tcrypt-hidden 2>/dev/null)
[ $? -ne 0 ] && ( echo "$out" | grep -q -v "TCRYPT legacy mode" ) && echo " [N/A]" && continue
out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen -r $file $MAP --tcrypt-hidden 2>&1)
ret=$?
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue
[ $ret -ne 0 ] && fail
UUID=$(lsblk -n -o UUID /dev/mapper/$MAP)
$CRYPTSETUP remove $MAP || fail
[ "$UUID" != "CAFE-BABE" ] && fail "UUID check failed."