mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 00:10:04 +01:00
Compare commits
141 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f7ed87e6c | ||
|
|
c59ea422cc | ||
|
|
0bcb71f742 | ||
|
|
7e38a3386e | ||
|
|
c25b5ef215 | ||
|
|
72fb507de2 | ||
|
|
45c4c95b98 | ||
|
|
e8861d1043 | ||
|
|
c48fcb743b | ||
|
|
d5d732ddf4 | ||
|
|
f83bd5cdf6 | ||
|
|
76c87c628f | ||
|
|
fa125a354d | ||
|
|
f184b54796 | ||
|
|
75925fb2f7 | ||
|
|
b780228ade | ||
|
|
91c012eff0 | ||
|
|
05d45c6948 | ||
|
|
a2c13fbc48 | ||
|
|
16c7aab99b | ||
|
|
0cf5e309a0 | ||
|
|
b5fbd682f2 | ||
|
|
90e04b0046 | ||
|
|
329f6562c2 | ||
|
|
852bad1ef4 | ||
|
|
aa44a61ab2 | ||
|
|
3e237cb490 | ||
|
|
7b206fb13d | ||
|
|
8f7e898341 | ||
|
|
7499d9f245 | ||
|
|
ba6e6f051a | ||
|
|
d4f4dfb54f | ||
|
|
3e7dedaf99 | ||
|
|
f18cd7ae81 | ||
|
|
0ae4fcf8eb | ||
|
|
d3d1e30c7c | ||
|
|
47d0cf495d | ||
|
|
2e883f9d91 | ||
|
|
af0c30e3ea | ||
|
|
da5a35356a | ||
|
|
d98cc3bb6c | ||
|
|
9697f17b9d | ||
|
|
ce3a9d172d | ||
|
|
4448ddc488 | ||
|
|
b77d3c66ae | ||
|
|
2debdfead5 | ||
|
|
b168c65fa1 | ||
|
|
2b46d171db | ||
|
|
64c131d132 | ||
|
|
678a251858 | ||
|
|
bf9d2f6cb0 | ||
|
|
61f5dcb11e | ||
|
|
e4387d2bd1 | ||
|
|
48906f354e | ||
|
|
1ddc098e43 | ||
|
|
165e6c234c | ||
|
|
1be631f43f | ||
|
|
f5f34c2f50 | ||
|
|
33f3619e98 | ||
|
|
3720b66d00 | ||
|
|
864bbc5472 | ||
|
|
080566a1fd | ||
|
|
d9766037a3 | ||
|
|
02821adc47 | ||
|
|
7b08fd4b7d | ||
|
|
0505c70be2 | ||
|
|
f247038e65 | ||
|
|
d7667e9e6e | ||
|
|
188cb114af | ||
|
|
35c49ababf | ||
|
|
faafe09bd0 | ||
|
|
a0e87c9420 | ||
|
|
d9d39f1812 | ||
|
|
82af225742 | ||
|
|
919f4df1a7 | ||
|
|
71a1698bf2 | ||
|
|
a987dd95b8 | ||
|
|
ab6ab8e65c | ||
|
|
3b28d66410 | ||
|
|
eee46ef2f4 | ||
|
|
3c189b4183 | ||
|
|
fd5ab0edf7 | ||
|
|
420387a7a5 | ||
|
|
fc740f8b6d | ||
|
|
834059ddfa | ||
|
|
5ec2fbcd38 | ||
|
|
2fbf5cd79f | ||
|
|
64ebe95751 | ||
|
|
77109b3a33 | ||
|
|
b43429e684 | ||
|
|
97e39f0744 | ||
|
|
fad592b512 | ||
|
|
565de3c536 | ||
|
|
c802269ea3 | ||
|
|
06268963fb | ||
|
|
2227797691 | ||
|
|
f0888c1fe0 | ||
|
|
eda2e62589 | ||
|
|
494d8ec04c | ||
|
|
bb8088ca0f | ||
|
|
26f4bc39fc | ||
|
|
025e4d9fc6 | ||
|
|
b2774d57ba | ||
|
|
51edfb4ec9 | ||
|
|
79019b1ced | ||
|
|
bc87140b5b | ||
|
|
1c5251069b | ||
|
|
0b6dfefcec | ||
|
|
a9e32c55c0 | ||
|
|
a494228407 | ||
|
|
9932b5fc5c | ||
|
|
966ba44a33 | ||
|
|
62c872eb49 | ||
|
|
434fee2e13 | ||
|
|
d3f829c065 | ||
|
|
83934bdcf3 | ||
|
|
3691add163 | ||
|
|
cc7a9e4607 | ||
|
|
943fa69da6 | ||
|
|
3bef291184 | ||
|
|
7316c53b04 | ||
|
|
5e1d1e1850 | ||
|
|
e52c8e148c | ||
|
|
7eb47f3db1 | ||
|
|
ec59d31d04 | ||
|
|
ddd15b63b2 | ||
|
|
e91b35a53d | ||
|
|
fb4079aa4d | ||
|
|
48b203a134 | ||
|
|
2746fd708f | ||
|
|
684f43d84d | ||
|
|
6b1be52e6b | ||
|
|
de6258d366 | ||
|
|
5e4dbf33be | ||
|
|
b03cb3f3d8 | ||
|
|
e08401a2ec | ||
|
|
0a9e7028ae | ||
|
|
ba0ecc54df | ||
|
|
6920f9dc27 | ||
|
|
ba2547212e | ||
|
|
bbe1a8a5b6 |
@@ -1,7 +1,7 @@
|
||||
language: c
|
||||
|
||||
sudo: required
|
||||
dist: xenial
|
||||
dist: bionic
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
@@ -15,7 +15,6 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- wip-luks2
|
||||
- v2_0_x
|
||||
|
||||
before_install:
|
||||
- uname -a
|
||||
|
||||
18
README.md
18
README.md
@@ -5,8 +5,8 @@ What the ...?
|
||||
**Cryptsetup** is a utility used to conveniently set up disk encryption based
|
||||
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
|
||||
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
|
||||
and **TrueCrypt** (including **VeraCrypt** extension) formats.
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
|
||||
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
|
||||
|
||||
The project also includes a **veritysetup** utility used to conveniently setup
|
||||
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
|
||||
@@ -44,16 +44,16 @@ Download
|
||||
--------
|
||||
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
|
||||
**The latest cryptsetup version is 2.2.1**
|
||||
* [cryptsetup-2.2.1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.xz)
|
||||
* Signature [cryptsetup-2.2.1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.sign)
|
||||
**The latest stable cryptsetup version is 2.3.0**
|
||||
* [cryptsetup-2.3.0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.xz)
|
||||
* Signature [cryptsetup-2.3.0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.2.1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.1-ReleaseNotes).
|
||||
* [Cryptsetup 2.3.0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.0-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 2.2.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-ReleaseNotes).
|
||||
* [Version 2.2.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.2-ReleaseNotes).
|
||||
* [Version 2.0.6](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.6-ReleaseNotes).
|
||||
|
||||
12
configure.ac
12
configure.ac
@@ -1,9 +1,9 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[2.2.2])
|
||||
AC_INIT([cryptsetup],[2.3.1])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=17:0:5
|
||||
LIBCRYPTSETUP_VERSION_INFO=18:0:6
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
@@ -33,6 +33,7 @@ AC_PROG_MAKE_SET
|
||||
AC_ENABLE_STATIC(no)
|
||||
LT_INIT
|
||||
PKG_PROG_PKG_CONFIG
|
||||
AM_ICONV
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl define PKG_CHECK_VAR for old pkg-config <= 0.28
|
||||
@@ -59,6 +60,12 @@ AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
|
||||
sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h stdint.h)
|
||||
AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
|
||||
[[
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
]])
|
||||
|
||||
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
|
||||
@@ -348,6 +355,7 @@ AC_CHECK_DECLS([dm_task_retry_remove], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_task_deferred_remove], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_device_has_mounted_fs], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_device_has_holders], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_device_get_name], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([DM_DEVICE_GET_TARGET_VERSION], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([DM_UDEV_DISABLE_DISK_RULES_FLAG], [have_cookie=yes], [have_cookie=no], [#include <libdevmapper.h>])
|
||||
if test "x$enable_udev" = xyes; then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libcryptsetup API log example
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libcryptsetup API - using LUKS device example
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 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
|
||||
|
||||
209
docs/v2.3.0-ReleaseNotes
Normal file
209
docs/v2.3.0-ReleaseNotes
Normal file
@@ -0,0 +1,209 @@
|
||||
Cryptsetup 2.3.0 Release Notes
|
||||
==============================
|
||||
Stable release with new experimental features and bug fixes.
|
||||
|
||||
Cryptsetup 2.3 version introduces support for BitLocker-compatible
|
||||
devices (BITLK format). This format is used in Windows systems,
|
||||
and in combination with a filesystem driver, cryptsetup now provides
|
||||
native read-write access to BitLocker Full Disk Encryption devices.
|
||||
|
||||
The BITLK implementation is based on publicly available information
|
||||
and it is an independent and opensource implementation that allows
|
||||
to access this proprietary disk encryption.
|
||||
|
||||
Changes since version 2.2.2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* BITLK (Windows BitLocker compatible) device access
|
||||
|
||||
BITLK userspace implementation is based on the master thesis and code
|
||||
provided by Vojtech Trefny. Also, thanks to other opensource projects
|
||||
like libbde (that provide alternative approach to decode this format)
|
||||
we were able to verify cryptsetup implementation.
|
||||
|
||||
NOTE: Support for the BITLK device is EXPERIMENTAL and will require
|
||||
a lot of testing. If you get some error message (mainly unsupported
|
||||
metadata in the on-disk header), please help us by submitting an issue
|
||||
to cryptsetup project, so we can fix it. Thank you!
|
||||
|
||||
Cryptsetup supports BITLK activation through passphrase or recovery
|
||||
passphrase for existing devices (BitLocker and Bitlocker to Go).
|
||||
|
||||
Activation through TPM, SmartCard, or any other key protector
|
||||
is not supported. And in some situations, mainly for TPM bind to some
|
||||
PCR registers, it could be even impossible on Linux in the future.
|
||||
|
||||
All metadata (key protectors) are handled read-only, cryptsetup cannot
|
||||
create or modify them. Except for old devices (created in old Vista
|
||||
systems), all format variants should be recognized.
|
||||
|
||||
Data devices can be activated read-write (followed by mounting through
|
||||
the proper filesystem driver). To access filesystem on the decrypted device
|
||||
you need properly installed driver (vfat, NTFS or exFAT).
|
||||
|
||||
Foe AES-XTS, activation is supported on all recent Linux kernels.
|
||||
|
||||
For older AES-CBC encryption, Linux Kernel version 5.3 is required
|
||||
(support for special IV variant); for AES-CBC with Elephant diffuser,
|
||||
Linux Kernel 5.6 is required.
|
||||
|
||||
Please note that CBC variants are legacy, and we provide it only
|
||||
for backward compatibility (to be able to access old drives).
|
||||
|
||||
Cryptsetup command now supports the new "bitlk" format and implement dump,
|
||||
open, status, and close actions.
|
||||
|
||||
To activate a BITLK device, use
|
||||
|
||||
# cryptsetup open --type bitlk <device> <name>
|
||||
or with alias
|
||||
# cryptsetup bitlkOpen <device> <name>
|
||||
|
||||
Then with properly installed fs driver (usually NTFS, vfat or exFAT),
|
||||
you can mount the plaintext device /dev/mapper<name> device as a common
|
||||
filesystem.
|
||||
|
||||
To print metadata information about BITLK device, use
|
||||
# crypotsetup bitlkDump <device>
|
||||
|
||||
To print information about the active device, use
|
||||
# cryptsetup status <name>
|
||||
|
||||
Example (activation of disk image):
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# Recent blkid recognizes BitLocker device,just to verity
|
||||
# blkid bitlocker_xts_ntfs.img
|
||||
bitlocker_xts_ntfs.img: TYPE="BitLocker"
|
||||
|
||||
# Print visible metadata information (on-disk, form the image)
|
||||
# cryptsetup bitlkDump bitlocker_xts_ntfs.img
|
||||
Info for BITLK device bitlocker_xts_ntfs.img.
|
||||
Version: 2
|
||||
GUID: ...
|
||||
Created: Wed Oct 23 17:38:15 2019
|
||||
Description: DESKTOP-xxxxxxx E: 23.10.2019
|
||||
Cipher name: aes
|
||||
Cipher mode: xts-plain64
|
||||
Cipher key: 128 bits
|
||||
|
||||
Keyslots:
|
||||
0: VMK
|
||||
GUID: ...
|
||||
Protection: VMK protected with passphrase
|
||||
Salt: ...
|
||||
Key data size: 44 [bytes]
|
||||
1: VMK
|
||||
GUID: ...
|
||||
Protection: VMK protected with recovery passphrase
|
||||
Salt: ...
|
||||
Key data size: 44 [bytes]
|
||||
2: FVEK
|
||||
Key data size: 44 [bytes]
|
||||
|
||||
# Activation (recovery passphrase works the same as password)
|
||||
# cryptsetup bitlkOpen bitlocker_xts_ntfs.img test -v
|
||||
Enter passphrase for bitlocker_xts_ntfs.img:
|
||||
Command successful.
|
||||
|
||||
# Information about the active device
|
||||
# cryptsetup status test
|
||||
/dev/mapper/test is active.
|
||||
type: BITLK
|
||||
cipher: aes-xts-plain64
|
||||
keysize: 128 bits
|
||||
...
|
||||
|
||||
# Plaintext device should now contain decrypted NTFS filesystem
|
||||
# blkid /dev/mapper/test
|
||||
/dev/mapper/test: UUID="..." TYPE="ntfs"
|
||||
|
||||
# And can be mounted
|
||||
# mount /dev/mapper/test /mnt/tst
|
||||
|
||||
# Deactivation
|
||||
# umount /mnt/tst
|
||||
# cryptsetup close test
|
||||
|
||||
* Veritysetup now supports activation with additional PKCS7 signature
|
||||
of root hash through --root-hash-signature option.
|
||||
The signature uses an in-kernel trusted key to validate the signature
|
||||
of the root hash during activation. This option requires Linux kernel
|
||||
5.4 with DM_VERITY_VERIFY_ROOTHASH_SIG option.
|
||||
|
||||
Verity devices activated with signature now has a special flag
|
||||
(with signature) active in device status (veritysetup status <name>).
|
||||
|
||||
Usage:
|
||||
# veritysetup open <data_device> name <hash_device> <root_hash> \
|
||||
--root-hash-signature=<roothash_p7_sig_file>
|
||||
|
||||
* Integritysetup now calculates hash integrity size according to algorithm
|
||||
instead of requiring an explicit tag size.
|
||||
|
||||
Previously, when integritysetup formats a device with hash or
|
||||
HMAC integrity checksums, it required explicitly tag size entry from
|
||||
a user (or used default value).
|
||||
This led to confusion and unexpected shortened tag sizes.
|
||||
|
||||
Now, libcryptsetup calculates tag size according to real hash output.
|
||||
Tag size can also be specified, then it warns if these values differ.
|
||||
|
||||
* Integritysetup now supports fixed padding for dm-integrity devices.
|
||||
|
||||
There was an in-kernel bug that wasted a lot of space when using metadata
|
||||
areas for integrity-protected devices if a larger sector size than
|
||||
512 bytes was used.
|
||||
This problem affects both stand-alone dm-integrity and also LUKS2 with
|
||||
authenticated encryption and larger sector size.
|
||||
|
||||
The new extension to dm-integrity superblock is needed, so devices
|
||||
with the new optimal padding cannot be activated on older systems.
|
||||
|
||||
Integritysetup/Cryptsetup will use new padding automatically if it
|
||||
detects the proper kernel. To create a compatible device with
|
||||
the old padding, use --integrity-legacy-padding option.
|
||||
|
||||
* A lot of fixes to online LUKS2 reecryption.
|
||||
|
||||
* Add crypt_resume_by_volume_key() function to libcryptsetup.
|
||||
If a user has a volume key available, the LUKS device can be resumed
|
||||
directly using the provided volume key.
|
||||
No keyslot derivation is needed, only the key digest is checked.
|
||||
|
||||
* Implement active device suspend info.
|
||||
Add CRYPT_ACTIVATE_SUSPENDED bit to crypt_get_active_device() flags
|
||||
that informs the caller that device is suspended (luksSuspend).
|
||||
|
||||
* Allow --test-passphrase for a detached header.
|
||||
Before this fix, we required a data device specified on the command
|
||||
line even though it was not necessary for the passphrase check.
|
||||
|
||||
* Allow --key-file option in legacy offline encryption.
|
||||
The option was ignored for LUKS1 encryption initialization.
|
||||
|
||||
* Export memory safe functions.
|
||||
To make developing of some extensions simpler, we now export
|
||||
functions to handle memory with proper wipe on deallocation.
|
||||
|
||||
* Fail crypt_keyslot_get_pbkdf for inactive LUKS1 keyslot.
|
||||
|
||||
Libcryptsetup API extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The libcryptsetup API is backward compatible for existing symbols.
|
||||
|
||||
New symbols
|
||||
crypt_set_compatibility
|
||||
crypt_get_compatibility;
|
||||
crypt_resume_by_volume_key;
|
||||
crypt_activate_by_signed_key;
|
||||
crypt_safe_alloc;
|
||||
crypt_safe_realloc;
|
||||
crypt_safe_free;
|
||||
crypt_safe_memzero;
|
||||
|
||||
New defines introduced :
|
||||
CRYPT_BITLK "BITLK" - BITLK (BitLocker-compatible mode
|
||||
CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING - dm-integrity legacy padding
|
||||
CRYPT_VERITY_ROOT_HASH_SIGNATURE - dm-verity root hash signature
|
||||
CRYPT_ACTIVATE_SUSPENDED - device suspended info flag
|
||||
45
docs/v2.3.1-ReleaseNotes
Normal file
45
docs/v2.3.1-ReleaseNotes
Normal file
@@ -0,0 +1,45 @@
|
||||
Cryptsetup 2.3.1 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.x should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.0
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Support VeraCrypt 128 bytes passwords.
|
||||
VeraCrypt now allows passwords of maximal length 128 bytes
|
||||
(compared to legacy TrueCrypt where it was limited by 64 bytes).
|
||||
|
||||
* Strip extra newline from BitLocker recovery keys
|
||||
There might be a trailing newline added by the text editor when
|
||||
the recovery passphrase was passed using the --key-file option.
|
||||
|
||||
* Detect separate libiconv library.
|
||||
It should fix compilation issues on distributions with iconv
|
||||
implemented in a separate library.
|
||||
|
||||
* Various fixes and workarounds to build on old Linux distributions.
|
||||
|
||||
* Split lines with hexadecimal digest printing for large key-sizes.
|
||||
|
||||
* Do not wipe the device with no integrity profile.
|
||||
With --integrity none we performed useless full device wipe.
|
||||
|
||||
* Workaround for dm-integrity kernel table bug.
|
||||
Some kernels show an invalid dm-integrity mapping table
|
||||
if superblock contains the "recalculate" bit. This causes
|
||||
integritysetup to not recognize the dm-integrity device.
|
||||
Integritysetup now specifies kernel options such a way that
|
||||
even on unpatched kernels mapping table is correct.
|
||||
|
||||
* Print error message if LUKS1 keyslot cannot be processed.
|
||||
If the crypto backend is missing support for hash algorithms
|
||||
used in PBKDF2, the error message was not visible.
|
||||
|
||||
* Properly align LUKS2 keyslots area on conversion.
|
||||
If the LUKS1 payload offset (data offset) is not aligned
|
||||
to 4 KiB boundary, new LUKS2 keyslots area in now aligned properly.
|
||||
|
||||
* Validate LUKS2 earlier on conversion to not corrupt the device
|
||||
if binary keyslots areas metadata are not correct.
|
||||
@@ -22,7 +22,8 @@ libcryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
-I $(top_srcdir)/lib/loopaes \
|
||||
-I $(top_srcdir)/lib/verity \
|
||||
-I $(top_srcdir)/lib/tcrypt \
|
||||
-I $(top_srcdir)/lib/integrity
|
||||
-I $(top_srcdir)/lib/integrity \
|
||||
-I $(top_srcdir)/lib/bitlk
|
||||
|
||||
libcryptsetup_la_DEPENDENCIES = libutils_io.la libcrypto_backend.la lib/libcryptsetup.sym
|
||||
|
||||
@@ -39,6 +40,7 @@ libcryptsetup_la_LIBADD = \
|
||||
@LIBARGON2_LIBS@ \
|
||||
@JSON_C_LIBS@ \
|
||||
@BLKID_LIBS@ \
|
||||
$(LTLIBICONV) \
|
||||
libcrypto_backend.la \
|
||||
libutils_io.la
|
||||
|
||||
@@ -64,6 +66,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/utils_device_locking.c \
|
||||
lib/utils_device_locking.h \
|
||||
lib/utils_pbkdf.c \
|
||||
lib/utils_safe_memory.c \
|
||||
lib/utils_storage_wrappers.c \
|
||||
lib/utils_storage_wrappers.h \
|
||||
lib/libdevmapper.c \
|
||||
@@ -74,7 +77,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/base64.h \
|
||||
lib/base64.c \
|
||||
lib/integrity/integrity.h \
|
||||
lib/integrity/integrity.c \
|
||||
lib/integrity/integrity.c \
|
||||
lib/loopaes/loopaes.h \
|
||||
lib/loopaes/loopaes.c \
|
||||
lib/tcrypt/tcrypt.h \
|
||||
@@ -90,7 +93,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/verity/verity.h \
|
||||
lib/verity/rs_encode_char.c \
|
||||
lib/verity/rs_decode_char.c \
|
||||
lib/verity/rs.h \
|
||||
lib/verity/rs.h \
|
||||
lib/luks2/luks2_disk_metadata.c \
|
||||
lib/luks2/luks2_json_format.c \
|
||||
lib/luks2/luks2_json_metadata.c \
|
||||
@@ -107,4 +110,6 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/luks2/luks2_internal.h \
|
||||
lib/luks2/luks2.h \
|
||||
lib/utils_blkid.c \
|
||||
lib/utils_blkid.h
|
||||
lib/utils_blkid.h \
|
||||
lib/bitlk/bitlk.h \
|
||||
lib/bitlk/bitlk.c
|
||||
|
||||
1204
lib/bitlk/bitlk.c
Normal file
1204
lib/bitlk/bitlk.c
Normal file
File diff suppressed because it is too large
Load Diff
130
lib/bitlk/bitlk.h
Normal file
130
lib/bitlk/bitlk.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* BITLK (BitLocker-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2019-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2019-2020 Milan Broz
|
||||
* Copyright (C) 2019-2020 Vojtech Trefny
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this file; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTSETUP_BITLK_H
|
||||
#define _CRYPTSETUP_BITLK_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct device;
|
||||
|
||||
#define BITLK_NONCE_SIZE 12
|
||||
#define BITLK_SALT_SIZE 16
|
||||
#define BITLK_VMK_MAC_TAG_SIZE 16
|
||||
|
||||
#define BITLK_STATE_NORMAL 0x0004
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENCRYPTION_TYPE_NORMAL = 0,
|
||||
BITLK_ENCRYPTION_TYPE_EOW,
|
||||
BITLK_ENCRYPTION_TYPE_UNKNOWN,
|
||||
} BITLKEncryptionType;
|
||||
|
||||
typedef enum {
|
||||
BITLK_PROTECTION_CLEAR_KEY = 0,
|
||||
BITLK_PROTECTION_TPM,
|
||||
BITLK_PROTECTION_STARTUP_KEY,
|
||||
BITLK_PROTECTION_TPM_PIN,
|
||||
BITLK_PROTECTION_RECOVERY_PASSPHRASE,
|
||||
BITLK_PROTECTION_PASSPHRASE,
|
||||
BITLK_PROTECTION_SMART_CARD,
|
||||
BITLK_PROTECTION_UNKNOWN,
|
||||
} BITLKVMKProtection;
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENTRY_TYPE_PROPERTY = 0x0000,
|
||||
BITLK_ENTRY_TYPE_VMK = 0x0002,
|
||||
BITLK_ENTRY_TYPE_FVEK = 0x0003,
|
||||
BITLK_ENTRY_TYPE_STARTUP_KEY = 0x0006,
|
||||
BITLK_ENTRY_TYPE_DESCRIPTION = 0x0007,
|
||||
BITLK_ENTRY_TYPE_VOLUME_HEADER = 0x000f,
|
||||
} BITLKFVEEntryType;
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENTRY_VALUE_ERASED = 0x0000,
|
||||
BITLK_ENTRY_VALUE_KEY = 0x0001,
|
||||
BITLK_ENTRY_VALUE_STRING = 0x0002,
|
||||
BITLK_ENTRY_VALUE_STRETCH_KEY = 0x0003,
|
||||
BITLK_ENTRY_VALUE_USE_KEY = 0x0004,
|
||||
BITLK_ENTRY_VALUE_ENCRYPTED_KEY = 0x0005,
|
||||
BITLK_ENTRY_VALUE_TPM_KEY = 0x0006,
|
||||
BITLK_ENTRY_VALUE_VALIDATION = 0x0007,
|
||||
BITLK_ENTRY_VALUE_VMK = 0x0008,
|
||||
BITLK_ENTRY_VALUE_EXTERNAL_KEY = 0x0009,
|
||||
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
|
||||
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
|
||||
} BITLKFVEEntryValue;
|
||||
|
||||
struct bitlk_vmk {
|
||||
char *guid;
|
||||
char *name;
|
||||
BITLKVMKProtection protection;
|
||||
uint8_t salt[BITLK_SALT_SIZE];
|
||||
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
|
||||
uint8_t nonce[BITLK_NONCE_SIZE];
|
||||
struct volume_key *vk;
|
||||
struct bitlk_vmk *next;
|
||||
};
|
||||
|
||||
struct bitlk_fvek {
|
||||
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
|
||||
uint8_t nonce[BITLK_NONCE_SIZE];
|
||||
struct volume_key *vk;
|
||||
};
|
||||
|
||||
struct bitlk_metadata {
|
||||
bool togo;
|
||||
bool state;
|
||||
BITLKEncryptionType type;
|
||||
const char *cipher;
|
||||
const char *cipher_mode;
|
||||
uint16_t key_size;
|
||||
char *guid;
|
||||
uint64_t creation_time;
|
||||
char *description;
|
||||
uint64_t metadata_offset[3];
|
||||
uint32_t metadata_version;
|
||||
uint64_t volume_header_offset;
|
||||
uint64_t volume_header_size;
|
||||
struct bitlk_vmk *vmks;
|
||||
struct bitlk_fvek *fvek;
|
||||
};
|
||||
|
||||
int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params);
|
||||
|
||||
int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params);
|
||||
|
||||
int BITLK_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
const struct bitlk_metadata *params,
|
||||
uint32_t flags);
|
||||
|
||||
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek);
|
||||
void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk);
|
||||
void BITLK_bitlk_metadata_free(struct bitlk_metadata *params);
|
||||
|
||||
#endif
|
||||
@@ -2,8 +2,8 @@
|
||||
* cryptsetup plain device helper functions
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Argon2 PBKDF2 library wrapper
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 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,8 +1,8 @@
|
||||
/*
|
||||
* Cipher performance check
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 Milan Broz
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,6 +23,10 @@
|
||||
#include <time.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is not simulating storage, so using disk block causes extreme overhead.
|
||||
* Let's use some fixed block size where results are more reliable...
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel cipher generic utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 Milan Broz
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 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,8 +1,8 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -119,6 +119,12 @@ int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t iv_offset,
|
||||
|
||||
bool crypt_storage_kernel_only(struct crypt_storage *ctx);
|
||||
|
||||
/* Temporary Bitlk helper */
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length);
|
||||
|
||||
/* Memzero helper (memset on stack can be optimized out) */
|
||||
static inline void crypt_backend_memzero(void *s, size_t n)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -55,5 +55,9 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length);
|
||||
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx);
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length);
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_INTERNAL_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation (skcipher)
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -40,6 +40,10 @@
|
||||
#define SOL_ALG 279
|
||||
#endif
|
||||
|
||||
#ifndef ALG_SET_AEAD_AUTHSIZE
|
||||
#define ALG_SET_AEAD_AUTHSIZE 5
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ciphers
|
||||
*
|
||||
@@ -49,7 +53,7 @@
|
||||
*/
|
||||
static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
const void *key, size_t key_length,
|
||||
struct sockaddr_alg *sa)
|
||||
size_t tag_length, struct sockaddr_alg *sa)
|
||||
{
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
@@ -71,6 +75,11 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, tag_length) < 0) {
|
||||
crypt_cipher_destroy_kernel(ctx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->opfd = accept(ctx->tfmfd, NULL, 0);
|
||||
if (ctx->opfd < 0) {
|
||||
crypt_cipher_destroy_kernel(ctx);
|
||||
@@ -93,12 +102,13 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
|
||||
|
||||
return _crypt_cipher_init(ctx, key, key_length, &sa);
|
||||
return _crypt_cipher_init(ctx, key, key_length, 0, &sa);
|
||||
}
|
||||
|
||||
/* The in/out should be aligned to page boundary */
|
||||
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *in, size_t in_length,
|
||||
char *out, size_t out_length,
|
||||
const char *iv, size_t iv_length,
|
||||
uint32_t direction)
|
||||
{
|
||||
@@ -109,7 +119,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
uint32_t *type;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void*)(uintptr_t)in,
|
||||
.iov_len = length,
|
||||
.iov_len = in_length,
|
||||
};
|
||||
int iv_msg_size = iv ? CMSG_SPACE(sizeof(*alg_iv) + iv_length) : 0;
|
||||
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
|
||||
@@ -120,7 +130,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
if (!in || !out || !length)
|
||||
if (!in || !out || !in_length)
|
||||
return -EINVAL;
|
||||
|
||||
if ((!iv && iv_length) || (iv && !iv_length))
|
||||
@@ -151,13 +161,13 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
}
|
||||
|
||||
len = sendmsg(ctx->opfd, &msg, 0);
|
||||
if (len != (ssize_t)length) {
|
||||
if (len != (ssize_t)(in_length)) {
|
||||
r = -EIO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
len = read(ctx->opfd, out, length);
|
||||
if (len != (ssize_t)length)
|
||||
len = read(ctx->opfd, out, out_length);
|
||||
if (len != (ssize_t)out_length)
|
||||
r = -EIO;
|
||||
bad:
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
@@ -168,7 +178,7 @@ int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, length, out, length,
|
||||
iv, iv_length, ALG_OP_ENCRYPT);
|
||||
}
|
||||
|
||||
@@ -176,7 +186,7 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, length, out, length,
|
||||
iv, iv_length, ALG_OP_DECRYPT);
|
||||
}
|
||||
|
||||
@@ -243,13 +253,56 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
memset(key, 0xab, key_length);
|
||||
*key = 0xef;
|
||||
|
||||
r = _crypt_cipher_init(&c, key, key_length, &sa);
|
||||
r = _crypt_cipher_init(&c, key, key_length, 0, &sa);
|
||||
crypt_cipher_destroy_kernel(&c);
|
||||
free(key);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
struct crypt_cipher_kernel c;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "aead",
|
||||
.salg_name = "ccm(aes)",
|
||||
};
|
||||
int r;
|
||||
char buffer[128], ccm_iv[16];
|
||||
|
||||
if (length + tag_length > sizeof(buffer))
|
||||
return -EINVAL;
|
||||
|
||||
if (iv_length > sizeof(ccm_iv) - 2)
|
||||
return -EINVAL;
|
||||
|
||||
r = _crypt_cipher_init(&c, key, key_length, tag_length, &sa);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
memcpy(buffer, in, length);
|
||||
memcpy(buffer + length, tag, tag_length);
|
||||
|
||||
/* CCM IV - RFC3610 */
|
||||
memset(ccm_iv, 0, sizeof(ccm_iv));
|
||||
ccm_iv[0] = 15 - iv_length - 1;
|
||||
memcpy(ccm_iv + 1, iv, iv_length);
|
||||
memset(ccm_iv + 1 + iv_length, 0, ccm_iv[0] + 1);
|
||||
iv_length = sizeof(ccm_iv);
|
||||
|
||||
r = _crypt_cipher_crypt(&c, buffer, length + tag_length, out, length,
|
||||
ccm_iv, iv_length, ALG_OP_DECRYPT);
|
||||
|
||||
crypt_cipher_destroy_kernel(&c);
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#else /* ENABLE_AF_ALG */
|
||||
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length)
|
||||
@@ -280,4 +333,11 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
/* Cannot check, expect success. */
|
||||
return 0;
|
||||
}
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* GCRYPT crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -479,3 +479,43 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return ctx->use_kernel;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
#ifdef GCRY_CCM_BLOCK_LEN
|
||||
gcry_cipher_hd_t hd;
|
||||
uint64_t l[3];
|
||||
int r = -EINVAL;
|
||||
|
||||
if (gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (gcry_cipher_setkey(hd, key, key_length))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_setiv(hd, iv, iv_length))
|
||||
goto out;
|
||||
|
||||
l[0] = length;
|
||||
l[1] = 0;
|
||||
l[2] = tag_length;
|
||||
if (gcry_cipher_ctl(hd, GCRYCTL_SET_CCM_LENGTHS, l, sizeof(l)))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_decrypt(hd, out, length, in, length))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_checktag(hd, tag, tag_length))
|
||||
goto out;
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
gcry_cipher_close(hd);
|
||||
return r;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -392,3 +392,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Nettle crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -433,3 +433,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* NSS crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -381,3 +381,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* OPENSSL crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 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,6 +35,8 @@
|
||||
#include <openssl/rand.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
|
||||
struct crypt_hash {
|
||||
@@ -505,3 +507,40 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return ctx->use_kernel;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
#ifdef EVP_CTRL_CCM_SET_IVLEN
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int len = 0, r = -EINVAL;
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL) != 1)
|
||||
goto out;
|
||||
|
||||
//EVP_CIPHER_CTX_key_length(ctx)
|
||||
//EVP_CIPHER_CTX_iv_length(ctx)
|
||||
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_length, NULL) != 1)
|
||||
goto out;
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_length, CONST_CAST(void*)tag) != 1)
|
||||
goto out;
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, (const unsigned char*)iv) != 1)
|
||||
goto out;
|
||||
|
||||
if (EVP_DecryptUpdate(ctx, (unsigned char*)out, &len, (const unsigned char*)in, length) == 1)
|
||||
r = 0;
|
||||
out:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return r;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generic wrapper for storage encryption modes and Initial Vectors
|
||||
* (reimplementation of some functions from Linux dm-crypt kernel)
|
||||
*
|
||||
* Copyright (C) 2014-2019 Milan Broz
|
||||
* Copyright (C) 2014-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 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,8 +1,8 @@
|
||||
/*
|
||||
* PBKDF performance check
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2016-2019 Ondrej Mosnacek
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2016-2020 Ondrej Mosnacek
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -27,6 +27,10 @@
|
||||
#include <sys/resource.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
#define BENCH_MIN_MS 250
|
||||
#define BENCH_MIN_MS_FAST 10
|
||||
#define BENCH_PERCENT_ATLEAST 95
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Integrity volume handling
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "integrity.h"
|
||||
@@ -41,8 +40,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
|
||||
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
|
||||
(sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
|
||||
sb->version != SB_VERSION_3)) {
|
||||
sb->version < SB_VERSION_1 || sb->version > SB_VERSION_4) {
|
||||
log_std(cd, "No integrity superblock detected on %s.\n",
|
||||
device_path(device));
|
||||
r = -EINVAL;
|
||||
@@ -58,7 +56,9 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params)
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags)
|
||||
{
|
||||
struct superblock sb;
|
||||
int r;
|
||||
@@ -70,6 +70,9 @@ int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *pa
|
||||
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
|
||||
params->tag_size = sb.integrity_tag_size;
|
||||
|
||||
if (flags)
|
||||
*flags = sb.flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -92,10 +95,11 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs
|
||||
if (sb.version == SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING))
|
||||
log_std(cd, "recalc_sector %" PRIu64 "\n", sb.recalc_sector);
|
||||
log_std(cd, "log2_blocks_per_bitmap %u\n", sb.log2_blocks_per_bitmap_bit);
|
||||
log_std(cd, "flags %s%s%s\n",
|
||||
log_std(cd, "flags %s%s%s%s\n",
|
||||
sb.flags & SB_FLAG_HAVE_JOURNAL_MAC ? "have_journal_mac " : "",
|
||||
sb.flags & SB_FLAG_RECALCULATING ? "recalculating " : "",
|
||||
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "");
|
||||
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "",
|
||||
sb.flags & SB_FLAG_FIXED_PADDING ? "fix_padding " : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -137,6 +141,27 @@ int INTEGRITY_key_size(struct crypt_device *cd, const char *integrity)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return hash or hmac(hash) size, if known */
|
||||
int INTEGRITY_hash_tag_size(const char *integrity)
|
||||
{
|
||||
char hash[MAX_CIPHER_LEN];
|
||||
int r;
|
||||
|
||||
if (!integrity)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(integrity, "crc32") || !strcmp(integrity, "crc32c"))
|
||||
return 4;
|
||||
|
||||
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
|
||||
if (r == 1)
|
||||
r = crypt_hash_size(hash);
|
||||
else
|
||||
r = crypt_hash_size(integrity);
|
||||
|
||||
return r < 0 ? 0 : r;
|
||||
}
|
||||
|
||||
int INTEGRITY_tag_size(struct crypt_device *cd,
|
||||
const char *integrity,
|
||||
const char *cipher,
|
||||
@@ -187,7 +212,7 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t flags)
|
||||
uint32_t flags, uint32_t sb_flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -198,12 +223,16 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
/* Workaround for kernel dm-integrity table bug */
|
||||
if (sb_flags & SB_FLAG_RECALCULATING)
|
||||
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
|
||||
r = INTEGRITY_data_sectors(cd, crypt_metadata_device(cd),
|
||||
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dm_integrity_target_set(&dmd->segment, 0, dmd->size,
|
||||
return dm_integrity_target_set(cd, &dmd->segment, 0, dmd->size,
|
||||
crypt_metadata_device(cd), crypt_data_device(cd),
|
||||
crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
|
||||
crypt_get_sector_size(cd), vk, journal_crypt_key,
|
||||
@@ -213,7 +242,8 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd)
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t sb_flags)
|
||||
{
|
||||
int r;
|
||||
uint32_t dmi_flags;
|
||||
@@ -238,7 +268,13 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
|
||||
r = dm_create_device(cd, name, type, dmd);
|
||||
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-integrity mapping."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (r < 0 && (sb_flags & SB_FLAG_FIXED_PADDING) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
!(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel does not support dm-integrity fixed metadata alignment."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -251,15 +287,16 @@ int INTEGRITY_activate(struct crypt_device *cd,
|
||||
struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint32_t flags)
|
||||
uint32_t flags, uint32_t sb_flags)
|
||||
{
|
||||
struct crypt_dm_active_device dmd = {};
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key, journal_mac_key, &dmd, flags);
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key,
|
||||
journal_mac_key, &dmd, flags, sb_flags);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd);
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd, sb_flags);
|
||||
dm_targets_free(cd, &dmd);
|
||||
return r;
|
||||
}
|
||||
@@ -289,7 +326,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
if (params && params->integrity_key_size)
|
||||
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
|
||||
|
||||
r = dm_integrity_target_set(tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||
crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
|
||||
crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
|
||||
journal_crypt_key, journal_mac_key, params);
|
||||
@@ -303,7 +340,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
|
||||
r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL);
|
||||
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-integrity mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Integrity header definition
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -34,10 +34,12 @@ struct crypt_dm_active_device;
|
||||
#define SB_VERSION_1 1
|
||||
#define SB_VERSION_2 2
|
||||
#define SB_VERSION_3 3
|
||||
#define SB_VERSION_4 4
|
||||
|
||||
#define SB_FLAG_HAVE_JOURNAL_MAC (1 << 0)
|
||||
#define SB_FLAG_RECALCULATING (1 << 1) /* V2 only */
|
||||
#define SB_FLAG_DIRTY_BITMAP (1 << 2) /* V3 only */
|
||||
#define SB_FLAG_FIXED_PADDING (1 << 3) /* V4 only */
|
||||
|
||||
struct superblock {
|
||||
uint8_t magic[8];
|
||||
@@ -53,7 +55,9 @@ struct superblock {
|
||||
uint64_t recalc_sector; /* V2 only */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params);
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags);
|
||||
|
||||
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset);
|
||||
|
||||
@@ -66,6 +70,7 @@ int INTEGRITY_tag_size(struct crypt_device *cd,
|
||||
const char *integrity,
|
||||
const char *cipher,
|
||||
const char *cipher_mode);
|
||||
int INTEGRITY_hash_tag_size(const char *integrity);
|
||||
|
||||
int INTEGRITY_format(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
@@ -78,7 +83,7 @@ int INTEGRITY_activate(struct crypt_device *cd,
|
||||
struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint32_t flags);
|
||||
uint32_t flags, uint32_t sb_flags);
|
||||
|
||||
int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
@@ -86,10 +91,11 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t flags);
|
||||
uint32_t flags, uint32_t sb_flags);
|
||||
|
||||
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd);
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t sb_flags);
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "bitops.h"
|
||||
@@ -77,6 +78,10 @@
|
||||
*_py = NULL; \
|
||||
} while (0)
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
struct crypt_device;
|
||||
struct luks2_reenc_context;
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -414,6 +414,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
|
||||
#define CRYPT_TCRYPT "TCRYPT"
|
||||
/** INTEGRITY dm-integrity device */
|
||||
#define CRYPT_INTEGRITY "INTEGRITY"
|
||||
/** BITLK (BitLocker-compatible mode) */
|
||||
#define CRYPT_BITLK "BITLK"
|
||||
|
||||
/** LUKS any version */
|
||||
#define CRYPT_LUKS NULL
|
||||
@@ -505,6 +507,8 @@ struct crypt_params_verity {
|
||||
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
|
||||
/** Create hash - format hash device */
|
||||
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
|
||||
/** Root hash signature required for activation */
|
||||
#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (1 << 3)
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -629,6 +633,26 @@ int crypt_format(struct crypt_device *cd,
|
||||
size_t volume_key_size,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* Set format compatibility flags.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param flags CRYPT_COMPATIBILITY_* flags
|
||||
*/
|
||||
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags);
|
||||
|
||||
/**
|
||||
* Get compatibility flags.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
* @returns compatibility flags
|
||||
*/
|
||||
uint32_t crypt_get_compatibility(struct crypt_device *cd);
|
||||
|
||||
/** dm-integrity device uses less effective (legacy) padding (old kernels) */
|
||||
#define CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING (1 << 0)
|
||||
|
||||
/**
|
||||
* Convert to new type for already existing device.
|
||||
*
|
||||
@@ -828,6 +852,20 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size);
|
||||
/**
|
||||
* Resume crypt device using provided volume key.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to resume
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of volume_key
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*/
|
||||
int crypt_resume_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -1061,6 +1099,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF (1 << 19)
|
||||
/** dm-integrity: direct writes, use bitmap to track dirty sectors */
|
||||
#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (1 << 20)
|
||||
/** device is suspended (key should be wiped from memory), output only */
|
||||
#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -1252,6 +1292,31 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
size_t volume_key_size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate VERITY device using provided key and optional signature).
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to create
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param signature buffer with signature for the key
|
||||
* @param signature_size bsize of signature buffer
|
||||
* @param flags activation flags
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
* @note For VERITY the volume key means root hash required for activation.
|
||||
* Because kernel dm-verity is always read only, you have to provide
|
||||
* CRYPT_ACTIVATE_READONLY flag always.
|
||||
*/
|
||||
int crypt_activate_by_signed_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate device using passphrase stored in kernel keyring.
|
||||
*
|
||||
@@ -1322,6 +1387,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
|
||||
*
|
||||
* @note For TCRYPT cipher chain is the volume key concatenated
|
||||
* for all ciphers in chain.
|
||||
* @note For VERITY the volume key means root hash used for activation.
|
||||
*/
|
||||
int crypt_volume_key_get(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -2251,6 +2317,53 @@ crypt_reencrypt_info crypt_reencrypt_status(struct crypt_device *cd,
|
||||
struct crypt_params_reencrypt *params);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup crypt-memory Safe memory helpers functions
|
||||
* @addtogroup crypt-memory
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate safe memory (content is safely wiped on deallocation).
|
||||
*
|
||||
* @param size size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void *crypt_safe_alloc(size_t size);
|
||||
|
||||
/**
|
||||
* Release safe memory, content is safely wiped
|
||||
* The pointer must be allocated with @link crypt_safe_alloc @endlink
|
||||
*
|
||||
* @param data pointer to memory to be deallocated
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void crypt_safe_free(void *data);
|
||||
|
||||
/**
|
||||
* Reallocate safe memory (content is copied and safely wiped on deallocation).
|
||||
*
|
||||
* @param data pointer to memory to be deallocated
|
||||
* @param size new size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
/**
|
||||
* Safe clear memory area (compile should not compile this call out).
|
||||
*
|
||||
* @param data pointer to memory to cleared
|
||||
* @param size new size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,9 @@ CRYPTSETUP_2.0 {
|
||||
crypt_set_label;
|
||||
crypt_set_data_device;
|
||||
|
||||
crypt_set_compatibility;
|
||||
crypt_get_compatibility;
|
||||
|
||||
crypt_memory_lock;
|
||||
crypt_metadata_locking;
|
||||
crypt_format;
|
||||
@@ -24,6 +27,7 @@ CRYPTSETUP_2.0 {
|
||||
crypt_resume_by_keyfile;
|
||||
crypt_resume_by_keyfile_offset;
|
||||
crypt_resume_by_keyfile_device_offset;
|
||||
crypt_resume_by_volume_key;
|
||||
crypt_free;
|
||||
|
||||
crypt_keyslot_add_by_passphrase;
|
||||
@@ -55,6 +59,7 @@ CRYPTSETUP_2.0 {
|
||||
crypt_activate_by_keyfile_offset;
|
||||
crypt_activate_by_keyfile_device_offset;
|
||||
crypt_activate_by_volume_key;
|
||||
crypt_activate_by_signed_key;
|
||||
crypt_activate_by_keyring;
|
||||
crypt_deactivate;
|
||||
crypt_deactivate_by_name;
|
||||
@@ -118,6 +123,11 @@ CRYPTSETUP_2.0 {
|
||||
crypt_reencrypt_init_by_keyring;
|
||||
crypt_reencrypt;
|
||||
crypt_reencrypt_status;
|
||||
|
||||
crypt_safe_alloc;
|
||||
crypt_safe_realloc;
|
||||
crypt_safe_free;
|
||||
crypt_safe_memzero;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libdevmapper.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -47,6 +46,7 @@
|
||||
#define DM_INTEGRITY_TARGET "integrity"
|
||||
#define DM_LINEAR_TARGET "linear"
|
||||
#define DM_ERROR_TARGET "error"
|
||||
#define DM_ZERO_TARGET "zero"
|
||||
#define RETRY_COUNT 5
|
||||
|
||||
/* Set if DM target versions were probed */
|
||||
@@ -168,6 +168,12 @@ static void _dm_set_crypt_compat(struct crypt_device *cd,
|
||||
_dm_flags |= DM_CAPI_STRING_SUPPORTED;
|
||||
}
|
||||
|
||||
if (_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_BITLK_EBOIV_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_BITLK_ELEPHANT_SUPPORTED;
|
||||
|
||||
_dm_crypt_checked = true;
|
||||
}
|
||||
|
||||
@@ -196,6 +202,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
|
||||
_dm_flags |= DM_VERITY_FEC_SUPPORTED;
|
||||
}
|
||||
|
||||
if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
|
||||
_dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
|
||||
|
||||
_dm_verity_checked = true;
|
||||
}
|
||||
|
||||
@@ -218,6 +227,9 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
|
||||
if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
|
||||
|
||||
_dm_integrity_checked = true;
|
||||
}
|
||||
|
||||
@@ -265,7 +277,7 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
|
||||
if ((target_type == DM_CRYPT && _dm_crypt_checked) ||
|
||||
(target_type == DM_VERITY && _dm_verity_checked) ||
|
||||
(target_type == DM_INTEGRITY && _dm_integrity_checked) ||
|
||||
(target_type == DM_LINEAR) ||
|
||||
(target_type == DM_LINEAR) || (target_type == DM_ZERO) ||
|
||||
(_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked))
|
||||
return 1;
|
||||
|
||||
@@ -346,7 +358,7 @@ int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
|
||||
if ((target == DM_CRYPT && _dm_crypt_checked) ||
|
||||
(target == DM_VERITY && _dm_verity_checked) ||
|
||||
(target == DM_INTEGRITY && _dm_integrity_checked) ||
|
||||
(target == DM_LINEAR)) /* nothing to check with linear */
|
||||
(target == DM_LINEAR) || (target == DM_ZERO)) /* nothing to check */
|
||||
return 0;
|
||||
|
||||
return -ENODEV;
|
||||
@@ -667,7 +679,7 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
int max_size, r, num_options = 0;
|
||||
struct crypt_params_verity *vp;
|
||||
char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
|
||||
char features[256], fec_features[256];
|
||||
char features[256], fec_features[256], verity_verify_args[512+32];
|
||||
|
||||
if (!tgt || !tgt->u.verity.vp)
|
||||
return NULL;
|
||||
@@ -697,6 +709,13 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
} else
|
||||
*fec_features = '\0';
|
||||
|
||||
if (tgt->u.verity.root_hash_sig_key_desc) {
|
||||
num_options += 2;
|
||||
snprintf(verity_verify_args, sizeof(verity_verify_args)-1,
|
||||
" root_hash_sig_key_desc %s", tgt->u.verity.root_hash_sig_key_desc);
|
||||
} else
|
||||
*verity_verify_args = '\0';
|
||||
|
||||
if (num_options)
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
|
||||
@@ -722,19 +741,22 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
max_size = strlen(hexroot) + strlen(hexsalt) +
|
||||
strlen(device_block_path(tgt->data_device)) +
|
||||
strlen(device_block_path(tgt->u.verity.hash_device)) +
|
||||
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128;
|
||||
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128 +
|
||||
strlen(verity_verify_args);
|
||||
|
||||
params = crypt_safe_alloc(max_size);
|
||||
if (!params)
|
||||
goto out;
|
||||
|
||||
r = snprintf(params, max_size,
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s",
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s%s",
|
||||
vp->hash_type, device_block_path(tgt->data_device),
|
||||
device_block_path(tgt->u.verity.hash_device),
|
||||
vp->data_block_size, vp->hash_block_size,
|
||||
vp->data_size, tgt->u.verity.hash_offset,
|
||||
vp->hash_name, hexroot, hexsalt, features, fec_features);
|
||||
vp->hash_name, hexroot, hexsalt, features, fec_features,
|
||||
verity_verify_args);
|
||||
|
||||
if (r < 0 || r >= max_size) {
|
||||
crypt_safe_free(params);
|
||||
params = NULL;
|
||||
@@ -866,6 +888,11 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
crypt_safe_free(hexkey);
|
||||
}
|
||||
if (tgt->u.integrity.fix_padding) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "fix_padding ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_RECALCULATE) {
|
||||
num_options++;
|
||||
@@ -922,6 +949,16 @@ static char *get_dm_linear_params(const struct dm_target *tgt, uint32_t flags)
|
||||
return params;
|
||||
}
|
||||
|
||||
static char *get_dm_zero_params(const struct dm_target *tgt, uint32_t flags)
|
||||
{
|
||||
char *params = crypt_safe_alloc(1);
|
||||
if (!params)
|
||||
return NULL;
|
||||
|
||||
params[0] = 0;
|
||||
return params;
|
||||
}
|
||||
|
||||
/* DM helpers */
|
||||
static int _dm_remove(const char *name, int udev_wait, int deferred)
|
||||
{
|
||||
@@ -1195,6 +1232,9 @@ static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *d
|
||||
case DM_LINEAR:
|
||||
target = DM_LINEAR_TARGET;
|
||||
break;
|
||||
case DM_ZERO:
|
||||
target = DM_ZERO_TARGET;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
@@ -1233,6 +1273,8 @@ static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
|
||||
tgt->params = get_dm_integrity_params(tgt, dmd->flags);
|
||||
else if (tgt->type == DM_LINEAR)
|
||||
tgt->params = get_dm_linear_params(tgt, dmd->flags);
|
||||
else if (tgt->type == DM_ZERO)
|
||||
tgt->params = get_dm_zero_params(tgt, dmd->flags);
|
||||
else {
|
||||
r = -ENOTSUP;
|
||||
goto err;
|
||||
@@ -1454,10 +1496,13 @@ static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target
|
||||
crypt_free_verity_params(tgt->u.verity.vp);
|
||||
device_free(cd, tgt->u.verity.hash_device);
|
||||
free(CONST_CAST(void*)tgt->u.verity.root_hash);
|
||||
free(CONST_CAST(void*)tgt->u.verity.root_hash_sig_key_desc);
|
||||
/* fall through */
|
||||
case DM_LINEAR:
|
||||
/* fall through */
|
||||
case DM_ERROR:
|
||||
/* fall through */
|
||||
case DM_ZERO:
|
||||
break;
|
||||
default:
|
||||
log_err(cd, _("Unknown dm target type."));
|
||||
@@ -1522,7 +1567,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
|
||||
/* If kernel keyring is not supported load key directly in dm-crypt */
|
||||
if ((*dmd_flags & CRYPT_ACTIVATE_KEYRING_KEY) &&
|
||||
!(dmt_flags & DM_KERNEL_KEYRING_SUPPORTED)) {
|
||||
log_dbg(cd, "dm-crypt doesn't support kernel keyring");
|
||||
log_dbg(cd, "dm-crypt does not support kernel keyring");
|
||||
*dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
ret = 1;
|
||||
}
|
||||
@@ -1530,7 +1575,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
|
||||
/* Drop performance options if not supported */
|
||||
if ((*dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
|
||||
!(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
|
||||
log_dbg(cd, "dm-crypt doesn't support performance options");
|
||||
log_dbg(cd, "dm-crypt does not support performance options");
|
||||
*dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
|
||||
ret = 1;
|
||||
}
|
||||
@@ -1556,7 +1601,8 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
if (r < 0 && dm_flags(cd, dmd->segment.type, &dmt_flags))
|
||||
goto out;
|
||||
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR) && check_retry(cd, &dmd->flags, dmt_flags))
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
|
||||
check_retry(cd, &dmd->flags, dmt_flags))
|
||||
r = _dm_create_device(cd, name, type, dmd->uuid, dmd);
|
||||
|
||||
if (r == -EINVAL &&
|
||||
@@ -1669,6 +1715,7 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
||||
strcmp(target_type, DM_VERITY_TARGET) &&
|
||||
strcmp(target_type, DM_INTEGRITY_TARGET) &&
|
||||
strcmp(target_type, DM_LINEAR_TARGET) &&
|
||||
strcmp(target_type, DM_ZERO_TARGET) &&
|
||||
strcmp(target_type, DM_ERROR_TARGET)))
|
||||
goto out;
|
||||
r = 0;
|
||||
@@ -1957,6 +2004,7 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
int r;
|
||||
struct device *data_device = NULL, *hash_device = NULL, *fec_device = NULL;
|
||||
char *hash_name = NULL, *root_hash = NULL, *salt = NULL, *fec_dev_str = NULL;
|
||||
char *root_hash_sig_key_desc = NULL;
|
||||
|
||||
if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
|
||||
vp = crypt_zalloc(sizeof(*vp));
|
||||
@@ -2140,6 +2188,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
if (vp)
|
||||
vp->fec_roots = val32;
|
||||
i++;
|
||||
} else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
|
||||
str = strsep(¶ms, " ");
|
||||
if (!str)
|
||||
goto err;
|
||||
if (!root_hash_sig_key_desc)
|
||||
root_hash_sig_key_desc = strdup(str);
|
||||
i++;
|
||||
if (vp)
|
||||
vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
|
||||
} else /* unknown option */
|
||||
goto err;
|
||||
}
|
||||
@@ -2165,11 +2222,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
vp->salt = salt;
|
||||
if (vp && fec_dev_str)
|
||||
vp->fec_device = fec_dev_str;
|
||||
if (root_hash_sig_key_desc)
|
||||
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
device_free(cd, data_device);
|
||||
device_free(cd, hash_device);
|
||||
device_free(cd, fec_device);
|
||||
free(root_hash_sig_key_desc);
|
||||
free(root_hash);
|
||||
free(hash_name);
|
||||
free(salt);
|
||||
@@ -2334,6 +2395,8 @@ static int _dm_target_query_integrity(struct crypt_device *cd,
|
||||
}
|
||||
} else if (!strcmp(arg, "recalculate")) {
|
||||
*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
} else if (!strcmp(arg, "fix_padding")) {
|
||||
tgt->u.integrity.fix_padding = true;
|
||||
} else /* unknown option */
|
||||
goto err;
|
||||
}
|
||||
@@ -2416,6 +2479,14 @@ static int _dm_target_query_error(struct crypt_device *cd, struct dm_target *tgt
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dm_target_query_zero(struct crypt_device *cd, struct dm_target *tgt)
|
||||
{
|
||||
tgt->type = DM_ZERO;
|
||||
tgt->direction = TARGET_QUERY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* on error retval has to be negative
|
||||
*
|
||||
@@ -2437,6 +2508,8 @@ static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const
|
||||
r = _dm_target_query_linear(cd, tgt, get_flags, params);
|
||||
else if (!strcmp(target_type, DM_ERROR_TARGET))
|
||||
r = _dm_target_query_error(cd, tgt);
|
||||
else if (!strcmp(target_type, DM_ZERO_TARGET))
|
||||
r = _dm_target_query_zero(cd, tgt);
|
||||
|
||||
if (!r) {
|
||||
tgt->offset = *start;
|
||||
@@ -2519,6 +2592,9 @@ static int _dm_query_device(struct crypt_device *cd, const char *name,
|
||||
if (dmi.read_only)
|
||||
dmd->flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (dmi.suspended)
|
||||
dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
|
||||
|
||||
tmp_uuid = dm_task_get_uuid(dmt);
|
||||
if (!tmp_uuid)
|
||||
dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
|
||||
@@ -2566,6 +2642,7 @@ int dm_query_device(struct crypt_device *cd, const char *name,
|
||||
|
||||
static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps, char **names, size_t names_offset, size_t names_length)
|
||||
{
|
||||
#if HAVE_DECL_DM_DEVICE_GET_NAME
|
||||
struct crypt_dm_active_device dmd;
|
||||
char dmname[PATH_MAX];
|
||||
unsigned i;
|
||||
@@ -2604,6 +2681,9 @@ static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_
|
||||
}
|
||||
|
||||
return count;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
|
||||
@@ -2841,8 +2921,8 @@ err:
|
||||
|
||||
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||
uint64_t hash_blocks, struct crypt_params_verity *vp)
|
||||
const char *root_hash, uint32_t root_hash_size, const char *root_hash_sig_key_desc,
|
||||
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp)
|
||||
{
|
||||
if (!data_device || !hash_device || !vp)
|
||||
return -EINVAL;
|
||||
@@ -2857,6 +2937,7 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
tgt->u.verity.fec_device = fec_device;
|
||||
tgt->u.verity.root_hash = root_hash;
|
||||
tgt->u.verity.root_hash_size = root_hash_size;
|
||||
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
|
||||
tgt->u.verity.hash_offset = hash_offset_block;
|
||||
tgt->u.verity.fec_offset = vp->fec_area_offset / vp->hash_block_size;
|
||||
tgt->u.verity.hash_blocks = hash_blocks;
|
||||
@@ -2865,16 +2946,21 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
int dm_integrity_target_set(struct crypt_device *cd,
|
||||
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *meta_device,
|
||||
struct device *data_device, uint64_t tag_size, uint64_t offset,
|
||||
uint32_t sector_size, struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
|
||||
const struct crypt_params_integrity *ip)
|
||||
{
|
||||
uint32_t dmi_flags;
|
||||
|
||||
if (!data_device)
|
||||
return -EINVAL;
|
||||
|
||||
_dm_check_versions(cd, DM_INTEGRITY);
|
||||
|
||||
tgt->type = DM_INTEGRITY;
|
||||
tgt->direction = TARGET_SET;
|
||||
tgt->offset = seg_offset;
|
||||
@@ -2890,6 +2976,11 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
|
||||
tgt->u.integrity.journal_crypt_key = journal_crypt_key;
|
||||
tgt->u.integrity.journal_integrity_key = journal_mac_key;
|
||||
|
||||
if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED) &&
|
||||
!(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING))
|
||||
tgt->u.integrity.fix_padding = true;
|
||||
|
||||
if (ip) {
|
||||
tgt->u.integrity.journal_size = ip->journal_size;
|
||||
tgt->u.integrity.journal_watermark = ip->journal_watermark;
|
||||
@@ -2920,3 +3011,13 @@ int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
|
||||
{
|
||||
tgt->type = DM_ZERO;
|
||||
tgt->direction = TARGET_SET;
|
||||
tgt->offset = seg_offset;
|
||||
tgt->size = seg_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -81,7 +81,7 @@ static int hash_keys(struct crypt_device *cd,
|
||||
const char *hash_name;
|
||||
char tweak, *key_ptr;
|
||||
unsigned int i;
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
hash_name = hash_override ?: get_hash(key_len_output);
|
||||
tweak = get_tweak(keys_count);
|
||||
@@ -242,7 +242,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
|
||||
if (r < 0 && !dm_flags(cd, DM_CRYPT, &dmc_flags) &&
|
||||
(dmc_flags & req_flags) != req_flags) {
|
||||
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping."));
|
||||
log_err(cd, _("Kernel does not support loop-AES compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "luks.h"
|
||||
@@ -89,7 +88,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
r = device_block_adjust(ctx, crypt_metadata_device(ctx), DEV_OK,
|
||||
sector, &dmd.size, &dmd.flags);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Device %s doesn't exist or access denied."),
|
||||
log_err(ctx, _("Device %s does not exist or access denied."),
|
||||
device_path(crypt_metadata_device(ctx)));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@@ -260,7 +259,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
}
|
||||
@@ -284,7 +283,7 @@ int LUKS_hdr_restore(
|
||||
buffer_size = LUKS_device_sectors(&hdr_file) << SECTOR_SHIFT;
|
||||
|
||||
if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) {
|
||||
log_err(ctx, _("Backup file doesn't contain valid LUKS header."));
|
||||
log_err(ctx, _("Backup file does not contain valid LUKS header."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -453,7 +452,7 @@ out:
|
||||
if (r)
|
||||
log_err(ctx, _("Repair failed."));
|
||||
crypt_free_volume_key(vk);
|
||||
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -692,7 +691,7 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
|
||||
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
|
||||
|
||||
crypt_free_volume_key(empty_key);
|
||||
crypt_memzero(buf, sizeof(buf));
|
||||
crypt_safe_memzero(buf, sizeof(buf));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -787,10 +786,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
return r;
|
||||
assert(pbkdf->iterations);
|
||||
|
||||
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
|
||||
if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK && pbkdf->time_ms == 0)
|
||||
PBKDF2_temp = LUKS_MKD_ITERATIONS_MIN;
|
||||
else /* iterations per ms * LUKS_MKD_ITERATIONS_MS */
|
||||
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
|
||||
|
||||
if (PBKDF2_temp > (double)UINT32_MAX)
|
||||
return -EINVAL;
|
||||
header->mkDigestIterations = at_least((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN);
|
||||
assert(header->mkDigestIterations);
|
||||
|
||||
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, vk->key,vk->keylength,
|
||||
header->mkDigestSalt, LUKS_SALTSIZE,
|
||||
@@ -982,8 +986,10 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
|
||||
derived_key->key, hdr->keyBytes,
|
||||
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
|
||||
r = LUKS_decrypt_from_storage(AfKey,
|
||||
@@ -1224,7 +1230,7 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
|
||||
|
||||
int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf)
|
||||
{
|
||||
if (keyslot >= LUKS_NUMKEYS || keyslot < 0)
|
||||
if (LUKS_keyslot_info(hdr, keyslot) < CRYPT_SLOT_ACTIVE)
|
||||
return -EINVAL;
|
||||
|
||||
pbkdf->type = CRYPT_KDF_PBKDF2;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -600,7 +600,8 @@ int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
|
||||
crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd,
|
||||
struct crypt_params_reencrypt *params);
|
||||
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock);
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock);
|
||||
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock);
|
||||
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock);
|
||||
|
||||
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, digest handling
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, PBKDF2 digest handler (LUKS1 compatible)
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -210,7 +210,7 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
|
||||
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
|
||||
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header does not match size 0x%04x.",
|
||||
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
#define _CRYPTSETUP_LUKS2_INTERNAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <json-c/json.h>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS2 header format code
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2019 Ondrej Kozina
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -45,11 +45,11 @@ void hexprint_base64(struct crypt_device *cd, json_object *jobj,
|
||||
&buf, &buf_len))
|
||||
return;
|
||||
|
||||
for (i = 0; i < buf_len / 2; i++)
|
||||
log_std(cd, "%02hhx%s", buf[i], sep);
|
||||
log_std(cd, "\n\t%s", line_sep);
|
||||
for (i = buf_len / 2; i < buf_len; i++)
|
||||
for (i = 0; i < buf_len; i++) {
|
||||
if (i && !(i % 16))
|
||||
log_std(cd, "\n\t%s", line_sep);
|
||||
log_std(cd, "%02hhx%s", buf[i], sep);
|
||||
}
|
||||
log_std(cd, "\n");
|
||||
free(buf);
|
||||
}
|
||||
@@ -459,12 +459,12 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
|
||||
json_size = (uint64_t)strlen(json);
|
||||
|
||||
if (hdr_json_size != json_area_size) {
|
||||
log_dbg(cd, "JSON area size doesn't match value in binary header.");
|
||||
log_dbg(cd, "JSON area size does not match value in binary header.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (json_size > json_area_size) {
|
||||
log_dbg(cd, "JSON doesn't fit in the designated area.");
|
||||
log_dbg(cd, "JSON does not fit in the designated area.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -970,13 +970,16 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
static int hdr_cleanup_and_validate(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
return LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
|
||||
@@ -984,11 +987,7 @@ int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
|
||||
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
|
||||
@@ -1159,7 +1158,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
device_free(cd, backup_device);
|
||||
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Backup file doesn't contain valid LUKS header."));
|
||||
log_err(cd, _("Backup file does not contain valid LUKS header."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1270,8 +1269,8 @@ out:
|
||||
LUKS2_hdr_free(cd, hdr);
|
||||
LUKS2_hdr_free(cd, &hdr_file);
|
||||
LUKS2_hdr_free(cd, &tmp_hdr);
|
||||
crypt_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_safe_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_free(buffer);
|
||||
|
||||
device_sync(cd, device);
|
||||
@@ -2157,7 +2156,7 @@ int LUKS2_activate(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags);
|
||||
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags, 0);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -2205,26 +2204,21 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
|
||||
struct dm_target *tgt;
|
||||
crypt_status_info ci;
|
||||
struct crypt_dm_active_device dmdc;
|
||||
char **dep, uuid[37], deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
|
||||
char **dep, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
|
||||
const char *namei = NULL;
|
||||
struct crypt_lock_handle *reencrypt_lock = NULL;
|
||||
|
||||
if (!dmd || !dmd->uuid)
|
||||
if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1))
|
||||
return -EINVAL;
|
||||
|
||||
/* uuid mismatch with metadata (if available) */
|
||||
if (hdr && crypt_uuid_cmp(dmd->uuid, hdr->uuid))
|
||||
return -EINVAL;
|
||||
|
||||
r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), CRYPT_SUBDEV "-%.32s", dmd->uuid + 6);
|
||||
if (r < 0 || (size_t)r != (sizeof(deps_uuid_prefix) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
r = snprintf(uuid, sizeof(uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
|
||||
dmd->uuid + 6, dmd->uuid + 14, dmd->uuid + 18, dmd->uuid + 22, dmd->uuid + 26);
|
||||
if (r < 0 || (size_t)r != (sizeof(uuid) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* uuid mismatch with metadata (if available) */
|
||||
if (hdr && strcmp(hdr->uuid, uuid))
|
||||
return -EINVAL;
|
||||
|
||||
tgt = &dmd->segment;
|
||||
|
||||
/* TODO: We have LUKS2 dependencies now */
|
||||
@@ -2236,7 +2230,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
|
||||
goto out;
|
||||
|
||||
if (contains_reencryption_helper(deps)) {
|
||||
r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot deactivate device."));
|
||||
@@ -2345,9 +2339,9 @@ int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uin
|
||||
reqs &= ~reqs_mask;
|
||||
|
||||
if (reqs_reencrypt(reqs) && !quiet)
|
||||
log_err(cd, _("Offline reencryption in progress. Aborting."));
|
||||
log_err(cd, _("Operation incompatible with device marked for legacy reencryption. Aborting."));
|
||||
if (reqs_reencrypt_online(reqs) && !quiet)
|
||||
log_err(cd, _("Online reencryption in progress. Aborting."));
|
||||
log_err(cd, _("Operation incompatible with device marked for LUKS2 reencryption. Aborting."));
|
||||
|
||||
/* any remaining unmasked requirement fails the check */
|
||||
return reqs ? -EINVAL : 0;
|
||||
@@ -2400,7 +2394,7 @@ int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object
|
||||
#endif
|
||||
}
|
||||
|
||||
/* jobj_dst must contain pointer initialised to NULL (see json-c json_object_deep_copy API) */
|
||||
/* jobj_dst must contain pointer initialized to NULL (see json-c json_object_deep_copy API) */
|
||||
int json_object_copy(json_object *jobj_src, json_object **jobj_dst)
|
||||
{
|
||||
if (!jobj_src || !jobj_dst || *jobj_dst)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, keyslot handling
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -79,19 +79,18 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr)
|
||||
/* Check if a keyslot is assigned to specific segment */
|
||||
static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
|
||||
{
|
||||
int keyslot_digest, segment_digest, s, count = 0;
|
||||
int keyslot_digest, count = 0;
|
||||
unsigned s;
|
||||
|
||||
keyslot_digest = LUKS2_digest_by_keyslot(hdr, keyslot);
|
||||
if (keyslot_digest < 0)
|
||||
return keyslot_digest;
|
||||
|
||||
if (segment >= 0) {
|
||||
segment_digest = LUKS2_digest_by_segment(hdr, segment);
|
||||
return segment_digest == keyslot_digest;
|
||||
}
|
||||
for (s = 0; s < 3; s++) {
|
||||
segment_digest = LUKS2_digest_by_segment(hdr, s);
|
||||
if (segment_digest == keyslot_digest)
|
||||
if (segment >= 0)
|
||||
return keyslot_digest == LUKS2_digest_by_segment(hdr, segment);
|
||||
|
||||
for (s = 0; s < json_segments_count(LUKS2_get_segments_jobj(hdr)); s++) {
|
||||
if (keyslot_digest == LUKS2_digest_by_segment(hdr, s))
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -310,28 +309,16 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
static int _open_and_verify(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
const keyslot_handler *h,
|
||||
int keyslot,
|
||||
int digest,
|
||||
const char *password,
|
||||
size_t password_len,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int key_size, r;
|
||||
int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
|
||||
r = _keyslot_for_digest(hdr, keyslot, digest);
|
||||
if (r) {
|
||||
if (r == -ENOENT)
|
||||
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
|
||||
return r;
|
||||
}
|
||||
|
||||
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
if (key_size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -350,9 +337,41 @@ static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
*vk = NULL;
|
||||
}
|
||||
|
||||
crypt_volume_key_set_id(*vk, r);
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
int digest,
|
||||
const char *password,
|
||||
size_t password_len,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int r;
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
|
||||
r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot));
|
||||
if (r) {
|
||||
log_dbg(cd, "Keyslot %d validation failed.", keyslot);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = _keyslot_for_digest(hdr, keyslot, digest);
|
||||
if (r) {
|
||||
if (r == -ENOENT)
|
||||
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
|
||||
return r;
|
||||
}
|
||||
|
||||
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
@@ -362,7 +381,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int key_size, r;
|
||||
int r;
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
@@ -380,29 +399,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
key_size = LUKS2_get_volume_key_size(hdr, segment);
|
||||
if (key_size < 0)
|
||||
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
if (key_size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
*vk = crypt_alloc_volume_key(key_size, NULL);
|
||||
if (!*vk)
|
||||
return -ENOMEM;
|
||||
|
||||
r = h->open(cd, keyslot, password, password_len, (*vk)->key, (*vk)->keylength);
|
||||
if (r < 0)
|
||||
log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r);
|
||||
else
|
||||
r = LUKS2_digest_verify(cd, hdr, *vk, keyslot);
|
||||
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
} else
|
||||
crypt_volume_key_set_id(*vk, r);
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
|
||||
}
|
||||
|
||||
static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
|
||||
@@ -520,7 +517,7 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
size_t password_len,
|
||||
struct volume_key **vks)
|
||||
{
|
||||
struct volume_key *vk;
|
||||
struct volume_key *vk = NULL;
|
||||
int digest_old, digest_new, r = -EINVAL;
|
||||
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||
|
||||
@@ -530,7 +527,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
crypt_volume_key_set_id(vk, digest_old);
|
||||
crypt_volume_key_add_next(vks, vk);
|
||||
}
|
||||
|
||||
@@ -540,7 +536,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_new, digest_new, password, password_len, &vk);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
crypt_volume_key_set_id(vk, digest_new);
|
||||
crypt_volume_key_add_next(vks, vk);
|
||||
}
|
||||
out:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS2 type keyslot handler
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
|
||||
*
|
||||
* Copyright (C) 2016-2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2018, Ondrej Kozina
|
||||
* Copyright (C) 2016-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS1 conversion code
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Ondrej Kozina
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Ondrej Kozina
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -402,6 +402,7 @@ static int json_luks1_object(struct luks_phdr *hdr_v1, struct json_object **luks
|
||||
|
||||
json_size = LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN;
|
||||
json_object_object_add(field, "json_size", json_object_new_uint64(json_size));
|
||||
keyslots_size -= (keyslots_size % 4096);
|
||||
json_object_object_add(field, "keyslots_size", json_object_new_uint64(keyslots_size));
|
||||
|
||||
*luks1_object = luks1_obj;
|
||||
@@ -466,7 +467,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
|
||||
r = 0;
|
||||
out:
|
||||
device_sync(cd, device);
|
||||
crypt_memzero(buf, buf_size);
|
||||
crypt_safe_memzero(buf, buf_size);
|
||||
free(buf);
|
||||
|
||||
return r;
|
||||
@@ -577,6 +578,12 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check future LUKS2 metadata before moving keyslots area */
|
||||
if (LUKS2_hdr_validate(cd, hdr2->jobj, hdr2->hdr_size - LUKS2_HDR_BIN_LEN)) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = luks_header_in_use(cd))) {
|
||||
if (r > 0)
|
||||
r = -EBUSY;
|
||||
@@ -586,6 +593,14 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
|
||||
// move keyslots 4k -> 32k offset
|
||||
buf_offset = 2 * LUKS2_HDR_16K_LEN;
|
||||
buf_size = luks1_size - LUKS_ALIGN_KEYSLOTS;
|
||||
|
||||
/* check future LUKS2 keyslots area is at least as large as LUKS1 keyslots area */
|
||||
if (buf_size > LUKS2_keyslots_size(hdr2->jobj)) {
|
||||
log_err(cd, _("Unable to move keyslot area. LUKS2 keyslots area too small."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = move_keyslot_areas(cd, 8 * SECTOR_SIZE, buf_offset, buf_size)) < 0) {
|
||||
log_err(cd, _("Unable to move keyslot area."));
|
||||
goto out;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption helpers
|
||||
*
|
||||
* Copyright (C) 2015-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019, Ondrej Kozina
|
||||
* Copyright (C) 2015-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -1401,12 +1401,12 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read journaled data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -1436,13 +1436,13 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -2531,7 +2531,7 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
else if (ri == CRYPT_REENCRYPT_CRASH)
|
||||
r = reencrypt_load_crashed(cd, hdr, device_size, &tmp);
|
||||
else if (ri == CRYPT_REENCRYPT_NONE) {
|
||||
log_err(cd, _("No LUKS2 reencryption in progress."));
|
||||
log_err(cd, _("Device not marked for LUKS2 reencryption."));
|
||||
return -EINVAL;
|
||||
} else
|
||||
r = -EINVAL;
|
||||
@@ -2546,21 +2546,10 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
static int reencrypt_lock_internal(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
int r;
|
||||
char *lock_resource;
|
||||
const char *tmp = crypt_get_uuid(cd);
|
||||
|
||||
if (!tmp && !uuid)
|
||||
return -EINVAL;
|
||||
if (!uuid)
|
||||
uuid = tmp;
|
||||
if (!tmp)
|
||||
tmp = uuid;
|
||||
if (strcmp(uuid, tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (!crypt_metadata_locking_enabled()) {
|
||||
*reencrypt_lock = NULL;
|
||||
@@ -2582,6 +2571,36 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
int r;
|
||||
char hdr_uuid[37];
|
||||
const char *uuid = crypt_get_uuid(cd);
|
||||
|
||||
if (!dm_uuid)
|
||||
return -EINVAL;
|
||||
|
||||
if (!uuid) {
|
||||
r = snprintf(hdr_uuid, sizeof(hdr_uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
|
||||
dm_uuid + 6, dm_uuid + 14, dm_uuid + 18, dm_uuid + 22, dm_uuid + 26);
|
||||
if (r < 0 || (size_t)r != (sizeof(hdr_uuid) - 1))
|
||||
return -EINVAL;
|
||||
} else if (crypt_uuid_cmp(dm_uuid, uuid))
|
||||
return -EINVAL;
|
||||
|
||||
return reencrypt_lock_internal(cd, uuid, reencrypt_lock);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
if (!cd || !crypt_get_type(cd) || strcmp(crypt_get_type(cd), CRYPT_LUKS2))
|
||||
return -EINVAL;
|
||||
|
||||
return reencrypt_lock_internal(cd, crypt_get_uuid(cd), reencrypt_lock);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock)
|
||||
{
|
||||
@@ -2605,7 +2624,7 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr *
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &h);
|
||||
r = crypt_reencrypt_lock(cd, &h);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption process is already running."));
|
||||
@@ -2809,7 +2828,7 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd,
|
||||
crypt_reencrypt_info ri;
|
||||
struct crypt_lock_handle *reencrypt_lock;
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot perform recovery."));
|
||||
@@ -2936,7 +2955,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
|
||||
r = reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params);
|
||||
|
||||
crypt_memzero(passphrase, passphrase_size);
|
||||
crypt_safe_memzero(passphrase, passphrase_size);
|
||||
free(passphrase);
|
||||
|
||||
return r;
|
||||
@@ -3386,7 +3405,7 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
|
||||
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
|
||||
if (r < 0)
|
||||
goto err;
|
||||
vk = vk->next;
|
||||
vk = crypt_volume_key_next(vk);
|
||||
}
|
||||
|
||||
if (luks2_check_device_size(cd, hdr, minimal_size, &device_size, true, false))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, internal segment handling
|
||||
*
|
||||
* Copyright (C) 2018-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019, Ondrej Kozina
|
||||
* Copyright (C) 2018-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, token handling
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -332,7 +332,7 @@ static void LUKS2_token_buffer_free(struct crypt_device *cd,
|
||||
if (h->buffer_free)
|
||||
h->buffer_free(buffer, buffer_len);
|
||||
else {
|
||||
crypt_memzero(buffer, buffer_len);
|
||||
crypt_safe_memzero(buffer, buffer_len);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, kernel keyring token
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* cryptsetup kernel RNG access functions
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
@@ -28,10 +27,6 @@
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
static int random_initialised = 0;
|
||||
|
||||
#define URANDOM_DEVICE "/dev/urandom"
|
||||
|
||||
381
lib/setup.c
381
lib/setup.c
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 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,7 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -36,6 +35,7 @@
|
||||
#include "verity.h"
|
||||
#include "tcrypt.h"
|
||||
#include "integrity.h"
|
||||
#include "bitlk.h"
|
||||
#include "utils_device_locking.h"
|
||||
#include "internal.h"
|
||||
|
||||
@@ -50,6 +50,7 @@ struct crypt_device {
|
||||
|
||||
struct volume_key *volume_key;
|
||||
int rng_type;
|
||||
uint32_t compatibility;
|
||||
struct crypt_pbkdf_type pbkdf;
|
||||
|
||||
/* global context scope settings */
|
||||
@@ -95,7 +96,7 @@ struct crypt_device {
|
||||
} loopaes;
|
||||
struct { /* used in CRYPT_VERITY */
|
||||
struct crypt_params_verity hdr;
|
||||
char *root_hash;
|
||||
const char *root_hash;
|
||||
unsigned int root_hash_size;
|
||||
char *uuid;
|
||||
struct device *fec_device;
|
||||
@@ -108,7 +109,12 @@ struct crypt_device {
|
||||
struct crypt_params_integrity params;
|
||||
struct volume_key *journal_mac_key;
|
||||
struct volume_key *journal_crypt_key;
|
||||
uint32_t sb_flags;
|
||||
} integrity;
|
||||
struct { /* used in CRYPT_BITLK */
|
||||
struct bitlk_metadata params;
|
||||
char *cipher_spec;
|
||||
} bitlk;
|
||||
struct { /* used if initialized without header by name */
|
||||
char *active_name;
|
||||
/* buffers, must refresh from kernel on every query */
|
||||
@@ -315,6 +321,11 @@ static int isINTEGRITY(const char *type)
|
||||
return (type && !strcmp(CRYPT_INTEGRITY, type));
|
||||
}
|
||||
|
||||
static int isBITLK(const char *type)
|
||||
{
|
||||
return (type && !strcmp(CRYPT_BITLK, type));
|
||||
}
|
||||
|
||||
static int _onlyLUKS(struct crypt_device *cd, uint32_t cdflags)
|
||||
{
|
||||
int r = 0;
|
||||
@@ -572,6 +583,9 @@ int crypt_init(struct crypt_device **cd, const char *device)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(NULL, "Allocating context for crypt device %s.", device ?: "(none)");
|
||||
#if !HAVE_DECL_O_CLOEXEC
|
||||
log_dbg(NULL, "Running without O_CLOEXEC.");
|
||||
#endif
|
||||
|
||||
if (!(h = malloc(sizeof(struct crypt_device))))
|
||||
return -ENOMEM;
|
||||
@@ -726,9 +740,6 @@ out:
|
||||
free(type);
|
||||
LUKS2_hdr_free(cd, &hdr2);
|
||||
}
|
||||
/* FIXME: why? */
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -763,7 +774,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
|
||||
if (isLUKS1(requested_type) || version == 1) {
|
||||
if (cd->type && isLUKS2(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -803,7 +814,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
memcpy(&cd->u.luks1.hdr, &hdr, sizeof(hdr));
|
||||
} else if (isLUKS2(requested_type) || version == 2 || version == 0) {
|
||||
if (cd->type && isLUKS1(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -822,7 +833,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -886,7 +897,7 @@ static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verit
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.hash_name);
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
|
||||
free(cd->u.verity.uuid);
|
||||
crypt_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
|
||||
crypt_safe_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -922,7 +933,7 @@ static int _crypt_load_integrity(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params);
|
||||
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params, &cd->u.integrity.sb_flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -965,6 +976,31 @@ static int _crypt_load_integrity(struct crypt_device *cd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _crypt_load_bitlk(struct crypt_device *cd,
|
||||
struct bitlk_metadata *params)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = init_crypto(cd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = BITLK_read_sb(cd, &cd->u.bitlk.params);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (asprintf(&cd->u.bitlk.cipher_spec, "%s-%s",
|
||||
cd->u.bitlk.params.cipher, cd->u.bitlk.params.cipher_mode) < 0) {
|
||||
cd->u.bitlk.cipher_spec = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!cd->type && !(cd->type = strdup(CRYPT_BITLK)))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_load(struct crypt_device *cd,
|
||||
const char *requested_type,
|
||||
void *params)
|
||||
@@ -987,29 +1023,35 @@ int crypt_load(struct crypt_device *cd,
|
||||
|
||||
if (!requested_type || isLUKS1(requested_type) || isLUKS2(requested_type)) {
|
||||
if (cd->type && !isLUKS1(cd->type) && !isLUKS2(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = _crypt_load_luks(cd, requested_type, 1, 0);
|
||||
} else if (isVERITY(requested_type)) {
|
||||
if (cd->type && !isVERITY(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_verity(cd, params);
|
||||
} else if (isTCRYPT(requested_type)) {
|
||||
if (cd->type && !isTCRYPT(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_tcrypt(cd, params);
|
||||
} else if (isINTEGRITY(requested_type)) {
|
||||
if (cd->type && !isINTEGRITY(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_integrity(cd, params);
|
||||
} else if (isBITLK(requested_type)) {
|
||||
if (cd->type && !isBITLK(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_bitlk(cd, params);
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1086,7 +1128,7 @@ static void crypt_free_type(struct crypt_device *cd)
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.hash_device);
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.fec_device);
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
|
||||
free(cd->u.verity.root_hash);
|
||||
free(CONST_CAST(void*)cd->u.verity.root_hash);
|
||||
free(cd->u.verity.uuid);
|
||||
device_free(cd, cd->u.verity.fec_device);
|
||||
} else if (isINTEGRITY(cd->type)) {
|
||||
@@ -1095,6 +1137,9 @@ static void crypt_free_type(struct crypt_device *cd)
|
||||
free(CONST_CAST(void*)cd->u.integrity.params.journal_crypt);
|
||||
crypt_free_volume_key(cd->u.integrity.journal_crypt_key);
|
||||
crypt_free_volume_key(cd->u.integrity.journal_mac_key);
|
||||
} else if (isBITLK(cd->type)) {
|
||||
free(cd->u.bitlk.cipher_spec);
|
||||
BITLK_bitlk_metadata_free(&cd->u.bitlk.params);
|
||||
} else if (!cd->type) {
|
||||
free(cd->u.none.active_name);
|
||||
cd->u.none.active_name = NULL;
|
||||
@@ -1247,6 +1292,13 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
|
||||
} else if (isTCRYPT(cd->type) && single_segment(&dmd) && tgt->type == DM_CRYPT) {
|
||||
r = TCRYPT_init_by_name(cd, name, dmd.uuid, tgt, &cd->device,
|
||||
&cd->u.tcrypt.params, &cd->u.tcrypt.hdr);
|
||||
} else if (isBITLK(cd->type)) {
|
||||
r = _crypt_load_bitlk(cd, NULL);
|
||||
if (r < 0) {
|
||||
log_dbg(cd, "BITLK device header not available.");
|
||||
crypt_set_null_type(cd);
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
out:
|
||||
dm_targets_free(cd, &dmd);
|
||||
@@ -1269,6 +1321,7 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
|
||||
r = dm_query_device(cd, name,
|
||||
DM_ACTIVE_DEVICE |
|
||||
DM_ACTIVE_VERITY_HASH_DEVICE |
|
||||
DM_ACTIVE_VERITY_ROOT_HASH |
|
||||
DM_ACTIVE_VERITY_PARAMS, &dmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -1300,6 +1353,7 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
|
||||
cd->u.verity.hdr.fec_roots = tgt->u.verity.vp->fec_roots;
|
||||
MOVE_REF(cd->u.verity.fec_device, tgt->u.verity.fec_device);
|
||||
MOVE_REF(cd->metadata_device, tgt->u.verity.hash_device);
|
||||
MOVE_REF(cd->u.verity.root_hash, tgt->u.verity.root_hash);
|
||||
}
|
||||
out:
|
||||
dm_targets_free(cd, &dmd);
|
||||
@@ -1413,6 +1467,8 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||
(*cd)->type = strdup(CRYPT_TCRYPT);
|
||||
else if (!strncmp(CRYPT_INTEGRITY, dmd.uuid, sizeof(CRYPT_INTEGRITY)-1))
|
||||
(*cd)->type = strdup(CRYPT_INTEGRITY);
|
||||
else if (!strncmp(CRYPT_BITLK, dmd.uuid, sizeof(CRYPT_BITLK)-1))
|
||||
(*cd)->type = strdup(CRYPT_BITLK);
|
||||
else
|
||||
log_dbg(NULL, "Unknown UUID set, some parameters are not set.");
|
||||
} else
|
||||
@@ -1424,7 +1480,7 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Try to initialise basic parameters from active device */
|
||||
/* Try to initialize basic parameters from active device */
|
||||
|
||||
if (tgt->type == DM_CRYPT || tgt->type == DM_LINEAR)
|
||||
r = _init_by_name_crypt(*cd, name);
|
||||
@@ -2090,6 +2146,7 @@ static int _crypt_format_integrity(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params)
|
||||
{
|
||||
int r;
|
||||
uint32_t integrity_tag_size;
|
||||
char *integrity = NULL, *journal_integrity = NULL, *journal_crypt = NULL;
|
||||
struct volume_key *journal_crypt_key = NULL, *journal_mac_key = NULL;
|
||||
|
||||
@@ -2146,6 +2203,14 @@ static int _crypt_format_integrity(struct crypt_device *cd,
|
||||
goto err;
|
||||
}
|
||||
|
||||
integrity_tag_size = INTEGRITY_hash_tag_size(integrity);
|
||||
if (integrity_tag_size > 0 && params->tag_size && integrity_tag_size != params->tag_size)
|
||||
log_std(cd, _("WARNING: Requested tag size %d bytes differs from %s size output (%d bytes).\n"),
|
||||
params->tag_size, integrity, integrity_tag_size);
|
||||
|
||||
if (params->tag_size)
|
||||
integrity_tag_size = params->tag_size;
|
||||
|
||||
cd->u.integrity.journal_crypt_key = journal_crypt_key;
|
||||
cd->u.integrity.journal_mac_key = journal_mac_key;
|
||||
cd->u.integrity.params.journal_size = params->journal_size;
|
||||
@@ -2154,7 +2219,7 @@ static int _crypt_format_integrity(struct crypt_device *cd,
|
||||
cd->u.integrity.params.interleave_sectors = params->interleave_sectors;
|
||||
cd->u.integrity.params.buffer_sectors = params->buffer_sectors;
|
||||
cd->u.integrity.params.sector_size = params->sector_size;
|
||||
cd->u.integrity.params.tag_size = params->tag_size;
|
||||
cd->u.integrity.params.tag_size = integrity_tag_size;
|
||||
cd->u.integrity.params.integrity = integrity;
|
||||
cd->u.integrity.params.journal_integrity = journal_integrity;
|
||||
cd->u.integrity.params.journal_crypt = journal_crypt;
|
||||
@@ -2701,7 +2766,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
||||
* explicit size stored in metadata (length != "dynamic")
|
||||
*/
|
||||
|
||||
/* Device context type must be initialised */
|
||||
/* Device context type must be initialized */
|
||||
if (!cd || !cd->type || !name)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -2902,8 +2967,8 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
else
|
||||
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
|
||||
|
||||
crypt_memzero(&hdr1, sizeof(hdr1));
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
crypt_safe_memzero(&hdr1, sizeof(hdr1));
|
||||
crypt_safe_memzero(&hdr2, sizeof(hdr2));
|
||||
} else if (isLUKS2(cd->type) && (!requested_type || isLUKS2(requested_type))) {
|
||||
r = LUKS2_hdr_restore(cd, &cd->u.luks2.hdr, backup_file);
|
||||
if (r)
|
||||
@@ -2938,7 +3003,7 @@ void crypt_free(struct crypt_device *cd)
|
||||
free(CONST_CAST(void*)cd->pbkdf.hash);
|
||||
|
||||
/* Some structures can contain keys (TCRYPT), wipe it */
|
||||
crypt_memzero(cd, sizeof(*cd));
|
||||
crypt_safe_memzero(cd, sizeof(*cd));
|
||||
free(cd);
|
||||
}
|
||||
|
||||
@@ -3147,7 +3212,7 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
r = dm_resume_and_reinstate_key(cd, name, vk);
|
||||
if (r)
|
||||
if (r < 0)
|
||||
log_err(cd, _("Error during resuming device %s."), name);
|
||||
out:
|
||||
crypt_safe_free(passphrase_read);
|
||||
@@ -3178,6 +3243,65 @@ int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
|
||||
keyfile, keyfile_size, keyfile_offset);
|
||||
}
|
||||
|
||||
int crypt_resume_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size)
|
||||
{
|
||||
struct volume_key *vk = NULL;
|
||||
int r;
|
||||
|
||||
if (!name || !volume_key)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(cd, "Resuming volume %s by volume key.", name);
|
||||
|
||||
if ((r = onlyLUKS(cd)))
|
||||
return r;
|
||||
|
||||
r = dm_status_suspended(cd, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!r) {
|
||||
log_err(cd, _("Volume %s is not suspended."), name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vk = crypt_alloc_volume_key(volume_key_size, volume_key);
|
||||
if (!vk)
|
||||
return -ENOMEM;
|
||||
|
||||
if (isLUKS1(cd->type))
|
||||
r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
|
||||
else if (isLUKS2(cd->type))
|
||||
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||
else
|
||||
r = -EINVAL;
|
||||
if (r == -EPERM || r == -ENOENT)
|
||||
log_err(cd, _("Volume key does not match the volume."));
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = 0;
|
||||
|
||||
if (crypt_use_keyring_for_vk(cd)) {
|
||||
r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr, vk, CRYPT_DEFAULT_SEGMENT);
|
||||
if (!r)
|
||||
r = crypt_volume_key_load_in_keyring(cd, vk);
|
||||
}
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = dm_resume_and_reinstate_key(cd, name, vk);
|
||||
if (r < 0)
|
||||
log_err(cd, _("Error during resuming device %s."), name);
|
||||
out:
|
||||
if (r < 0)
|
||||
crypt_drop_keyring_key(cd, vk);
|
||||
crypt_free_volume_key(vk);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keyslot manipulation
|
||||
*/
|
||||
@@ -3621,7 +3745,7 @@ static int _create_device_with_integrity(struct crypt_device *cd,
|
||||
|
||||
device_check = dmd->flags & CRYPT_ACTIVATE_SHARED ? DEV_OK : DEV_EXCL;
|
||||
|
||||
r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi);
|
||||
r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi, 0);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -3643,6 +3767,27 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int kernel_keyring_support(void)
|
||||
{
|
||||
static unsigned _checked = 0;
|
||||
|
||||
if (!_checked) {
|
||||
_kernel_keyring_supported = keyring_check();
|
||||
_checked = 1;
|
||||
}
|
||||
|
||||
return _kernel_keyring_supported;
|
||||
}
|
||||
|
||||
static int dmcrypt_keyring_bug(void)
|
||||
{
|
||||
uint64_t kversion;
|
||||
|
||||
if (kernel_version(&kversion))
|
||||
return 1;
|
||||
return kversion < version(4,15,0,0);
|
||||
}
|
||||
|
||||
int create_or_reload_device(struct crypt_device *cd, const char *name,
|
||||
const char *type, struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
@@ -3717,7 +3862,7 @@ static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct
|
||||
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
|
||||
if (r < 0)
|
||||
return r;
|
||||
vk = vk->next;
|
||||
vk = crypt_volume_key_next(vk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -3830,7 +3975,7 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd,
|
||||
if (crypt_use_keyring_for_vk(cd))
|
||||
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot activate device."));
|
||||
@@ -3974,8 +4119,12 @@ static int _activate_by_passphrase(struct crypt_device *cd,
|
||||
} else if (isLUKS2(cd->type)) {
|
||||
r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags);
|
||||
keyslot = r;
|
||||
} else if (isBITLK(cd->type)) {
|
||||
r = BITLK_activate(cd, name, passphrase, passphrase_size,
|
||||
&cd->u.bitlk.params, flags);
|
||||
keyslot = 0;
|
||||
} else {
|
||||
log_err(cd, _("Device type is not properly initialised."));
|
||||
log_err(cd, _("Device type is not properly initialized."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
@@ -4114,7 +4263,6 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
|
||||
return crypt_activate_by_keyfile_device_offset(cd, name, keyslot, keyfile,
|
||||
keyfile_size, keyfile_offset, flags);
|
||||
}
|
||||
|
||||
int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
@@ -4209,25 +4357,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
if (!r && name)
|
||||
r = LUKS2_activate(cd, name, vk, flags);
|
||||
} else if (isVERITY(cd->type)) {
|
||||
/* volume_key == root hash */
|
||||
if (!volume_key || !volume_key_size) {
|
||||
log_err(cd, _("Incorrect root hash specified for verity device."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = VERITY_activate(cd, name, volume_key, volume_key_size, cd->u.verity.fec_device,
|
||||
&cd->u.verity.hdr, flags|CRYPT_ACTIVATE_READONLY);
|
||||
|
||||
if (r == -EPERM) {
|
||||
free(cd->u.verity.root_hash);
|
||||
cd->u.verity.root_hash = NULL;
|
||||
} if (!r) {
|
||||
cd->u.verity.root_hash_size = volume_key_size;
|
||||
if (!cd->u.verity.root_hash)
|
||||
cd->u.verity.root_hash = malloc(volume_key_size);
|
||||
if (cd->u.verity.root_hash)
|
||||
memcpy(cd->u.verity.root_hash, volume_key, volume_key_size);
|
||||
}
|
||||
r = crypt_activate_by_signed_key(cd, name, volume_key, volume_key_size, NULL, 0, flags);
|
||||
} else if (isTCRYPT(cd->type)) {
|
||||
if (!name)
|
||||
return 0;
|
||||
@@ -4243,9 +4373,10 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
}
|
||||
r = INTEGRITY_activate(cd, name, &cd->u.integrity.params, vk,
|
||||
cd->u.integrity.journal_crypt_key,
|
||||
cd->u.integrity.journal_mac_key, flags);
|
||||
cd->u.integrity.journal_mac_key, flags,
|
||||
cd->u.integrity.sb_flags);
|
||||
} else {
|
||||
log_err(cd, _("Device type is not properly initialised."));
|
||||
log_err(cd, _("Device type is not properly initialized."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
@@ -4256,6 +4387,77 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_activate_by_signed_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
uint32_t flags)
|
||||
{
|
||||
char description[512];
|
||||
int r;
|
||||
|
||||
if (!cd || !isVERITY(cd->type))
|
||||
return -EINVAL;
|
||||
|
||||
if (!volume_key || !volume_key_size || (!name && signature)) {
|
||||
log_err(cd, _("Incorrect root hash specified for verity device."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg(cd, "%s volume %s by signed key.", name ? "Activating" : "Checking", name ?: "");
|
||||
|
||||
if (cd->u.verity.hdr.flags & CRYPT_VERITY_ROOT_HASH_SIGNATURE && !signature) {
|
||||
log_err(cd, _("Root hash signature required."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = _activate_check_status(cd, name, flags & CRYPT_ACTIVATE_REFRESH);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (signature && !kernel_keyring_support()) {
|
||||
log_err(cd, _("Kernel keyring missing: required for passing signature to kernel."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* volume_key == root hash */
|
||||
free(CONST_CAST(void*)cd->u.verity.root_hash);
|
||||
cd->u.verity.root_hash = NULL;
|
||||
|
||||
if (signature) {
|
||||
r = snprintf(description, sizeof(description)-1, "cryptsetup:%s%s%s",
|
||||
crypt_get_uuid(cd) ?: "", crypt_get_uuid(cd) ? "-" : "", name);
|
||||
if (r < 0)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(cd, "Adding signature into keyring %s", description);
|
||||
r = keyring_add_key_in_thread_keyring(USER_KEY, description, signature, signature_size);
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to load key in kernel keyring."));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = VERITY_activate(cd, name, volume_key, volume_key_size,
|
||||
signature ? description : NULL,
|
||||
cd->u.verity.fec_device,
|
||||
&cd->u.verity.hdr, flags | CRYPT_ACTIVATE_READONLY);
|
||||
|
||||
if (!r) {
|
||||
cd->u.verity.root_hash_size = volume_key_size;
|
||||
cd->u.verity.root_hash = malloc(volume_key_size);
|
||||
if (cd->u.verity.root_hash)
|
||||
memcpy(CONST_CAST(void*)cd->u.verity.root_hash, volume_key, volume_key_size);
|
||||
}
|
||||
|
||||
if (signature)
|
||||
crypt_drop_keyring_key_by_description(cd, description, USER_KEY);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t flags)
|
||||
{
|
||||
struct crypt_device *fake_cd = NULL;
|
||||
@@ -4295,7 +4497,7 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
|
||||
if (isLUKS2(cd->type))
|
||||
hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||
|
||||
if (!strncmp(CRYPT_LUKS2, dmd.uuid ?: "", sizeof(CRYPT_LUKS2)-1) || hdr2)
|
||||
if ((dmd.uuid && !strncmp(CRYPT_LUKS2, dmd.uuid, sizeof(CRYPT_LUKS2)-1)) || hdr2)
|
||||
r = LUKS2_deactivate(cd, name, hdr2, &dmd, flags);
|
||||
else if (isTCRYPT(cd->type))
|
||||
r = TCRYPT_deactivate(cd, name, flags);
|
||||
@@ -4415,7 +4617,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
struct volume_key *vk = NULL;
|
||||
int key_len, r = -EINVAL;
|
||||
|
||||
if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !passphrase))
|
||||
if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !isVERITY(cd->type) && !passphrase))
|
||||
return -EINVAL;
|
||||
|
||||
if (isLUKS2(cd->type) && keyslot != CRYPT_ANY_SLOT)
|
||||
@@ -4445,10 +4647,18 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
passphrase, passphrase_size, &vk);
|
||||
} else if (isTCRYPT(cd->type)) {
|
||||
r = TCRYPT_get_volume_key(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params, &vk);
|
||||
} else if (isVERITY(cd->type)) {
|
||||
/* volume_key == root hash */
|
||||
if (cd->u.verity.root_hash) {
|
||||
memcpy(volume_key, cd->u.verity.root_hash, cd->u.verity.root_hash_size);
|
||||
*volume_key_size = cd->u.verity.root_hash_size;
|
||||
r = 0;
|
||||
} else
|
||||
log_err(cd, _("Cannot retrieve root hash for verity device."));
|
||||
} else
|
||||
log_err(cd, _("This operation is not supported for %s crypt device."), cd->type ?: "(none)");
|
||||
|
||||
if (r >= 0) {
|
||||
if (r >= 0 && vk) {
|
||||
memcpy(volume_key, vk->key, vk->keylength);
|
||||
*volume_key_size = vk->keylength;
|
||||
}
|
||||
@@ -4475,6 +4685,9 @@ int crypt_volume_key_verify(struct crypt_device *cd,
|
||||
r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
|
||||
else if (isLUKS2(cd->type))
|
||||
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||
else
|
||||
r = -EINVAL;
|
||||
|
||||
|
||||
if (r == -EPERM)
|
||||
log_err(cd, _("Volume key does not match the volume."));
|
||||
@@ -4513,6 +4726,20 @@ int crypt_memory_lock(struct crypt_device *cd, int lock)
|
||||
return lock ? crypt_memlock_inc(cd) : crypt_memlock_dec(cd);
|
||||
}
|
||||
|
||||
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags)
|
||||
{
|
||||
if (cd)
|
||||
cd->compatibility = flags;
|
||||
}
|
||||
|
||||
uint32_t crypt_get_compatibility(struct crypt_device *cd)
|
||||
{
|
||||
if (cd)
|
||||
return cd->compatibility;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reporting
|
||||
*/
|
||||
@@ -4632,6 +4859,8 @@ int crypt_dump(struct crypt_device *cd)
|
||||
return TCRYPT_dump(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
|
||||
else if (isINTEGRITY(cd->type))
|
||||
return INTEGRITY_dump(cd, crypt_data_device(cd), 0);
|
||||
else if (isBITLK(cd->type))
|
||||
return BITLK_dump(cd, crypt_data_device(cd), &cd->u.bitlk.params);
|
||||
|
||||
log_err(cd, _("Dump operation is not supported for this device type."));
|
||||
return -EINVAL;
|
||||
@@ -4650,6 +4879,8 @@ const char *crypt_get_cipher_spec(struct crypt_device *cd)
|
||||
return cd->u.plain.cipher_spec;
|
||||
else if (isLOOPAES(cd->type))
|
||||
return cd->u.loopaes.cipher_spec;
|
||||
else if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.cipher_spec;
|
||||
else if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.cipher_spec;
|
||||
|
||||
@@ -4680,6 +4911,9 @@ const char *crypt_get_cipher(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return cd->u.tcrypt.params.cipher;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.cipher;
|
||||
|
||||
if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.cipher;
|
||||
|
||||
@@ -4710,6 +4944,9 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return cd->u.tcrypt.params.mode;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.cipher_mode;
|
||||
|
||||
if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.cipher_mode;
|
||||
|
||||
@@ -4784,6 +5021,9 @@ const char *crypt_get_uuid(struct crypt_device *cd)
|
||||
if (isVERITY(cd->type))
|
||||
return cd->u.verity.uuid;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.guid;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -4844,6 +5084,9 @@ int crypt_get_volume_key_size(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return cd->u.tcrypt.params.key_size;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.key_size / 8;
|
||||
|
||||
if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.key_size;
|
||||
|
||||
@@ -5025,6 +5268,9 @@ uint64_t crypt_get_data_offset(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.volume_header_size / SECTOR_SIZE;
|
||||
|
||||
return cd->data_offset;
|
||||
}
|
||||
|
||||
@@ -5144,7 +5390,7 @@ int crypt_get_verity_info(struct crypt_device *cd,
|
||||
vp->data_size = cd->u.verity.hdr.data_size;
|
||||
vp->hash_area_offset = cd->u.verity.hdr.hash_area_offset;
|
||||
vp->hash_type = cd->u.verity.hdr.hash_type;
|
||||
vp->flags = cd->u.verity.hdr.flags & CRYPT_VERITY_NO_HEADER;
|
||||
vp->flags = cd->u.verity.hdr.flags & (CRYPT_VERITY_NO_HEADER | CRYPT_VERITY_ROOT_HASH_SIGNATURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5596,7 +5842,7 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
|
||||
|
||||
r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, ¶ms);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Failed to initialise default LUKS2 keyslot parameters."));
|
||||
log_err(cd, _("Failed to initialize default LUKS2 keyslot parameters."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5624,32 +5870,11 @@ out:
|
||||
* Keyring handling
|
||||
*/
|
||||
|
||||
static int kernel_keyring_support(void)
|
||||
{
|
||||
static unsigned _checked = 0;
|
||||
|
||||
if (!_checked) {
|
||||
_kernel_keyring_supported = keyring_check();
|
||||
_checked = 1;
|
||||
}
|
||||
|
||||
return _kernel_keyring_supported;
|
||||
}
|
||||
|
||||
static int dmcrypt_keyring_bug(void)
|
||||
{
|
||||
uint64_t kversion;
|
||||
|
||||
if (kernel_version(&kversion))
|
||||
return 1;
|
||||
return kversion < version(4,15,0,0);
|
||||
}
|
||||
|
||||
int crypt_use_keyring_for_vk(struct crypt_device *cd)
|
||||
{
|
||||
uint32_t dmc_flags;
|
||||
|
||||
/* dm backend must be initialised */
|
||||
/* dm backend must be initialized */
|
||||
if (!cd || !isLUKS2(cd->type))
|
||||
return 0;
|
||||
|
||||
@@ -5770,7 +5995,7 @@ int crypt_activate_by_keyring(struct crypt_device *cd,
|
||||
|
||||
r = _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
|
||||
|
||||
crypt_memzero(passphrase, passphrase_size);
|
||||
crypt_safe_memzero(passphrase, passphrase_size);
|
||||
free(passphrase);
|
||||
|
||||
return r;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -301,8 +300,8 @@ static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
|
||||
}
|
||||
|
||||
crypt_cipher_destroy(cipher);
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -369,8 +368,8 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
|
||||
crypt_cipher_destroy(cipher);
|
||||
}
|
||||
|
||||
crypt_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
crypt_safe_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_safe_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -420,8 +419,8 @@ out:
|
||||
if (cipher[j])
|
||||
crypt_cipher_destroy(cipher[j]);
|
||||
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -474,13 +473,13 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
crypt_safe_memzero(&hdr2, sizeof(hdr2));
|
||||
return r;
|
||||
}
|
||||
|
||||
static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
unsigned char pool[TCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile)
|
||||
unsigned char pool[VCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile, int keyfiles_pool_length)
|
||||
{
|
||||
unsigned char *data;
|
||||
int i, j, fd, data_size, r = -EIO;
|
||||
@@ -512,12 +511,12 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
pool[j++] += (unsigned char)(crc >> 16);
|
||||
pool[j++] += (unsigned char)(crc >> 8);
|
||||
pool[j++] += (unsigned char)(crc);
|
||||
j %= TCRYPT_KEY_POOL_LEN;
|
||||
j %= keyfiles_pool_length;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
crypt_memzero(&crc, sizeof(crc));
|
||||
crypt_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
crypt_safe_memzero(&crc, sizeof(crc));
|
||||
crypt_safe_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
free(data);
|
||||
|
||||
return r;
|
||||
@@ -527,29 +526,41 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params)
|
||||
{
|
||||
unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size;
|
||||
unsigned char pwd[VCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size, max_passphrase_size;
|
||||
char *key;
|
||||
unsigned int i, skipped = 0, iterations;
|
||||
int r = -EPERM;
|
||||
int r = -EPERM, keyfiles_pool_length;
|
||||
|
||||
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
|
||||
return -ENOMEM;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_VERA_MODES) {
|
||||
max_passphrase_size = VCRYPT_KEY_POOL_LEN;
|
||||
/* Really. Keyfile pool length depends on passphrase size in Veracrypt. */
|
||||
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN)
|
||||
keyfiles_pool_length = VCRYPT_KEY_POOL_LEN;
|
||||
else
|
||||
keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
|
||||
} else {
|
||||
max_passphrase_size = TCRYPT_KEY_POOL_LEN;
|
||||
keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
|
||||
}
|
||||
|
||||
if (params->keyfiles_count)
|
||||
passphrase_size = TCRYPT_KEY_POOL_LEN;
|
||||
passphrase_size = max_passphrase_size;
|
||||
else
|
||||
passphrase_size = params->passphrase_size;
|
||||
|
||||
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded."),
|
||||
TCRYPT_KEY_POOL_LEN);
|
||||
if (params->passphrase_size > max_passphrase_size) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%zu) exceeded."),
|
||||
max_passphrase_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Calculate pool content from keyfiles */
|
||||
for (i = 0; i < params->keyfiles_count; i++) {
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i], keyfiles_pool_length);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
@@ -619,9 +630,9 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
params->cipher, params->mode, params->key_size);
|
||||
}
|
||||
out:
|
||||
crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
crypt_safe_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
if (key)
|
||||
crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
crypt_safe_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
free(key);
|
||||
return r;
|
||||
}
|
||||
@@ -747,7 +758,7 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (strstr(params->mode, "-tcrypt")) {
|
||||
log_err(cd, _("Kernel doesn't support activation for this TCRYPT legacy mode."));
|
||||
log_err(cd, _("Kernel does not support activation for this TCRYPT legacy mode."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -859,7 +870,7 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
|
||||
if (r < 0 &&
|
||||
(dm_flags(cd, DM_CRYPT, &dmc_flags) || ((dmc_flags & req_flags) != req_flags))) {
|
||||
log_err(cd, _("Kernel doesn't support TCRYPT compatible mapping."));
|
||||
log_err(cd, _("Kernel does not support TCRYPT compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#define TCRYPT_LRW_IKEY_LEN 16
|
||||
#define TCRYPT_KEY_POOL_LEN 64
|
||||
#define VCRYPT_KEY_POOL_LEN 128
|
||||
#define TCRYPT_KEYFILE_LEN 1048576
|
||||
|
||||
#define TCRYPT_HDR_FLAG_SYSTEM (1 << 0)
|
||||
|
||||
11
lib/utils.c
11
lib/utils.c
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -130,7 +129,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
/* read error */
|
||||
return -1;
|
||||
}
|
||||
@@ -142,7 +141,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
bytes -= bytes_r;
|
||||
}
|
||||
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
return bytes == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -181,7 +180,7 @@ int crypt_keyfile_device_read(struct crypt_device *cd, const char *keyfile,
|
||||
key_size = DEFAULT_KEYFILE_SIZE_MAXKB * 1024 + 1;
|
||||
unlimited_read = 1;
|
||||
/* use 4k for buffer (page divisor but avoid huge pages) */
|
||||
buflen = 4096 - sizeof(struct safe_allocation);
|
||||
buflen = 4096 - sizeof(size_t); // sizeof(struct safe_allocation);
|
||||
} else
|
||||
buflen = key_size;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library, cipher benchmark
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -72,7 +72,7 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
if (r == -ERANGE)
|
||||
log_dbg(cd, "Measured cipher runtime is too low.");
|
||||
else if (r == -ENOTSUP || r == -ENOENT)
|
||||
log_dbg(cd, "Cannot initialise cipher %s, mode %s.", cipher, cipher_mode);
|
||||
log_dbg(cd, "Cannot initialize cipher %s, mode %s.", cipher, cipher_mode);
|
||||
|
||||
out:
|
||||
free(buffer);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkid probe utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -310,9 +310,9 @@ int blk_supported(void)
|
||||
|
||||
off_t blk_get_offset(struct blkid_handle *h)
|
||||
{
|
||||
const char *offset;
|
||||
off_t offset_value = -1;
|
||||
#ifdef HAVE_BLKID
|
||||
const char *offset;
|
||||
if (blk_is_superblock(h)) {
|
||||
if (!blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
|
||||
offset_value = strtoll(offset, NULL, 10);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkid probe utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -149,79 +149,6 @@ int crypt_parse_pbkdf(const char *s, const char **pbkdf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replacement for memset(s, 0, n) on stack that can be optimized out
|
||||
* Also used in safe allocations for explicit memory wipe.
|
||||
*/
|
||||
void crypt_memzero(void *s, size_t n)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
|
||||
while(n--)
|
||||
*p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
crypt_memzero(&alloc->data, size);
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
void crypt_safe_free(void *data)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
crypt_memzero(data, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
void *crypt_safe_realloc(void *data, size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
void *new_data;
|
||||
|
||||
new_data = crypt_safe_alloc(size);
|
||||
|
||||
if (new_data && data) {
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
if (size > alloc->size)
|
||||
size = alloc->size;
|
||||
|
||||
memcpy(new_data, data, size);
|
||||
}
|
||||
|
||||
crypt_safe_free(data);
|
||||
return new_data;
|
||||
}
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
{
|
||||
char buf[3] = "xx\0", *endp, *bytes;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -29,14 +29,6 @@
|
||||
#define MAX_CIPHER_LEN_STR "31"
|
||||
#define MAX_KEYFILES 32
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
/* Not to be used directly */
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
int crypt_parse_name_and_mode(const char *s, char *cipher,
|
||||
int *key_nums, char *cipher_mode);
|
||||
int crypt_parse_hash_integrity_mode(const char *s, char *integrity);
|
||||
@@ -44,12 +36,6 @@ int crypt_parse_integrity_mode(const char *s, char *integrity,
|
||||
int *integrity_key_size);
|
||||
int crypt_parse_pbkdf(const char *s, const char **pbkdf);
|
||||
|
||||
void *crypt_safe_alloc(size_t size);
|
||||
void crypt_safe_free(void *data);
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
void crypt_memzero(void *s, size_t n);
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
|
||||
|
||||
#endif /* _UTILS_CRYPT_H */
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -145,7 +144,7 @@ static int device_read_test(int devfd)
|
||||
if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize)
|
||||
r = 0;
|
||||
|
||||
crypt_memzero(buffer, sizeof(buffer));
|
||||
crypt_safe_memzero(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -185,7 +184,7 @@ static int device_ready(struct crypt_device *cd, struct device *device)
|
||||
}
|
||||
|
||||
if (devfd < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied."),
|
||||
log_err(cd, _("Device %s does not exist or access denied."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Metadata on-disk locking for processes serialization
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Metadata on-disk locking for processes serialization
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 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,7 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -64,8 +64,12 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
|
||||
#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
|
||||
#define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */
|
||||
#define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */
|
||||
#define DM_INTEGRITY_FIX_PADDING_SUPPORTED (1 << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */
|
||||
#define DM_BITLK_EBOIV_SUPPORTED (1 << 20) /* EBOIV for BITLK supported */
|
||||
#define DM_BITLK_ELEPHANT_SUPPORTED (1 << 21) /* Elephant diffuser for BITLK supported */
|
||||
#define DM_VERITY_SIGNATURE_SUPPORTED (1 << 22) /* Verity option root_hash_sig_key_desc supported */
|
||||
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
|
||||
enum tdirection { TARGET_SET = 1, TARGET_QUERY };
|
||||
|
||||
int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags);
|
||||
@@ -110,6 +114,7 @@ struct dm_target {
|
||||
|
||||
const char *root_hash;
|
||||
uint32_t root_hash_size;
|
||||
const char *root_hash_sig_key_desc;
|
||||
|
||||
uint64_t hash_offset; /* hash offset in blocks (not header) */
|
||||
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
|
||||
@@ -138,10 +143,14 @@ struct dm_target {
|
||||
struct volume_key *journal_crypt_key;
|
||||
|
||||
struct device *meta_device;
|
||||
|
||||
bool fix_padding;
|
||||
} integrity;
|
||||
struct {
|
||||
uint64_t offset;
|
||||
} linear;
|
||||
struct {
|
||||
} zero;
|
||||
} u;
|
||||
|
||||
char *params;
|
||||
@@ -175,9 +184,10 @@ int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg
|
||||
uint32_t tag_size, uint32_t sector_size);
|
||||
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||
uint64_t hash_blocks, struct crypt_params_verity *vp);
|
||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
const char *root_hash, uint32_t root_hash_size, const char *root_hash_sig_key_desc,
|
||||
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp);
|
||||
int dm_integrity_target_set(struct crypt_device *cd,
|
||||
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *meta_device,
|
||||
struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
|
||||
struct volume_key *vk,
|
||||
@@ -185,6 +195,7 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
|
||||
const struct crypt_params_integrity *ip);
|
||||
int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, uint64_t data_offset);
|
||||
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size);
|
||||
|
||||
int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags);
|
||||
int dm_status_device(struct crypt_device *cd, const char *name);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kernel keyring utilities
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -25,15 +25,14 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "utils_keyring.h"
|
||||
|
||||
#ifndef HAVE_KEY_SERIAL_T
|
||||
#define HAVE_KEY_SERIAL_T
|
||||
#include <stdint.h>
|
||||
typedef int32_t key_serial_t;
|
||||
#endif
|
||||
|
||||
#include "utils_crypt.h"
|
||||
#include "utils_keyring.h"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
@@ -178,7 +177,7 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
if (ret < 0) {
|
||||
err = errno;
|
||||
if (buf)
|
||||
crypt_memzero(buf, len);
|
||||
crypt_safe_memzero(buf, len);
|
||||
free(buf);
|
||||
return -err;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kernel keyring syscall wrappers
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* utils_pbkdf - PBKDF settings for libcryptsetup
|
||||
*
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
102
lib/utils_safe_memory.c
Normal file
102
lib/utils_safe_memory.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* utils_safe_memory - safe memory helpers
|
||||
*
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Replacement for memset(s, 0, n) on stack that can be optimized out
|
||||
* Also used in safe allocations for explicit memory wipe.
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(data, size);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)data;
|
||||
|
||||
while(size--)
|
||||
*p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
crypt_safe_memzero(&alloc->data, size);
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
void crypt_safe_free(void *data)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
crypt_safe_memzero(data, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
void *crypt_safe_realloc(void *data, size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
void *new_data;
|
||||
|
||||
new_data = crypt_safe_alloc(size);
|
||||
|
||||
if (new_data && data) {
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
if (size > alloc->size)
|
||||
size = alloc->size;
|
||||
|
||||
memcpy(new_data, data, size);
|
||||
}
|
||||
|
||||
crypt_safe_free(data);
|
||||
return new_data;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generic wrapper for storage functions
|
||||
* (experimental only)
|
||||
*
|
||||
* Copyright (C) 2018, Ondrej Kozina
|
||||
* Copyright (C) 2018-2020, Ondrej Kozina
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -108,7 +107,7 @@ static int crypt_storage_dmcrypt_init(
|
||||
r = device_block_adjust(cd, device, DEV_OK,
|
||||
device_offset, &dmd.size, &dmd.flags);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied."),
|
||||
log_err(cd, _("Device %s does not exist or access denied."),
|
||||
device_path(device));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generic wrapper for storage functions
|
||||
* (experimental only)
|
||||
*
|
||||
* Copyright (C) 2018, Ondrej Kozina
|
||||
* Copyright (C) 2018-2020, Ondrej Kozina
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_wipe - wipe a device
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
@@ -56,7 +55,7 @@ static int crypt_wipe_special(struct crypt_device *cd, int fd, size_t bsize,
|
||||
size_t alignment, char *buffer,
|
||||
uint64_t offset, size_t size)
|
||||
{
|
||||
int r;
|
||||
int r = 0;
|
||||
unsigned int i;
|
||||
ssize_t written;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2004 Phil Karn, KA9Q
|
||||
* libcryptsetup modifications
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2002, Phil Karn, KA9Q
|
||||
* libcryptsetup modifications
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2002, Phil Karn, KA9Q
|
||||
* libcryptsetup modifications
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 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
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
@@ -66,7 +65,7 @@ int VERITY_read_sb(struct crypt_device *cd,
|
||||
sizeof(struct verity_sb), device_path(device), sb_offset);
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device %s doesn't use on-disk header."),
|
||||
log_err(cd, _("Verity device %s does not use on-disk header."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -169,7 +168,7 @@ int VERITY_write_sb(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device %s doesn't use on-disk header."),
|
||||
log_err(cd, _("Verity device %s does not use on-disk header."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -235,6 +234,7 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
const char *signature_description,
|
||||
struct device *fec_device,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags)
|
||||
@@ -252,6 +252,11 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
name ?: "[none]", verity_hdr->hash_name);
|
||||
|
||||
if (verity_hdr->flags & CRYPT_VERITY_CHECK_HASH) {
|
||||
if (signature_description) {
|
||||
log_err(cd, _("Root hash signature verification is not supported."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg(cd, "Verification of data in userspace required.");
|
||||
r = VERITY_verify(cd, verity_hdr, root_hash, root_hash_size);
|
||||
|
||||
@@ -291,7 +296,8 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
|
||||
r = dm_verity_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
|
||||
crypt_metadata_device(cd), fec_device, root_hash,
|
||||
root_hash_size, VERITY_hash_offset_block(verity_hdr),
|
||||
root_hash_size, signature_description,
|
||||
VERITY_hash_offset_block(verity_hdr),
|
||||
VERITY_hash_blocks(cd, verity_hdr), verity_hdr);
|
||||
|
||||
if (r)
|
||||
@@ -299,7 +305,11 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
|
||||
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd);
|
||||
if (r < 0 && (dm_flags(cd, DM_VERITY, &dmv_flags) || !(dmv_flags & DM_VERITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-verity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-verity mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r < 0 && signature_description && !(dmv_flags & DM_VERITY_SIGNATURE_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel does not support dm-verity signature option."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r < 0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 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
|
||||
@@ -46,6 +46,7 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
const char *signature_description,
|
||||
struct device *fec_device,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags);
|
||||
@@ -57,7 +58,7 @@ int VERITY_verify(struct crypt_device *cd,
|
||||
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
char *root_hash,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
int VERITY_FEC_process(struct crypt_device *cd,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* dm-verity Forward Error Correction (FEC) support
|
||||
*
|
||||
* Copyright (C) 2015 Google, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 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
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "verity.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 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
|
||||
@@ -102,7 +102,7 @@ static int hash_levels(size_t hash_block_size, size_t digest_size,
|
||||
off_t *hash_level_block, off_t *hash_level_size)
|
||||
{
|
||||
size_t hash_per_block_bits;
|
||||
off_t s;
|
||||
off_t s, s_shift;
|
||||
int i;
|
||||
|
||||
if (!digest_size)
|
||||
@@ -124,7 +124,10 @@ static int hash_levels(size_t hash_block_size, size_t digest_size,
|
||||
if (hash_level_block)
|
||||
hash_level_block[i] = *hash_position;
|
||||
// verity position of block data_file_blocks at level i
|
||||
s = (data_file_blocks + ((off_t)1 << ((i + 1) * hash_per_block_bits)) - 1) >> ((i + 1) * hash_per_block_bits);
|
||||
s_shift = (i + 1) * hash_per_block_bits;
|
||||
if (s_shift > 63)
|
||||
return -EINVAL;
|
||||
s = (data_file_blocks + ((off_t)1 << s_shift) - 1) >> ((i + 1) * hash_per_block_bits);
|
||||
if (hash_level_size)
|
||||
hash_level_size[i] = s;
|
||||
if ((*hash_position + s) < *hash_position ||
|
||||
@@ -418,7 +421,7 @@ int VERITY_verify(struct crypt_device *cd,
|
||||
/* Create verity hash */
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
char *root_hash,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
unsigned pgsize = (unsigned)crypt_getpagesize();
|
||||
@@ -439,7 +442,7 @@ int VERITY_create(struct crypt_device *cd,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
VERITY_hash_offset_block(verity_hdr),
|
||||
root_hash,
|
||||
CONST_CAST(char*)root_hash,
|
||||
root_hash_size,
|
||||
verity_hdr->salt,
|
||||
verity_hdr->salt_size);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* cryptsetup volume key implementation
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -47,7 +47,7 @@ struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key)
|
||||
if (key)
|
||||
memcpy(&vk->key, key, keylength);
|
||||
else
|
||||
crypt_memzero(&vk->key, keylength);
|
||||
crypt_safe_memzero(&vk->key, keylength);
|
||||
}
|
||||
|
||||
return vk;
|
||||
@@ -120,7 +120,7 @@ void crypt_free_volume_key(struct volume_key *vk)
|
||||
struct volume_key *vk_next;
|
||||
|
||||
while (vk) {
|
||||
crypt_memzero(vk->key, vk->keylength);
|
||||
crypt_safe_memzero(vk->key, vk->keylength);
|
||||
vk->keylength = 0;
|
||||
free(CONST_CAST(void*)vk->key_description);
|
||||
vk_next = vk->next;
|
||||
|
||||
@@ -285,9 +285,9 @@ Please attach the output of the failed command with the
|
||||
.SH AUTHORS
|
||||
Cryptsetup-reencrypt was written by Milan Broz <gmazyland@gmail.com>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012-2019 Milan Broz
|
||||
Copyright \(co 2012-2020 Milan Broz
|
||||
.br
|
||||
Copyright \(co 2012-2019 Red Hat, Inc.
|
||||
Copyright \(co 2012-2020 Red Hat, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
@@ -12,7 +12,7 @@ and can hence offer more features than plain dm-crypt. On the other
|
||||
hand, the header is visible and vulnerable to damage.
|
||||
|
||||
In addition, cryptsetup provides limited support for the use of
|
||||
loop-AES volumes and for TrueCrypt compatible volumes.
|
||||
loop-AES volumes, TrueCrypt, VeraCrypt and BitLocker compatible volumes.
|
||||
|
||||
.SH PLAIN DM-CRYPT OR LUKS?
|
||||
.PP
|
||||
@@ -84,6 +84,8 @@ For backward compatibility there are \fBopen\fR command aliases:
|
||||
\fBloopaesOpen\fR: open \-\-type loopaes
|
||||
.br
|
||||
\fBtcryptOpen\fR: open \-\-type tcrypt
|
||||
.br
|
||||
\fBbitlkOpen\fR: open \-\-type bitlk
|
||||
|
||||
\fB<options>\fR are type specific and are described below
|
||||
for individual device types. For \fBcreate\fR, the order of the <name>
|
||||
@@ -743,6 +745,47 @@ TrueCrypt.
|
||||
|
||||
Please note that cryptsetup does not use TrueCrypt code, please report
|
||||
all problems related to this compatibility extension to the cryptsetup project.
|
||||
|
||||
.SH BITLK (Windows BitLocker-compatible) EXTENSION (EXPERIMENTAL)
|
||||
cryptsetup supports mapping of BitLocker and BitLocker to Go encrypted partition
|
||||
using a native Linux kernel API.
|
||||
Header formatting and BITLK header changes are not supported, cryptsetup
|
||||
never changes BITLK header on-device.
|
||||
|
||||
\fBWARNING:\fR This extension is EXPERIMENTAL.
|
||||
|
||||
BITLK extension requires kernel userspace crypto API to be available
|
||||
(for details see TCRYPT section).
|
||||
|
||||
Cryptsetup should recognize all BITLK header variants, except legacy
|
||||
header used in Windows Vista systems and partially decrypted BitLocker devices.
|
||||
Activation of legacy devices encrypted in CBC mode requires at least
|
||||
Linux kernel version 5.3 and for devices using Elephant diffuser kernel 5.6.
|
||||
|
||||
The \fBbitlkDump\fR command should work for all recognized BITLK devices
|
||||
and doesn't require superuser privilege.
|
||||
|
||||
For unlocking with the \fBopen\fR a password or a recovery passphrase must
|
||||
be provided. Other unlocking methods (TPM, SmartCard) are not supported.
|
||||
|
||||
.PP
|
||||
\fIopen\fR \-\-type bitlk <device> <name>
|
||||
.br
|
||||
\fIbitlkOpen\fR <device> <name> (\fBold syntax\fR)
|
||||
.IP
|
||||
Opens the BITLK (a BitLocker-compatible) <device> and sets up
|
||||
a mapping <name>.
|
||||
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-readonly, \-\-test\-passphrase,
|
||||
\-\-allow-discards].
|
||||
|
||||
.PP
|
||||
\fIbitlkDump\fR <device>
|
||||
.IP
|
||||
Dump the header information of a BITLK device.
|
||||
|
||||
Please note that cryptsetup does not use any Windows BitLocker code, please report
|
||||
all problems related to this compatibility extension to the cryptsetup project.
|
||||
.SH MISCELLANEOUS
|
||||
.PP
|
||||
\fIrepair\fR <device>
|
||||
@@ -1128,6 +1171,7 @@ e.g. 12345678-1234-1234-1234-123456789abc.
|
||||
.B "\-\-allow\-discards\fR"
|
||||
Allow the use of discard (TRIM) requests for the device.
|
||||
This option is only relevant for \fIopen\fR action.
|
||||
This is also not supported for LUKS2 devices with data integrity protection.
|
||||
|
||||
\fBWARNING:\fR This command can have a negative security impact
|
||||
because it can make filesystem-level operations visible on
|
||||
@@ -1576,6 +1620,9 @@ for integrity protected devices.
|
||||
If you want to format LUKS2 device with data integrity protection,
|
||||
use \fI\-\-integrity\fR option.
|
||||
|
||||
Since dm-integrity doesn't support discards (TRIM), dm-crypt device on top of it
|
||||
inherits this, so integrity protection mode doesn't support discards either.
|
||||
|
||||
Some integrity modes requires two independent keys (key for encryption
|
||||
and for authentication). Both these keys are stored in one LUKS keyslot.
|
||||
|
||||
@@ -1636,9 +1683,9 @@ Copyright \(co 2004-2006 Clemens Fruhwirth
|
||||
.br
|
||||
Copyright \(co 2012-2014 Arno Wagner
|
||||
.br
|
||||
Copyright \(co 2009-2019 Red Hat, Inc.
|
||||
Copyright \(co 2009-2020 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2009-2019 Milan Broz
|
||||
Copyright \(co 2009-2020 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.
|
||||
|
||||
@@ -165,8 +165,8 @@ The file with the integrity key.
|
||||
.TP
|
||||
.B "\-\-journal\-crypt ALGORITHM"
|
||||
Encryption algorithm for journal data area.
|
||||
You can use a block cipher here such as cbc(aes) or
|
||||
a stream cipher, for example, chacha20 or ctr(aes).
|
||||
You can use a block cipher here such as cbc-aes or
|
||||
a stream cipher, for example, chacha20 or ctr-aes.
|
||||
.TP
|
||||
.B "\-\-journal\-crypt\-key\-size BYTES"
|
||||
The size of the journal encryption key.
|
||||
@@ -223,9 +223,9 @@ Please attach the output of the failed command with the
|
||||
The integritysetup tool is written by Milan Broz <gmazyland@gmail.com>
|
||||
and is part of the cryptsetup project.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2016-2019 Red Hat, Inc.
|
||||
Copyright \(co 2016-2020 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2016-2019 Milan Broz
|
||||
Copyright \(co 2016-2020 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.
|
||||
|
||||
@@ -40,7 +40,7 @@ The <root_hash> is a hexadecimal string.
|
||||
|
||||
\fB<options>\fR can be [\-\-hash-offset, \-\-no-superblock,
|
||||
\-\-ignore-corruption or \-\-restart-on-corruption, \-\-ignore-zero-blocks,
|
||||
\-\-check-at-most-once]
|
||||
\-\-check-at-most-once, \-\-root-hash-signature]
|
||||
|
||||
If option \-\-no-superblock is used, you have to use as the same options
|
||||
as in initial format operation.
|
||||
@@ -165,6 +165,10 @@ This is the offset, in bytes, from the start of the FEC device to the beginning
|
||||
Number of generator roots. This equals to the number of parity bytes in the encoding data.
|
||||
In RS(M, N) encoding, the number of roots is M-N. M is 255 and M-N is between 2 and 24 (including).
|
||||
.TP
|
||||
.B "\-\-root-hash-signature=FILE"
|
||||
Path to roothash signature file used to verify the root hash (in kernel).
|
||||
This feature requires Linux kernel version 5.4 or more recent.
|
||||
.TP
|
||||
.SH RETURN CODES
|
||||
Veritysetup returns 0 on success and a non-zero value on error.
|
||||
|
||||
@@ -215,9 +219,9 @@ The first implementation of veritysetup was written by Chrome OS authors.
|
||||
This version is based on verification code written by Mikulas Patocka <mpatocka@redhat.com>
|
||||
and rewritten for libcryptsetup by Milan Broz <gmazyland@gmail.com>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012-2019 Red Hat, Inc.
|
||||
Copyright \(co 2012-2020 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2012-2019 Milan Broz
|
||||
Copyright \(co 2012-2020 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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Example of LUKS2 kesylot handler (EXAMPLE)
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz <gmazyland@gmail.com>
|
||||
* Copyright (C) 2016-2020 Milan Broz <gmazyland@gmail.com>
|
||||
*
|
||||
* Use:
|
||||
* - generate LUKS device
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Example of LUKS2 token storing third party metadata (EXAMPLE)
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz <gmazyland@gmail.com>
|
||||
* Copyright (C) 2016-2020 Milan Broz <gmazyland@gmail.com>
|
||||
*
|
||||
* Use:
|
||||
* - generate LUKS device
|
||||
|
||||
@@ -22,6 +22,7 @@ lib/luks1/keyencryption.c
|
||||
lib/luks1/keymanage.c
|
||||
lib/loopaes/loopaes.c
|
||||
lib/tcrypt/tcrypt.c
|
||||
lib/bitlk/bitlk.c
|
||||
lib/verity/verity.c
|
||||
lib/verity/verity_hash.c
|
||||
lib/verity/verity_fec.c
|
||||
|
||||
1793
po/cryptsetup.pot
1793
po/cryptsetup.pot
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user