mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-07 00:40:01 +01:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64d6b339a0 | ||
|
|
4f5f1b78c4 | ||
|
|
3e886ecf57 | ||
|
|
210ea612b3 | ||
|
|
3350ff017f | ||
|
|
7b42254975 | ||
|
|
e84b1ed7c0 | ||
|
|
f3f1bfd73a | ||
|
|
89f795d7b4 | ||
|
|
c36a7968f4 | ||
|
|
3762c8b76e | ||
|
|
872becdbbd | ||
|
|
c9694437d2 | ||
|
|
64ad90f73c | ||
|
|
166d23a813 | ||
|
|
59fdf2a6bb | ||
|
|
3640eaa726 | ||
|
|
2250d5f71f | ||
|
|
d9678325a2 | ||
|
|
dc8c47d936 | ||
|
|
5b7100ff87 | ||
|
|
4afa592160 | ||
|
|
54c7a2b0aa | ||
|
|
9cabc9bf05 | ||
|
|
dfd46df8a5 | ||
|
|
25cd4f3a1d | ||
|
|
d5b594dd12 | ||
|
|
803686ea4b | ||
|
|
3add769b51 | ||
|
|
d5a72cd65a | ||
|
|
d63163e46c | ||
|
|
62d690492c | ||
|
|
54d81a6258 | ||
|
|
56679a6e4a | ||
|
|
e0788d9d61 | ||
|
|
833e066853 | ||
|
|
02f860140d | ||
|
|
027cebade3 | ||
|
|
bb8dbfdf5b | ||
|
|
8e380183f8 | ||
|
|
4f89028c67 | ||
|
|
6b4c33d3a5 | ||
|
|
7a2e6990ca | ||
|
|
98ba2f2333 | ||
|
|
4e4d933d7b | ||
|
|
91c739958c | ||
|
|
1a6e1ae918 | ||
|
|
aedf39a9ca | ||
|
|
a274cd3a74 | ||
|
|
6be21469fb | ||
|
|
e0d3ff8aeb | ||
|
|
0614ab6b07 | ||
|
|
49e55c0f42 | ||
|
|
be4edbb460 | ||
|
|
4d30237f7a | ||
|
|
a3c0f6784b | ||
|
|
6d4c2db3b1 | ||
|
|
1436f2a0a0 | ||
|
|
e6a46bf827 | ||
|
|
9563aa33c8 | ||
|
|
6225c901fe | ||
|
|
cad0cbf0c8 | ||
|
|
1fc441f091 | ||
|
|
22849ccd11 | ||
|
|
a809224ec7 | ||
|
|
ae23ecb9b2 | ||
|
|
0db77f3ace | ||
|
|
779c80c581 | ||
|
|
00ced59c1a | ||
|
|
20595f4b14 |
2
AUTHORS
2
AUTHORS
@@ -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
327
FAQ
@@ -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
8
TODO
@@ -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).
|
||||
|
||||
23
configure.ac
23
configure.ac
@@ -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"])
|
||||
|
||||
|
||||
@@ -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
54
docs/v1.6.5-ReleaseNotes
Normal file
@@ -0,0 +1,54 @@
|
||||
Cryptsetup 1.6.5 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.6.4
|
||||
|
||||
* Allow LUKS header operation handling without requiring root privilege.
|
||||
It means that you can manipulate with keyslots as a regular user, only
|
||||
write access to device (or image) is required.
|
||||
|
||||
This requires kernel crypto wrapper (similar to TrueCrypt device handling)
|
||||
to be available (CRYPTO_USER_API_SKCIPHER kernel option).
|
||||
If this kernel interface is not available, code fallbacks to old temporary
|
||||
keyslot device creation (where root privilege is required).
|
||||
|
||||
Note that activation, deactivation, resize and suspend operations still
|
||||
need root privilege (limitation of kernel device-mapper backend).
|
||||
|
||||
* Fix internal PBKDF2 key derivation function implementation for alternative
|
||||
crypto backends (kernel, NSS) which do not support PBKDF2 directly and have
|
||||
issues with longer HMAC keys.
|
||||
|
||||
This fixes the problem for long keyfiles where either calculation is too slow
|
||||
(because of internal rehashing in every iteration) or there is a limit
|
||||
(kernel backend seems to not support HMAC key longer than 20480 bytes).
|
||||
|
||||
(Note that for recent version of gcrypt, nettle or openssl the internal
|
||||
PBKDF2 code is not compiled in and crypto library internal functions are
|
||||
used instead.)
|
||||
|
||||
* Support for Python3 for simple Python binding.
|
||||
Python >= 2.6 is now required. You can set Python compiled version by setting
|
||||
--with-python_version configure option (together with --enable-python).
|
||||
|
||||
* Use internal PBKDF2 in Nettle library for Nettle crypto backend.
|
||||
Cryptsetup compilation requires Nettle >= 2.6 (if using Nettle crypto backend).
|
||||
|
||||
* Allow simple status of crypt device without providing metadata header.
|
||||
The command "cryptsetup status" will print basic info, even if you
|
||||
do not provide detached header argument.
|
||||
|
||||
* Allow to specify ECB mode in cryptsetup benchmark.
|
||||
|
||||
* Add some LUKS images for regression testing.
|
||||
Note that if image with Whirlpool fails, the most probable cause is that
|
||||
you have old gcrypt library with flawed whirlpool hash.
|
||||
Read FAQ section 8.3 for more info.
|
||||
|
||||
Cryptsetup API NOTE:
|
||||
The direct terminal handling for passphrase entry will be removed from
|
||||
libcryptsetup in next major version (application should handle it itself).
|
||||
|
||||
It means that you have to always either provide password in buffer or set
|
||||
your own password callback function trhough crypt_set_password_callback().
|
||||
See API documentation (or libcryptsetup.h) for more info.
|
||||
29
docs/v1.6.6-ReleaseNotes
Normal file
29
docs/v1.6.6-ReleaseNotes
Normal 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.
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
291
lib/crypto_backend/crypto_storage.c
Normal file
291
lib/crypto_backend/crypto_storage.c
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
120
lib/setup.c
120
lib/setup.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Python bindings to libcryptsetup test
|
||||
#
|
||||
# Copyright (C) 2011, Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2011-2014, Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +18,8 @@
|
||||
# License along with this file; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
@@ -31,11 +33,11 @@ DEVICE = "pycryptsetup_test_dev"
|
||||
|
||||
def log(level, txt):
|
||||
if level == pycryptsetup.CRYPT_LOG_ERROR:
|
||||
print txt,
|
||||
print(txt,end="")
|
||||
return
|
||||
|
||||
def askyes(txt):
|
||||
print "Question:", txt
|
||||
print("Question:", txt)
|
||||
return 1
|
||||
|
||||
def askpassword(txt):
|
||||
@@ -43,17 +45,17 @@ def askpassword(txt):
|
||||
|
||||
def print_status(c):
|
||||
r = c.status()
|
||||
print "status :",
|
||||
print("status :",end="")
|
||||
if r == pycryptsetup.CRYPT_ACTIVE:
|
||||
print "ACTIVE"
|
||||
print("ACTIVE")
|
||||
elif r == pycryptsetup.CRYPT_INACTIVE:
|
||||
print "INACTIVE"
|
||||
print("INACTIVE")
|
||||
else:
|
||||
print "ERROR"
|
||||
print("ERROR")
|
||||
return
|
||||
|
||||
if os.geteuid() != 0:
|
||||
print "WARNING: You must be root to run this test, test skipped."
|
||||
print("WARNING: You must be root to run this test, test skipped.")
|
||||
sys.exit(0)
|
||||
|
||||
os.system("dd if=/dev/zero of=" + IMG + " bs=1M count=32 >/dev/null 2>&1")
|
||||
@@ -69,36 +71,36 @@ c = pycryptsetup.CryptSetup(
|
||||
c.debugLevel(pycryptsetup.CRYPT_DEBUG_NONE);
|
||||
c.iterationTime(1)
|
||||
r = c.isLuks()
|
||||
print "isLuks :", r
|
||||
print("isLuks :", r)
|
||||
c.askyes(message = "Is there anybody out there?")
|
||||
c.log(priority = pycryptsetup.CRYPT_LOG_ERROR, message = "Nobody there...\n")
|
||||
c.luksFormat(cipher = "aes", cipherMode= "xts-plain64", keysize = 512)
|
||||
print "isLuks :", c.isLuks()
|
||||
print "luksUUID:", c.luksUUID()
|
||||
print "addKeyVK:", c.addKeyByVolumeKey(newPassphrase = PASSWORD, slot = 2)
|
||||
print "addKeyP :", c.addKeyByPassphrase(passphrase = PASSWORD,
|
||||
newPassphrase = PASSWORD2, slot = 3)
|
||||
print "removeP :", c.removePassphrase(passphrase = PASSWORD2)
|
||||
print "addKeyP :", c.addKeyByPassphrase(PASSWORD, PASSWORD2)
|
||||
print("isLuks :", c.isLuks())
|
||||
print("luksUUID:", c.luksUUID())
|
||||
print("addKeyVK:", c.addKeyByVolumeKey(newPassphrase = PASSWORD, slot = 2))
|
||||
print("addKeyP :", c.addKeyByPassphrase(passphrase = PASSWORD,
|
||||
newPassphrase = PASSWORD2, slot = 3))
|
||||
print("removeP :", c.removePassphrase(passphrase = PASSWORD2))
|
||||
print("addKeyP :", c.addKeyByPassphrase(PASSWORD, PASSWORD2))
|
||||
# original api required wrong passphrase parameter here
|
||||
# print "killSlot:", c.killSlot(passphrase = "xxx", slot = 0)
|
||||
print "killSlot:", c.killSlot(slot = 0)
|
||||
print "activate:", c.activate(name = DEVICE, passphrase = PASSWORD)
|
||||
print "suspend :", c.suspend()
|
||||
print("killSlot:", c.killSlot(slot = 0))
|
||||
print("activate:", c.activate(name = DEVICE, passphrase = PASSWORD))
|
||||
print("suspend :", c.suspend())
|
||||
# os.system("dmsetup info -c " + DEVICE)
|
||||
print "resume :", c.resume(passphrase = PASSWORD)
|
||||
print("resume :", c.resume(passphrase = PASSWORD))
|
||||
print_status(c)
|
||||
info = c.info()
|
||||
print "cipher :", info["cipher"]
|
||||
print "cmode :", info["cipher_mode"]
|
||||
print "keysize :", info["keysize"]
|
||||
print "dir :", info["dir"]
|
||||
print "device :", info["device"]
|
||||
print "offset :", info["offset"]
|
||||
print "name :", info["name"]
|
||||
print "uuid :", info["uuid"]
|
||||
print("cipher :", info["cipher"])
|
||||
print("cmode :", info["cipher_mode"])
|
||||
print("keysize :", info["keysize"])
|
||||
print("dir :", info["dir"])
|
||||
print("device :", info["device"])
|
||||
print("offset :", info["offset"])
|
||||
print("name :", info["name"])
|
||||
print("uuid :", info["uuid"])
|
||||
# os.system("cryptsetup luksDump " + info["device"])
|
||||
print "deact. :", c.deactivate()
|
||||
print("deact. :", c.deactivate())
|
||||
|
||||
del c
|
||||
|
||||
@@ -109,7 +111,7 @@ c = pycryptsetup.CryptSetup(
|
||||
logFunc = log,
|
||||
passwordDialog = askpassword)
|
||||
|
||||
print "activate:", c.activate(name = DEVICE, passphrase = PASSWORD)
|
||||
print("activate:", c.activate(name = DEVICE, passphrase = PASSWORD))
|
||||
|
||||
c2 = pycryptsetup.CryptSetup(
|
||||
name = DEVICE,
|
||||
@@ -118,13 +120,13 @@ c2 = pycryptsetup.CryptSetup(
|
||||
passwordDialog = askpassword)
|
||||
|
||||
info = c2.info()
|
||||
print "cipher :", info["cipher"]
|
||||
print "cmode :", info["cipher_mode"]
|
||||
print "keysize :", info["keysize"]
|
||||
print("cipher :", info["cipher"])
|
||||
print("cmode :", info["cipher_mode"])
|
||||
print("keysize :", info["keysize"])
|
||||
|
||||
print "deact. :", c.deactivate()
|
||||
print("deact. :", c.deactivate())
|
||||
r = c2.deactivate()
|
||||
print "deact. :", r
|
||||
print("deact. :", r)
|
||||
del c
|
||||
del c2
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Python bindings to libcryptsetup
|
||||
*
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2014, Red Hat, Inc. All rights reserved.
|
||||
* Written by Martin Sivak
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
@@ -25,6 +25,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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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, ¶ms), "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);
|
||||
|
||||
|
||||
@@ -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
58
tests/device-test
Executable 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
|
||||
@@ -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
80
tests/luks1-compat-test
Executable 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
BIN
tests/luks1-images.tar.bz2
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
|
||||
|
||||
@@ -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."
|
||||
|
||||
Reference in New Issue
Block a user