mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 08:20:07 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fd1c62de9 | ||
|
|
9cc749d9fa | ||
|
|
46a4c80269 | ||
|
|
5fec16407b | ||
|
|
cebc1638e3 |
@@ -1,15 +0,0 @@
|
||||
### Issue description
|
||||
<!-- Please, shortly describe the issue here. -->
|
||||
|
||||
### Steps for reproducing the issue
|
||||
<!-- How it can be reproduced? Include all important steps. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what distribution you are using. -->
|
||||
|
||||
### Debug log
|
||||
<!-- Paste a debug log of the failing command (add --debug option) between the markers below (to keep raw debug format).-->
|
||||
```
|
||||
Output with --debug option:
|
||||
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
### Documentation issue
|
||||
<!-- Please, shortly describe the issue in documentation here. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what cryptsetup version you are using. -->
|
||||
@@ -1,5 +0,0 @@
|
||||
### New feature description
|
||||
<!-- Please, shortly describe the requested feature here. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what distribution and cryptsetup version you are using. -->
|
||||
@@ -1,9 +1,7 @@
|
||||
language: c
|
||||
|
||||
sudo: required
|
||||
os: linux
|
||||
dist: focal
|
||||
group: edge
|
||||
dist: xenial
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
@@ -17,7 +15,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- wip-luks2
|
||||
- v2.3.x
|
||||
- v2_0_x
|
||||
|
||||
before_install:
|
||||
- uname -a
|
||||
|
||||
4
README
4
README
@@ -14,7 +14,7 @@ FAQ:
|
||||
MAILING LIST:
|
||||
|
||||
E-MAIL: dm-crypt@saout.de
|
||||
URL: https://www.saout.de/mailman/listinfo/dm-crypt
|
||||
URL: http://www.saout.de/mailman/listinfo/dm-crypt
|
||||
|
||||
DOWNLOAD:
|
||||
|
||||
@@ -28,4 +28,4 @@ SOURCE CODE:
|
||||
NLS (PO TRANSLATIONS):
|
||||
|
||||
PO files are maintained by:
|
||||
https://translationproject.org/domain/cryptsetup.html
|
||||
http://translationproject.org/domain/cryptsetup.html
|
||||
|
||||
25
README.md
25
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**,
|
||||
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
|
||||
and **TrueCrypt** (including **VeraCrypt** extension) 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,19 +44,16 @@ Download
|
||||
--------
|
||||
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
|
||||
**The latest stable cryptsetup version is 2.3.2**
|
||||
* [cryptsetup-2.3.2.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.2.tar.xz)
|
||||
* Signature [cryptsetup-2.3.2.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.2.tar.sign)
|
||||
**The latest cryptsetup version is 2.2.2**
|
||||
* [cryptsetup-2.2.2.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.xz)
|
||||
* Signature [cryptsetup-2.2.2.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.3.2 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.2-ReleaseNotes).
|
||||
* [Cryptsetup 2.2.2 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.2-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 2.3.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.1.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.1.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.1-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.2.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-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).
|
||||
@@ -73,7 +70,7 @@ For libcryptsetup documentation see [libcryptsetup API](https://mbroz.fedorapeop
|
||||
|
||||
The libcryptsetup API/ABI changes are tracked in [compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).
|
||||
|
||||
NLS PO files are maintained by [TranslationProject](https://translationproject.org/domain/cryptsetup.html).
|
||||
NLS PO files are maintained by [TranslationProject](http://translationproject.org/domain/cryptsetup.html).
|
||||
|
||||
Help!
|
||||
-----
|
||||
@@ -82,5 +79,5 @@ For cryptsetup and LUKS related questions, please use the dm-crypt mailing list,
|
||||
|
||||
If you want to subscribe just send an empty mail to [dm-crypt-subscribe@saout.de](mailto:dm-crypt-subscribe@saout.de).
|
||||
|
||||
You can also browse [list archive](https://www.saout.de/pipermail/dm-crypt/) or read it through
|
||||
You can also browse [list archive](http://www.saout.de/pipermail/dm-crypt/) or read it through
|
||||
[web interface](https://marc.info/?l=dm-crypt).
|
||||
|
||||
21
configure.ac
21
configure.ac
@@ -1,9 +1,9 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[2.3.4])
|
||||
AC_INIT([cryptsetup],[2.2.2])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=18:0:6
|
||||
LIBCRYPTSETUP_VERSION_INFO=17:0:5
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
@@ -33,7 +33,6 @@ 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
|
||||
@@ -57,15 +56,8 @@ dnl ==========================================================================
|
||||
AC_C_RESTRICT
|
||||
|
||||
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.])])
|
||||
@@ -146,6 +138,14 @@ AC_DEFUN([NO_FIPS], [
|
||||
fi
|
||||
])
|
||||
|
||||
dnl LUKS2 online reencryption
|
||||
AC_ARG_ENABLE([luks2-reencryption],
|
||||
AS_HELP_STRING([--disable-luks2-reencryption], [disable LUKS2 online reencryption extension]),
|
||||
[], [enable_luks2_reencryption=yes])
|
||||
if test "x$enable_luks2_reencryption" = "xyes"; then
|
||||
AC_DEFINE(USE_LUKS2_REENCRYPTION, 1, [Use LUKS2 online reencryption extension])
|
||||
fi
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl pwquality library (cryptsetup CLI only)
|
||||
AC_ARG_ENABLE([pwquality],
|
||||
@@ -355,7 +355,6 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 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,209 +0,0 @@
|
||||
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
|
||||
@@ -1,45 +0,0 @@
|
||||
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.
|
||||
@@ -1,42 +0,0 @@
|
||||
Cryptsetup 2.3.2 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.x should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Support compilation with json-c library version 0.14.
|
||||
|
||||
* Update FAQ document for some LUKS2 specific information.
|
||||
|
||||
* Add option to dump content of LUKS2 unbound keyslot:
|
||||
cryptsetup luksDump --unbound -S <slot> <device>
|
||||
or optionally with --master-key-file option.
|
||||
|
||||
The slot number --key-slot (-S) option is mandatory here.
|
||||
|
||||
An unbound keyslot store a key is that is not assigned to data
|
||||
area on disk (LUKS2 allows to store arbitrary keys).
|
||||
|
||||
* Rephrase some error messages and remove redundant end-of-lines.
|
||||
|
||||
* Add support for discards (TRIM) for standalone dm-integrity devices.
|
||||
Linux kernel 5.7 adds support for optional discard/TRIM operation
|
||||
over dm-integrity devices.
|
||||
|
||||
It is now supported through --allow-discards integritysetup option.
|
||||
Note you need to add this flag in all activation calls.
|
||||
|
||||
Note that this option cannot be used for LUKS2 authenticated encryption
|
||||
(that uses dm-integrity for storing additional per-sector metadata).
|
||||
|
||||
* Fix cryptsetup-reencrypt to work on devices that do not allow
|
||||
direct-io device access.
|
||||
|
||||
* Fix a crash in the BitLocker-compatible code error path.
|
||||
|
||||
* Fix Veracrypt compatible support for longer (>64 bytes) passphrases.
|
||||
It allows some older images to be correctly opened again.
|
||||
The issue was introduced in version 2.3.1.
|
||||
@@ -1,42 +0,0 @@
|
||||
Cryptsetup 2.3.3 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.x should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix BitLocker compatible device access that uses native 4kB sectors.
|
||||
|
||||
Devices formatted with storage that natively support 4096-bytes
|
||||
sectors can also use this sector size for encryption units.
|
||||
|
||||
* Support large IV count (--iv-large-sectors) cryptsetup option
|
||||
for plain device mapping.
|
||||
|
||||
The large IV count is supported in dm-crypt together with larger
|
||||
sector encryption. It counts the Initialization Vector (IV) in
|
||||
a larger sector size instead of 512-bytes sectors.
|
||||
|
||||
This option does not have any performance or security impact,
|
||||
but it can be used for accessing incompatible existing disk images
|
||||
from other systems.
|
||||
|
||||
Only open action with plain device type and sector size > 512 bytes
|
||||
are supported.
|
||||
|
||||
* Fix a memory leak in BitLocker compatible handling.
|
||||
|
||||
* Allow EBOIV (Initialization Vector algorithm) use.
|
||||
|
||||
The EBOIV initialization vector is intended to be used internally
|
||||
with BitLocker devices (for CBC mode). It can now be used also
|
||||
outside of the BitLocker compatible code.
|
||||
|
||||
* Require both keyslot cipher and key size options.
|
||||
|
||||
If these LUKS2 keyslot parameters were not specified together,
|
||||
cryptsetup silently failed.
|
||||
|
||||
* Update to man pages and FAQ.
|
||||
@@ -1,112 +0,0 @@
|
||||
Cryptsetup 2.3.4 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release with a security fix (32-bit only).
|
||||
|
||||
All users of cryptsetup 2.2.x and later should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.3
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix a possible out-of-bounds memory write while validating LUKS2 data
|
||||
segments metadata (CVE-2020-14382).
|
||||
|
||||
This problem can be triggered only on 32-bit builds (64-bit systems
|
||||
are not affected).
|
||||
|
||||
LUKS2 format validation code contains a bug in segments validation code
|
||||
where the code does not check for possible overflow on memory allocation.
|
||||
|
||||
Due to the bug, the libcryptsetup can be tricked to expect such allocation
|
||||
was successful. Later it may read data from image crafted by an attacker and
|
||||
actually write such data beyond allocated memory.
|
||||
|
||||
The bug was introduced in cryptsetup 2.2.0. All later releases until 2.3.4
|
||||
are affected.
|
||||
|
||||
If you only backport the fix for this CVE, these master branch git commits
|
||||
should be backported:
|
||||
52f5cb8cedf22fb3e14c744814ec8af7614146c7
|
||||
46ee71edcd13e1dad50815ad65c28779aa6f7503
|
||||
752c9a52798f11d3b765b673ebaa3058eb25316e
|
||||
|
||||
Thanks to Tobias Stoeckmann for discovering this issue.
|
||||
|
||||
* Ignore reported optimal IO size if not aligned to minimal page size.
|
||||
|
||||
Some USB enclosures report bogus block device topology (see lsblk -t) that
|
||||
prevents LUKS2 format with 4k sector size (reported values are not correctly
|
||||
aligned). The code now ignores such values and uses the default alignment.
|
||||
|
||||
* Added support for new no_read/write_wrokqueue dm-crypt options (kernel 5.9).
|
||||
|
||||
These performance options, introduced in kernel 5.9, configure dm-crypt
|
||||
to bypass read or write workqueues and run encryption synchronously.
|
||||
|
||||
Use --perf-no_read_workqueue or --perf-no_write_workqueue cryptsetup arguments
|
||||
to use these dm-crypt flags.
|
||||
|
||||
These options are available only for low-level dm-crypt performance tuning,
|
||||
use only if you need a change to default dm-crypt behavior.
|
||||
|
||||
For LUKS2, these flags can be persistently stored in metadata with
|
||||
the --persistent option.
|
||||
|
||||
* Added support panic_on_corruption option for dm-verity devices (kernel 5.9).
|
||||
|
||||
Veritysetup now supports --panic-on-corruption argument that configures
|
||||
the dm-verity device to panics kernel if a corruption is detected.
|
||||
|
||||
This option is intended for specific configurations, do not use it in
|
||||
standard configurations.
|
||||
|
||||
* Support --master-key-file option for online LUKS2 reencryption
|
||||
|
||||
This can be used for reencryption of devices that uses protected key AES cipher
|
||||
on some mainframes crypto accelerators.
|
||||
|
||||
* Always return EEXIST error code if a device already exists.
|
||||
|
||||
Some libcryptsetup functions (activate_by*) now return EEXIST error code,
|
||||
so the caller can distinguish that call fails because some parallel process
|
||||
already activated the device.
|
||||
Previously all fails returned EINVAL (invalid value).
|
||||
|
||||
* Fix a problem in integritysetup if a hash algorithm has dash in the name.
|
||||
|
||||
If users want to use blake2b/blake2s, the kernel algorithm name includes
|
||||
a dash (like "blake2s-256").
|
||||
Theses algorithms can now be used for integritysetup devices.
|
||||
|
||||
* Fix crypto backend to properly handle ECB mode.
|
||||
|
||||
Even though it should never be used, it should still work for testing :)
|
||||
This fixes a bug introduced in cryptsetup version 2.3.2.
|
||||
|
||||
* TrueCrypt/VeraCrypt compatible mode now supports the activation of devices
|
||||
with a larger sector.
|
||||
|
||||
TrueCrypt/VeraCrypt always uses 512-byte sector for encryption, but for devices
|
||||
with a larger native sector, it stores this value in the header.
|
||||
|
||||
This patch allows activation of such devices, basically ignoring
|
||||
the mentioned sector size.
|
||||
|
||||
* LUKS2: Do not create excessively large headers.
|
||||
|
||||
When creating a LUKS2 header with a specified --offset larger than
|
||||
the LUKS2 header size, do not create a larger file than needed.
|
||||
|
||||
* Fix unspecified sector size for BitLocker compatible mode.
|
||||
|
||||
Some BitLocker devices can contain zeroed sector size in the header.
|
||||
In this case, the 512-byte sector should be used.
|
||||
The bug was introduced in version 2.3.3.
|
||||
|
||||
* Fix reading key data size in metadata for BitLocker compatible mode.
|
||||
|
||||
Such devices with an unexpected entry in metadata can now be activated.
|
||||
|
||||
Thanks to all users reporting these problems, BitLocker metadata documentation
|
||||
is not publicly available, and we depend only on these reports.
|
||||
|
||||
* Fix typos in documentation.
|
||||
@@ -22,8 +22,7 @@ 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/bitlk
|
||||
-I $(top_srcdir)/lib/integrity
|
||||
|
||||
libcryptsetup_la_DEPENDENCIES = libutils_io.la libcrypto_backend.la lib/libcryptsetup.sym
|
||||
|
||||
@@ -40,7 +39,6 @@ libcryptsetup_la_LIBADD = \
|
||||
@LIBARGON2_LIBS@ \
|
||||
@JSON_C_LIBS@ \
|
||||
@BLKID_LIBS@ \
|
||||
$(LTLIBICONV) \
|
||||
libcrypto_backend.la \
|
||||
libutils_io.la
|
||||
|
||||
@@ -66,7 +64,6 @@ 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 \
|
||||
@@ -77,7 +74,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 \
|
||||
@@ -93,7 +90,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 \
|
||||
@@ -110,6 +107,4 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/luks2/luks2_internal.h \
|
||||
lib/luks2/luks2.h \
|
||||
lib/utils_blkid.c \
|
||||
lib/utils_blkid.h \
|
||||
lib/bitlk/bitlk.h \
|
||||
lib/bitlk/bitlk.c
|
||||
lib/utils_blkid.h
|
||||
|
||||
1224
lib/bitlk/bitlk.c
1224
lib/bitlk/bitlk.c
File diff suppressed because it is too large
Load Diff
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* 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 {
|
||||
uint16_t sector_size;
|
||||
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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Argon2 PBKDF2 library wrapper
|
||||
*
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Milan Broz
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 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,10 +23,6 @@
|
||||
#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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Milan Broz
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -51,7 +51,6 @@ static const struct cipher_alg cipher_algs[] = {
|
||||
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
|
||||
{ "xchacha12,aes", "adiantum", 32, false },
|
||||
{ "xchacha20,aes", "adiantum", 32, false },
|
||||
{ "sm4", NULL, 16, false },
|
||||
{ NULL, NULL, 0, false }
|
||||
};
|
||||
|
||||
@@ -73,13 +72,7 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
|
||||
{
|
||||
const struct cipher_alg *ca = _get_alg(name, mode);
|
||||
|
||||
if (!ca)
|
||||
return -EINVAL;
|
||||
|
||||
if (mode && !strcasecmp(mode, "ecb"))
|
||||
return 0;
|
||||
|
||||
return ca->blocksize;
|
||||
return ca ? ca->blocksize : -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_cipher_wrapped_key(const char *name, const char *mode)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -26,12 +26,13 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct crypt_hash;
|
||||
struct crypt_hmac;
|
||||
struct crypt_cipher;
|
||||
struct crypt_storage;
|
||||
|
||||
int crypt_backend_init(void);
|
||||
int crypt_backend_init(struct crypt_device *ctx);
|
||||
void crypt_backend_destroy(void);
|
||||
|
||||
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
|
||||
@@ -109,7 +110,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
/* Storage encryption wrappers */
|
||||
int crypt_storage_init(struct crypt_storage **ctx, size_t sector_size,
|
||||
const char *cipher, const char *cipher_mode,
|
||||
const void *key, size_t key_length, bool large_iv);
|
||||
const void *key, size_t key_length);
|
||||
void crypt_storage_destroy(struct crypt_storage *ctx);
|
||||
int crypt_storage_decrypt(struct crypt_storage *ctx, uint64_t iv_offset,
|
||||
uint64_t length, char *buffer);
|
||||
@@ -118,12 +119,6 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 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,9 +55,5 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 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,10 +40,6 @@
|
||||
#define SOL_ALG 279
|
||||
#endif
|
||||
|
||||
#ifndef ALG_SET_AEAD_AUTHSIZE
|
||||
#define ALG_SET_AEAD_AUTHSIZE 5
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ciphers
|
||||
*
|
||||
@@ -53,7 +49,7 @@
|
||||
*/
|
||||
static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
const void *key, size_t key_length,
|
||||
size_t tag_length, struct sockaddr_alg *sa)
|
||||
struct sockaddr_alg *sa)
|
||||
{
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
@@ -75,11 +71,6 @@ 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);
|
||||
@@ -102,13 +93,12 @@ 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, 0, &sa);
|
||||
return _crypt_cipher_init(ctx, key, key_length, &sa);
|
||||
}
|
||||
|
||||
/* The in/out should be aligned to page boundary */
|
||||
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, size_t in_length,
|
||||
char *out, size_t out_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
uint32_t direction)
|
||||
{
|
||||
@@ -119,7 +109,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 = in_length,
|
||||
.iov_len = length,
|
||||
};
|
||||
int iv_msg_size = iv ? CMSG_SPACE(sizeof(*alg_iv) + iv_length) : 0;
|
||||
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
|
||||
@@ -130,7 +120,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
if (!in || !out || !in_length)
|
||||
if (!in || !out || !length)
|
||||
return -EINVAL;
|
||||
|
||||
if ((!iv && iv_length) || (iv && !iv_length))
|
||||
@@ -161,13 +151,13 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
}
|
||||
|
||||
len = sendmsg(ctx->opfd, &msg, 0);
|
||||
if (len != (ssize_t)(in_length)) {
|
||||
if (len != (ssize_t)length) {
|
||||
r = -EIO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
len = read(ctx->opfd, out, out_length);
|
||||
if (len != (ssize_t)out_length)
|
||||
len = read(ctx->opfd, out, length);
|
||||
if (len != (ssize_t)length)
|
||||
r = -EIO;
|
||||
bad:
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
@@ -178,7 +168,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, length, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
iv, iv_length, ALG_OP_ENCRYPT);
|
||||
}
|
||||
|
||||
@@ -186,7 +176,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, length, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
iv, iv_length, ALG_OP_DECRYPT);
|
||||
}
|
||||
|
||||
@@ -253,56 +243,13 @@ 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, 0, &sa);
|
||||
r = _crypt_cipher_init(&c, key, key_length, &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)
|
||||
@@ -333,11 +280,4 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -53,7 +53,7 @@ struct crypt_cipher {
|
||||
|
||||
/*
|
||||
* Test for wrong Whirlpool variant,
|
||||
* Ref: https://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
|
||||
* Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
|
||||
*/
|
||||
static void crypt_hash_test_whirlpool_bug(void)
|
||||
{
|
||||
@@ -89,7 +89,7 @@ static void crypt_hash_test_whirlpool_bug(void)
|
||||
crypto_backend_whirlpool_bug = 1;
|
||||
}
|
||||
|
||||
int crypt_backend_init(void)
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -479,43 +479,3 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -110,7 +110,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_backend_init(void)
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
struct utsname uts;
|
||||
struct sockaddr_alg sa = {
|
||||
@@ -392,12 +392,3 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -213,7 +213,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(void)
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -433,12 +433,3 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -75,7 +75,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(void)
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -381,12 +381,3 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 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,8 +35,6 @@
|
||||
#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 {
|
||||
@@ -121,7 +119,7 @@ static const char *openssl_backend_version(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
int crypt_backend_init(void)
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -507,40 +505,3 @@ 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-2020 Milan Broz
|
||||
* Copyright (C) 2014-2019 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -31,16 +31,16 @@
|
||||
* IV documentation: https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
|
||||
*/
|
||||
struct crypt_sector_iv {
|
||||
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE, IV_EBOIV } type;
|
||||
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE } type;
|
||||
int iv_size;
|
||||
char *iv;
|
||||
struct crypt_cipher *cipher;
|
||||
int shift;
|
||||
struct crypt_cipher *essiv_cipher;
|
||||
int benbi_shift;
|
||||
};
|
||||
|
||||
/* Block encryption storage context */
|
||||
struct crypt_storage {
|
||||
size_t sector_size;
|
||||
unsigned sector_shift;
|
||||
unsigned iv_shift;
|
||||
struct crypt_cipher *cipher;
|
||||
struct crypt_sector_iv cipher_iv;
|
||||
@@ -56,15 +56,12 @@ static int int_log2(unsigned int x)
|
||||
|
||||
static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
const char *cipher_name, const char *mode_name,
|
||||
const char *iv_name, const void *key, size_t key_length,
|
||||
size_t sector_size)
|
||||
const char *iv_name, const void *key, size_t key_length)
|
||||
{
|
||||
int r;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
|
||||
if (ctx->iv_size < 0 || (strcmp(mode_name, "ecb") && ctx->iv_size < 8))
|
||||
if (ctx->iv_size < 8)
|
||||
return -ENOENT;
|
||||
|
||||
if (!strcmp(cipher_name, "cipher_null") ||
|
||||
@@ -89,6 +86,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
char *hash_name = strchr(iv_name, ':');
|
||||
int hash_size;
|
||||
char tmp[256];
|
||||
int r;
|
||||
|
||||
if (!hash_name)
|
||||
return -EINVAL;
|
||||
@@ -116,7 +114,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
|
||||
r = crypt_cipher_init(&ctx->essiv_cipher, cipher_name, "ecb",
|
||||
tmp, hash_size);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
if (r)
|
||||
@@ -129,15 +127,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
return -EINVAL;
|
||||
|
||||
ctx->type = IV_BENBI;
|
||||
ctx->shift = SECTOR_SHIFT - log;
|
||||
} else if (!strncasecmp(iv_name, "eboiv", 5)) {
|
||||
r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
|
||||
key, key_length);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ctx->type = IV_EBOIV;
|
||||
ctx->shift = int_log2(sector_size);
|
||||
ctx->benbi_shift = SECTOR_SHIFT - log;
|
||||
} else
|
||||
return -ENOENT;
|
||||
|
||||
@@ -173,20 +163,14 @@ static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector
|
||||
case IV_ESSIV:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
*(uint64_t *)ctx->iv = cpu_to_le64(sector);
|
||||
return crypt_cipher_encrypt(ctx->cipher,
|
||||
return crypt_cipher_encrypt(ctx->essiv_cipher,
|
||||
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
|
||||
break;
|
||||
case IV_BENBI:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
val = cpu_to_be64((sector << ctx->shift) + 1);
|
||||
val = cpu_to_be64((sector << ctx->benbi_shift) + 1);
|
||||
memcpy(ctx->iv + ctx->iv_size - sizeof(val), &val, sizeof(val));
|
||||
break;
|
||||
case IV_EBOIV:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
*(uint64_t *)ctx->iv = cpu_to_le64(sector << ctx->shift);
|
||||
return crypt_cipher_encrypt(ctx->cipher,
|
||||
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -196,8 +180,8 @@ static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector
|
||||
|
||||
static void crypt_sector_iv_destroy(struct crypt_sector_iv *ctx)
|
||||
{
|
||||
if (ctx->type == IV_ESSIV || ctx->type == IV_EBOIV)
|
||||
crypt_cipher_destroy(ctx->cipher);
|
||||
if (ctx->type == IV_ESSIV)
|
||||
crypt_cipher_destroy(ctx->essiv_cipher);
|
||||
|
||||
if (ctx->iv) {
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
@@ -213,8 +197,7 @@ int crypt_storage_init(struct crypt_storage **ctx,
|
||||
size_t sector_size,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
const void *key, size_t key_length,
|
||||
bool large_iv)
|
||||
const void *key, size_t key_length)
|
||||
{
|
||||
struct crypt_storage *s;
|
||||
char mode_name[64];
|
||||
@@ -246,14 +229,14 @@ int crypt_storage_init(struct crypt_storage **ctx,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size);
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length);
|
||||
if (r) {
|
||||
crypt_storage_destroy(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
s->sector_size = sector_size;
|
||||
s->iv_shift = large_iv ? int_log2(sector_size) - SECTOR_SHIFT : 0;
|
||||
s->sector_shift = int_log2(sector_size);
|
||||
s->iv_shift = s->sector_shift - SECTOR_SHIFT;
|
||||
|
||||
*ctx = s;
|
||||
return 0;
|
||||
@@ -266,20 +249,19 @@ int crypt_storage_decrypt(struct crypt_storage *ctx,
|
||||
uint64_t i;
|
||||
int r = 0;
|
||||
|
||||
if (length & (ctx->sector_size - 1))
|
||||
if (length & ((1 << ctx->sector_shift) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
|
||||
return -EINVAL;
|
||||
length >>= ctx->sector_shift;
|
||||
|
||||
for (i = 0; i < length; i += ctx->sector_size) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
|
||||
for (i = 0; i < length; i++) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, iv_offset + (uint64_t)(i << ctx->iv_shift));
|
||||
if (r)
|
||||
break;
|
||||
r = crypt_cipher_decrypt(ctx->cipher,
|
||||
&buffer[i],
|
||||
&buffer[i],
|
||||
ctx->sector_size,
|
||||
&buffer[i << ctx->sector_shift],
|
||||
&buffer[i << ctx->sector_shift],
|
||||
1 << ctx->sector_shift,
|
||||
ctx->cipher_iv.iv,
|
||||
ctx->cipher_iv.iv_size);
|
||||
if (r)
|
||||
@@ -296,20 +278,19 @@ int crypt_storage_encrypt(struct crypt_storage *ctx,
|
||||
uint64_t i;
|
||||
int r = 0;
|
||||
|
||||
if (length & (ctx->sector_size - 1))
|
||||
if (length & ((1 << ctx->sector_shift) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
|
||||
return -EINVAL;
|
||||
length >>= ctx->sector_shift;
|
||||
|
||||
for (i = 0; i < length; i += ctx->sector_size) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
|
||||
for (i = 0; i < length; i++) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, iv_offset + (i << ctx->iv_shift));
|
||||
if (r)
|
||||
break;
|
||||
r = crypt_cipher_encrypt(ctx->cipher,
|
||||
&buffer[i],
|
||||
&buffer[i],
|
||||
ctx->sector_size,
|
||||
&buffer[i << ctx->sector_shift],
|
||||
&buffer[i << ctx->sector_shift],
|
||||
1 << ctx->sector_shift,
|
||||
ctx->cipher_iv.iv,
|
||||
ctx->cipher_iv.iv_size);
|
||||
if (r)
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2016-2020 Ondrej Mosnacek
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2016-2019 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,10 +27,6 @@
|
||||
#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-2020 Milan Broz
|
||||
* Copyright (C) 2016-2019 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,6 +22,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "integrity.h"
|
||||
@@ -40,7 +41,8 @@ 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_4) {
|
||||
(sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
|
||||
sb->version != SB_VERSION_3)) {
|
||||
log_std(cd, "No integrity superblock detected on %s.\n",
|
||||
device_path(device));
|
||||
r = -EINVAL;
|
||||
@@ -56,9 +58,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags)
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params)
|
||||
{
|
||||
struct superblock sb;
|
||||
int r;
|
||||
@@ -70,9 +70,6 @@ int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
|
||||
params->tag_size = sb.integrity_tag_size;
|
||||
|
||||
if (flags)
|
||||
*flags = sb.flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,11 +92,10 @@ 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%s\n",
|
||||
log_std(cd, "flags %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_FIXED_PADDING ? "fix_padding " : "");
|
||||
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -141,27 +137,6 @@ 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,
|
||||
@@ -212,7 +187,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 sb_flags)
|
||||
uint32_t flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -223,16 +198,12 @@ 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(cd, &dmd->segment, 0, dmd->size,
|
||||
return dm_integrity_target_set(&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,
|
||||
@@ -242,8 +213,7 @@ 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,
|
||||
uint32_t sb_flags)
|
||||
struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
int r;
|
||||
uint32_t dmi_flags;
|
||||
@@ -268,13 +238,7 @@ 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 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."));
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -287,16 +251,15 @@ 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 sb_flags)
|
||||
uint32_t flags)
|
||||
{
|
||||
struct crypt_dm_active_device dmd = {};
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key,
|
||||
journal_mac_key, &dmd, flags, sb_flags);
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key, journal_mac_key, &dmd, flags);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd, sb_flags);
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd);
|
||||
dm_targets_free(cd, &dmd);
|
||||
return r;
|
||||
}
|
||||
@@ -326,7 +289,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(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||
r = dm_integrity_target_set(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);
|
||||
@@ -340,7 +303,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 does not support dm-integrity mapping."));
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Integrity header definition
|
||||
*
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
* Copyright (C) 2016-2019 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,12 +34,10 @@ 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];
|
||||
@@ -55,9 +53,7 @@ struct superblock {
|
||||
uint64_t recalc_sector; /* V2 only */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags);
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params);
|
||||
|
||||
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset);
|
||||
|
||||
@@ -70,7 +66,6 @@ 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,
|
||||
@@ -83,7 +78,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 sb_flags);
|
||||
uint32_t flags);
|
||||
|
||||
int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
@@ -91,11 +86,10 @@ 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 sb_flags);
|
||||
uint32_t flags);
|
||||
|
||||
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t sb_flags);
|
||||
struct crypt_dm_active_device *dmd);
|
||||
#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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,7 +30,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "bitops.h"
|
||||
@@ -78,10 +77,6 @@
|
||||
*_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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,8 +414,6 @@ 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
|
||||
@@ -507,8 +505,6 @@ 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)
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -633,26 +629,6 @@ 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.
|
||||
*
|
||||
@@ -852,20 +828,6 @@ 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);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -1099,16 +1061,6 @@ 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)
|
||||
/** use IV sector counted in sector_size instead of default 512 bytes sectors */
|
||||
#define CRYPT_ACTIVATE_IV_LARGE_SECTORS (1 << 22)
|
||||
/** dm-verity: panic_on_corruption flag - panic kernel on corruption */
|
||||
#define CRYPT_ACTIVATE_PANIC_ON_CORRUPTION (1 << 23)
|
||||
/** dm-crypt: bypass internal workqueue and process read requests synchronously. */
|
||||
#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
|
||||
/** dm-crypt: bypass internal workqueue and process write requests synchronously. */
|
||||
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -1300,31 +1252,6 @@ 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.
|
||||
*
|
||||
@@ -1395,7 +1322,6 @@ 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,
|
||||
@@ -2325,53 +2251,6 @@ 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,9 +12,6 @@ CRYPTSETUP_2.0 {
|
||||
crypt_set_label;
|
||||
crypt_set_data_device;
|
||||
|
||||
crypt_set_compatibility;
|
||||
crypt_get_compatibility;
|
||||
|
||||
crypt_memory_lock;
|
||||
crypt_metadata_locking;
|
||||
crypt_format;
|
||||
@@ -27,7 +24,6 @@ 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;
|
||||
@@ -59,7 +55,6 @@ 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;
|
||||
@@ -123,11 +118,6 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,6 +27,7 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libdevmapper.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -46,7 +47,6 @@
|
||||
#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,15 +168,6 @@ 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;
|
||||
|
||||
if (_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_CRYPT_NO_WORKQUEUE_SUPPORTED;
|
||||
|
||||
_dm_crypt_checked = true;
|
||||
}
|
||||
|
||||
@@ -205,12 +196,6 @@ 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;
|
||||
|
||||
if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
|
||||
_dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
|
||||
|
||||
_dm_verity_checked = true;
|
||||
}
|
||||
|
||||
@@ -233,12 +218,6 @@ 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;
|
||||
|
||||
if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
|
||||
|
||||
_dm_integrity_checked = true;
|
||||
}
|
||||
|
||||
@@ -286,7 +265,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_ZERO) ||
|
||||
(target_type == DM_LINEAR) ||
|
||||
(_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked))
|
||||
return 1;
|
||||
|
||||
@@ -367,7 +346,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) || (target == DM_ZERO)) /* nothing to check */
|
||||
(target == DM_LINEAR)) /* nothing to check with linear */
|
||||
return 0;
|
||||
|
||||
return -ENODEV;
|
||||
@@ -621,12 +600,6 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
|
||||
num_options++;
|
||||
if (tgt->u.crypt.integrity)
|
||||
num_options++;
|
||||
|
||||
@@ -637,13 +610,10 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
|
||||
*sector_feature = '\0';
|
||||
|
||||
if (num_options) {
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s%s%s%s", num_options,
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
|
||||
(flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
|
||||
(flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "",
|
||||
(flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? " no_read_workqueue" : "",
|
||||
(flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? " no_write_workqueue" : "",
|
||||
(flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "",
|
||||
sector_feature, integrity_dm);
|
||||
} else
|
||||
*features = '\0';
|
||||
@@ -697,7 +667,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], verity_verify_args[512+32];
|
||||
char features[256], fec_features[256];
|
||||
|
||||
if (!tgt || !tgt->u.verity.vp)
|
||||
return NULL;
|
||||
@@ -705,19 +675,14 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
vp = tgt->u.verity.vp;
|
||||
|
||||
/* These flags are not compatible */
|
||||
if ((flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) &&
|
||||
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION))
|
||||
flags &= ~CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
|
||||
if ((flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) &&
|
||||
(flags & (CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)))
|
||||
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION))
|
||||
flags &= ~CRYPT_ACTIVATE_IGNORE_CORRUPTION;
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
|
||||
@@ -732,18 +697,10 @@ 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%s", num_options,
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
|
||||
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
|
||||
else
|
||||
@@ -765,22 +722,19 @@ 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(verity_verify_args);
|
||||
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128;
|
||||
|
||||
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%s",
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %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,
|
||||
verity_verify_args);
|
||||
|
||||
vp->hash_name, hexroot, hexsalt, features, fec_features);
|
||||
if (r < 0 || r >= max_size) {
|
||||
crypt_safe_free(params);
|
||||
params = NULL;
|
||||
@@ -912,11 +866,6 @@ 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++;
|
||||
@@ -924,12 +873,6 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "allow_discards ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (tgt->u.integrity.meta_device) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "meta_device:%s ",
|
||||
@@ -979,16 +922,6 @@ 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)
|
||||
{
|
||||
@@ -1262,9 +1195,6 @@ 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;
|
||||
}
|
||||
@@ -1303,8 +1233,6 @@ 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;
|
||||
@@ -1323,12 +1251,6 @@ err:
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool dm_device_exists(struct crypt_device *cd, const char *name)
|
||||
{
|
||||
int r = dm_status_device(cd, name);
|
||||
return (r >= 0 || r == -EEXIST);
|
||||
}
|
||||
|
||||
static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type,
|
||||
const char *uuid, struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
@@ -1378,11 +1300,8 @@ static int _dm_create_device(struct crypt_device *cd, const char *name, const ch
|
||||
if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_run(dmt)) {
|
||||
if (dm_device_exists(cd, name))
|
||||
r = -EEXIST;
|
||||
if (!dm_task_run(dmt))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dm_task_get_info(dmt, &dmi))
|
||||
r = 0;
|
||||
@@ -1535,13 +1454,10 @@ 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."));
|
||||
@@ -1606,7 +1522,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 does not support kernel keyring");
|
||||
log_dbg(cd, "dm-crypt doesn't support kernel keyring");
|
||||
*dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
ret = 1;
|
||||
}
|
||||
@@ -1614,19 +1530,11 @@ 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 does not support performance options");
|
||||
log_dbg(cd, "dm-crypt doesn't support performance options");
|
||||
*dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* Drop no workqueue options if not supported */
|
||||
if ((*dmd_flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
|
||||
!(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED)) {
|
||||
log_dbg(cd, "dm-crypt does not support performance options");
|
||||
*dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1648,22 +1556,14 @@ 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 || dmd->segment.type == DM_ZERO) &&
|
||||
check_retry(cd, &dmd->flags, dmt_flags)) {
|
||||
log_dbg(cd, "Retrying open without incompatible options.");
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR) && check_retry(cd, &dmd->flags, dmt_flags))
|
||||
r = _dm_create_device(cd, name, type, dmd->uuid, dmd);
|
||||
}
|
||||
|
||||
if (r == -EINVAL &&
|
||||
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_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
|
||||
if (r == -EINVAL &&
|
||||
dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) &&
|
||||
!(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
|
||||
CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
|
||||
CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
|
||||
@@ -1671,10 +1571,6 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
!(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
|
||||
!(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_VERITY &&
|
||||
dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity FEC options are not supported."));
|
||||
@@ -1690,10 +1586,6 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
!(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
|
||||
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) &&
|
||||
!(dmt_flags & DM_INTEGRITY_BITMAP_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-integrity bitmap mode is not supported."));
|
||||
@@ -1721,17 +1613,11 @@ int dm_reload_device(struct crypt_device *cd, const char *name,
|
||||
|
||||
if (r == -EINVAL && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR)) {
|
||||
if ((dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
if ((dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!dm_flags(cd, DM_INTEGRITY, &dmt_flags) && !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
}
|
||||
|
||||
if (!r && resume)
|
||||
@@ -1769,7 +1655,6 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = -EEXIST;
|
||||
dm_get_next_target(dmt, NULL, &start, &length,
|
||||
&target_type, ¶ms);
|
||||
|
||||
@@ -1784,7 +1669,6 @@ 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;
|
||||
@@ -1968,12 +1852,6 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
|
||||
*act_flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
|
||||
else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
|
||||
*act_flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
|
||||
else if (!strcasecmp(arg, "no_read_workqueue"))
|
||||
*act_flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
|
||||
else if (!strcasecmp(arg, "no_write_workqueue"))
|
||||
*act_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
|
||||
else if (!strcasecmp(arg, "iv_large_sectors"))
|
||||
*act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
|
||||
else if (sscanf(arg, "integrity:%u:", &val) == 1) {
|
||||
tgt->u.crypt.tag_size = val;
|
||||
rintegrity = strchr(arg + strlen("integrity:"), ':');
|
||||
@@ -2079,7 +1957,6 @@ 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));
|
||||
@@ -2222,8 +2099,6 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
*act_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
|
||||
else if (!strcasecmp(arg, "restart_on_corruption"))
|
||||
*act_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
|
||||
else if (!strcasecmp(arg, "panic_on_corruption"))
|
||||
*act_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
|
||||
else if (!strcasecmp(arg, "ignore_zero_blocks"))
|
||||
*act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
|
||||
else if (!strcasecmp(arg, "check_at_most_once"))
|
||||
@@ -2265,15 +2140,6 @@ 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;
|
||||
}
|
||||
@@ -2299,15 +2165,11 @@ 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);
|
||||
@@ -2472,10 +2334,6 @@ 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 if (!strcmp(arg, "allow_discards")) {
|
||||
*act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
} else /* unknown option */
|
||||
goto err;
|
||||
}
|
||||
@@ -2558,14 +2416,6 @@ 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
|
||||
*
|
||||
@@ -2587,8 +2437,6 @@ 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;
|
||||
@@ -2671,9 +2519,6 @@ 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;
|
||||
@@ -2721,7 +2566,6 @@ 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;
|
||||
@@ -2760,9 +2604,6 @@ 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)
|
||||
@@ -3000,8 +2841,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, const char *root_hash_sig_key_desc,
|
||||
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp)
|
||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||
uint64_t hash_blocks, struct crypt_params_verity *vp)
|
||||
{
|
||||
if (!data_device || !hash_device || !vp)
|
||||
return -EINVAL;
|
||||
@@ -3016,7 +2857,6 @@ 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;
|
||||
@@ -3025,21 +2865,16 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_integrity_target_set(struct crypt_device *cd,
|
||||
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
int dm_integrity_target_set(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;
|
||||
@@ -3055,11 +2890,6 @@ int dm_integrity_target_set(struct crypt_device *cd,
|
||||
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;
|
||||
@@ -3090,13 +2920,3 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 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 = 0;
|
||||
int r;
|
||||
|
||||
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 does not support loop-AES compatible mapping."));
|
||||
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 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,6 +22,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "luks.h"
|
||||
@@ -88,7 +89,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 does not exist or access denied."),
|
||||
log_err(ctx, _("Device %s doesn't exist or access denied."),
|
||||
device_path(crypt_metadata_device(ctx)));
|
||||
return -EIO;
|
||||
}
|
||||
@@ -153,7 +154,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
return -EINVAL;
|
||||
|
||||
/* Encrypt buffer */
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
|
||||
if (r)
|
||||
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
@@ -218,7 +219,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
if (MISALIGNED_512(dstLength))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
|
||||
if (r)
|
||||
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2019 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,6 +23,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@@ -259,7 +260,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
}
|
||||
@@ -283,7 +284,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 does not contain valid LUKS header."));
|
||||
log_err(ctx, _("Backup file doesn't contain valid LUKS header."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -452,7 +453,7 @@ out:
|
||||
if (r)
|
||||
log_err(ctx, _("Repair failed."));
|
||||
crypt_free_volume_key(vk);
|
||||
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -691,7 +692,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_safe_memzero(buf, sizeof(buf));
|
||||
crypt_memzero(buf, sizeof(buf));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -786,15 +787,10 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
return r;
|
||||
assert(pbkdf->iterations);
|
||||
|
||||
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;
|
||||
|
||||
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,
|
||||
@@ -986,10 +982,8 @@ 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) {
|
||||
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
|
||||
r = LUKS_decrypt_from_storage(AfKey,
|
||||
@@ -1230,7 +1224,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 (LUKS_keyslot_info(hdr, keyslot) < CRYPT_SLOT_ACTIVE)
|
||||
if (keyslot >= LUKS_NUMKEYS || keyslot < 0)
|
||||
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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -523,7 +523,7 @@ int LUKS2_check_metadata_area_size(uint64_t metadata_size);
|
||||
int LUKS2_check_keyslots_area_size(uint64_t keyslots_size);
|
||||
|
||||
int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr, bool detached_header);
|
||||
struct luks2_hdr *hdr);
|
||||
|
||||
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
|
||||
int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic);
|
||||
@@ -600,8 +600,7 @@ 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, 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);
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, const char *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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 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 does not match size 0x%04x.",
|
||||
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header doesn't 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 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,6 +23,7 @@
|
||||
#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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -337,7 +337,7 @@ err:
|
||||
}
|
||||
|
||||
int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr, bool detached_header)
|
||||
struct luks2_hdr *hdr)
|
||||
{
|
||||
int r;
|
||||
uint64_t offset, length;
|
||||
@@ -352,7 +352,7 @@ int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
|
||||
/* On detached header wipe at least the first 4k */
|
||||
if (detached_header) {
|
||||
if (length == 0) {
|
||||
length = 4096;
|
||||
wipe_block = 4096;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2020 Ondrej Kozina
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2019 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; i++) {
|
||||
if (i && !(i % 16))
|
||||
log_std(cd, "\n\t%s", line_sep);
|
||||
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++)
|
||||
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 does not match value in binary header.");
|
||||
log_dbg(cd, "JSON area size doesn't match value in binary header.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (json_size > json_area_size) {
|
||||
log_dbg(cd, "JSON does not fit in the designated area.");
|
||||
log_dbg(cd, "JSON doesn't fit in the designated area.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -594,9 +594,9 @@ static bool validate_segment_intervals(struct crypt_device *cd,
|
||||
static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
{
|
||||
json_object *jobj_segments, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type, *jobj_flags, *jobj;
|
||||
struct interval *intervals;
|
||||
uint64_t offset, size;
|
||||
int i, r, count, first_backup = -1;
|
||||
struct interval *intervals = NULL;
|
||||
|
||||
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments)) {
|
||||
log_dbg(cd, "Missing segments section.");
|
||||
@@ -676,18 +676,10 @@ static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* avoid needlessly large allocation when first backup segment is invalid */
|
||||
if (first_backup >= count) {
|
||||
log_dbg(cd, "Gap between last regular segment and backup segment at key %d.", first_backup);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (first_backup < 0)
|
||||
first_backup = count;
|
||||
|
||||
if ((size_t)first_backup < SIZE_MAX / sizeof(*intervals))
|
||||
intervals = malloc(first_backup * sizeof(*intervals));
|
||||
|
||||
intervals = malloc(first_backup * sizeof(*intervals));
|
||||
if (!intervals) {
|
||||
log_dbg(cd, "Not enough memory.");
|
||||
return 1;
|
||||
@@ -978,16 +970,13 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hdr_cleanup_and_validate(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
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))
|
||||
/* 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 -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
|
||||
@@ -995,7 +984,11 @@ 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)
|
||||
{
|
||||
if (hdr_cleanup_and_validate(cd, 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 -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
|
||||
@@ -1166,7 +1159,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 does not contain valid LUKS header."));
|
||||
log_err(cd, _("Backup file doesn't contain valid LUKS header."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1277,8 +1270,8 @@ out:
|
||||
LUKS2_hdr_free(cd, hdr);
|
||||
LUKS2_hdr_free(cd, &hdr_file);
|
||||
LUKS2_hdr_free(cd, &tmp_hdr);
|
||||
crypt_safe_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_safe_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_free(buffer);
|
||||
|
||||
device_sync(cd, device);
|
||||
@@ -1297,8 +1290,6 @@ static const struct {
|
||||
{ CRYPT_ACTIVATE_SAME_CPU_CRYPT, "same-cpu-crypt" },
|
||||
{ CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS, "submit-from-crypt-cpus" },
|
||||
{ CRYPT_ACTIVATE_NO_JOURNAL, "no-journal" },
|
||||
{ CRYPT_ACTIVATE_NO_READ_WORKQUEUE, "no-read-workqueue" },
|
||||
{ CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE, "no-write-workqueue" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@@ -2166,12 +2157,7 @@ int LUKS2_activate(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags, 0);
|
||||
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -2219,21 +2205,26 @@ 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, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
|
||||
char **dep, uuid[37], 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 || 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))
|
||||
if (!dmd || !dmd->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 */
|
||||
@@ -2245,7 +2236,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_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot deactivate device."));
|
||||
@@ -2354,9 +2345,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, _("Operation incompatible with device marked for legacy reencryption. Aborting."));
|
||||
log_err(cd, _("Offline reencryption in progress. Aborting."));
|
||||
if (reqs_reencrypt_online(reqs) && !quiet)
|
||||
log_err(cd, _("Operation incompatible with device marked for LUKS2 reencryption. Aborting."));
|
||||
log_err(cd, _("Online reencryption in progress. Aborting."));
|
||||
|
||||
/* any remaining unmasked requirement fails the check */
|
||||
return reqs ? -EINVAL : 0;
|
||||
@@ -2409,7 +2400,7 @@ int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object
|
||||
#endif
|
||||
}
|
||||
|
||||
/* jobj_dst must contain pointer initialized to NULL (see json-c json_object_deep_copy API) */
|
||||
/* jobj_dst must contain pointer initialised 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 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,9 @@ extern const keyslot_handler reenc_keyslot;
|
||||
|
||||
static const keyslot_handler *keyslot_handlers[LUKS2_KEYSLOTS_MAX] = {
|
||||
&luks2_keyslot,
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
&reenc_keyslot,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -79,18 +81,19 @@ 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, count = 0;
|
||||
unsigned s;
|
||||
int keyslot_digest, segment_digest, s, count = 0;
|
||||
|
||||
keyslot_digest = LUKS2_digest_by_keyslot(hdr, keyslot);
|
||||
if (keyslot_digest < 0)
|
||||
return 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))
|
||||
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)
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -309,16 +312,28 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _open_and_verify(struct crypt_device *cd,
|
||||
static int LUKS2_open_and_verify_by_digest(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)
|
||||
{
|
||||
int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
const keyslot_handler *h;
|
||||
int key_size, r;
|
||||
|
||||
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;
|
||||
|
||||
@@ -337,41 +352,9 @@ static int _open_and_verify(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,
|
||||
@@ -381,7 +364,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int r;
|
||||
int key_size, r;
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
@@ -399,7 +382,29 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
|
||||
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;
|
||||
}
|
||||
|
||||
static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
|
||||
@@ -517,7 +522,7 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
size_t password_len,
|
||||
struct volume_key **vks)
|
||||
{
|
||||
struct volume_key *vk = NULL;
|
||||
struct volume_key *vk;
|
||||
int digest_old, digest_new, r = -EINVAL;
|
||||
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||
|
||||
@@ -527,6 +532,7 @@ 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);
|
||||
}
|
||||
|
||||
@@ -536,6 +542,7 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -48,7 +48,7 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength,
|
||||
return -EINVAL;
|
||||
|
||||
/* Encrypt buffer */
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
if (r) {
|
||||
log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
|
||||
return r;
|
||||
@@ -103,7 +103,7 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
if (MISALIGNED_512(dstLength))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
if (r) {
|
||||
log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
|
||||
return r;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
|
||||
*
|
||||
* Copyright (C) 2016-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020, Ondrej Kozina
|
||||
* Copyright (C) 2016-2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2018, 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Ondrej Kozina
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Ondrej Kozina
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -467,7 +467,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
|
||||
r = 0;
|
||||
out:
|
||||
device_sync(cd, device);
|
||||
crypt_safe_memzero(buf, buf_size);
|
||||
crypt_memzero(buf, buf_size);
|
||||
free(buf);
|
||||
|
||||
return r;
|
||||
@@ -578,12 +578,6 @@ 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;
|
||||
@@ -675,7 +669,7 @@ static int keyslot_LUKS1_compatible(struct crypt_device *cd, struct luks2_hdr *h
|
||||
int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct luks_phdr *hdr1)
|
||||
{
|
||||
size_t buf_size, buf_offset;
|
||||
char cipher[LUKS_CIPHERNAME_L], cipher_mode[LUKS_CIPHERMODE_L];
|
||||
char cipher[LUKS_CIPHERNAME_L-1], cipher_mode[LUKS_CIPHERMODE_L-1];
|
||||
char digest[LUKS_DIGESTSIZE], digest_salt[LUKS_SALTSIZE];
|
||||
const char *hash;
|
||||
size_t len;
|
||||
@@ -824,10 +818,8 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
strncpy(hdr1->cipherName, cipher, LUKS_CIPHERNAME_L - 1);
|
||||
hdr1->cipherName[LUKS_CIPHERNAME_L-1] = '\0';
|
||||
strncpy(hdr1->cipherMode, cipher_mode, LUKS_CIPHERMODE_L - 1);
|
||||
hdr1->cipherMode[LUKS_CIPHERMODE_L-1] = '\0';
|
||||
strncpy(hdr1->cipherName, cipher, sizeof(hdr1->cipherName) - 1);
|
||||
strncpy(hdr1->cipherMode, cipher_mode, sizeof(hdr1->cipherMode) - 1);
|
||||
|
||||
if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption helpers
|
||||
*
|
||||
* Copyright (C) 2015-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020, Ondrej Kozina
|
||||
* Copyright (C) 2015-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "luks2_internal.h"
|
||||
#include "utils_device_locking.h"
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static json_object *reencrypt_segment(struct luks2_hdr *hdr, unsigned new)
|
||||
{
|
||||
return LUKS2_get_segment_by_flag(hdr, new ? "backup-final" : "backup-previous");
|
||||
@@ -85,7 +86,7 @@ static uint64_t reencrypt_get_data_offset_old(struct luks2_hdr *hdr)
|
||||
{
|
||||
return reencrypt_data_offset(hdr, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
static int reencrypt_digest(struct luks2_hdr *hdr, unsigned new)
|
||||
{
|
||||
int segment = LUKS2_get_segment_id_by_flag(hdr, new ? "backup-final" : "backup-previous");
|
||||
@@ -144,7 +145,7 @@ static const char *reencrypt_resilience_hash(struct luks2_hdr *hdr)
|
||||
|
||||
return json_object_get_string(jobj_hash);
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static uint32_t reencrypt_alignment(struct luks2_hdr *hdr)
|
||||
{
|
||||
json_object *jobj_keyslot, *jobj_area, *jobj_type, *jobj_hash, *jobj_sector_size;
|
||||
@@ -560,7 +561,7 @@ static int reencrypt_make_post_segments(struct crypt_device *cd,
|
||||
|
||||
return rh->jobj_segs_post ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
#endif
|
||||
static uint64_t reencrypt_data_shift(struct luks2_hdr *hdr)
|
||||
{
|
||||
json_object *jobj_keyslot, *jobj_area, *jobj_data_shift;
|
||||
@@ -666,7 +667,7 @@ void LUKS2_reenc_context_free(struct crypt_device *cd, struct luks2_reenc_contex
|
||||
crypt_unlock_internal(cd, rh->reenc_lock);
|
||||
free(rh);
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static size_t reencrypt_get_alignment(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr)
|
||||
{
|
||||
@@ -1401,12 +1402,12 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read journaled data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -1436,13 +1437,13 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -2531,7 +2532,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, _("Device not marked for LUKS2 reencryption."));
|
||||
log_err(cd, _("No LUKS2 reencryption in progress."));
|
||||
return -EINVAL;
|
||||
} else
|
||||
r = -EINVAL;
|
||||
@@ -2545,11 +2546,22 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reencrypt_lock_internal(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
#endif
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock(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;
|
||||
@@ -2571,42 +2583,12 @@ 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)
|
||||
{
|
||||
crypt_unlock_internal(cd, reencrypt_lock);
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
@@ -2624,7 +2606,7 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr *
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = crypt_reencrypt_lock(cd, &h);
|
||||
r = crypt_reencrypt_lock(cd, NULL, &h);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption process is already running."));
|
||||
@@ -2828,7 +2810,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, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot perform recovery."));
|
||||
@@ -2861,7 +2843,7 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd,
|
||||
crypt_reencrypt_unlock(cd, reencrypt_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
static int reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *passphrase,
|
||||
@@ -2872,6 +2854,7 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
const char *cipher_mode,
|
||||
const struct crypt_params_reencrypt *params)
|
||||
{
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
int r;
|
||||
crypt_reencrypt_info ri;
|
||||
struct volume_key *vks = NULL;
|
||||
@@ -2882,7 +2865,7 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
if (flags & CRYPT_REENCRYPT_RECOVERY)
|
||||
return reencrypt_recovery_by_passphrase(cd, hdr, keyslot_old, keyslot_new, passphrase, passphrase_size);
|
||||
|
||||
if (cipher && !crypt_cipher_wrapped_key(cipher, cipher_mode)) {
|
||||
if (cipher) {
|
||||
r = crypt_keyslot_get_key_size(cd, keyslot_new);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -2927,6 +2910,10 @@ out:
|
||||
crypt_drop_keyring_key(cd, vks);
|
||||
crypt_free_volume_key(vks);
|
||||
return r < 0 ? r : LUKS2_find_keyslot(hdr, "reencrypt");
|
||||
#else
|
||||
log_err(cd, _("This operation is not supported for this device type."));
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
@@ -2955,7 +2942,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_safe_memzero(passphrase, passphrase_size);
|
||||
crypt_memzero(passphrase, passphrase_size);
|
||||
free(passphrase);
|
||||
|
||||
return r;
|
||||
@@ -2979,6 +2966,7 @@ int crypt_reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
return reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params);
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static reenc_status_t reencrypt_step(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
struct luks2_reenc_context *rh,
|
||||
@@ -3219,10 +3207,11 @@ static int reencrypt_teardown(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
int crypt_reencrypt(struct crypt_device *cd,
|
||||
int (*progress)(uint64_t size, uint64_t offset, void *usrptr))
|
||||
{
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
int r;
|
||||
crypt_reencrypt_info ri;
|
||||
struct luks2_hdr *hdr;
|
||||
@@ -3280,8 +3269,12 @@ int crypt_reencrypt(struct crypt_device *cd,
|
||||
|
||||
r = reencrypt_teardown(cd, hdr, rh, rs, quit, progress);
|
||||
return r;
|
||||
#else
|
||||
log_err(cd, _("This operation is not supported for this device type."));
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static int reencrypt_recovery(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
uint64_t device_size,
|
||||
@@ -3317,7 +3310,7 @@ err:
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* use only for calculation of minimal data device size.
|
||||
* The real data offset is taken directly from segments!
|
||||
@@ -3332,7 +3325,7 @@ int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise)
|
||||
|
||||
return blockwise ? data_offset : data_offset << SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
/* internal only */
|
||||
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)
|
||||
{
|
||||
@@ -3405,7 +3398,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 = crypt_volume_key_next(vk);
|
||||
vk = vk->next;
|
||||
}
|
||||
|
||||
if (luks2_check_device_size(cd, hdr, minimal_size, &device_size, true, false))
|
||||
@@ -3422,7 +3415,7 @@ err:
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
}
|
||||
|
||||
#endif
|
||||
crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd, struct crypt_params_reencrypt *params)
|
||||
{
|
||||
crypt_reencrypt_info ri;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, internal segment handling
|
||||
*
|
||||
* Copyright (C) 2018-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020, Ondrej Kozina
|
||||
* Copyright (C) 2018-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019, 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 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_safe_memzero(buffer, buffer_len);
|
||||
crypt_memzero(buffer, buffer_len);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, kernel keyring token
|
||||
*
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 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,6 +20,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
@@ -27,6 +28,10 @@
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
static int random_initialised = 0;
|
||||
|
||||
#define URANDOM_DEVICE "/dev/urandom"
|
||||
|
||||
455
lib/setup.c
455
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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,6 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -35,7 +36,6 @@
|
||||
#include "verity.h"
|
||||
#include "tcrypt.h"
|
||||
#include "integrity.h"
|
||||
#include "bitlk.h"
|
||||
#include "utils_device_locking.h"
|
||||
#include "internal.h"
|
||||
|
||||
@@ -50,7 +50,6 @@ struct crypt_device {
|
||||
|
||||
struct volume_key *volume_key;
|
||||
int rng_type;
|
||||
uint32_t compatibility;
|
||||
struct crypt_pbkdf_type pbkdf;
|
||||
|
||||
/* global context scope settings */
|
||||
@@ -96,7 +95,7 @@ struct crypt_device {
|
||||
} loopaes;
|
||||
struct { /* used in CRYPT_VERITY */
|
||||
struct crypt_params_verity hdr;
|
||||
const char *root_hash;
|
||||
char *root_hash;
|
||||
unsigned int root_hash_size;
|
||||
char *uuid;
|
||||
struct device *fec_device;
|
||||
@@ -109,12 +108,7 @@ 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 */
|
||||
@@ -230,7 +224,7 @@ int init_crypto(struct crypt_device *ctx)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_backend_init();
|
||||
r = crypt_backend_init(ctx);
|
||||
if (r < 0)
|
||||
log_err(ctx, _("Cannot initialize crypto backend."));
|
||||
|
||||
@@ -321,11 +315,6 @@ 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;
|
||||
@@ -583,9 +572,6 @@ 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;
|
||||
@@ -740,6 +726,9 @@ out:
|
||||
free(type);
|
||||
LUKS2_hdr_free(cd, &hdr2);
|
||||
}
|
||||
/* FIXME: why? */
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -774,7 +763,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 initialized to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -814,7 +803,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 initialized to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -833,7 +822,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -897,7 +886,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_safe_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
|
||||
crypt_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -933,7 +922,7 @@ static int _crypt_load_integrity(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params, &cd->u.integrity.sb_flags);
|
||||
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -976,31 +965,6 @@ 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)
|
||||
@@ -1023,35 +987,29 @@ 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 initialized to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialised 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 initialized to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialised 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 initialized to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialised 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 initialized to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialised 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;
|
||||
|
||||
@@ -1128,7 +1086,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(CONST_CAST(void*)cd->u.verity.root_hash);
|
||||
free(cd->u.verity.root_hash);
|
||||
free(cd->u.verity.uuid);
|
||||
device_free(cd, cd->u.verity.fec_device);
|
||||
} else if (isINTEGRITY(cd->type)) {
|
||||
@@ -1137,9 +1095,6 @@ 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;
|
||||
@@ -1292,13 +1247,6 @@ 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);
|
||||
@@ -1321,7 +1269,6 @@ 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;
|
||||
@@ -1353,7 +1300,6 @@ 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);
|
||||
@@ -1467,8 +1413,6 @@ 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
|
||||
@@ -1480,7 +1424,7 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Try to initialize basic parameters from active device */
|
||||
/* Try to initialise basic parameters from active device */
|
||||
|
||||
if (tgt->type == DM_CRYPT || tgt->type == DM_LINEAR)
|
||||
r = _init_by_name_crypt(*cd, name);
|
||||
@@ -1874,7 +1818,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr, cd->metadata_device != NULL);
|
||||
r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Cannot wipe header on device %s."),
|
||||
mdata_device_path(cd));
|
||||
@@ -2146,7 +2090,6 @@ 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;
|
||||
|
||||
@@ -2203,14 +2146,6 @@ 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;
|
||||
@@ -2219,7 +2154,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 = integrity_tag_size;
|
||||
cd->u.integrity.params.tag_size = params->tag_size;
|
||||
cd->u.integrity.params.integrity = integrity;
|
||||
cd->u.integrity.params.journal_integrity = journal_integrity;
|
||||
cd->u.integrity.params.journal_crypt = journal_crypt;
|
||||
@@ -2766,7 +2701,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 initialized */
|
||||
/* Device context type must be initialised */
|
||||
if (!cd || !cd->type || !name)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -2967,8 +2902,8 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
else
|
||||
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
|
||||
|
||||
crypt_safe_memzero(&hdr1, sizeof(hdr1));
|
||||
crypt_safe_memzero(&hdr2, sizeof(hdr2));
|
||||
crypt_memzero(&hdr1, sizeof(hdr1));
|
||||
crypt_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)
|
||||
@@ -3003,7 +2938,7 @@ void crypt_free(struct crypt_device *cd)
|
||||
free(CONST_CAST(void*)cd->pbkdf.hash);
|
||||
|
||||
/* Some structures can contain keys (TCRYPT), wipe it */
|
||||
crypt_safe_memzero(cd, sizeof(*cd));
|
||||
crypt_memzero(cd, sizeof(*cd));
|
||||
free(cd);
|
||||
}
|
||||
|
||||
@@ -3212,7 +3147,7 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
r = dm_resume_and_reinstate_key(cd, name, vk);
|
||||
if (r < 0)
|
||||
if (r)
|
||||
log_err(cd, _("Error during resuming device %s."), name);
|
||||
out:
|
||||
crypt_safe_free(passphrase_read);
|
||||
@@ -3243,65 +3178,6 @@ 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
|
||||
*/
|
||||
@@ -3745,7 +3621,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, 0);
|
||||
r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -3767,27 +3643,6 @@ 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)
|
||||
{
|
||||
@@ -3853,21 +3708,6 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks)
|
||||
{
|
||||
int r;
|
||||
struct volume_key *vk = vks;
|
||||
|
||||
while (vk) {
|
||||
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
|
||||
if (r < 0)
|
||||
return r;
|
||||
vk = crypt_volume_key_next(vk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See fixmes in _open_and_activate_luks2 */
|
||||
int update_reencryption_flag(struct crypt_device *cd, int enable, bool commit);
|
||||
|
||||
@@ -3909,6 +3749,22 @@ out:
|
||||
return r < 0 ? r : keyslot;
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks)
|
||||
{
|
||||
int r;
|
||||
struct volume_key *vk = vks;
|
||||
|
||||
while (vk) {
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _open_all_keys(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
@@ -3975,7 +3831,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, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot activate device."));
|
||||
@@ -4070,6 +3926,28 @@ static int _open_and_activate_luks2(struct crypt_device *cd,
|
||||
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
static int _open_and_activate_luks2(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
const char *name,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
uint32_t flags)
|
||||
{
|
||||
crypt_reencrypt_info ri;
|
||||
|
||||
ri = LUKS2_reenc_status(&cd->u.luks2.hdr);
|
||||
if (ri == CRYPT_REENCRYPT_INVALID)
|
||||
return -EINVAL;
|
||||
|
||||
if (ri > CRYPT_REENCRYPT_NONE) {
|
||||
log_err(cd, _("This operation is not supported for this device type."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return _open_and_activate(cd, keyslot, name, passphrase, passphrase_size, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _activate_by_passphrase(struct crypt_device *cd,
|
||||
const char *name,
|
||||
@@ -4119,12 +3997,8 @@ 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 initialized."));
|
||||
log_err(cd, _("Device type is not properly initialised."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
@@ -4161,26 +4035,21 @@ static int _activate_loopaes(struct crypt_device *cd,
|
||||
|
||||
static int _activate_check_status(struct crypt_device *cd, const char *name, unsigned reload)
|
||||
{
|
||||
int r;
|
||||
crypt_status_info ci;
|
||||
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
r = dm_status_device(cd, name);
|
||||
|
||||
if (r >= 0 && reload)
|
||||
return 0;
|
||||
|
||||
if (r >= 0 || r == -EEXIST) {
|
||||
ci = crypt_status(cd, name);
|
||||
if (ci == CRYPT_INVALID) {
|
||||
log_err(cd, _("Cannot use device %s, name is invalid or still in use."), name);
|
||||
return -EINVAL;
|
||||
} else if (ci >= CRYPT_ACTIVE && !reload) {
|
||||
log_err(cd, _("Device %s already exists."), name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (r == -ENODEV)
|
||||
return 0;
|
||||
|
||||
log_err(cd, _("Cannot use device %s, name is invalid or still in use."), name);
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// activation/deactivation of device mapping
|
||||
@@ -4268,6 +4137,7 @@ 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,
|
||||
@@ -4362,7 +4232,25 @@ 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)) {
|
||||
r = crypt_activate_by_signed_key(cd, name, volume_key, volume_key_size, NULL, 0, flags);
|
||||
/* 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);
|
||||
}
|
||||
} else if (isTCRYPT(cd->type)) {
|
||||
if (!name)
|
||||
return 0;
|
||||
@@ -4378,10 +4266,9 @@ 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.sb_flags);
|
||||
cd->u.integrity.journal_mac_key, flags);
|
||||
} else {
|
||||
log_err(cd, _("Device type is not properly initialized."));
|
||||
log_err(cd, _("Device type is not properly initialised."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
@@ -4392,77 +4279,6 @@ 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;
|
||||
@@ -4502,7 +4318,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 ((dmd.uuid && !strncmp(CRYPT_LUKS2, dmd.uuid, sizeof(CRYPT_LUKS2)-1)) || hdr2)
|
||||
if (!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);
|
||||
@@ -4622,7 +4438,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) && !isVERITY(cd->type) && !passphrase))
|
||||
if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !passphrase))
|
||||
return -EINVAL;
|
||||
|
||||
if (isLUKS2(cd->type) && keyslot != CRYPT_ANY_SLOT)
|
||||
@@ -4652,18 +4468,10 @@ 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 && vk) {
|
||||
if (r >= 0) {
|
||||
memcpy(volume_key, vk->key, vk->keylength);
|
||||
*volume_key_size = vk->keylength;
|
||||
}
|
||||
@@ -4690,9 +4498,6 @@ 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."));
|
||||
@@ -4731,20 +4536,6 @@ 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
|
||||
*/
|
||||
@@ -4864,8 +4655,6 @@ 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;
|
||||
@@ -4884,8 +4673,6 @@ 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;
|
||||
|
||||
@@ -4916,9 +4703,6 @@ 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;
|
||||
|
||||
@@ -4949,9 +4733,6 @@ 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;
|
||||
|
||||
@@ -5026,9 +4807,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -5089,9 +4867,6 @@ 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;
|
||||
|
||||
@@ -5273,9 +5048,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -5395,7 +5167,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 | CRYPT_VERITY_ROOT_HASH_SIGNATURE);
|
||||
vp->flags = cd->u.verity.hdr.flags & CRYPT_VERITY_NO_HEADER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5847,7 +5619,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 initialize default LUKS2 keyslot parameters."));
|
||||
log_err(cd, _("Failed to initialise default LUKS2 keyslot parameters."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5875,11 +5647,32 @@ 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 initialized */
|
||||
/* dm backend must be initialised */
|
||||
if (!cd || !isLUKS2(cd->type))
|
||||
return 0;
|
||||
|
||||
@@ -6000,7 +5793,7 @@ int crypt_activate_by_keyring(struct crypt_device *cd,
|
||||
|
||||
r = _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
|
||||
|
||||
crypt_safe_memzero(passphrase, passphrase_size);
|
||||
crypt_memzero(passphrase, passphrase_size);
|
||||
free(passphrase);
|
||||
|
||||
return r;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 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,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -300,8 +301,8 @@ static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
|
||||
}
|
||||
|
||||
crypt_cipher_destroy(cipher);
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -368,8 +369,8 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
|
||||
crypt_cipher_destroy(cipher);
|
||||
}
|
||||
|
||||
crypt_safe_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_safe_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
crypt_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -419,8 +420,8 @@ out:
|
||||
if (cipher[j])
|
||||
crypt_cipher_destroy(cipher[j]);
|
||||
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -473,13 +474,13 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
crypt_safe_memzero(&hdr2, sizeof(hdr2));
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
return r;
|
||||
}
|
||||
|
||||
static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
unsigned char pool[VCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile, int keyfiles_pool_length)
|
||||
unsigned char pool[TCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile)
|
||||
{
|
||||
unsigned char *data;
|
||||
int i, j, fd, data_size, r = -EIO;
|
||||
@@ -511,12 +512,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 %= keyfiles_pool_length;
|
||||
j %= TCRYPT_KEY_POOL_LEN;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
crypt_safe_memzero(&crc, sizeof(crc));
|
||||
crypt_safe_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
crypt_memzero(&crc, sizeof(crc));
|
||||
crypt_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
free(data);
|
||||
|
||||
return r;
|
||||
@@ -526,39 +527,29 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params)
|
||||
{
|
||||
unsigned char pwd[VCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size, max_passphrase_size;
|
||||
unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size;
|
||||
char *key;
|
||||
unsigned int i, skipped = 0, iterations;
|
||||
int r = -EPERM, keyfiles_pool_length;
|
||||
int r = -EPERM;
|
||||
|
||||
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
|
||||
return -ENOMEM;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_VERA_MODES &&
|
||||
params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
|
||||
/* Really. Keyfile pool length depends on passphrase size in Veracrypt. */
|
||||
max_passphrase_size = VCRYPT_KEY_POOL_LEN;
|
||||
keyfiles_pool_length = VCRYPT_KEY_POOL_LEN;
|
||||
} else {
|
||||
max_passphrase_size = TCRYPT_KEY_POOL_LEN;
|
||||
keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
|
||||
}
|
||||
|
||||
if (params->keyfiles_count)
|
||||
passphrase_size = max_passphrase_size;
|
||||
passphrase_size = TCRYPT_KEY_POOL_LEN;
|
||||
else
|
||||
passphrase_size = params->passphrase_size;
|
||||
|
||||
if (params->passphrase_size > max_passphrase_size) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%zu) exceeded."),
|
||||
max_passphrase_size);
|
||||
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded."),
|
||||
TCRYPT_KEY_POOL_LEN);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Calculate pool content from keyfiles */
|
||||
for (i = 0; i < params->keyfiles_count; i++) {
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i], keyfiles_pool_length);
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
@@ -628,9 +619,9 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
params->cipher, params->mode, params->key_size);
|
||||
}
|
||||
out:
|
||||
crypt_safe_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
if (key)
|
||||
crypt_safe_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
free(key);
|
||||
return r;
|
||||
}
|
||||
@@ -749,14 +740,14 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (hdr->d.sector_size % SECTOR_SIZE) {
|
||||
if (hdr->d.sector_size && hdr->d.sector_size != SECTOR_SIZE) {
|
||||
log_err(cd, _("Activation is not supported for %d sector size."),
|
||||
hdr->d.sector_size);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (strstr(params->mode, "-tcrypt")) {
|
||||
log_err(cd, _("Kernel does not support activation for this TCRYPT legacy mode."));
|
||||
log_err(cd, _("Kernel doesn't support activation for this TCRYPT legacy mode."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -769,12 +760,15 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
if (!algs)
|
||||
return -EINVAL;
|
||||
|
||||
if (hdr->d.sector_size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
|
||||
dmd.size = 0;
|
||||
else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER)
|
||||
dmd.size = hdr->d.hidden_volume_size / SECTOR_SIZE;
|
||||
dmd.size = hdr->d.hidden_volume_size / hdr->d.sector_size;
|
||||
else
|
||||
dmd.size = hdr->d.volume_size / SECTOR_SIZE;
|
||||
dmd.size = hdr->d.volume_size / hdr->d.sector_size;
|
||||
|
||||
if (dmd.flags & CRYPT_ACTIVATE_SHARED)
|
||||
device_check = DEV_OK;
|
||||
@@ -865,7 +859,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 does not support TCRYPT compatible mapping."));
|
||||
log_err(cd, _("Kernel doesn't support TCRYPT compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -1039,11 +1033,11 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
|
||||
if (hdr->d.version > 3)
|
||||
return (hdr->d.mk_offset / SECTOR_SIZE);
|
||||
return (hdr->d.mk_offset / hdr->d.sector_size);
|
||||
if (device_size(crypt_metadata_device(cd), &size) < 0)
|
||||
return 0;
|
||||
return (size - hdr->d.hidden_volume_size +
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
|
||||
}
|
||||
goto hdr_offset;
|
||||
}
|
||||
@@ -1052,11 +1046,11 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
|
||||
if (device_size(crypt_metadata_device(cd), &size) < 0)
|
||||
return 0;
|
||||
return (size - hdr->d.hidden_volume_size +
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
|
||||
}
|
||||
|
||||
hdr_offset:
|
||||
return hdr->d.mk_offset / SECTOR_SIZE;
|
||||
return hdr->d.mk_offset / hdr->d.sector_size;
|
||||
}
|
||||
|
||||
uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
|
||||
@@ -1070,7 +1064,7 @@ uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
|
||||
else if (params->mode && !strncmp(params->mode, "lrw", 3))
|
||||
iv_offset = 0;
|
||||
else
|
||||
iv_offset = hdr->d.mk_offset / SECTOR_SIZE;
|
||||
iv_offset = hdr->d.mk_offset / hdr->d.sector_size;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
|
||||
iv_offset += crypt_dev_partition_offset(device_path(crypt_metadata_device(cd)));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 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,7 +42,6 @@
|
||||
|
||||
#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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,6 +23,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -129,7 +130,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
/* read error */
|
||||
return -1;
|
||||
}
|
||||
@@ -141,7 +142,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
bytes -= bytes_r;
|
||||
}
|
||||
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
return bytes == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -180,7 +181,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(size_t); // sizeof(struct safe_allocation);
|
||||
buflen = 4096 - sizeof(struct safe_allocation);
|
||||
} else
|
||||
buflen = key_size;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library, cipher benchmark
|
||||
*
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -48,12 +48,6 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
if (posix_memalign(&buffer, crypt_getpagesize(), buffer_size))
|
||||
goto out;
|
||||
|
||||
r = crypt_cipher_ivsize(cipher, cipher_mode);
|
||||
if (r >= 0 && iv_size != (size_t)r) {
|
||||
log_dbg(cd, "IV length for benchmark adjusted to %i bytes (requested %zu).", r, iv_size);
|
||||
iv_size = r;
|
||||
}
|
||||
|
||||
if (iv_size) {
|
||||
iv = malloc(iv_size);
|
||||
if (!iv)
|
||||
@@ -77,9 +71,9 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
|
||||
if (r == -ERANGE)
|
||||
log_dbg(cd, "Measured cipher runtime is too low.");
|
||||
else if (r)
|
||||
log_dbg(cd, "Cannot initialize cipher %s, mode %s, key size %zu, IV size %zu.",
|
||||
cipher, cipher_mode, volume_key_size, iv_size);
|
||||
else if (r == -ENOTSUP || r == -ENOENT)
|
||||
log_dbg(cd, "Cannot initialise cipher %s, mode %s.", cipher, cipher_mode);
|
||||
|
||||
out:
|
||||
free(buffer);
|
||||
free(key);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkid probe utilities
|
||||
*
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -77,10 +76,8 @@ int crypt_parse_hash_integrity_mode(const char *s, char *integrity)
|
||||
return -EINVAL;
|
||||
|
||||
r = sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s", mode, hash);
|
||||
if (r == 2 && !isdigit(hash[0]))
|
||||
if (r == 2)
|
||||
r = snprintf(integrity, MAX_CIPHER_LEN, "%s(%s)", mode, hash);
|
||||
else if (r == 2)
|
||||
r = snprintf(integrity, MAX_CIPHER_LEN, "%s-%s", mode, hash);
|
||||
else if (r == 1)
|
||||
r = snprintf(integrity, MAX_CIPHER_LEN, "%s", mode);
|
||||
else
|
||||
@@ -152,6 +149,79 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,6 +29,14 @@
|
||||
#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);
|
||||
@@ -36,6 +44,12 @@ 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,6 +24,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -144,7 +145,7 @@ static int device_read_test(int devfd)
|
||||
if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize)
|
||||
r = 0;
|
||||
|
||||
crypt_safe_memzero(buffer, sizeof(buffer));
|
||||
crypt_memzero(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -184,7 +185,7 @@ static int device_ready(struct crypt_device *cd, struct device *device)
|
||||
}
|
||||
|
||||
if (devfd < 0) {
|
||||
log_err(cd, _("Device %s does not exist or access denied."),
|
||||
log_err(cd, _("Device %s doesn't exist or access denied."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -520,16 +521,10 @@ void device_topology_alignment(struct crypt_device *cd,
|
||||
|
||||
temp_alignment = (unsigned long)min_io_size;
|
||||
|
||||
/*
|
||||
* Ignore bogus opt-io that could break alignment.
|
||||
* Also real opt_io_size should be aligned to minimal page size (4k).
|
||||
* Some bogus USB enclosures reports wrong data here.
|
||||
*/
|
||||
/* Ignore bogus opt-io that could break alignment */
|
||||
if ((temp_alignment < (unsigned long)opt_io_size) &&
|
||||
!((unsigned long)opt_io_size % temp_alignment) && !MISALIGNED_4K(opt_io_size))
|
||||
!((unsigned long)opt_io_size % temp_alignment))
|
||||
temp_alignment = (unsigned long)opt_io_size;
|
||||
else if (opt_io_size)
|
||||
log_err(cd, _("Ignoring bogus optimal-io size for data device (%u bytes)."), opt_io_size);
|
||||
|
||||
/* If calculated alignment is multiple of default, keep default */
|
||||
if (temp_alignment && (default_alignment % temp_alignment))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Metadata on-disk locking for processes serialization
|
||||
*
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 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,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,6 +26,7 @@
|
||||
#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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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,15 +64,8 @@ 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 */
|
||||
#define DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is supported */
|
||||
#define DM_VERITY_PANIC_CORRUPTION_SUPPORTED (1 << 24) /* dm-verity panic on corruption */
|
||||
#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */
|
||||
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, 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);
|
||||
@@ -117,7 +110,6 @@ 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) */
|
||||
@@ -146,14 +138,10 @@ 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;
|
||||
@@ -187,10 +175,9 @@ 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, 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,
|
||||
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,
|
||||
struct device *meta_device,
|
||||
struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
|
||||
struct volume_key *vk,
|
||||
@@ -198,7 +185,6 @@ int dm_integrity_target_set(struct crypt_device *cd,
|
||||
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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 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,14 +25,15 @@
|
||||
#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
|
||||
@@ -177,7 +178,7 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
if (ret < 0) {
|
||||
err = errno;
|
||||
if (buf)
|
||||
crypt_safe_memzero(buf, len);
|
||||
crypt_memzero(buf, len);
|
||||
free(buf);
|
||||
return -err;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kernel keyring syscall wrappers
|
||||
*
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 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-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user