mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 16:30:04 +01:00
Compare commits
224 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
780ebb4680 | ||
|
|
02a579af59 | ||
|
|
9bcf1c4b8d | ||
|
|
dec9b4f7c7 | ||
|
|
4701842829 | ||
|
|
488b4bdbe8 | ||
|
|
c8d886b422 | ||
|
|
a83bbd2e92 | ||
|
|
c3a47cb72f | ||
|
|
0971e55d4d | ||
|
|
6f45c7a8ac | ||
|
|
c567d852a5 | ||
|
|
0b38128e21 | ||
|
|
b9daa8b2ee | ||
|
|
878c7173c3 | ||
|
|
f69b980dcf | ||
|
|
33378792ca | ||
|
|
c7a2b4d5e3 | ||
|
|
4a077fc2c9 | ||
|
|
f309ec21d7 | ||
|
|
e261cf7481 | ||
|
|
fa8390b23e | ||
|
|
af89858d47 | ||
|
|
e6a3569743 | ||
|
|
604abec333 | ||
|
|
790666ffb0 | ||
|
|
c9f6ccff9f | ||
|
|
02b3f42500 | ||
|
|
e10724accb | ||
|
|
5b68dec43a | ||
|
|
9d13da0050 | ||
|
|
1e94425279 | ||
|
|
fc48f9bc08 | ||
|
|
2eb25910a1 | ||
|
|
1dab341b33 | ||
|
|
1f7ed87e6c | ||
|
|
c59ea422cc | ||
|
|
0bcb71f742 | ||
|
|
7e38a3386e | ||
|
|
c25b5ef215 | ||
|
|
72fb507de2 | ||
|
|
45c4c95b98 | ||
|
|
e8861d1043 | ||
|
|
c48fcb743b | ||
|
|
d5d732ddf4 | ||
|
|
f83bd5cdf6 | ||
|
|
76c87c628f | ||
|
|
fa125a354d | ||
|
|
f184b54796 | ||
|
|
75925fb2f7 | ||
|
|
b780228ade | ||
|
|
91c012eff0 | ||
|
|
05d45c6948 | ||
|
|
a2c13fbc48 | ||
|
|
16c7aab99b | ||
|
|
0cf5e309a0 | ||
|
|
b5fbd682f2 | ||
|
|
90e04b0046 | ||
|
|
329f6562c2 | ||
|
|
852bad1ef4 | ||
|
|
aa44a61ab2 | ||
|
|
3e237cb490 | ||
|
|
7b206fb13d | ||
|
|
8f7e898341 | ||
|
|
7499d9f245 | ||
|
|
ba6e6f051a | ||
|
|
d4f4dfb54f | ||
|
|
3e7dedaf99 | ||
|
|
f18cd7ae81 | ||
|
|
0ae4fcf8eb | ||
|
|
d3d1e30c7c | ||
|
|
47d0cf495d | ||
|
|
2e883f9d91 | ||
|
|
af0c30e3ea | ||
|
|
da5a35356a | ||
|
|
d98cc3bb6c | ||
|
|
9697f17b9d | ||
|
|
ce3a9d172d | ||
|
|
4448ddc488 | ||
|
|
b77d3c66ae | ||
|
|
2debdfead5 | ||
|
|
b168c65fa1 | ||
|
|
2b46d171db | ||
|
|
64c131d132 | ||
|
|
678a251858 | ||
|
|
bf9d2f6cb0 | ||
|
|
61f5dcb11e | ||
|
|
e4387d2bd1 | ||
|
|
48906f354e | ||
|
|
1ddc098e43 | ||
|
|
165e6c234c | ||
|
|
1be631f43f | ||
|
|
f5f34c2f50 | ||
|
|
33f3619e98 | ||
|
|
3720b66d00 | ||
|
|
864bbc5472 | ||
|
|
080566a1fd | ||
|
|
d9766037a3 | ||
|
|
02821adc47 | ||
|
|
7b08fd4b7d | ||
|
|
0505c70be2 | ||
|
|
f247038e65 | ||
|
|
d7667e9e6e | ||
|
|
188cb114af | ||
|
|
35c49ababf | ||
|
|
faafe09bd0 | ||
|
|
a0e87c9420 | ||
|
|
d9d39f1812 | ||
|
|
82af225742 | ||
|
|
919f4df1a7 | ||
|
|
71a1698bf2 | ||
|
|
a987dd95b8 | ||
|
|
ab6ab8e65c | ||
|
|
3b28d66410 | ||
|
|
eee46ef2f4 | ||
|
|
3c189b4183 | ||
|
|
fd5ab0edf7 | ||
|
|
420387a7a5 | ||
|
|
fc740f8b6d | ||
|
|
834059ddfa | ||
|
|
5ec2fbcd38 | ||
|
|
2fbf5cd79f | ||
|
|
64ebe95751 | ||
|
|
77109b3a33 | ||
|
|
b43429e684 | ||
|
|
97e39f0744 | ||
|
|
fad592b512 | ||
|
|
565de3c536 | ||
|
|
c802269ea3 | ||
|
|
06268963fb | ||
|
|
2227797691 | ||
|
|
f0888c1fe0 | ||
|
|
eda2e62589 | ||
|
|
494d8ec04c | ||
|
|
bb8088ca0f | ||
|
|
26f4bc39fc | ||
|
|
025e4d9fc6 | ||
|
|
b2774d57ba | ||
|
|
51edfb4ec9 | ||
|
|
79019b1ced | ||
|
|
bc87140b5b | ||
|
|
1c5251069b | ||
|
|
0b6dfefcec | ||
|
|
a9e32c55c0 | ||
|
|
a494228407 | ||
|
|
9932b5fc5c | ||
|
|
966ba44a33 | ||
|
|
62c872eb49 | ||
|
|
434fee2e13 | ||
|
|
d3f829c065 | ||
|
|
83934bdcf3 | ||
|
|
3691add163 | ||
|
|
cc7a9e4607 | ||
|
|
943fa69da6 | ||
|
|
3bef291184 | ||
|
|
7316c53b04 | ||
|
|
5e1d1e1850 | ||
|
|
e52c8e148c | ||
|
|
7eb47f3db1 | ||
|
|
ec59d31d04 | ||
|
|
ddd15b63b2 | ||
|
|
e91b35a53d | ||
|
|
fb4079aa4d | ||
|
|
48b203a134 | ||
|
|
2746fd708f | ||
|
|
684f43d84d | ||
|
|
6b1be52e6b | ||
|
|
de6258d366 | ||
|
|
5e4dbf33be | ||
|
|
b03cb3f3d8 | ||
|
|
e08401a2ec | ||
|
|
0a9e7028ae | ||
|
|
ba0ecc54df | ||
|
|
6920f9dc27 | ||
|
|
ba2547212e | ||
|
|
bbe1a8a5b6 | ||
|
|
c82728f04d | ||
|
|
cc0d33bca7 | ||
|
|
3933ec7dce | ||
|
|
f8c9507612 | ||
|
|
7c5c9ae8fd | ||
|
|
cd00792fe9 | ||
|
|
df390509b2 | ||
|
|
dd6abe9375 | ||
|
|
a3f199d0a3 | ||
|
|
8e3b85ee12 | ||
|
|
e60fbfc865 | ||
|
|
a512488fd7 | ||
|
|
1981d909cf | ||
|
|
ea14f2c98c | ||
|
|
c81becf10d | ||
|
|
1433d040ae | ||
|
|
206b70c837 | ||
|
|
bb857dcef2 | ||
|
|
5568a780a9 | ||
|
|
7c2086967b | ||
|
|
f7fbf4d38c | ||
|
|
0c8cf5c1e0 | ||
|
|
33f2af1c09 | ||
|
|
c9a7e6e4ec | ||
|
|
86bb4ea8f2 | ||
|
|
99c4e83994 | ||
|
|
ca2f5a8160 | ||
|
|
7af304251e | ||
|
|
15f5126296 | ||
|
|
21edd66892 | ||
|
|
3e9d6b6960 | ||
|
|
62b580904b | ||
|
|
c4c4f9d159 | ||
|
|
67a5ec1567 | ||
|
|
c646832bfe | ||
|
|
539d4756f2 | ||
|
|
8714e115ad | ||
|
|
9c38e09ad3 | ||
|
|
5628d7d8b5 | ||
|
|
5f2e8d6062 | ||
|
|
630e336ea0 | ||
|
|
430852736d | ||
|
|
4eeb741358 | ||
|
|
bb1ce4a069 | ||
|
|
5e3e4a225e | ||
|
|
583d05e32a | ||
|
|
2c0914b2ba | ||
|
|
3ebedfe7b0 |
15
.gitlab/issue_templates/Bug.md
Normal file
15
.gitlab/issue_templates/Bug.md
Normal file
@@ -0,0 +1,15 @@
|
||||
### 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:
|
||||
|
||||
```
|
||||
5
.gitlab/issue_templates/Documentation.md
Normal file
5
.gitlab/issue_templates/Documentation.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### Documentation issue
|
||||
<!-- Please, shortly describe the issue in documentation here. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what cryptsetup version you are using. -->
|
||||
5
.gitlab/issue_templates/Feature.md
Normal file
5
.gitlab/issue_templates/Feature.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### New feature description
|
||||
<!-- Please, shortly describe the requested feature here. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what distribution and cryptsetup version you are using. -->
|
||||
@@ -1,7 +1,7 @@
|
||||
language: c
|
||||
|
||||
sudo: required
|
||||
dist: xenial
|
||||
dist: bionic
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
@@ -15,7 +15,6 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- wip-luks2
|
||||
- v2_0_x
|
||||
|
||||
before_install:
|
||||
- uname -a
|
||||
|
||||
1
AUTHORS
1
AUTHORS
@@ -1,3 +1,4 @@
|
||||
Jana Saout <jana@saout.de>
|
||||
Clemens Fruhwirth <clemens@endorphin.org>
|
||||
Milan Broz <gmazyland@gmail.com>
|
||||
Ondrej Kozina <okozina@redhat.com>
|
||||
|
||||
@@ -15,6 +15,8 @@ AM_CPPFLAGS = \
|
||||
AM_CFLAGS = -Wall
|
||||
AM_LDFLAGS =
|
||||
|
||||
LDADD = $(LTLIBINTL) -lm
|
||||
|
||||
tmpfilesddir = @DEFAULT_TMPFILESDIR@
|
||||
|
||||
noinst_LTLIBRARIES =
|
||||
|
||||
54
README.md
54
README.md
@@ -5,8 +5,8 @@ What the ...?
|
||||
**Cryptsetup** is a utility used to conveniently set up disk encryption based
|
||||
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
|
||||
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
|
||||
and **TrueCrypt** (including **VeraCrypt** extension) formats.
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
|
||||
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
|
||||
|
||||
The project also includes a **veritysetup** utility used to conveniently setup
|
||||
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
|
||||
@@ -44,55 +44,25 @@ Download
|
||||
--------
|
||||
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
|
||||
**The latest cryptsetup version is 2.2.0**
|
||||
* [cryptsetup-2.2.0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.xz)
|
||||
* Signature [cryptsetup-2.2.0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.sign)
|
||||
**The latest stable cryptsetup version is 2.3.1**
|
||||
* [cryptsetup-2.3.1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.1.tar.xz)
|
||||
* Signature [cryptsetup-2.3.1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.1.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.2.0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-ReleaseNotes).
|
||||
* [Cryptsetup 2.3.1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.1-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 2.1.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/cryptsetup-2.1.0.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/cryptsetup-2.1.0.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/v2.1.0-ReleaseNotes).
|
||||
* [Version 2.3.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.0-ReleaseNotes).
|
||||
* [Version 2.2.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.2-ReleaseNotes).
|
||||
* [Version 2.0.6](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.6-ReleaseNotes).
|
||||
* [Version 2.0.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.5-ReleaseNotes).
|
||||
* [Version 2.0.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.4-ReleaseNotes).
|
||||
* [Version 2.0.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.3-ReleaseNotes).
|
||||
* [Version 2.0.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.2-ReleaseNotes).
|
||||
* [Version 2.0.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.1.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.1.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.1-ReleaseNotes).
|
||||
* [Version 2.0.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.0.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.0.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.0-ReleaseNotes).
|
||||
* [Version 1.7.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.5-ReleaseNotes).
|
||||
* [Version 1.7.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.4.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.4.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.4-ReleaseNotes).
|
||||
* [Version 1.7.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.3.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.3.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.3-ReleaseNotes).
|
||||
* [Version 1.7.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.2.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.2.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.2-ReleaseNotes).
|
||||
* [Version 1.7.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.1.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.1.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.1-ReleaseNotes).
|
||||
* [Version 1.7.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.0.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.0.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes).
|
||||
|
||||
Source and API docs
|
||||
-------------------
|
||||
|
||||
13
configure.ac
13
configure.ac
@@ -1,9 +1,9 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[2.2.1])
|
||||
AC_INIT([cryptsetup],[2.3.2])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=17:0:5
|
||||
LIBCRYPTSETUP_VERSION_INFO=18:0:6
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
@@ -33,6 +33,7 @@ AC_PROG_MAKE_SET
|
||||
AC_ENABLE_STATIC(no)
|
||||
LT_INIT
|
||||
PKG_PROG_PKG_CONFIG
|
||||
AM_ICONV
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl define PKG_CHECK_VAR for old pkg-config <= 0.28
|
||||
@@ -59,6 +60,12 @@ AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
|
||||
sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h stdint.h)
|
||||
AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
|
||||
[[
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
]])
|
||||
|
||||
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
|
||||
@@ -348,6 +355,8 @@ 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
|
||||
if test "x$have_cookie" = xno; then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libcryptsetup API log example
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libcryptsetup API - using LUKS device example
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
56
docs/v2.2.2-ReleaseNotes
Normal file
56
docs/v2.2.2-ReleaseNotes
Normal file
@@ -0,0 +1,56 @@
|
||||
Cryptsetup 2.2.2 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.1 and 2.2 should upgrade to this version.
|
||||
|
||||
Changes since version 2.2.1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Print error message if a keyslot open failed for a different reason
|
||||
than wrong passwords (for example there is not enough memory).
|
||||
Only an exit code was present in this case.
|
||||
|
||||
* The progress function switches unit sizes (B/s to GiB/s) according
|
||||
to the actual speed. Also, it properly calculates speed in the case
|
||||
of a resumed reencryption operation.
|
||||
|
||||
* The --version now supports short -V short option and better handles
|
||||
common option priorities.
|
||||
|
||||
* If cryptsetup wipes signatures during format actions through blkid,
|
||||
it also prints signature device offsets.
|
||||
|
||||
* Compilation now properly uses LTLIBINTL gettext setting in Makefiles.
|
||||
|
||||
* Device-mapper backend now supports new DM_GET_TARGET_VERSION ioctl
|
||||
(available since Linux kernel 5.4).
|
||||
This should help to detect some kernel/userspace incompatibilities
|
||||
earlier later after a failed device activation.
|
||||
|
||||
* Fixes LUKS2 reencryption on systems without kernel keyring.
|
||||
|
||||
* Fixes unlocking prompt for partitions mapped through loop devices
|
||||
(to properly show the backing device).
|
||||
|
||||
* For LUKS2 decryption, a device is now marked for deferred removal
|
||||
to be automatically deactivated.
|
||||
|
||||
* Reencryption now limits hotzone size to be maximal 1 GiB or 1/4
|
||||
system memory (if lower).
|
||||
|
||||
* Reencryption now retains activation flags during online reencryption.
|
||||
|
||||
* Reencryption now allows LUKS2 device to activate device right after
|
||||
LUKS2 encryption is initialized through optional active device name
|
||||
for cryptsetup reencrypt --encrypt command.
|
||||
This could help with automated encryption during boot.
|
||||
|
||||
NOTE: It means that part of the device is still not encrypted during
|
||||
activation. Use with care!
|
||||
|
||||
* Fixes failure in resize and plain format activation if activated device
|
||||
size was not aligned to underlying logical device size.
|
||||
|
||||
* Fixes conversion to LUKS2 format with detached header if a detached
|
||||
header size was smaller than the expected aligned LUKS1 header size.
|
||||
209
docs/v2.3.0-ReleaseNotes
Normal file
209
docs/v2.3.0-ReleaseNotes
Normal file
@@ -0,0 +1,209 @@
|
||||
Cryptsetup 2.3.0 Release Notes
|
||||
==============================
|
||||
Stable release with new experimental features and bug fixes.
|
||||
|
||||
Cryptsetup 2.3 version introduces support for BitLocker-compatible
|
||||
devices (BITLK format). This format is used in Windows systems,
|
||||
and in combination with a filesystem driver, cryptsetup now provides
|
||||
native read-write access to BitLocker Full Disk Encryption devices.
|
||||
|
||||
The BITLK implementation is based on publicly available information
|
||||
and it is an independent and opensource implementation that allows
|
||||
to access this proprietary disk encryption.
|
||||
|
||||
Changes since version 2.2.2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* BITLK (Windows BitLocker compatible) device access
|
||||
|
||||
BITLK userspace implementation is based on the master thesis and code
|
||||
provided by Vojtech Trefny. Also, thanks to other opensource projects
|
||||
like libbde (that provide alternative approach to decode this format)
|
||||
we were able to verify cryptsetup implementation.
|
||||
|
||||
NOTE: Support for the BITLK device is EXPERIMENTAL and will require
|
||||
a lot of testing. If you get some error message (mainly unsupported
|
||||
metadata in the on-disk header), please help us by submitting an issue
|
||||
to cryptsetup project, so we can fix it. Thank you!
|
||||
|
||||
Cryptsetup supports BITLK activation through passphrase or recovery
|
||||
passphrase for existing devices (BitLocker and Bitlocker to Go).
|
||||
|
||||
Activation through TPM, SmartCard, or any other key protector
|
||||
is not supported. And in some situations, mainly for TPM bind to some
|
||||
PCR registers, it could be even impossible on Linux in the future.
|
||||
|
||||
All metadata (key protectors) are handled read-only, cryptsetup cannot
|
||||
create or modify them. Except for old devices (created in old Vista
|
||||
systems), all format variants should be recognized.
|
||||
|
||||
Data devices can be activated read-write (followed by mounting through
|
||||
the proper filesystem driver). To access filesystem on the decrypted device
|
||||
you need properly installed driver (vfat, NTFS or exFAT).
|
||||
|
||||
Foe AES-XTS, activation is supported on all recent Linux kernels.
|
||||
|
||||
For older AES-CBC encryption, Linux Kernel version 5.3 is required
|
||||
(support for special IV variant); for AES-CBC with Elephant diffuser,
|
||||
Linux Kernel 5.6 is required.
|
||||
|
||||
Please note that CBC variants are legacy, and we provide it only
|
||||
for backward compatibility (to be able to access old drives).
|
||||
|
||||
Cryptsetup command now supports the new "bitlk" format and implement dump,
|
||||
open, status, and close actions.
|
||||
|
||||
To activate a BITLK device, use
|
||||
|
||||
# cryptsetup open --type bitlk <device> <name>
|
||||
or with alias
|
||||
# cryptsetup bitlkOpen <device> <name>
|
||||
|
||||
Then with properly installed fs driver (usually NTFS, vfat or exFAT),
|
||||
you can mount the plaintext device /dev/mapper<name> device as a common
|
||||
filesystem.
|
||||
|
||||
To print metadata information about BITLK device, use
|
||||
# crypotsetup bitlkDump <device>
|
||||
|
||||
To print information about the active device, use
|
||||
# cryptsetup status <name>
|
||||
|
||||
Example (activation of disk image):
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# Recent blkid recognizes BitLocker device,just to verity
|
||||
# blkid bitlocker_xts_ntfs.img
|
||||
bitlocker_xts_ntfs.img: TYPE="BitLocker"
|
||||
|
||||
# Print visible metadata information (on-disk, form the image)
|
||||
# cryptsetup bitlkDump bitlocker_xts_ntfs.img
|
||||
Info for BITLK device bitlocker_xts_ntfs.img.
|
||||
Version: 2
|
||||
GUID: ...
|
||||
Created: Wed Oct 23 17:38:15 2019
|
||||
Description: DESKTOP-xxxxxxx E: 23.10.2019
|
||||
Cipher name: aes
|
||||
Cipher mode: xts-plain64
|
||||
Cipher key: 128 bits
|
||||
|
||||
Keyslots:
|
||||
0: VMK
|
||||
GUID: ...
|
||||
Protection: VMK protected with passphrase
|
||||
Salt: ...
|
||||
Key data size: 44 [bytes]
|
||||
1: VMK
|
||||
GUID: ...
|
||||
Protection: VMK protected with recovery passphrase
|
||||
Salt: ...
|
||||
Key data size: 44 [bytes]
|
||||
2: FVEK
|
||||
Key data size: 44 [bytes]
|
||||
|
||||
# Activation (recovery passphrase works the same as password)
|
||||
# cryptsetup bitlkOpen bitlocker_xts_ntfs.img test -v
|
||||
Enter passphrase for bitlocker_xts_ntfs.img:
|
||||
Command successful.
|
||||
|
||||
# Information about the active device
|
||||
# cryptsetup status test
|
||||
/dev/mapper/test is active.
|
||||
type: BITLK
|
||||
cipher: aes-xts-plain64
|
||||
keysize: 128 bits
|
||||
...
|
||||
|
||||
# Plaintext device should now contain decrypted NTFS filesystem
|
||||
# blkid /dev/mapper/test
|
||||
/dev/mapper/test: UUID="..." TYPE="ntfs"
|
||||
|
||||
# And can be mounted
|
||||
# mount /dev/mapper/test /mnt/tst
|
||||
|
||||
# Deactivation
|
||||
# umount /mnt/tst
|
||||
# cryptsetup close test
|
||||
|
||||
* Veritysetup now supports activation with additional PKCS7 signature
|
||||
of root hash through --root-hash-signature option.
|
||||
The signature uses an in-kernel trusted key to validate the signature
|
||||
of the root hash during activation. This option requires Linux kernel
|
||||
5.4 with DM_VERITY_VERIFY_ROOTHASH_SIG option.
|
||||
|
||||
Verity devices activated with signature now has a special flag
|
||||
(with signature) active in device status (veritysetup status <name>).
|
||||
|
||||
Usage:
|
||||
# veritysetup open <data_device> name <hash_device> <root_hash> \
|
||||
--root-hash-signature=<roothash_p7_sig_file>
|
||||
|
||||
* Integritysetup now calculates hash integrity size according to algorithm
|
||||
instead of requiring an explicit tag size.
|
||||
|
||||
Previously, when integritysetup formats a device with hash or
|
||||
HMAC integrity checksums, it required explicitly tag size entry from
|
||||
a user (or used default value).
|
||||
This led to confusion and unexpected shortened tag sizes.
|
||||
|
||||
Now, libcryptsetup calculates tag size according to real hash output.
|
||||
Tag size can also be specified, then it warns if these values differ.
|
||||
|
||||
* Integritysetup now supports fixed padding for dm-integrity devices.
|
||||
|
||||
There was an in-kernel bug that wasted a lot of space when using metadata
|
||||
areas for integrity-protected devices if a larger sector size than
|
||||
512 bytes was used.
|
||||
This problem affects both stand-alone dm-integrity and also LUKS2 with
|
||||
authenticated encryption and larger sector size.
|
||||
|
||||
The new extension to dm-integrity superblock is needed, so devices
|
||||
with the new optimal padding cannot be activated on older systems.
|
||||
|
||||
Integritysetup/Cryptsetup will use new padding automatically if it
|
||||
detects the proper kernel. To create a compatible device with
|
||||
the old padding, use --integrity-legacy-padding option.
|
||||
|
||||
* A lot of fixes to online LUKS2 reecryption.
|
||||
|
||||
* Add crypt_resume_by_volume_key() function to libcryptsetup.
|
||||
If a user has a volume key available, the LUKS device can be resumed
|
||||
directly using the provided volume key.
|
||||
No keyslot derivation is needed, only the key digest is checked.
|
||||
|
||||
* Implement active device suspend info.
|
||||
Add CRYPT_ACTIVATE_SUSPENDED bit to crypt_get_active_device() flags
|
||||
that informs the caller that device is suspended (luksSuspend).
|
||||
|
||||
* Allow --test-passphrase for a detached header.
|
||||
Before this fix, we required a data device specified on the command
|
||||
line even though it was not necessary for the passphrase check.
|
||||
|
||||
* Allow --key-file option in legacy offline encryption.
|
||||
The option was ignored for LUKS1 encryption initialization.
|
||||
|
||||
* Export memory safe functions.
|
||||
To make developing of some extensions simpler, we now export
|
||||
functions to handle memory with proper wipe on deallocation.
|
||||
|
||||
* Fail crypt_keyslot_get_pbkdf for inactive LUKS1 keyslot.
|
||||
|
||||
Libcryptsetup API extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The libcryptsetup API is backward compatible for existing symbols.
|
||||
|
||||
New symbols
|
||||
crypt_set_compatibility
|
||||
crypt_get_compatibility;
|
||||
crypt_resume_by_volume_key;
|
||||
crypt_activate_by_signed_key;
|
||||
crypt_safe_alloc;
|
||||
crypt_safe_realloc;
|
||||
crypt_safe_free;
|
||||
crypt_safe_memzero;
|
||||
|
||||
New defines introduced :
|
||||
CRYPT_BITLK "BITLK" - BITLK (BitLocker-compatible mode
|
||||
CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING - dm-integrity legacy padding
|
||||
CRYPT_VERITY_ROOT_HASH_SIGNATURE - dm-verity root hash signature
|
||||
CRYPT_ACTIVATE_SUSPENDED - device suspended info flag
|
||||
45
docs/v2.3.1-ReleaseNotes
Normal file
45
docs/v2.3.1-ReleaseNotes
Normal file
@@ -0,0 +1,45 @@
|
||||
Cryptsetup 2.3.1 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.x should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.0
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Support VeraCrypt 128 bytes passwords.
|
||||
VeraCrypt now allows passwords of maximal length 128 bytes
|
||||
(compared to legacy TrueCrypt where it was limited by 64 bytes).
|
||||
|
||||
* Strip extra newline from BitLocker recovery keys
|
||||
There might be a trailing newline added by the text editor when
|
||||
the recovery passphrase was passed using the --key-file option.
|
||||
|
||||
* Detect separate libiconv library.
|
||||
It should fix compilation issues on distributions with iconv
|
||||
implemented in a separate library.
|
||||
|
||||
* Various fixes and workarounds to build on old Linux distributions.
|
||||
|
||||
* Split lines with hexadecimal digest printing for large key-sizes.
|
||||
|
||||
* Do not wipe the device with no integrity profile.
|
||||
With --integrity none we performed useless full device wipe.
|
||||
|
||||
* Workaround for dm-integrity kernel table bug.
|
||||
Some kernels show an invalid dm-integrity mapping table
|
||||
if superblock contains the "recalculate" bit. This causes
|
||||
integritysetup to not recognize the dm-integrity device.
|
||||
Integritysetup now specifies kernel options such a way that
|
||||
even on unpatched kernels mapping table is correct.
|
||||
|
||||
* Print error message if LUKS1 keyslot cannot be processed.
|
||||
If the crypto backend is missing support for hash algorithms
|
||||
used in PBKDF2, the error message was not visible.
|
||||
|
||||
* Properly align LUKS2 keyslots area on conversion.
|
||||
If the LUKS1 payload offset (data offset) is not aligned
|
||||
to 4 KiB boundary, new LUKS2 keyslots area in now aligned properly.
|
||||
|
||||
* Validate LUKS2 earlier on conversion to not corrupt the device
|
||||
if binary keyslots areas metadata are not correct.
|
||||
42
docs/v2.3.2-ReleaseNotes
Normal file
42
docs/v2.3.2-ReleaseNotes
Normal file
@@ -0,0 +1,42 @@
|
||||
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.
|
||||
@@ -22,7 +22,8 @@ libcryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
-I $(top_srcdir)/lib/loopaes \
|
||||
-I $(top_srcdir)/lib/verity \
|
||||
-I $(top_srcdir)/lib/tcrypt \
|
||||
-I $(top_srcdir)/lib/integrity
|
||||
-I $(top_srcdir)/lib/integrity \
|
||||
-I $(top_srcdir)/lib/bitlk
|
||||
|
||||
libcryptsetup_la_DEPENDENCIES = libutils_io.la libcrypto_backend.la lib/libcryptsetup.sym
|
||||
|
||||
@@ -39,6 +40,7 @@ libcryptsetup_la_LIBADD = \
|
||||
@LIBARGON2_LIBS@ \
|
||||
@JSON_C_LIBS@ \
|
||||
@BLKID_LIBS@ \
|
||||
$(LTLIBICONV) \
|
||||
libcrypto_backend.la \
|
||||
libutils_io.la
|
||||
|
||||
@@ -64,6 +66,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/utils_device_locking.c \
|
||||
lib/utils_device_locking.h \
|
||||
lib/utils_pbkdf.c \
|
||||
lib/utils_safe_memory.c \
|
||||
lib/utils_storage_wrappers.c \
|
||||
lib/utils_storage_wrappers.h \
|
||||
lib/libdevmapper.c \
|
||||
@@ -74,7 +77,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/base64.h \
|
||||
lib/base64.c \
|
||||
lib/integrity/integrity.h \
|
||||
lib/integrity/integrity.c \
|
||||
lib/integrity/integrity.c \
|
||||
lib/loopaes/loopaes.h \
|
||||
lib/loopaes/loopaes.c \
|
||||
lib/tcrypt/tcrypt.h \
|
||||
@@ -90,7 +93,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/verity/verity.h \
|
||||
lib/verity/rs_encode_char.c \
|
||||
lib/verity/rs_decode_char.c \
|
||||
lib/verity/rs.h \
|
||||
lib/verity/rs.h \
|
||||
lib/luks2/luks2_disk_metadata.c \
|
||||
lib/luks2/luks2_json_format.c \
|
||||
lib/luks2/luks2_json_metadata.c \
|
||||
@@ -107,4 +110,6 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/luks2/luks2_internal.h \
|
||||
lib/luks2/luks2.h \
|
||||
lib/utils_blkid.c \
|
||||
lib/utils_blkid.h
|
||||
lib/utils_blkid.h \
|
||||
lib/bitlk/bitlk.h \
|
||||
lib/bitlk/bitlk.c
|
||||
|
||||
1204
lib/bitlk/bitlk.c
Normal file
1204
lib/bitlk/bitlk.c
Normal file
File diff suppressed because it is too large
Load Diff
130
lib/bitlk/bitlk.h
Normal file
130
lib/bitlk/bitlk.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* BITLK (BitLocker-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2019-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2019-2020 Milan Broz
|
||||
* Copyright (C) 2019-2020 Vojtech Trefny
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this file; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTSETUP_BITLK_H
|
||||
#define _CRYPTSETUP_BITLK_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct device;
|
||||
|
||||
#define BITLK_NONCE_SIZE 12
|
||||
#define BITLK_SALT_SIZE 16
|
||||
#define BITLK_VMK_MAC_TAG_SIZE 16
|
||||
|
||||
#define BITLK_STATE_NORMAL 0x0004
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENCRYPTION_TYPE_NORMAL = 0,
|
||||
BITLK_ENCRYPTION_TYPE_EOW,
|
||||
BITLK_ENCRYPTION_TYPE_UNKNOWN,
|
||||
} BITLKEncryptionType;
|
||||
|
||||
typedef enum {
|
||||
BITLK_PROTECTION_CLEAR_KEY = 0,
|
||||
BITLK_PROTECTION_TPM,
|
||||
BITLK_PROTECTION_STARTUP_KEY,
|
||||
BITLK_PROTECTION_TPM_PIN,
|
||||
BITLK_PROTECTION_RECOVERY_PASSPHRASE,
|
||||
BITLK_PROTECTION_PASSPHRASE,
|
||||
BITLK_PROTECTION_SMART_CARD,
|
||||
BITLK_PROTECTION_UNKNOWN,
|
||||
} BITLKVMKProtection;
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENTRY_TYPE_PROPERTY = 0x0000,
|
||||
BITLK_ENTRY_TYPE_VMK = 0x0002,
|
||||
BITLK_ENTRY_TYPE_FVEK = 0x0003,
|
||||
BITLK_ENTRY_TYPE_STARTUP_KEY = 0x0006,
|
||||
BITLK_ENTRY_TYPE_DESCRIPTION = 0x0007,
|
||||
BITLK_ENTRY_TYPE_VOLUME_HEADER = 0x000f,
|
||||
} BITLKFVEEntryType;
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENTRY_VALUE_ERASED = 0x0000,
|
||||
BITLK_ENTRY_VALUE_KEY = 0x0001,
|
||||
BITLK_ENTRY_VALUE_STRING = 0x0002,
|
||||
BITLK_ENTRY_VALUE_STRETCH_KEY = 0x0003,
|
||||
BITLK_ENTRY_VALUE_USE_KEY = 0x0004,
|
||||
BITLK_ENTRY_VALUE_ENCRYPTED_KEY = 0x0005,
|
||||
BITLK_ENTRY_VALUE_TPM_KEY = 0x0006,
|
||||
BITLK_ENTRY_VALUE_VALIDATION = 0x0007,
|
||||
BITLK_ENTRY_VALUE_VMK = 0x0008,
|
||||
BITLK_ENTRY_VALUE_EXTERNAL_KEY = 0x0009,
|
||||
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
|
||||
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
|
||||
} BITLKFVEEntryValue;
|
||||
|
||||
struct bitlk_vmk {
|
||||
char *guid;
|
||||
char *name;
|
||||
BITLKVMKProtection protection;
|
||||
uint8_t salt[BITLK_SALT_SIZE];
|
||||
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
|
||||
uint8_t nonce[BITLK_NONCE_SIZE];
|
||||
struct volume_key *vk;
|
||||
struct bitlk_vmk *next;
|
||||
};
|
||||
|
||||
struct bitlk_fvek {
|
||||
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
|
||||
uint8_t nonce[BITLK_NONCE_SIZE];
|
||||
struct volume_key *vk;
|
||||
};
|
||||
|
||||
struct bitlk_metadata {
|
||||
bool togo;
|
||||
bool state;
|
||||
BITLKEncryptionType type;
|
||||
const char *cipher;
|
||||
const char *cipher_mode;
|
||||
uint16_t key_size;
|
||||
char *guid;
|
||||
uint64_t creation_time;
|
||||
char *description;
|
||||
uint64_t metadata_offset[3];
|
||||
uint32_t metadata_version;
|
||||
uint64_t volume_header_offset;
|
||||
uint64_t volume_header_size;
|
||||
struct bitlk_vmk *vmks;
|
||||
struct bitlk_fvek *fvek;
|
||||
};
|
||||
|
||||
int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params);
|
||||
|
||||
int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params);
|
||||
|
||||
int BITLK_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
const struct bitlk_metadata *params,
|
||||
uint32_t flags);
|
||||
|
||||
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek);
|
||||
void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk);
|
||||
void BITLK_bitlk_metadata_free(struct bitlk_metadata *params);
|
||||
|
||||
#endif
|
||||
@@ -2,8 +2,8 @@
|
||||
* cryptsetup plain device helper functions
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Argon2 PBKDF2 library wrapper
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Cipher performance check
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 Milan Broz
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,6 +23,10 @@
|
||||
#include <time.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is not simulating storage, so using disk block causes extreme overhead.
|
||||
* Let's use some fixed block size where results are more reliable...
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel cipher generic utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 Milan Broz
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -51,6 +51,7 @@ 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 }
|
||||
};
|
||||
|
||||
@@ -72,7 +73,13 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
|
||||
{
|
||||
const struct cipher_alg *ca = _get_alg(name, mode);
|
||||
|
||||
return ca ? ca->blocksize : -EINVAL;
|
||||
if (!ca)
|
||||
return -EINVAL;
|
||||
|
||||
if (mode && !strcasecmp(mode, "ecb"))
|
||||
return 0;
|
||||
|
||||
return ca->blocksize;
|
||||
}
|
||||
|
||||
int crypt_cipher_wrapped_key(const char *name, const char *mode)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -26,13 +26,12 @@
|
||||
#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(struct crypt_device *ctx);
|
||||
int crypt_backend_init(void);
|
||||
void crypt_backend_destroy(void);
|
||||
|
||||
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
|
||||
@@ -119,6 +118,12 @@ int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t iv_offset,
|
||||
|
||||
bool crypt_storage_kernel_only(struct crypt_storage *ctx);
|
||||
|
||||
/* Temporary Bitlk helper */
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length);
|
||||
|
||||
/* Memzero helper (memset on stack can be optimized out) */
|
||||
static inline void crypt_backend_memzero(void *s, size_t n)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -55,5 +55,9 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length);
|
||||
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx);
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length);
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_INTERNAL_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation (skcipher)
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -40,6 +40,10 @@
|
||||
#define SOL_ALG 279
|
||||
#endif
|
||||
|
||||
#ifndef ALG_SET_AEAD_AUTHSIZE
|
||||
#define ALG_SET_AEAD_AUTHSIZE 5
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ciphers
|
||||
*
|
||||
@@ -49,7 +53,7 @@
|
||||
*/
|
||||
static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
const void *key, size_t key_length,
|
||||
struct sockaddr_alg *sa)
|
||||
size_t tag_length, struct sockaddr_alg *sa)
|
||||
{
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
@@ -71,6 +75,11 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, tag_length) < 0) {
|
||||
crypt_cipher_destroy_kernel(ctx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->opfd = accept(ctx->tfmfd, NULL, 0);
|
||||
if (ctx->opfd < 0) {
|
||||
crypt_cipher_destroy_kernel(ctx);
|
||||
@@ -93,12 +102,13 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
|
||||
|
||||
return _crypt_cipher_init(ctx, key, key_length, &sa);
|
||||
return _crypt_cipher_init(ctx, key, key_length, 0, &sa);
|
||||
}
|
||||
|
||||
/* The in/out should be aligned to page boundary */
|
||||
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *in, size_t in_length,
|
||||
char *out, size_t out_length,
|
||||
const char *iv, size_t iv_length,
|
||||
uint32_t direction)
|
||||
{
|
||||
@@ -109,7 +119,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
uint32_t *type;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void*)(uintptr_t)in,
|
||||
.iov_len = length,
|
||||
.iov_len = in_length,
|
||||
};
|
||||
int iv_msg_size = iv ? CMSG_SPACE(sizeof(*alg_iv) + iv_length) : 0;
|
||||
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
|
||||
@@ -120,7 +130,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
if (!in || !out || !length)
|
||||
if (!in || !out || !in_length)
|
||||
return -EINVAL;
|
||||
|
||||
if ((!iv && iv_length) || (iv && !iv_length))
|
||||
@@ -151,13 +161,13 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
}
|
||||
|
||||
len = sendmsg(ctx->opfd, &msg, 0);
|
||||
if (len != (ssize_t)length) {
|
||||
if (len != (ssize_t)(in_length)) {
|
||||
r = -EIO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
len = read(ctx->opfd, out, length);
|
||||
if (len != (ssize_t)length)
|
||||
len = read(ctx->opfd, out, out_length);
|
||||
if (len != (ssize_t)out_length)
|
||||
r = -EIO;
|
||||
bad:
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
@@ -168,7 +178,7 @@ int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, length, out, length,
|
||||
iv, iv_length, ALG_OP_ENCRYPT);
|
||||
}
|
||||
|
||||
@@ -176,7 +186,7 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, length, out, length,
|
||||
iv, iv_length, ALG_OP_DECRYPT);
|
||||
}
|
||||
|
||||
@@ -243,13 +253,56 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
memset(key, 0xab, key_length);
|
||||
*key = 0xef;
|
||||
|
||||
r = _crypt_cipher_init(&c, key, key_length, &sa);
|
||||
r = _crypt_cipher_init(&c, key, key_length, 0, &sa);
|
||||
crypt_cipher_destroy_kernel(&c);
|
||||
free(key);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
struct crypt_cipher_kernel c;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "aead",
|
||||
.salg_name = "ccm(aes)",
|
||||
};
|
||||
int r;
|
||||
char buffer[128], ccm_iv[16];
|
||||
|
||||
if (length + tag_length > sizeof(buffer))
|
||||
return -EINVAL;
|
||||
|
||||
if (iv_length > sizeof(ccm_iv) - 2)
|
||||
return -EINVAL;
|
||||
|
||||
r = _crypt_cipher_init(&c, key, key_length, tag_length, &sa);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
memcpy(buffer, in, length);
|
||||
memcpy(buffer + length, tag, tag_length);
|
||||
|
||||
/* CCM IV - RFC3610 */
|
||||
memset(ccm_iv, 0, sizeof(ccm_iv));
|
||||
ccm_iv[0] = 15 - iv_length - 1;
|
||||
memcpy(ccm_iv + 1, iv, iv_length);
|
||||
memset(ccm_iv + 1 + iv_length, 0, ccm_iv[0] + 1);
|
||||
iv_length = sizeof(ccm_iv);
|
||||
|
||||
r = _crypt_cipher_crypt(&c, buffer, length + tag_length, out, length,
|
||||
ccm_iv, iv_length, ALG_OP_DECRYPT);
|
||||
|
||||
crypt_cipher_destroy_kernel(&c);
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#else /* ENABLE_AF_ALG */
|
||||
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length)
|
||||
@@ -280,4 +333,11 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
/* Cannot check, expect success. */
|
||||
return 0;
|
||||
}
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* GCRYPT crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -89,7 +89,7 @@ static void crypt_hash_test_whirlpool_bug(void)
|
||||
crypto_backend_whirlpool_bug = 1;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -479,3 +479,43 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return ctx->use_kernel;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
#ifdef GCRY_CCM_BLOCK_LEN
|
||||
gcry_cipher_hd_t hd;
|
||||
uint64_t l[3];
|
||||
int r = -EINVAL;
|
||||
|
||||
if (gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (gcry_cipher_setkey(hd, key, key_length))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_setiv(hd, iv, iv_length))
|
||||
goto out;
|
||||
|
||||
l[0] = length;
|
||||
l[1] = 0;
|
||||
l[2] = tag_length;
|
||||
if (gcry_cipher_ctl(hd, GCRYCTL_SET_CCM_LENGTHS, l, sizeof(l)))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_decrypt(hd, out, length, in, length))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_checktag(hd, tag, tag_length))
|
||||
goto out;
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
gcry_cipher_close(hd);
|
||||
return r;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -110,7 +110,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
struct utsname uts;
|
||||
struct sockaddr_alg sa = {
|
||||
@@ -392,3 +392,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Nettle crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -213,7 +213,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -433,3 +433,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* NSS crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -75,7 +75,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -381,3 +381,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* OPENSSL crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <openssl/rand.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
|
||||
struct crypt_hash {
|
||||
@@ -119,7 +121,7 @@ static const char *openssl_backend_version(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -505,3 +507,40 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return ctx->use_kernel;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
#ifdef EVP_CTRL_CCM_SET_IVLEN
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int len = 0, r = -EINVAL;
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL) != 1)
|
||||
goto out;
|
||||
|
||||
//EVP_CIPHER_CTX_key_length(ctx)
|
||||
//EVP_CIPHER_CTX_iv_length(ctx)
|
||||
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_length, NULL) != 1)
|
||||
goto out;
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_length, CONST_CAST(void*)tag) != 1)
|
||||
goto out;
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, (const unsigned char*)iv) != 1)
|
||||
goto out;
|
||||
|
||||
if (EVP_DecryptUpdate(ctx, (unsigned char*)out, &len, (const unsigned char*)in, length) == 1)
|
||||
r = 0;
|
||||
out:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return r;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generic wrapper for storage encryption modes and Initial Vectors
|
||||
* (reimplementation of some functions from Linux dm-crypt kernel)
|
||||
*
|
||||
* Copyright (C) 2014-2019 Milan Broz
|
||||
* Copyright (C) 2014-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* PBKDF performance check
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2016-2019 Ondrej Mosnacek
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
* Copyright (C) 2016-2020 Ondrej Mosnacek
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -27,6 +27,10 @@
|
||||
#include <sys/resource.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
#define BENCH_MIN_MS 250
|
||||
#define BENCH_MIN_MS_FAST 10
|
||||
#define BENCH_PERCENT_ATLEAST 95
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Integrity volume handling
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "integrity.h"
|
||||
@@ -41,8 +40,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
|
||||
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
|
||||
(sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
|
||||
sb->version != SB_VERSION_3)) {
|
||||
sb->version < SB_VERSION_1 || sb->version > SB_VERSION_4) {
|
||||
log_std(cd, "No integrity superblock detected on %s.\n",
|
||||
device_path(device));
|
||||
r = -EINVAL;
|
||||
@@ -58,7 +56,9 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params)
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags)
|
||||
{
|
||||
struct superblock sb;
|
||||
int r;
|
||||
@@ -70,6 +70,9 @@ int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *pa
|
||||
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
|
||||
params->tag_size = sb.integrity_tag_size;
|
||||
|
||||
if (flags)
|
||||
*flags = sb.flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -92,10 +95,11 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs
|
||||
if (sb.version == SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING))
|
||||
log_std(cd, "recalc_sector %" PRIu64 "\n", sb.recalc_sector);
|
||||
log_std(cd, "log2_blocks_per_bitmap %u\n", sb.log2_blocks_per_bitmap_bit);
|
||||
log_std(cd, "flags %s%s%s\n",
|
||||
log_std(cd, "flags %s%s%s%s\n",
|
||||
sb.flags & SB_FLAG_HAVE_JOURNAL_MAC ? "have_journal_mac " : "",
|
||||
sb.flags & SB_FLAG_RECALCULATING ? "recalculating " : "",
|
||||
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "");
|
||||
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "",
|
||||
sb.flags & SB_FLAG_FIXED_PADDING ? "fix_padding " : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -137,6 +141,27 @@ int INTEGRITY_key_size(struct crypt_device *cd, const char *integrity)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return hash or hmac(hash) size, if known */
|
||||
int INTEGRITY_hash_tag_size(const char *integrity)
|
||||
{
|
||||
char hash[MAX_CIPHER_LEN];
|
||||
int r;
|
||||
|
||||
if (!integrity)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(integrity, "crc32") || !strcmp(integrity, "crc32c"))
|
||||
return 4;
|
||||
|
||||
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
|
||||
if (r == 1)
|
||||
r = crypt_hash_size(hash);
|
||||
else
|
||||
r = crypt_hash_size(integrity);
|
||||
|
||||
return r < 0 ? 0 : r;
|
||||
}
|
||||
|
||||
int INTEGRITY_tag_size(struct crypt_device *cd,
|
||||
const char *integrity,
|
||||
const char *cipher,
|
||||
@@ -187,7 +212,7 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t flags)
|
||||
uint32_t flags, uint32_t sb_flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -198,12 +223,16 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
/* Workaround for kernel dm-integrity table bug */
|
||||
if (sb_flags & SB_FLAG_RECALCULATING)
|
||||
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
|
||||
r = INTEGRITY_data_sectors(cd, crypt_metadata_device(cd),
|
||||
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dm_integrity_target_set(&dmd->segment, 0, dmd->size,
|
||||
return dm_integrity_target_set(cd, &dmd->segment, 0, dmd->size,
|
||||
crypt_metadata_device(cd), crypt_data_device(cd),
|
||||
crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
|
||||
crypt_get_sector_size(cd), vk, journal_crypt_key,
|
||||
@@ -213,7 +242,8 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd)
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t sb_flags)
|
||||
{
|
||||
int r;
|
||||
uint32_t dmi_flags;
|
||||
@@ -238,7 +268,13 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
|
||||
r = dm_create_device(cd, name, type, dmd);
|
||||
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-integrity mapping."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (r < 0 && (sb_flags & SB_FLAG_FIXED_PADDING) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
!(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel does not support dm-integrity fixed metadata alignment."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -251,15 +287,16 @@ int INTEGRITY_activate(struct crypt_device *cd,
|
||||
struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint32_t flags)
|
||||
uint32_t flags, uint32_t sb_flags)
|
||||
{
|
||||
struct crypt_dm_active_device dmd = {};
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key, journal_mac_key, &dmd, flags);
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key,
|
||||
journal_mac_key, &dmd, flags, sb_flags);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd);
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd, sb_flags);
|
||||
dm_targets_free(cd, &dmd);
|
||||
return r;
|
||||
}
|
||||
@@ -289,7 +326,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
if (params && params->integrity_key_size)
|
||||
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
|
||||
|
||||
r = dm_integrity_target_set(tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||
crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
|
||||
crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
|
||||
journal_crypt_key, journal_mac_key, params);
|
||||
@@ -303,7 +340,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
|
||||
r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL);
|
||||
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-integrity mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Integrity header definition
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -34,10 +34,12 @@ struct crypt_dm_active_device;
|
||||
#define SB_VERSION_1 1
|
||||
#define SB_VERSION_2 2
|
||||
#define SB_VERSION_3 3
|
||||
#define SB_VERSION_4 4
|
||||
|
||||
#define SB_FLAG_HAVE_JOURNAL_MAC (1 << 0)
|
||||
#define SB_FLAG_RECALCULATING (1 << 1) /* V2 only */
|
||||
#define SB_FLAG_DIRTY_BITMAP (1 << 2) /* V3 only */
|
||||
#define SB_FLAG_FIXED_PADDING (1 << 3) /* V4 only */
|
||||
|
||||
struct superblock {
|
||||
uint8_t magic[8];
|
||||
@@ -53,7 +55,9 @@ struct superblock {
|
||||
uint64_t recalc_sector; /* V2 only */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params);
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags);
|
||||
|
||||
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset);
|
||||
|
||||
@@ -66,6 +70,7 @@ int INTEGRITY_tag_size(struct crypt_device *cd,
|
||||
const char *integrity,
|
||||
const char *cipher,
|
||||
const char *cipher_mode);
|
||||
int INTEGRITY_hash_tag_size(const char *integrity);
|
||||
|
||||
int INTEGRITY_format(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
@@ -78,7 +83,7 @@ int INTEGRITY_activate(struct crypt_device *cd,
|
||||
struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint32_t flags);
|
||||
uint32_t flags, uint32_t sb_flags);
|
||||
|
||||
int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
@@ -86,10 +91,11 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t flags);
|
||||
uint32_t flags, uint32_t sb_flags);
|
||||
|
||||
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd);
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t sb_flags);
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "bitops.h"
|
||||
@@ -77,6 +78,10 @@
|
||||
*_py = NULL; \
|
||||
} while (0)
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
struct crypt_device;
|
||||
struct luks2_reenc_context;
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -414,6 +414,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
|
||||
#define CRYPT_TCRYPT "TCRYPT"
|
||||
/** INTEGRITY dm-integrity device */
|
||||
#define CRYPT_INTEGRITY "INTEGRITY"
|
||||
/** BITLK (BitLocker-compatible mode) */
|
||||
#define CRYPT_BITLK "BITLK"
|
||||
|
||||
/** LUKS any version */
|
||||
#define CRYPT_LUKS NULL
|
||||
@@ -505,6 +507,8 @@ struct crypt_params_verity {
|
||||
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
|
||||
/** Create hash - format hash device */
|
||||
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
|
||||
/** Root hash signature required for activation */
|
||||
#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (1 << 3)
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -629,6 +633,26 @@ int crypt_format(struct crypt_device *cd,
|
||||
size_t volume_key_size,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* Set format compatibility flags.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param flags CRYPT_COMPATIBILITY_* flags
|
||||
*/
|
||||
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags);
|
||||
|
||||
/**
|
||||
* Get compatibility flags.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
* @returns compatibility flags
|
||||
*/
|
||||
uint32_t crypt_get_compatibility(struct crypt_device *cd);
|
||||
|
||||
/** dm-integrity device uses less effective (legacy) padding (old kernels) */
|
||||
#define CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING (1 << 0)
|
||||
|
||||
/**
|
||||
* Convert to new type for already existing device.
|
||||
*
|
||||
@@ -828,6 +852,20 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size);
|
||||
/**
|
||||
* Resume crypt device using provided volume key.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to resume
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of volume_key
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*/
|
||||
int crypt_resume_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -1061,6 +1099,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF (1 << 19)
|
||||
/** dm-integrity: direct writes, use bitmap to track dirty sectors */
|
||||
#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (1 << 20)
|
||||
/** device is suspended (key should be wiped from memory), output only */
|
||||
#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -1252,6 +1292,31 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
size_t volume_key_size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate VERITY device using provided key and optional signature).
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to create
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param signature buffer with signature for the key
|
||||
* @param signature_size bsize of signature buffer
|
||||
* @param flags activation flags
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
* @note For VERITY the volume key means root hash required for activation.
|
||||
* Because kernel dm-verity is always read only, you have to provide
|
||||
* CRYPT_ACTIVATE_READONLY flag always.
|
||||
*/
|
||||
int crypt_activate_by_signed_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate device using passphrase stored in kernel keyring.
|
||||
*
|
||||
@@ -1322,6 +1387,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
|
||||
*
|
||||
* @note For TCRYPT cipher chain is the volume key concatenated
|
||||
* for all ciphers in chain.
|
||||
* @note For VERITY the volume key means root hash used for activation.
|
||||
*/
|
||||
int crypt_volume_key_get(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -2251,6 +2317,53 @@ crypt_reencrypt_info crypt_reencrypt_status(struct crypt_device *cd,
|
||||
struct crypt_params_reencrypt *params);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup crypt-memory Safe memory helpers functions
|
||||
* @addtogroup crypt-memory
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate safe memory (content is safely wiped on deallocation).
|
||||
*
|
||||
* @param size size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void *crypt_safe_alloc(size_t size);
|
||||
|
||||
/**
|
||||
* Release safe memory, content is safely wiped
|
||||
* The pointer must be allocated with @link crypt_safe_alloc @endlink
|
||||
*
|
||||
* @param data pointer to memory to be deallocated
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void crypt_safe_free(void *data);
|
||||
|
||||
/**
|
||||
* Reallocate safe memory (content is copied and safely wiped on deallocation).
|
||||
*
|
||||
* @param data pointer to memory to be deallocated
|
||||
* @param size new size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
/**
|
||||
* Safe clear memory area (compile should not compile this call out).
|
||||
*
|
||||
* @param data pointer to memory to cleared
|
||||
* @param size new size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocate memory or @e NULL.
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,9 @@ CRYPTSETUP_2.0 {
|
||||
crypt_set_label;
|
||||
crypt_set_data_device;
|
||||
|
||||
crypt_set_compatibility;
|
||||
crypt_get_compatibility;
|
||||
|
||||
crypt_memory_lock;
|
||||
crypt_metadata_locking;
|
||||
crypt_format;
|
||||
@@ -24,6 +27,7 @@ CRYPTSETUP_2.0 {
|
||||
crypt_resume_by_keyfile;
|
||||
crypt_resume_by_keyfile_offset;
|
||||
crypt_resume_by_keyfile_device_offset;
|
||||
crypt_resume_by_volume_key;
|
||||
crypt_free;
|
||||
|
||||
crypt_keyslot_add_by_passphrase;
|
||||
@@ -55,6 +59,7 @@ CRYPTSETUP_2.0 {
|
||||
crypt_activate_by_keyfile_offset;
|
||||
crypt_activate_by_keyfile_device_offset;
|
||||
crypt_activate_by_volume_key;
|
||||
crypt_activate_by_signed_key;
|
||||
crypt_activate_by_keyring;
|
||||
crypt_deactivate;
|
||||
crypt_deactivate_by_name;
|
||||
@@ -118,6 +123,11 @@ CRYPTSETUP_2.0 {
|
||||
crypt_reencrypt_init_by_keyring;
|
||||
crypt_reencrypt;
|
||||
crypt_reencrypt_status;
|
||||
|
||||
crypt_safe_alloc;
|
||||
crypt_safe_realloc;
|
||||
crypt_safe_free;
|
||||
crypt_safe_memzero;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libdevmapper.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -47,6 +46,7 @@
|
||||
#define DM_INTEGRITY_TARGET "integrity"
|
||||
#define DM_LINEAR_TARGET "linear"
|
||||
#define DM_ERROR_TARGET "error"
|
||||
#define DM_ZERO_TARGET "zero"
|
||||
#define RETRY_COUNT 5
|
||||
|
||||
/* Set if DM target versions were probed */
|
||||
@@ -168,6 +168,12 @@ static void _dm_set_crypt_compat(struct crypt_device *cd,
|
||||
_dm_flags |= DM_CAPI_STRING_SUPPORTED;
|
||||
}
|
||||
|
||||
if (_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_BITLK_EBOIV_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_BITLK_ELEPHANT_SUPPORTED;
|
||||
|
||||
_dm_crypt_checked = true;
|
||||
}
|
||||
|
||||
@@ -196,6 +202,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
|
||||
_dm_flags |= DM_VERITY_FEC_SUPPORTED;
|
||||
}
|
||||
|
||||
if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
|
||||
_dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
|
||||
|
||||
_dm_verity_checked = true;
|
||||
}
|
||||
|
||||
@@ -218,9 +227,48 @@ 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;
|
||||
}
|
||||
|
||||
/* We use this for loading target module */
|
||||
static void _dm_check_target(dm_target_type target_type)
|
||||
{
|
||||
#if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
|
||||
struct dm_task *dmt;
|
||||
const char *target_name = NULL;
|
||||
|
||||
if (!(_dm_flags & DM_GET_TARGET_VERSION_SUPPORTED))
|
||||
return;
|
||||
|
||||
if (target_type == DM_CRYPT)
|
||||
target_name = DM_CRYPT_TARGET;
|
||||
else if (target_type == DM_VERITY)
|
||||
target_name = DM_VERITY_TARGET;
|
||||
else if (target_type == DM_INTEGRITY)
|
||||
target_name = DM_INTEGRITY_TARGET;
|
||||
else
|
||||
return;
|
||||
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_GET_TARGET_VERSION)))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_set_name(dmt, target_name))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_run(dmt))
|
||||
goto out;
|
||||
out:
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_type)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
@@ -232,13 +280,15 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
|
||||
if ((target_type == DM_CRYPT && _dm_crypt_checked) ||
|
||||
(target_type == DM_VERITY && _dm_verity_checked) ||
|
||||
(target_type == DM_INTEGRITY && _dm_integrity_checked) ||
|
||||
(target_type == DM_LINEAR) ||
|
||||
(target_type == DM_LINEAR) || (target_type == DM_ZERO) ||
|
||||
(_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked))
|
||||
return 1;
|
||||
|
||||
/* Shut up DM while checking */
|
||||
_quiet_log = 1;
|
||||
|
||||
_dm_check_target(target_type);
|
||||
|
||||
/* FIXME: add support to DM so it forces crypt target module load here */
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
|
||||
goto out;
|
||||
@@ -259,6 +309,10 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
|
||||
#if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
|
||||
if (_dm_satisfies_version(4, 27, 0, dm_maj, dm_min, dm_patch))
|
||||
_dm_flags |= DM_DEFERRED_SUPPORTED;
|
||||
#endif
|
||||
#if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
|
||||
if (_dm_satisfies_version(4, 41, 0, dm_maj, dm_min, dm_patch))
|
||||
_dm_flags |= DM_GET_TARGET_VERSION_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -307,7 +361,7 @@ int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
|
||||
if ((target == DM_CRYPT && _dm_crypt_checked) ||
|
||||
(target == DM_VERITY && _dm_verity_checked) ||
|
||||
(target == DM_INTEGRITY && _dm_integrity_checked) ||
|
||||
(target == DM_LINEAR)) /* nothing to check with linear */
|
||||
(target == DM_LINEAR) || (target == DM_ZERO)) /* nothing to check */
|
||||
return 0;
|
||||
|
||||
return -ENODEV;
|
||||
@@ -628,7 +682,7 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
int max_size, r, num_options = 0;
|
||||
struct crypt_params_verity *vp;
|
||||
char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
|
||||
char features[256], fec_features[256];
|
||||
char features[256], fec_features[256], verity_verify_args[512+32];
|
||||
|
||||
if (!tgt || !tgt->u.verity.vp)
|
||||
return NULL;
|
||||
@@ -658,6 +712,13 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
} else
|
||||
*fec_features = '\0';
|
||||
|
||||
if (tgt->u.verity.root_hash_sig_key_desc) {
|
||||
num_options += 2;
|
||||
snprintf(verity_verify_args, sizeof(verity_verify_args)-1,
|
||||
" root_hash_sig_key_desc %s", tgt->u.verity.root_hash_sig_key_desc);
|
||||
} else
|
||||
*verity_verify_args = '\0';
|
||||
|
||||
if (num_options)
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
|
||||
@@ -683,19 +744,22 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
max_size = strlen(hexroot) + strlen(hexsalt) +
|
||||
strlen(device_block_path(tgt->data_device)) +
|
||||
strlen(device_block_path(tgt->u.verity.hash_device)) +
|
||||
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128;
|
||||
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128 +
|
||||
strlen(verity_verify_args);
|
||||
|
||||
params = crypt_safe_alloc(max_size);
|
||||
if (!params)
|
||||
goto out;
|
||||
|
||||
r = snprintf(params, max_size,
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s",
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s%s",
|
||||
vp->hash_type, device_block_path(tgt->data_device),
|
||||
device_block_path(tgt->u.verity.hash_device),
|
||||
vp->data_block_size, vp->hash_block_size,
|
||||
vp->data_size, tgt->u.verity.hash_offset,
|
||||
vp->hash_name, hexroot, hexsalt, features, fec_features);
|
||||
vp->hash_name, hexroot, hexsalt, features, fec_features,
|
||||
verity_verify_args);
|
||||
|
||||
if (r < 0 || r >= max_size) {
|
||||
crypt_safe_free(params);
|
||||
params = NULL;
|
||||
@@ -827,6 +891,11 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
crypt_safe_free(hexkey);
|
||||
}
|
||||
if (tgt->u.integrity.fix_padding) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "fix_padding ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_RECALCULATE) {
|
||||
num_options++;
|
||||
@@ -834,6 +903,12 @@ 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 ",
|
||||
@@ -883,6 +958,16 @@ static char *get_dm_linear_params(const struct dm_target *tgt, uint32_t flags)
|
||||
return params;
|
||||
}
|
||||
|
||||
static char *get_dm_zero_params(const struct dm_target *tgt, uint32_t flags)
|
||||
{
|
||||
char *params = crypt_safe_alloc(1);
|
||||
if (!params)
|
||||
return NULL;
|
||||
|
||||
params[0] = 0;
|
||||
return params;
|
||||
}
|
||||
|
||||
/* DM helpers */
|
||||
static int _dm_remove(const char *name, int udev_wait, int deferred)
|
||||
{
|
||||
@@ -1156,6 +1241,9 @@ static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *d
|
||||
case DM_LINEAR:
|
||||
target = DM_LINEAR_TARGET;
|
||||
break;
|
||||
case DM_ZERO:
|
||||
target = DM_ZERO_TARGET;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
@@ -1194,6 +1282,8 @@ static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
|
||||
tgt->params = get_dm_integrity_params(tgt, dmd->flags);
|
||||
else if (tgt->type == DM_LINEAR)
|
||||
tgt->params = get_dm_linear_params(tgt, dmd->flags);
|
||||
else if (tgt->type == DM_ZERO)
|
||||
tgt->params = get_dm_zero_params(tgt, dmd->flags);
|
||||
else {
|
||||
r = -ENOTSUP;
|
||||
goto err;
|
||||
@@ -1415,10 +1505,13 @@ static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target
|
||||
crypt_free_verity_params(tgt->u.verity.vp);
|
||||
device_free(cd, tgt->u.verity.hash_device);
|
||||
free(CONST_CAST(void*)tgt->u.verity.root_hash);
|
||||
free(CONST_CAST(void*)tgt->u.verity.root_hash_sig_key_desc);
|
||||
/* fall through */
|
||||
case DM_LINEAR:
|
||||
/* fall through */
|
||||
case DM_ERROR:
|
||||
/* fall through */
|
||||
case DM_ZERO:
|
||||
break;
|
||||
default:
|
||||
log_err(cd, _("Unknown dm target type."));
|
||||
@@ -1483,7 +1576,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
|
||||
/* If kernel keyring is not supported load key directly in dm-crypt */
|
||||
if ((*dmd_flags & CRYPT_ACTIVATE_KEYRING_KEY) &&
|
||||
!(dmt_flags & DM_KERNEL_KEYRING_SUPPORTED)) {
|
||||
log_dbg(cd, "dm-crypt doesn't support kernel keyring");
|
||||
log_dbg(cd, "dm-crypt does not support kernel keyring");
|
||||
*dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
ret = 1;
|
||||
}
|
||||
@@ -1491,7 +1584,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
|
||||
/* Drop performance options if not supported */
|
||||
if ((*dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
|
||||
!(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
|
||||
log_dbg(cd, "dm-crypt doesn't support performance options");
|
||||
log_dbg(cd, "dm-crypt does not support performance options");
|
||||
*dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
|
||||
ret = 1;
|
||||
}
|
||||
@@ -1517,7 +1610,8 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
if (r < 0 && dm_flags(cd, dmd->segment.type, &dmt_flags))
|
||||
goto out;
|
||||
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR) && check_retry(cd, &dmd->flags, dmt_flags))
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
|
||||
check_retry(cd, &dmd->flags, dmt_flags))
|
||||
r = _dm_create_device(cd, name, type, dmd->uuid, dmd);
|
||||
|
||||
if (r == -EINVAL &&
|
||||
@@ -1547,6 +1641,10 @@ 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."));
|
||||
@@ -1579,6 +1677,9 @@ int dm_reload_device(struct crypt_device *cd, const char *name,
|
||||
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)
|
||||
@@ -1630,6 +1731,7 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
||||
strcmp(target_type, DM_VERITY_TARGET) &&
|
||||
strcmp(target_type, DM_INTEGRITY_TARGET) &&
|
||||
strcmp(target_type, DM_LINEAR_TARGET) &&
|
||||
strcmp(target_type, DM_ZERO_TARGET) &&
|
||||
strcmp(target_type, DM_ERROR_TARGET)))
|
||||
goto out;
|
||||
r = 0;
|
||||
@@ -1918,6 +2020,7 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
int r;
|
||||
struct device *data_device = NULL, *hash_device = NULL, *fec_device = NULL;
|
||||
char *hash_name = NULL, *root_hash = NULL, *salt = NULL, *fec_dev_str = NULL;
|
||||
char *root_hash_sig_key_desc = NULL;
|
||||
|
||||
if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
|
||||
vp = crypt_zalloc(sizeof(*vp));
|
||||
@@ -2101,6 +2204,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
if (vp)
|
||||
vp->fec_roots = val32;
|
||||
i++;
|
||||
} else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
|
||||
str = strsep(¶ms, " ");
|
||||
if (!str)
|
||||
goto err;
|
||||
if (!root_hash_sig_key_desc)
|
||||
root_hash_sig_key_desc = strdup(str);
|
||||
i++;
|
||||
if (vp)
|
||||
vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
|
||||
} else /* unknown option */
|
||||
goto err;
|
||||
}
|
||||
@@ -2126,11 +2238,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
vp->salt = salt;
|
||||
if (vp && fec_dev_str)
|
||||
vp->fec_device = fec_dev_str;
|
||||
if (root_hash_sig_key_desc)
|
||||
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
device_free(cd, data_device);
|
||||
device_free(cd, hash_device);
|
||||
device_free(cd, fec_device);
|
||||
free(root_hash_sig_key_desc);
|
||||
free(root_hash);
|
||||
free(hash_name);
|
||||
free(salt);
|
||||
@@ -2295,6 +2411,10 @@ 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;
|
||||
}
|
||||
@@ -2377,6 +2497,14 @@ static int _dm_target_query_error(struct crypt_device *cd, struct dm_target *tgt
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dm_target_query_zero(struct crypt_device *cd, struct dm_target *tgt)
|
||||
{
|
||||
tgt->type = DM_ZERO;
|
||||
tgt->direction = TARGET_QUERY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* on error retval has to be negative
|
||||
*
|
||||
@@ -2398,6 +2526,8 @@ static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const
|
||||
r = _dm_target_query_linear(cd, tgt, get_flags, params);
|
||||
else if (!strcmp(target_type, DM_ERROR_TARGET))
|
||||
r = _dm_target_query_error(cd, tgt);
|
||||
else if (!strcmp(target_type, DM_ZERO_TARGET))
|
||||
r = _dm_target_query_zero(cd, tgt);
|
||||
|
||||
if (!r) {
|
||||
tgt->offset = *start;
|
||||
@@ -2480,6 +2610,9 @@ static int _dm_query_device(struct crypt_device *cd, const char *name,
|
||||
if (dmi.read_only)
|
||||
dmd->flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (dmi.suspended)
|
||||
dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
|
||||
|
||||
tmp_uuid = dm_task_get_uuid(dmt);
|
||||
if (!tmp_uuid)
|
||||
dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
|
||||
@@ -2527,6 +2660,7 @@ int dm_query_device(struct crypt_device *cd, const char *name,
|
||||
|
||||
static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps, char **names, size_t names_offset, size_t names_length)
|
||||
{
|
||||
#if HAVE_DECL_DM_DEVICE_GET_NAME
|
||||
struct crypt_dm_active_device dmd;
|
||||
char dmname[PATH_MAX];
|
||||
unsigned i;
|
||||
@@ -2565,6 +2699,9 @@ static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_
|
||||
}
|
||||
|
||||
return count;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
|
||||
@@ -2802,8 +2939,8 @@ err:
|
||||
|
||||
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||
uint64_t hash_blocks, struct crypt_params_verity *vp)
|
||||
const char *root_hash, uint32_t root_hash_size, const char *root_hash_sig_key_desc,
|
||||
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp)
|
||||
{
|
||||
if (!data_device || !hash_device || !vp)
|
||||
return -EINVAL;
|
||||
@@ -2818,6 +2955,7 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
tgt->u.verity.fec_device = fec_device;
|
||||
tgt->u.verity.root_hash = root_hash;
|
||||
tgt->u.verity.root_hash_size = root_hash_size;
|
||||
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
|
||||
tgt->u.verity.hash_offset = hash_offset_block;
|
||||
tgt->u.verity.fec_offset = vp->fec_area_offset / vp->hash_block_size;
|
||||
tgt->u.verity.hash_blocks = hash_blocks;
|
||||
@@ -2826,16 +2964,21 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
int dm_integrity_target_set(struct crypt_device *cd,
|
||||
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *meta_device,
|
||||
struct device *data_device, uint64_t tag_size, uint64_t offset,
|
||||
uint32_t sector_size, struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
|
||||
const struct crypt_params_integrity *ip)
|
||||
{
|
||||
uint32_t dmi_flags;
|
||||
|
||||
if (!data_device)
|
||||
return -EINVAL;
|
||||
|
||||
_dm_check_versions(cd, DM_INTEGRITY);
|
||||
|
||||
tgt->type = DM_INTEGRITY;
|
||||
tgt->direction = TARGET_SET;
|
||||
tgt->offset = seg_offset;
|
||||
@@ -2851,6 +2994,11 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
|
||||
tgt->u.integrity.journal_crypt_key = journal_crypt_key;
|
||||
tgt->u.integrity.journal_integrity_key = journal_mac_key;
|
||||
|
||||
if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED) &&
|
||||
!(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING))
|
||||
tgt->u.integrity.fix_padding = true;
|
||||
|
||||
if (ip) {
|
||||
tgt->u.integrity.journal_size = ip->journal_size;
|
||||
tgt->u.integrity.journal_watermark = ip->journal_watermark;
|
||||
@@ -2881,3 +3029,13 @@ int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
|
||||
{
|
||||
tgt->type = DM_ZERO;
|
||||
tgt->direction = TARGET_SET;
|
||||
tgt->offset = seg_offset;
|
||||
tgt->size = seg_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -81,7 +81,7 @@ static int hash_keys(struct crypt_device *cd,
|
||||
const char *hash_name;
|
||||
char tweak, *key_ptr;
|
||||
unsigned int i;
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
hash_name = hash_override ?: get_hash(key_len_output);
|
||||
tweak = get_tweak(keys_count);
|
||||
@@ -242,7 +242,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
|
||||
if (r < 0 && !dm_flags(cd, DM_CRYPT, &dmc_flags) &&
|
||||
(dmc_flags & req_flags) != req_flags) {
|
||||
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping."));
|
||||
log_err(cd, _("Kernel does not support loop-AES compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "luks.h"
|
||||
@@ -89,7 +88,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
r = device_block_adjust(ctx, crypt_metadata_device(ctx), DEV_OK,
|
||||
sector, &dmd.size, &dmd.flags);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Device %s doesn't exist or access denied."),
|
||||
log_err(ctx, _("Device %s does not exist or access denied."),
|
||||
device_path(crypt_metadata_device(ctx)));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@@ -260,7 +259,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
}
|
||||
@@ -284,7 +283,7 @@ int LUKS_hdr_restore(
|
||||
buffer_size = LUKS_device_sectors(&hdr_file) << SECTOR_SHIFT;
|
||||
|
||||
if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) {
|
||||
log_err(ctx, _("Backup file doesn't contain valid LUKS header."));
|
||||
log_err(ctx, _("Backup file does not contain valid LUKS header."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -453,7 +452,7 @@ out:
|
||||
if (r)
|
||||
log_err(ctx, _("Repair failed."));
|
||||
crypt_free_volume_key(vk);
|
||||
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -692,7 +691,7 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
|
||||
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
|
||||
|
||||
crypt_free_volume_key(empty_key);
|
||||
crypt_memzero(buf, sizeof(buf));
|
||||
crypt_safe_memzero(buf, sizeof(buf));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -787,10 +786,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
return r;
|
||||
assert(pbkdf->iterations);
|
||||
|
||||
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
|
||||
if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK && pbkdf->time_ms == 0)
|
||||
PBKDF2_temp = LUKS_MKD_ITERATIONS_MIN;
|
||||
else /* iterations per ms * LUKS_MKD_ITERATIONS_MS */
|
||||
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
|
||||
|
||||
if (PBKDF2_temp > (double)UINT32_MAX)
|
||||
return -EINVAL;
|
||||
header->mkDigestIterations = at_least((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN);
|
||||
assert(header->mkDigestIterations);
|
||||
|
||||
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, vk->key,vk->keylength,
|
||||
header->mkDigestSalt, LUKS_SALTSIZE,
|
||||
@@ -982,8 +986,10 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
|
||||
derived_key->key, hdr->keyBytes,
|
||||
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
|
||||
r = LUKS_decrypt_from_storage(AfKey,
|
||||
@@ -1224,7 +1230,7 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
|
||||
|
||||
int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf)
|
||||
{
|
||||
if (keyslot >= LUKS_NUMKEYS || keyslot < 0)
|
||||
if (LUKS_keyslot_info(hdr, keyslot) < CRYPT_SLOT_ACTIVE)
|
||||
return -EINVAL;
|
||||
|
||||
pbkdf->type = CRYPT_KDF_PBKDF2;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -55,6 +55,9 @@
|
||||
/* 20 MiBs */
|
||||
#define LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH 0x1400000
|
||||
|
||||
/* 1 GiB */
|
||||
#define LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH 0x40000000
|
||||
|
||||
struct device;
|
||||
|
||||
/*
|
||||
@@ -162,6 +165,7 @@ struct luks2_reenc_context {
|
||||
char *device_name;
|
||||
char *hotzone_name;
|
||||
char *overlay_name;
|
||||
uint32_t flags;
|
||||
|
||||
/* reencryption window persistence attributes */
|
||||
struct reenc_protection rp;
|
||||
@@ -596,7 +600,8 @@ int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
|
||||
crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd,
|
||||
struct crypt_params_reencrypt *params);
|
||||
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock);
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock);
|
||||
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock);
|
||||
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock);
|
||||
|
||||
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, digest handling
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, PBKDF2 digest handler (LUKS1 compatible)
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -210,7 +210,7 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
|
||||
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
|
||||
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header does not match size 0x%04x.",
|
||||
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
#define _CRYPTSETUP_LUKS2_INTERNAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <json-c/json.h>
|
||||
|
||||
@@ -59,9 +58,9 @@ json_object *LUKS2_get_segments_jobj(struct luks2_hdr *hdr);
|
||||
void hexprint_base64(struct crypt_device *cd, json_object *jobj,
|
||||
const char *sep, const char *line_sep);
|
||||
|
||||
uint64_t json_object_get_uint64(json_object *jobj);
|
||||
uint32_t json_object_get_uint32(json_object *jobj);
|
||||
json_object *json_object_new_uint64(uint64_t value);
|
||||
uint64_t crypt_jobj_get_uint64(json_object *jobj);
|
||||
uint32_t crypt_jobj_get_uint32(json_object *jobj);
|
||||
json_object *crypt_jobj_new_uint64(uint64_t value);
|
||||
|
||||
int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object *jobj_val);
|
||||
void json_object_object_del_by_uint(json_object *jobj, unsigned key);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS2 header format code
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -325,8 +325,8 @@ int LUKS2_generate_hdr(
|
||||
|
||||
json_object_object_add_by_uint(jobj_segments, 0, jobj_segment);
|
||||
|
||||
json_object_object_add(jobj_config, "json_size", json_object_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN));
|
||||
json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint64(keyslots_size));
|
||||
json_object_object_add(jobj_config, "json_size", crypt_jobj_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN));
|
||||
json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
|
||||
|
||||
JSON_DBG(cd, hdr->jobj, "Header JSON:");
|
||||
return 0;
|
||||
@@ -400,6 +400,6 @@ int LUKS2_set_keyslots_size(struct crypt_device *cd,
|
||||
if (!json_object_object_get_ex(hdr->jobj, "config", &jobj_config))
|
||||
return 1;
|
||||
|
||||
json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint64(keyslots_size));
|
||||
json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2019 Ondrej Kozina
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
* Copyright (C) 2015-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -45,11 +45,11 @@ void hexprint_base64(struct crypt_device *cd, json_object *jobj,
|
||||
&buf, &buf_len))
|
||||
return;
|
||||
|
||||
for (i = 0; i < buf_len / 2; i++)
|
||||
log_std(cd, "%02hhx%s", buf[i], sep);
|
||||
log_std(cd, "\n\t%s", line_sep);
|
||||
for (i = buf_len / 2; i < buf_len; i++)
|
||||
for (i = 0; i < buf_len; i++) {
|
||||
if (i && !(i % 16))
|
||||
log_std(cd, "\n\t%s", line_sep);
|
||||
log_std(cd, "%02hhx%s", buf[i], sep);
|
||||
}
|
||||
log_std(cd, "\n");
|
||||
free(buf);
|
||||
}
|
||||
@@ -219,7 +219,7 @@ int LUKS2_get_default_segment(struct luks2_hdr *hdr)
|
||||
* json_type_int needs to be validated first.
|
||||
* See validate_json_uint32()
|
||||
*/
|
||||
uint32_t json_object_get_uint32(json_object *jobj)
|
||||
uint32_t crypt_jobj_get_uint32(json_object *jobj)
|
||||
{
|
||||
return json_object_get_int64(jobj);
|
||||
}
|
||||
@@ -234,21 +234,21 @@ static json_bool json_str_to_uint64(json_object *jobj, uint64_t *value)
|
||||
tmp = strtoull(json_object_get_string(jobj), &endptr, 10);
|
||||
if (*endptr || errno) {
|
||||
*value = 0;
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*value = tmp;
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t json_object_get_uint64(json_object *jobj)
|
||||
uint64_t crypt_jobj_get_uint64(json_object *jobj)
|
||||
{
|
||||
uint64_t r;
|
||||
json_str_to_uint64(jobj, &r);
|
||||
return r;
|
||||
}
|
||||
|
||||
json_object *json_object_new_uint64(uint64_t value)
|
||||
json_object *crypt_jobj_new_uint64(uint64_t value)
|
||||
{
|
||||
/* 18446744073709551615 */
|
||||
char num[21];
|
||||
@@ -273,9 +273,9 @@ static json_bool numbered(struct crypt_device *cd, const char *name, const char
|
||||
for (i = 0; key[i]; i++)
|
||||
if (!isdigit(key[i])) {
|
||||
log_dbg(cd, "%s \"%s\" is not in numbered form.", name, key);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
json_object *json_contains(struct crypt_device *cd, json_object *jobj, const char *name,
|
||||
@@ -300,7 +300,7 @@ json_bool validate_json_uint32(json_object *jobj)
|
||||
errno = 0;
|
||||
tmp = json_object_get_int64(jobj);
|
||||
|
||||
return (errno || tmp < 0 || tmp > UINT32_MAX) ? FALSE : TRUE;
|
||||
return (errno || tmp < 0 || tmp > UINT32_MAX) ? 0 : 1;
|
||||
}
|
||||
|
||||
static json_bool validate_keyslots_array(struct crypt_device *cd,
|
||||
@@ -313,17 +313,17 @@ static json_bool validate_keyslots_array(struct crypt_device *cd,
|
||||
jobj = json_object_array_get_idx(jarr, i);
|
||||
if (!json_object_is_type(jobj, json_type_string)) {
|
||||
log_dbg(cd, "Illegal value type in keyslots array at index %d.", i);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!json_contains(cd, jobj_keys, "", "Keyslots section",
|
||||
json_object_get_string(jobj), json_type_object))
|
||||
return FALSE;
|
||||
return 0;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static json_bool validate_segments_array(struct crypt_device *cd,
|
||||
@@ -336,17 +336,17 @@ static json_bool validate_segments_array(struct crypt_device *cd,
|
||||
jobj = json_object_array_get_idx(jarr, i);
|
||||
if (!json_object_is_type(jobj, json_type_string)) {
|
||||
log_dbg(cd, "Illegal value type in segments array at index %d.", i);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!json_contains(cd, jobj_segments, "", "Segments section",
|
||||
json_object_get_string(jobj), json_type_object))
|
||||
return FALSE;
|
||||
return 0;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static json_bool segment_has_digest(const char *segment_name, json_object *jobj_digests)
|
||||
@@ -357,10 +357,10 @@ static json_bool segment_has_digest(const char *segment_name, json_object *jobj_
|
||||
UNUSED(key);
|
||||
json_object_object_get_ex(val, "segments", &jobj_segments);
|
||||
if (LUKS2_array_jobj(jobj_segments, segment_name))
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static json_bool validate_intervals(struct crypt_device *cd,
|
||||
@@ -372,18 +372,18 @@ static json_bool validate_intervals(struct crypt_device *cd,
|
||||
while (i < length) {
|
||||
if (ix[i].offset < 2 * metadata_size) {
|
||||
log_dbg(cd, "Illegal area offset: %" PRIu64 ".", ix[i].offset);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ix[i].length) {
|
||||
log_dbg(cd, "Area length must be greater than zero.");
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ix[i].offset + ix[i].length) > keyslots_area_end) {
|
||||
log_dbg(cd, "Area [%" PRIu64 ", %" PRIu64 "] overflows binary keyslots area (ends at offset: %" PRIu64 ").",
|
||||
ix[i].offset, ix[i].offset + ix[i].length, keyslots_area_end);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < length; j++) {
|
||||
@@ -393,14 +393,14 @@ static json_bool validate_intervals(struct crypt_device *cd,
|
||||
log_dbg(cd, "Overlapping areas [%" PRIu64 ",%" PRIu64 "] and [%" PRIu64 ",%" PRIu64 "].",
|
||||
ix[i].offset, ix[i].offset + ix[i].length,
|
||||
ix[j].offset, ix[j].offset + ix[j].length);
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int LUKS2_keyslot_validate(struct crypt_device *cd, json_object *hdr_jobj, json_object *hdr_keyslot, const char *key)
|
||||
@@ -455,16 +455,16 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
|
||||
|
||||
json = json_object_to_json_string_ext(hdr_jobj,
|
||||
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
|
||||
json_area_size = json_object_get_uint64(jobj1);
|
||||
json_area_size = crypt_jobj_get_uint64(jobj1);
|
||||
json_size = (uint64_t)strlen(json);
|
||||
|
||||
if (hdr_json_size != json_area_size) {
|
||||
log_dbg(cd, "JSON area size doesn't match value in binary header.");
|
||||
log_dbg(cd, "JSON area size does not match value in binary header.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (json_size > json_area_size) {
|
||||
log_dbg(cd, "JSON doesn't fit in the designated area.");
|
||||
log_dbg(cd, "JSON does not fit in the designated area.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -543,7 +543,7 @@ static int hdr_validate_crypt_segment(struct crypt_device *cd,
|
||||
return 1;
|
||||
}
|
||||
|
||||
sector_size = json_object_get_uint32(jobj_sector_size);
|
||||
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
|
||||
if (!sector_size || MISALIGNED_512(sector_size)) {
|
||||
log_dbg(cd, "Illegal sector size: %" PRIu32, sector_size);
|
||||
return 1;
|
||||
@@ -970,13 +970,16 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
static int hdr_cleanup_and_validate(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
return LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
|
||||
@@ -984,11 +987,7 @@ int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
|
||||
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
|
||||
@@ -1159,7 +1158,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
device_free(cd, backup_device);
|
||||
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Backup file doesn't contain valid LUKS header."));
|
||||
log_err(cd, _("Backup file does not contain valid LUKS header."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1270,8 +1269,8 @@ out:
|
||||
LUKS2_hdr_free(cd, hdr);
|
||||
LUKS2_hdr_free(cd, &hdr_file);
|
||||
LUKS2_hdr_free(cd, &tmp_hdr);
|
||||
crypt_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_safe_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_free(buffer);
|
||||
|
||||
device_sync(cd, device);
|
||||
@@ -1567,7 +1566,7 @@ static void hdr_dump_keyslots(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
log_std(cd, " %s: %s%s\n", slot, tmps, r == -ENOENT ? " (unbound)" : "");
|
||||
|
||||
if (json_object_object_get_ex(val, "key_size", &jobj2))
|
||||
log_std(cd, "\tKey: %u bits\n", json_object_get_uint32(jobj2) * 8);
|
||||
log_std(cd, "\tKey: %u bits\n", crypt_jobj_get_uint32(jobj2) * 8);
|
||||
|
||||
log_std(cd, "\tPriority: %s\n", get_priority_desc(val));
|
||||
|
||||
@@ -1650,7 +1649,7 @@ static void hdr_dump_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
log_std(cd, "\tcipher: %s\n", json_object_get_string(jobj1));
|
||||
|
||||
if (json_object_object_get_ex(jobj_segment, "sector_size", &jobj1))
|
||||
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", json_object_get_uint32(jobj1));
|
||||
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", crypt_jobj_get_uint32(jobj1));
|
||||
|
||||
if (json_object_object_get_ex(jobj_segment, "integrity", &jobj1) &&
|
||||
json_object_object_get_ex(jobj1, "type", &jobj2))
|
||||
@@ -1747,7 +1746,7 @@ int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic)
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp += json_object_get_uint64(jobj_size);
|
||||
tmp += crypt_jobj_get_uint64(jobj_size);
|
||||
}
|
||||
|
||||
/* impossible, real device size must not be zero */
|
||||
@@ -2157,7 +2156,12 @@ int LUKS2_activate(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags);
|
||||
if (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);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -2205,26 +2209,21 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
|
||||
struct dm_target *tgt;
|
||||
crypt_status_info ci;
|
||||
struct crypt_dm_active_device dmdc;
|
||||
char **dep, uuid[37], deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
|
||||
char **dep, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
|
||||
const char *namei = NULL;
|
||||
struct crypt_lock_handle *reencrypt_lock = NULL;
|
||||
|
||||
if (!dmd || !dmd->uuid)
|
||||
if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1))
|
||||
return -EINVAL;
|
||||
|
||||
/* uuid mismatch with metadata (if available) */
|
||||
if (hdr && crypt_uuid_cmp(dmd->uuid, hdr->uuid))
|
||||
return -EINVAL;
|
||||
|
||||
r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), CRYPT_SUBDEV "-%.32s", dmd->uuid + 6);
|
||||
if (r < 0 || (size_t)r != (sizeof(deps_uuid_prefix) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
r = snprintf(uuid, sizeof(uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
|
||||
dmd->uuid + 6, dmd->uuid + 14, dmd->uuid + 18, dmd->uuid + 22, dmd->uuid + 26);
|
||||
if (r < 0 || (size_t)r != (sizeof(uuid) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* uuid mismatch with metadata (if available) */
|
||||
if (hdr && strcmp(hdr->uuid, uuid))
|
||||
return -EINVAL;
|
||||
|
||||
tgt = &dmd->segment;
|
||||
|
||||
/* TODO: We have LUKS2 dependencies now */
|
||||
@@ -2236,7 +2235,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
|
||||
goto out;
|
||||
|
||||
if (contains_reencryption_helper(deps)) {
|
||||
r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot deactivate device."));
|
||||
@@ -2345,9 +2344,9 @@ int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uin
|
||||
reqs &= ~reqs_mask;
|
||||
|
||||
if (reqs_reencrypt(reqs) && !quiet)
|
||||
log_err(cd, _("Offline reencryption in progress. Aborting."));
|
||||
log_err(cd, _("Operation incompatible with device marked for legacy reencryption. Aborting."));
|
||||
if (reqs_reencrypt_online(reqs) && !quiet)
|
||||
log_err(cd, _("Online reencryption in progress. Aborting."));
|
||||
log_err(cd, _("Operation incompatible with device marked for LUKS2 reencryption. Aborting."));
|
||||
|
||||
/* any remaining unmasked requirement fails the check */
|
||||
return reqs ? -EINVAL : 0;
|
||||
@@ -2400,7 +2399,7 @@ int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object
|
||||
#endif
|
||||
}
|
||||
|
||||
/* jobj_dst must contain pointer initialised to NULL (see json-c json_object_deep_copy API) */
|
||||
/* jobj_dst must contain pointer initialized to NULL (see json-c json_object_deep_copy API) */
|
||||
int json_object_copy(json_object *jobj_src, json_object **jobj_dst)
|
||||
{
|
||||
if (!jobj_src || !jobj_dst || *jobj_dst)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, keyslot handling
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -79,19 +79,18 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr)
|
||||
/* Check if a keyslot is assigned to specific segment */
|
||||
static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
|
||||
{
|
||||
int keyslot_digest, segment_digest, s, count = 0;
|
||||
int keyslot_digest, count = 0;
|
||||
unsigned s;
|
||||
|
||||
keyslot_digest = LUKS2_digest_by_keyslot(hdr, keyslot);
|
||||
if (keyslot_digest < 0)
|
||||
return keyslot_digest;
|
||||
|
||||
if (segment >= 0) {
|
||||
segment_digest = LUKS2_digest_by_segment(hdr, segment);
|
||||
return segment_digest == keyslot_digest;
|
||||
}
|
||||
for (s = 0; s < 3; s++) {
|
||||
segment_digest = LUKS2_digest_by_segment(hdr, s);
|
||||
if (segment_digest == keyslot_digest)
|
||||
if (segment >= 0)
|
||||
return keyslot_digest == LUKS2_digest_by_segment(hdr, segment);
|
||||
|
||||
for (s = 0; s < json_segments_count(LUKS2_get_segments_jobj(hdr)); s++) {
|
||||
if (keyslot_digest == LUKS2_digest_by_segment(hdr, s))
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -301,37 +300,25 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
|
||||
|
||||
if (!json_object_object_get_ex(jobj_area, "offset", &jobj))
|
||||
return -EINVAL;
|
||||
*offset = json_object_get_uint64(jobj);
|
||||
*offset = crypt_jobj_get_uint64(jobj);
|
||||
|
||||
if (!json_object_object_get_ex(jobj_area, "size", &jobj))
|
||||
return -EINVAL;
|
||||
*length = json_object_get_uint64(jobj);
|
||||
*length = crypt_jobj_get_uint64(jobj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
static int _open_and_verify(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
const keyslot_handler *h,
|
||||
int keyslot,
|
||||
int digest,
|
||||
const char *password,
|
||||
size_t password_len,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int key_size, r;
|
||||
int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
|
||||
r = _keyslot_for_digest(hdr, keyslot, digest);
|
||||
if (r) {
|
||||
if (r == -ENOENT)
|
||||
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
|
||||
return r;
|
||||
}
|
||||
|
||||
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
if (key_size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -350,9 +337,41 @@ static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
*vk = NULL;
|
||||
}
|
||||
|
||||
crypt_volume_key_set_id(*vk, r);
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
int digest,
|
||||
const char *password,
|
||||
size_t password_len,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int r;
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
|
||||
r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot));
|
||||
if (r) {
|
||||
log_dbg(cd, "Keyslot %d validation failed.", keyslot);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = _keyslot_for_digest(hdr, keyslot, digest);
|
||||
if (r) {
|
||||
if (r == -ENOENT)
|
||||
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
|
||||
return r;
|
||||
}
|
||||
|
||||
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
@@ -362,7 +381,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int key_size, r;
|
||||
int r;
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
@@ -380,29 +399,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
key_size = LUKS2_get_volume_key_size(hdr, segment);
|
||||
if (key_size < 0)
|
||||
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
if (key_size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
*vk = crypt_alloc_volume_key(key_size, NULL);
|
||||
if (!*vk)
|
||||
return -ENOMEM;
|
||||
|
||||
r = h->open(cd, keyslot, password, password_len, (*vk)->key, (*vk)->keylength);
|
||||
if (r < 0)
|
||||
log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r);
|
||||
else
|
||||
r = LUKS2_digest_verify(cd, hdr, *vk, keyslot);
|
||||
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
} else
|
||||
crypt_volume_key_set_id(*vk, r);
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
|
||||
}
|
||||
|
||||
static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
|
||||
@@ -520,7 +517,7 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
size_t password_len,
|
||||
struct volume_key **vks)
|
||||
{
|
||||
struct volume_key *vk;
|
||||
struct volume_key *vk = NULL;
|
||||
int digest_old, digest_new, r = -EINVAL;
|
||||
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||
|
||||
@@ -530,7 +527,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
crypt_volume_key_set_id(vk, digest_old);
|
||||
crypt_volume_key_add_next(vks, vk);
|
||||
}
|
||||
|
||||
@@ -540,13 +536,17 @@ 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:
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vks);
|
||||
*vks = NULL;
|
||||
|
||||
if (r == -ENOMEM)
|
||||
log_err(cd, _("Not enough available memory to open a keyslot."));
|
||||
else if (r != -EPERM)
|
||||
log_err(cd, _("Keyslot open failed."));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -579,6 +579,13 @@ int LUKS2_keyslot_open(struct crypt_device *cd,
|
||||
} else
|
||||
r = LUKS2_open_and_verify(cd, hdr, keyslot, segment, password, password_len, vk);
|
||||
|
||||
if (r < 0) {
|
||||
if (r == -ENOMEM)
|
||||
log_err(cd, _("Not enough available memory to open a keyslot."));
|
||||
else if (r != -EPERM)
|
||||
log_err(cd, _("Keyslot open failed."));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -828,8 +835,8 @@ int placeholder_keyslot_alloc(struct crypt_device *cd,
|
||||
|
||||
/* Area object */
|
||||
jobj_area = json_object_new_object();
|
||||
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
|
||||
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
|
||||
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
|
||||
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
|
||||
json_object_object_add(jobj_keyslot, "area", jobj_area);
|
||||
|
||||
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS2 type keyslot handler
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -220,7 +220,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
|
||||
|
||||
if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
|
||||
return -EINVAL;
|
||||
area_offset = json_object_get_uint64(jobj2);
|
||||
area_offset = crypt_jobj_get_uint64(jobj2);
|
||||
|
||||
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
|
||||
return -EINVAL;
|
||||
@@ -313,7 +313,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
|
||||
|
||||
if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
|
||||
return -EINVAL;
|
||||
area_offset = json_object_get_uint64(jobj2);
|
||||
area_offset = crypt_jobj_get_uint64(jobj2);
|
||||
|
||||
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
|
||||
return -EINVAL;
|
||||
@@ -494,8 +494,8 @@ static int luks2_keyslot_alloc(struct crypt_device *cd,
|
||||
/* Area object */
|
||||
jobj_area = json_object_new_object();
|
||||
json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
|
||||
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
|
||||
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
|
||||
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
|
||||
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
|
||||
json_object_object_add(jobj_keyslot, "area", jobj_area);
|
||||
|
||||
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
|
||||
@@ -607,7 +607,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
|
||||
log_std(cd, "\tCipher: %s\n", json_object_get_string(jobj1));
|
||||
|
||||
json_object_object_get_ex(jobj_area, "key_size", &jobj1);
|
||||
log_std(cd, "\tCipher key: %u bits\n", json_object_get_uint32(jobj1) * 8);
|
||||
log_std(cd, "\tCipher key: %u bits\n", crypt_jobj_get_uint32(jobj1) * 8);
|
||||
|
||||
json_object_object_get_ex(jobj_kdf, "type", &jobj1);
|
||||
log_std(cd, "\tPBKDF: %s\n", json_object_get_string(jobj1));
|
||||
@@ -617,7 +617,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
|
||||
log_std(cd, "\tHash: %s\n", json_object_get_string(jobj1));
|
||||
|
||||
json_object_object_get_ex(jobj_kdf, "iterations", &jobj1);
|
||||
log_std(cd, "\tIterations: %" PRIu64 "\n", json_object_get_uint64(jobj1));
|
||||
log_std(cd, "\tIterations: %" PRIu64 "\n", crypt_jobj_get_uint64(jobj1));
|
||||
} else {
|
||||
json_object_object_get_ex(jobj_kdf, "time", &jobj1);
|
||||
log_std(cd, "\tTime cost: %" PRIu64 "\n", json_object_get_int64(jobj1));
|
||||
@@ -640,10 +640,10 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
|
||||
log_std(cd, "\tAF hash: %s\n", json_object_get_string(jobj1));
|
||||
|
||||
json_object_object_get_ex(jobj_area, "offset", &jobj1);
|
||||
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
|
||||
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
|
||||
|
||||
json_object_object_get_ex(jobj_area, "size", &jobj1);
|
||||
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
|
||||
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
|
||||
*
|
||||
* Copyright (C) 2016-2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2018, Ondrej Kozina
|
||||
* Copyright (C) 2016-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -67,13 +67,13 @@ int reenc_keyslot_alloc(struct crypt_device *cd,
|
||||
|
||||
if (params->data_shift) {
|
||||
json_object_object_add(jobj_area, "type", json_object_new_string("datashift"));
|
||||
json_object_object_add(jobj_area, "shift_size", json_object_new_uint64(params->data_shift << SECTOR_SHIFT));
|
||||
json_object_object_add(jobj_area, "shift_size", crypt_jobj_new_uint64(params->data_shift << SECTOR_SHIFT));
|
||||
} else
|
||||
/* except data shift protection, initial setting is irrelevant. Type can be changed during reencryption */
|
||||
json_object_object_add(jobj_area, "type", json_object_new_string("none"));
|
||||
|
||||
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
|
||||
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
|
||||
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
|
||||
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
|
||||
|
||||
json_object_object_add(jobj_keyslot, "type", json_object_new_string("reencrypt"));
|
||||
json_object_object_add(jobj_keyslot, "key_size", json_object_new_int(1)); /* useless but mandatory */
|
||||
@@ -113,8 +113,8 @@ static int reenc_keyslot_store_data(struct crypt_device *cd,
|
||||
!json_object_object_get_ex(jobj_area, "size", &jobj_length))
|
||||
return -EINVAL;
|
||||
|
||||
area_offset = json_object_get_uint64(jobj_offset);
|
||||
area_length = json_object_get_uint64(jobj_length);
|
||||
area_offset = crypt_jobj_get_uint64(jobj_offset);
|
||||
area_length = crypt_jobj_get_uint64(jobj_length);
|
||||
|
||||
if (!area_offset || !area_length || ((uint64_t)buffer_len > area_length))
|
||||
return -EINVAL;
|
||||
@@ -242,14 +242,14 @@ static int reenc_keyslot_dump(struct crypt_device *cd, int keyslot)
|
||||
log_std(cd, "\t%-12s%d [bytes]\n", "Hash data:", json_object_get_int(jobj1));
|
||||
} else if (!strcmp(json_object_get_string(jobj_resilience), "datashift")) {
|
||||
json_object_object_get_ex(jobj_area, "shift_size", &jobj1);
|
||||
log_std(cd, "\t%-12s%" PRIu64 "[bytes]\n", "Shift size:", json_object_get_uint64(jobj1));
|
||||
log_std(cd, "\t%-12s%" PRIu64 "[bytes]\n", "Shift size:", crypt_jobj_get_uint64(jobj1));
|
||||
}
|
||||
|
||||
json_object_object_get_ex(jobj_area, "offset", &jobj1);
|
||||
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
|
||||
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
|
||||
|
||||
json_object_object_get_ex(jobj_area, "size", &jobj1);
|
||||
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
|
||||
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -304,7 +304,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
|
||||
return -EINVAL;
|
||||
if (!validate_json_uint32(jobj_sector_size))
|
||||
return -EINVAL;
|
||||
sector_size = json_object_get_uint32(jobj_sector_size);
|
||||
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
|
||||
if (sector_size < SECTOR_SIZE || NOTPOW2(sector_size)) {
|
||||
log_dbg(cd, "Invalid sector_size (%" PRIu32 ") for checksum resilience mode.", sector_size);
|
||||
return -EINVAL;
|
||||
@@ -313,7 +313,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
|
||||
if (!(jobj_shift_size = json_contains(cd, jobj_area, "type:datashift", "Keyslot area", "shift_size", json_type_string)))
|
||||
return -EINVAL;
|
||||
|
||||
shift_size = json_object_get_uint64(jobj_shift_size);
|
||||
shift_size = crypt_jobj_get_uint64(jobj_shift_size);
|
||||
if (!shift_size)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS1 conversion code
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Ondrej Kozina
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020 Ondrej Kozina
|
||||
* Copyright (C) 2015-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -91,8 +91,8 @@ static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struc
|
||||
}
|
||||
area_size = offs_b - offs_a;
|
||||
json_object_object_add(jobj_area, "key_size", json_object_new_int(hdr_v1->keyBytes));
|
||||
json_object_object_add(jobj_area, "offset", json_object_new_uint64(offset));
|
||||
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_size));
|
||||
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(offset));
|
||||
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_size));
|
||||
json_object_object_add(keyslot_obj, "area", jobj_area);
|
||||
|
||||
*keyslot_object = keyslot_obj;
|
||||
@@ -145,7 +145,7 @@ static int json_luks1_segment(const struct luks_phdr *hdr_v1, struct json_object
|
||||
/* offset field */
|
||||
number = (uint64_t)hdr_v1->payloadOffset * SECTOR_SIZE;
|
||||
|
||||
field = json_object_new_uint64(number);
|
||||
field = crypt_jobj_new_uint64(number);
|
||||
if (!field) {
|
||||
json_object_put(segment_obj);
|
||||
return -ENOMEM;
|
||||
@@ -401,8 +401,9 @@ static int json_luks1_object(struct luks_phdr *hdr_v1, struct json_object **luks
|
||||
json_object_object_add(luks1_obj, "config", field);
|
||||
|
||||
json_size = LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN;
|
||||
json_object_object_add(field, "json_size", json_object_new_uint64(json_size));
|
||||
json_object_object_add(field, "keyslots_size", json_object_new_uint64(keyslots_size));
|
||||
json_object_object_add(field, "json_size", crypt_jobj_new_uint64(json_size));
|
||||
keyslots_size -= (keyslots_size % 4096);
|
||||
json_object_object_add(field, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
|
||||
|
||||
*luks1_object = luks1_obj;
|
||||
return 0;
|
||||
@@ -418,8 +419,8 @@ static void move_keyslot_offset(json_object *jobj, int offset_add)
|
||||
UNUSED(key);
|
||||
json_object_object_get_ex(val, "area", &jobj_area);
|
||||
json_object_object_get_ex(jobj_area, "offset", &jobj2);
|
||||
offset = json_object_get_uint64(jobj2) + offset_add;
|
||||
json_object_object_add(jobj_area, "offset", json_object_new_uint64(offset));
|
||||
offset = crypt_jobj_get_uint64(jobj2) + offset_add;
|
||||
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(offset));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +467,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
|
||||
r = 0;
|
||||
out:
|
||||
device_sync(cd, device);
|
||||
crypt_memzero(buf, buf_size);
|
||||
crypt_safe_memzero(buf, buf_size);
|
||||
free(buf);
|
||||
|
||||
return r;
|
||||
@@ -518,7 +519,7 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
|
||||
int r;
|
||||
json_object *jobj = NULL;
|
||||
size_t buf_size, buf_offset, luks1_size, luks1_shift = 2 * LUKS2_HDR_16K_LEN - LUKS_ALIGN_KEYSLOTS;
|
||||
uint64_t max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
|
||||
uint64_t required_size, max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
|
||||
|
||||
/* for detached headers max size == device size */
|
||||
if (!max_size && (r = device_size(crypt_metadata_device(cd), &max_size)))
|
||||
@@ -539,11 +540,18 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
|
||||
|
||||
log_dbg(cd, "Max size: %" PRIu64 ", LUKS1 (full) header size %zu , required shift: %zu",
|
||||
max_size, luks1_size, luks1_shift);
|
||||
if ((max_size - luks1_size) < luks1_shift) {
|
||||
|
||||
required_size = luks1_size + luks1_shift;
|
||||
|
||||
if ((max_size < required_size) &&
|
||||
device_fallocate(crypt_metadata_device(cd), required_size)) {
|
||||
log_err(cd, _("Unable to move keyslot area. Not enough space."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (max_size < required_size)
|
||||
max_size = required_size;
|
||||
|
||||
r = json_luks1_object(hdr1, &jobj, max_size - 2 * LUKS2_HDR_16K_LEN);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -570,6 +578,12 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check future LUKS2 metadata before moving keyslots area */
|
||||
if (LUKS2_hdr_validate(cd, hdr2->jobj, hdr2->hdr_size - LUKS2_HDR_BIN_LEN)) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = luks_header_in_use(cd))) {
|
||||
if (r > 0)
|
||||
r = -EBUSY;
|
||||
@@ -579,6 +593,14 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
|
||||
// move keyslots 4k -> 32k offset
|
||||
buf_offset = 2 * LUKS2_HDR_16K_LEN;
|
||||
buf_size = luks1_size - LUKS_ALIGN_KEYSLOTS;
|
||||
|
||||
/* check future LUKS2 keyslots area is at least as large as LUKS1 keyslots area */
|
||||
if (buf_size > LUKS2_keyslots_size(hdr2->jobj)) {
|
||||
log_err(cd, _("Unable to move keyslot area. LUKS2 keyslots area too small."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = move_keyslot_areas(cd, 8 * SECTOR_SIZE, buf_offset, buf_size)) < 0) {
|
||||
log_err(cd, _("Unable to move keyslot area."));
|
||||
goto out;
|
||||
@@ -742,7 +764,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
return -EINVAL;
|
||||
if (!json_object_object_get_ex(jobj_area, "offset", &jobj1))
|
||||
return -EINVAL;
|
||||
offset = json_object_get_uint64(jobj1);
|
||||
offset = crypt_jobj_get_uint64(jobj1);
|
||||
} else {
|
||||
if (LUKS2_find_area_gap(cd, hdr2, key_size, &offset, &area_length))
|
||||
return -EINVAL;
|
||||
@@ -774,7 +796,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
|
||||
if (!json_object_object_get_ex(jobj_kdf, "iterations", &jobj1))
|
||||
continue;
|
||||
hdr1->keyblock[i].passwordIterations = json_object_get_uint32(jobj1);
|
||||
hdr1->keyblock[i].passwordIterations = crypt_jobj_get_uint32(jobj1);
|
||||
|
||||
if (!json_object_object_get_ex(jobj_kdf, "salt", &jobj1))
|
||||
continue;
|
||||
@@ -815,7 +837,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
|
||||
if (!json_object_object_get_ex(jobj_digest, "iterations", &jobj1))
|
||||
return -EINVAL;
|
||||
hdr1->mkDigestIterations = json_object_get_uint32(jobj1);
|
||||
hdr1->mkDigestIterations = crypt_jobj_get_uint32(jobj1);
|
||||
|
||||
if (!json_object_object_get_ex(jobj_digest, "digest", &jobj1))
|
||||
return -EINVAL;
|
||||
@@ -840,7 +862,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
|
||||
if (!json_object_object_get_ex(jobj_segment, "offset", &jobj1))
|
||||
return -EINVAL;
|
||||
offset = json_object_get_uint64(jobj1) / SECTOR_SIZE;
|
||||
offset = crypt_jobj_get_uint64(jobj1) / SECTOR_SIZE;
|
||||
if (offset > UINT32_MAX)
|
||||
return -EINVAL;
|
||||
/* FIXME: LUKS1 requires offset == 0 || offset >= luks1_hdr_size */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption helpers
|
||||
*
|
||||
* Copyright (C) 2015-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019, Ondrej Kozina
|
||||
* Copyright (C) 2015-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2020, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -165,7 +165,7 @@ static uint32_t reencrypt_alignment(struct luks2_hdr *hdr)
|
||||
if (!json_object_object_get_ex(jobj_area, "sector_size", &jobj_sector_size))
|
||||
return 0;
|
||||
|
||||
return json_object_get_uint32(jobj_sector_size);
|
||||
return crypt_jobj_get_uint32(jobj_sector_size);
|
||||
}
|
||||
|
||||
static json_object *_enc_create_segments_shift_after(struct crypt_device *cd,
|
||||
@@ -200,13 +200,13 @@ static json_object *_enc_create_segments_shift_after(struct crypt_device *cd,
|
||||
json_segment_remove_flag(jobj_seg_new, "in-reencryption");
|
||||
tmp = rh->length;
|
||||
} else {
|
||||
json_object_object_add(jobj_seg_new, "offset", json_object_new_uint64(rh->offset + data_offset));
|
||||
json_object_object_add(jobj_seg_new, "iv_tweak", json_object_new_uint64(rh->offset >> SECTOR_SHIFT));
|
||||
json_object_object_add(jobj_seg_new, "offset", crypt_jobj_new_uint64(rh->offset + data_offset));
|
||||
json_object_object_add(jobj_seg_new, "iv_tweak", crypt_jobj_new_uint64(rh->offset >> SECTOR_SHIFT));
|
||||
tmp = json_segment_get_size(jobj_seg_new, 0) + rh->length;
|
||||
}
|
||||
|
||||
/* alter size of new segment, reenc_seg == 0 we're finished */
|
||||
json_object_object_add(jobj_seg_new, "size", reenc_seg > 0 ? json_object_new_uint64(tmp) : json_object_new_string("dynamic"));
|
||||
json_object_object_add(jobj_seg_new, "size", reenc_seg > 0 ? crypt_jobj_new_uint64(tmp) : json_object_new_string("dynamic"));
|
||||
json_object_object_add_by_uint(jobj_segs_post, reenc_seg, jobj_seg_new);
|
||||
|
||||
return jobj_segs_post;
|
||||
@@ -256,7 +256,7 @@ static json_object *reencrypt_make_hot_segments_encrypt_shift(struct crypt_devic
|
||||
jobj_seg_shrunk = NULL;
|
||||
if (json_object_copy(LUKS2_get_segment_jobj(hdr, sg), &jobj_seg_shrunk))
|
||||
goto err;
|
||||
json_object_object_add(jobj_seg_shrunk, "size", json_object_new_uint64(segment_size - rh->length));
|
||||
json_object_object_add(jobj_seg_shrunk, "size", crypt_jobj_new_uint64(segment_size - rh->length));
|
||||
json_object_object_add_by_uint(jobj_segs_hot, sg++, jobj_seg_shrunk);
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ static json_object *reencrypt_make_post_segments_forward(struct crypt_device *cd
|
||||
goto err;
|
||||
jobj_old_seg = jobj_old_seg_copy;
|
||||
fixed_length = rh->device_size - fixed_length;
|
||||
json_object_object_add(jobj_old_seg, "size", json_object_new_uint64(fixed_length));
|
||||
json_object_object_add(jobj_old_seg, "size", crypt_jobj_new_uint64(fixed_length));
|
||||
} else
|
||||
json_object_get(jobj_old_seg);
|
||||
json_object_object_add_by_uint(jobj_segs_post, 1, jobj_old_seg);
|
||||
@@ -491,7 +491,7 @@ static json_object *reencrypt_make_hot_segments_backward(struct crypt_device *cd
|
||||
if (rh->offset) {
|
||||
if (json_object_copy(LUKS2_get_segment_jobj(hdr, 0), &jobj_old_seg))
|
||||
goto err;
|
||||
json_object_object_add(jobj_old_seg, "size", json_object_new_uint64(rh->offset));
|
||||
json_object_object_add(jobj_old_seg, "size", crypt_jobj_new_uint64(rh->offset));
|
||||
|
||||
json_object_object_add_by_uint(jobj_segs_hot, sg++, jobj_old_seg);
|
||||
}
|
||||
@@ -575,7 +575,7 @@ static uint64_t reencrypt_data_shift(struct luks2_hdr *hdr)
|
||||
if (!json_object_object_get_ex(jobj_area, "shift_size", &jobj_data_shift))
|
||||
return 0;
|
||||
|
||||
return json_object_get_uint64(jobj_data_shift);
|
||||
return crypt_jobj_get_uint64(jobj_data_shift);
|
||||
}
|
||||
|
||||
static crypt_reencrypt_mode_info reencrypt_mode(struct luks2_hdr *hdr)
|
||||
@@ -824,7 +824,7 @@ static uint64_t reencrypt_length(struct crypt_device *cd,
|
||||
uint64_t length_max)
|
||||
{
|
||||
unsigned long dummy, optimal_alignment;
|
||||
uint64_t length;
|
||||
uint64_t length, soft_mem_limit;
|
||||
|
||||
if (rh->rp.type == REENC_PROTECTION_NONE)
|
||||
length = length_max ?: LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH;
|
||||
@@ -835,6 +835,16 @@ static uint64_t reencrypt_length(struct crypt_device *cd,
|
||||
else
|
||||
length = keyslot_area_length;
|
||||
|
||||
/* hard limit */
|
||||
if (length > LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH)
|
||||
length = LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH;
|
||||
|
||||
/* soft limit is 1/4 of system memory */
|
||||
soft_mem_limit = crypt_getphysmemory_kb() << 8; /* multiply by (1024/4) */
|
||||
|
||||
if (soft_mem_limit && length > soft_mem_limit)
|
||||
length = soft_mem_limit;
|
||||
|
||||
if (length_max && length > length_max)
|
||||
length = length_max;
|
||||
|
||||
@@ -940,6 +950,11 @@ static int reencrypt_context_init(struct crypt_device *cd, struct luks2_hdr *hdr
|
||||
rh->fixed_length = false;
|
||||
|
||||
rh->length = reencrypt_length(cd, hdr, rh, area_length, params->max_hotzone_size << SECTOR_SHIFT);
|
||||
if (!rh->length) {
|
||||
log_dbg(cd, "Invalid reencryption length.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (reencrypt_offset(hdr, rh->direction, device_size, &rh->length, &rh->offset)) {
|
||||
log_dbg(cd, "Failed to get reencryption offset.");
|
||||
return -EINVAL;
|
||||
@@ -1386,12 +1401,12 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read journaled data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -1421,13 +1436,13 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -1777,14 +1792,15 @@ out:
|
||||
* 2) can't we derive hotzone device name from crypt context? (unlocked name, device uuid, etc?)
|
||||
*/
|
||||
static int reencrypt_load_overlay_device(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
const char *overlay, const char *hotzone, struct volume_key *vks, uint64_t size)
|
||||
const char *overlay, const char *hotzone, struct volume_key *vks, uint64_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
char hz_path[PATH_MAX];
|
||||
int r;
|
||||
|
||||
struct device *hz_dev = NULL;
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.flags = CRYPT_ACTIVATE_KEYRING_KEY,
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
log_dbg(cd, "Loading new table for overlay device %s.", overlay);
|
||||
@@ -1868,15 +1884,12 @@ err:
|
||||
}
|
||||
|
||||
static int reencrypt_swap_backing_device(struct crypt_device *cd, const char *name,
|
||||
const char *new_backend_name, uint32_t flags)
|
||||
const char *new_backend_name)
|
||||
{
|
||||
int r;
|
||||
struct device *overlay_dev = NULL;
|
||||
char overlay_path[PATH_MAX] = { 0 };
|
||||
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.flags = flags,
|
||||
};
|
||||
struct crypt_dm_active_device dmd = {};
|
||||
|
||||
log_dbg(cd, "Redirecting %s mapping to new backing device: %s.", name, new_backend_name);
|
||||
|
||||
@@ -1902,7 +1915,7 @@ static int reencrypt_swap_backing_device(struct crypt_device *cd, const char *na
|
||||
r = dm_reload_device(cd, name, &dmd, 0, 0);
|
||||
if (!r) {
|
||||
log_dbg(cd, "Resuming device %s", name);
|
||||
r = dm_resume_device(cd, name, dmd.flags);
|
||||
r = dm_resume_device(cd, name, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -1971,7 +1984,7 @@ static int reencrypt_init_device_stack(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
/* swap origin mapping to overlay device */
|
||||
r = reencrypt_swap_backing_device(cd, rh->device_name, rh->overlay_name, CRYPT_ACTIVATE_KEYRING_KEY);
|
||||
r = reencrypt_swap_backing_device(cd, rh->device_name, rh->overlay_name);
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to load new mapping for device %s."), rh->device_name);
|
||||
goto err;
|
||||
@@ -2033,9 +2046,10 @@ static int reencrypt_refresh_overlay_devices(struct crypt_device *cd,
|
||||
const char *overlay,
|
||||
const char *hotzone,
|
||||
struct volume_key *vks,
|
||||
uint64_t device_size)
|
||||
uint64_t device_size,
|
||||
uint32_t flags)
|
||||
{
|
||||
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone, vks, device_size);
|
||||
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone, vks, device_size, flags);
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to reload device %s."), overlay);
|
||||
return REENC_ERR;
|
||||
@@ -2223,8 +2237,9 @@ static int reencrypt_verify_and_upload_keys(struct crypt_device *cd, struct luks
|
||||
else {
|
||||
if (LUKS2_digest_verify_by_digest(cd, hdr, digest_new, vk) != digest_new)
|
||||
return -EINVAL;
|
||||
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
|
||||
if (r)
|
||||
|
||||
if (crypt_use_keyring_for_vk(cd) &&
|
||||
(r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk))))
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -2239,8 +2254,8 @@ static int reencrypt_verify_and_upload_keys(struct crypt_device *cd, struct luks
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
|
||||
if (r)
|
||||
if (crypt_use_keyring_for_vk(cd) &&
|
||||
(r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk))))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -2516,7 +2531,7 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
else if (ri == CRYPT_REENCRYPT_CRASH)
|
||||
r = reencrypt_load_crashed(cd, hdr, device_size, &tmp);
|
||||
else if (ri == CRYPT_REENCRYPT_NONE) {
|
||||
log_err(cd, _("No LUKS2 reencryption in progress."));
|
||||
log_err(cd, _("Device not marked for LUKS2 reencryption."));
|
||||
return -EINVAL;
|
||||
} else
|
||||
r = -EINVAL;
|
||||
@@ -2531,21 +2546,10 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
static int reencrypt_lock_internal(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
int r;
|
||||
char *lock_resource;
|
||||
const char *tmp = crypt_get_uuid(cd);
|
||||
|
||||
if (!tmp && !uuid)
|
||||
return -EINVAL;
|
||||
if (!uuid)
|
||||
uuid = tmp;
|
||||
if (!tmp)
|
||||
tmp = uuid;
|
||||
if (strcmp(uuid, tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (!crypt_metadata_locking_enabled()) {
|
||||
*reencrypt_lock = NULL;
|
||||
@@ -2567,6 +2571,36 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
int r;
|
||||
char hdr_uuid[37];
|
||||
const char *uuid = crypt_get_uuid(cd);
|
||||
|
||||
if (!dm_uuid)
|
||||
return -EINVAL;
|
||||
|
||||
if (!uuid) {
|
||||
r = snprintf(hdr_uuid, sizeof(hdr_uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
|
||||
dm_uuid + 6, dm_uuid + 14, dm_uuid + 18, dm_uuid + 22, dm_uuid + 26);
|
||||
if (r < 0 || (size_t)r != (sizeof(hdr_uuid) - 1))
|
||||
return -EINVAL;
|
||||
} else if (crypt_uuid_cmp(dm_uuid, uuid))
|
||||
return -EINVAL;
|
||||
|
||||
return reencrypt_lock_internal(cd, uuid, reencrypt_lock);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
if (!cd || !crypt_get_type(cd) || strcmp(crypt_get_type(cd), CRYPT_LUKS2))
|
||||
return -EINVAL;
|
||||
|
||||
return reencrypt_lock_internal(cd, crypt_get_uuid(cd), reencrypt_lock);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock)
|
||||
{
|
||||
@@ -2590,7 +2624,7 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr *
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &h);
|
||||
r = crypt_reencrypt_lock(cd, &h);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption process is already running."));
|
||||
@@ -2637,6 +2671,7 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
|
||||
uint64_t minimal_size, device_size, mapping_size = 0, required_size = 0;
|
||||
bool dynamic;
|
||||
struct crypt_params_reencrypt rparams = {};
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (params) {
|
||||
rparams = *params;
|
||||
@@ -2693,6 +2728,7 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
|
||||
DM_ACTIVE_CRYPT_CIPHER, &dmd_target);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
flags = dmd_target.flags;
|
||||
|
||||
r = LUKS2_assembly_multisegment_dmd(cd, hdr, *vks, LUKS2_get_segments_jobj(hdr), &dmd_source);
|
||||
if (!r) {
|
||||
@@ -2767,6 +2803,8 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
|
||||
}
|
||||
}
|
||||
|
||||
rh->flags = flags;
|
||||
|
||||
MOVE_REF(rh->vks, *vks);
|
||||
MOVE_REF(rh->reenc_lock, reencrypt_lock);
|
||||
|
||||
@@ -2790,7 +2828,7 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd,
|
||||
crypt_reencrypt_info ri;
|
||||
struct crypt_lock_handle *reencrypt_lock;
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot perform recovery."));
|
||||
@@ -2917,7 +2955,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
|
||||
r = reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params);
|
||||
|
||||
crypt_memzero(passphrase, passphrase_size);
|
||||
crypt_safe_memzero(passphrase, passphrase_size);
|
||||
free(passphrase);
|
||||
|
||||
return r;
|
||||
@@ -2968,7 +3006,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (online) {
|
||||
r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name, rh->vks, rh->device_size);
|
||||
r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name, rh->vks, rh->device_size, rh->flags);
|
||||
/* Teardown overlay devices with dm-error. None bio shall pass! */
|
||||
if (r != REENC_OK)
|
||||
return r;
|
||||
@@ -3092,6 +3130,7 @@ static int reencrypt_wipe_moved_segment(struct crypt_device *cd, struct luks2_hd
|
||||
static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr, struct luks2_reenc_context *rh)
|
||||
{
|
||||
int i, r;
|
||||
uint32_t dmt_flags;
|
||||
bool finished = !(rh->device_size > rh->progress);
|
||||
|
||||
if (rh->rp.type == REENC_PROTECTION_NONE &&
|
||||
@@ -3101,16 +3140,20 @@ static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
}
|
||||
|
||||
if (rh->online) {
|
||||
r = LUKS2_reload(cd, rh->device_name, rh->vks, rh->device_size, CRYPT_ACTIVATE_KEYRING_KEY | CRYPT_ACTIVATE_SHARED);
|
||||
r = LUKS2_reload(cd, rh->device_name, rh->vks, rh->device_size, rh->flags);
|
||||
if (r)
|
||||
log_err(cd, _("Failed to reload device %s."), rh->device_name);
|
||||
if (!r) {
|
||||
r = dm_resume_device(cd, rh->device_name, 0);
|
||||
r = dm_resume_device(cd, rh->device_name, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
|
||||
if (r)
|
||||
log_err(cd, _("Failed to resume device %s."), rh->device_name);
|
||||
}
|
||||
dm_remove_device(cd, rh->overlay_name, 0);
|
||||
dm_remove_device(cd, rh->hotzone_name, 0);
|
||||
|
||||
if (!r && finished && rh->mode == CRYPT_REENCRYPT_DECRYPT &&
|
||||
!dm_flags(cd, DM_LINEAR, &dmt_flags) && (dmt_flags & DM_DEFERRED_SUPPORTED))
|
||||
dm_remove_device(cd, rh->device_name, CRYPT_DEACTIVATE_DEFERRED);
|
||||
}
|
||||
|
||||
if (finished) {
|
||||
@@ -3342,7 +3385,7 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
|
||||
uint64_t minimal_size, device_size;
|
||||
int keyslot, r = -EINVAL;
|
||||
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||
struct volume_key *vk, *_vks = NULL;
|
||||
struct volume_key *vk = NULL, *_vks = NULL;
|
||||
|
||||
log_dbg(cd, "Entering reencryption crash recovery.");
|
||||
|
||||
@@ -3355,12 +3398,14 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
|
||||
goto err;
|
||||
keyslot = r;
|
||||
|
||||
vk = _vks;
|
||||
if (crypt_use_keyring_for_vk(cd))
|
||||
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)
|
||||
goto err;
|
||||
vk = vk->next;
|
||||
vk = crypt_volume_key_next(vk);
|
||||
}
|
||||
|
||||
if (luks2_check_device_size(cd, hdr, minimal_size, &device_size, true, false))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, internal segment handling
|
||||
*
|
||||
* Copyright (C) 2018-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019, Ondrej Kozina
|
||||
* Copyright (C) 2018-2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -55,7 +55,7 @@ uint64_t json_segment_get_offset(json_object *jobj_segment, unsigned blockwise)
|
||||
!json_object_object_get_ex(jobj_segment, "offset", &jobj))
|
||||
return 0;
|
||||
|
||||
return blockwise ? json_object_get_uint64(jobj) >> SECTOR_SHIFT : json_object_get_uint64(jobj);
|
||||
return blockwise ? crypt_jobj_get_uint64(jobj) >> SECTOR_SHIFT : crypt_jobj_get_uint64(jobj);
|
||||
}
|
||||
|
||||
const char *json_segment_type(json_object *jobj_segment)
|
||||
@@ -77,7 +77,7 @@ uint64_t json_segment_get_iv_offset(json_object *jobj_segment)
|
||||
!json_object_object_get_ex(jobj_segment, "iv_tweak", &jobj))
|
||||
return 0;
|
||||
|
||||
return json_object_get_uint64(jobj);
|
||||
return crypt_jobj_get_uint64(jobj);
|
||||
}
|
||||
|
||||
uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise)
|
||||
@@ -88,7 +88,7 @@ uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise)
|
||||
!json_object_object_get_ex(jobj_segment, "size", &jobj))
|
||||
return 0;
|
||||
|
||||
return blockwise ? json_object_get_uint64(jobj) >> SECTOR_SHIFT : json_object_get_uint64(jobj);
|
||||
return blockwise ? crypt_jobj_get_uint64(jobj) >> SECTOR_SHIFT : crypt_jobj_get_uint64(jobj);
|
||||
}
|
||||
|
||||
const char *json_segment_get_cipher(json_object *jobj_segment)
|
||||
@@ -229,8 +229,8 @@ static json_object *_segment_create_generic(const char *type, uint64_t offset, c
|
||||
return NULL;
|
||||
|
||||
json_object_object_add(jobj, "type", json_object_new_string(type));
|
||||
json_object_object_add(jobj, "offset", json_object_new_uint64(offset));
|
||||
json_object_object_add(jobj, "size", length ? json_object_new_uint64(*length) : json_object_new_string("dynamic"));
|
||||
json_object_object_add(jobj, "offset", crypt_jobj_new_uint64(offset));
|
||||
json_object_object_add(jobj, "size", length ? crypt_jobj_new_uint64(*length) : json_object_new_string("dynamic"));
|
||||
|
||||
return jobj;
|
||||
}
|
||||
@@ -252,7 +252,7 @@ json_object *json_segment_create_crypt(uint64_t offset,
|
||||
if (!jobj)
|
||||
return NULL;
|
||||
|
||||
json_object_object_add(jobj, "iv_tweak", json_object_new_uint64(iv_offset));
|
||||
json_object_object_add(jobj, "iv_tweak", crypt_jobj_new_uint64(iv_offset));
|
||||
json_object_object_add(jobj, "encryption", json_object_new_string(cipher));
|
||||
json_object_object_add(jobj, "sector_size", json_object_new_int(sector_size));
|
||||
if (reencryption)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, token handling
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -332,7 +332,7 @@ static void LUKS2_token_buffer_free(struct crypt_device *cd,
|
||||
if (h->buffer_free)
|
||||
h->buffer_free(buffer, buffer_len);
|
||||
else {
|
||||
crypt_memzero(buffer, buffer_len);
|
||||
crypt_safe_memzero(buffer, buffer_len);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, kernel keyring token
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* cryptsetup kernel RNG access functions
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
@@ -28,10 +27,6 @@
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
static int random_initialised = 0;
|
||||
|
||||
#define URANDOM_DEVICE "/dev/urandom"
|
||||
|
||||
398
lib/setup.c
398
lib/setup.c
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -36,6 +35,7 @@
|
||||
#include "verity.h"
|
||||
#include "tcrypt.h"
|
||||
#include "integrity.h"
|
||||
#include "bitlk.h"
|
||||
#include "utils_device_locking.h"
|
||||
#include "internal.h"
|
||||
|
||||
@@ -50,6 +50,7 @@ struct crypt_device {
|
||||
|
||||
struct volume_key *volume_key;
|
||||
int rng_type;
|
||||
uint32_t compatibility;
|
||||
struct crypt_pbkdf_type pbkdf;
|
||||
|
||||
/* global context scope settings */
|
||||
@@ -95,7 +96,7 @@ struct crypt_device {
|
||||
} loopaes;
|
||||
struct { /* used in CRYPT_VERITY */
|
||||
struct crypt_params_verity hdr;
|
||||
char *root_hash;
|
||||
const char *root_hash;
|
||||
unsigned int root_hash_size;
|
||||
char *uuid;
|
||||
struct device *fec_device;
|
||||
@@ -108,7 +109,12 @@ struct crypt_device {
|
||||
struct crypt_params_integrity params;
|
||||
struct volume_key *journal_mac_key;
|
||||
struct volume_key *journal_crypt_key;
|
||||
uint32_t sb_flags;
|
||||
} integrity;
|
||||
struct { /* used in CRYPT_BITLK */
|
||||
struct bitlk_metadata params;
|
||||
char *cipher_spec;
|
||||
} bitlk;
|
||||
struct { /* used if initialized without header by name */
|
||||
char *active_name;
|
||||
/* buffers, must refresh from kernel on every query */
|
||||
@@ -224,7 +230,7 @@ int init_crypto(struct crypt_device *ctx)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_backend_init(ctx);
|
||||
r = crypt_backend_init();
|
||||
if (r < 0)
|
||||
log_err(ctx, _("Cannot initialize crypto backend."));
|
||||
|
||||
@@ -315,6 +321,11 @@ static int isINTEGRITY(const char *type)
|
||||
return (type && !strcmp(CRYPT_INTEGRITY, type));
|
||||
}
|
||||
|
||||
static int isBITLK(const char *type)
|
||||
{
|
||||
return (type && !strcmp(CRYPT_BITLK, type));
|
||||
}
|
||||
|
||||
static int _onlyLUKS(struct crypt_device *cd, uint32_t cdflags)
|
||||
{
|
||||
int r = 0;
|
||||
@@ -510,6 +521,11 @@ int PLAIN_activate(struct crypt_device *cd,
|
||||
log_dbg(cd, "Trying to activate PLAIN device %s using cipher %s.",
|
||||
name, crypt_get_cipher_spec(cd));
|
||||
|
||||
if (MISALIGNED(size, device_block_size(cd, crypt_data_device(cd)) >> SECTOR_SHIFT)) {
|
||||
log_err(cd, _("Device size is not aligned to device logical block size."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
|
||||
vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd),
|
||||
crypt_get_data_offset(cd), crypt_get_integrity(cd),
|
||||
@@ -567,6 +583,9 @@ int crypt_init(struct crypt_device **cd, const char *device)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(NULL, "Allocating context for crypt device %s.", device ?: "(none)");
|
||||
#if !HAVE_DECL_O_CLOEXEC
|
||||
log_dbg(NULL, "Running without O_CLOEXEC.");
|
||||
#endif
|
||||
|
||||
if (!(h = malloc(sizeof(struct crypt_device))))
|
||||
return -ENOMEM;
|
||||
@@ -659,10 +678,10 @@ int crypt_init_data_device(struct crypt_device **cd, const char *device, const c
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_init(cd, device);
|
||||
if (r || !data_device)
|
||||
if (r || !data_device || !strcmp(device, data_device))
|
||||
return r;
|
||||
|
||||
log_dbg(NULL, "Setting ciphertext data device to %s.", data_device ?: "(none)");
|
||||
log_dbg(NULL, "Setting ciphertext data device to %s.", data_device);
|
||||
r = _crypt_set_data_device(*cd, data_device);
|
||||
if (r) {
|
||||
crypt_free(*cd);
|
||||
@@ -721,9 +740,6 @@ out:
|
||||
free(type);
|
||||
LUKS2_hdr_free(cd, &hdr2);
|
||||
}
|
||||
/* FIXME: why? */
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -758,7 +774,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
|
||||
if (isLUKS1(requested_type) || version == 1) {
|
||||
if (cd->type && isLUKS2(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -798,7 +814,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
memcpy(&cd->u.luks1.hdr, &hdr, sizeof(hdr));
|
||||
} else if (isLUKS2(requested_type) || version == 2 || version == 0) {
|
||||
if (cd->type && isLUKS1(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -817,7 +833,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -881,7 +897,7 @@ static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verit
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.hash_name);
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
|
||||
free(cd->u.verity.uuid);
|
||||
crypt_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
|
||||
crypt_safe_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -917,7 +933,7 @@ static int _crypt_load_integrity(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params);
|
||||
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params, &cd->u.integrity.sb_flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -960,6 +976,31 @@ static int _crypt_load_integrity(struct crypt_device *cd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _crypt_load_bitlk(struct crypt_device *cd,
|
||||
struct bitlk_metadata *params)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = init_crypto(cd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = BITLK_read_sb(cd, &cd->u.bitlk.params);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (asprintf(&cd->u.bitlk.cipher_spec, "%s-%s",
|
||||
cd->u.bitlk.params.cipher, cd->u.bitlk.params.cipher_mode) < 0) {
|
||||
cd->u.bitlk.cipher_spec = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!cd->type && !(cd->type = strdup(CRYPT_BITLK)))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_load(struct crypt_device *cd,
|
||||
const char *requested_type,
|
||||
void *params)
|
||||
@@ -982,29 +1023,35 @@ int crypt_load(struct crypt_device *cd,
|
||||
|
||||
if (!requested_type || isLUKS1(requested_type) || isLUKS2(requested_type)) {
|
||||
if (cd->type && !isLUKS1(cd->type) && !isLUKS2(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = _crypt_load_luks(cd, requested_type, 1, 0);
|
||||
} else if (isVERITY(requested_type)) {
|
||||
if (cd->type && !isVERITY(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_verity(cd, params);
|
||||
} else if (isTCRYPT(requested_type)) {
|
||||
if (cd->type && !isTCRYPT(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_tcrypt(cd, params);
|
||||
} else if (isINTEGRITY(requested_type)) {
|
||||
if (cd->type && !isINTEGRITY(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialised to type %s", cd->type);
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_integrity(cd, params);
|
||||
} else if (isBITLK(requested_type)) {
|
||||
if (cd->type && !isBITLK(cd->type)) {
|
||||
log_dbg(cd, "Context is already initialized to type %s", cd->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = _crypt_load_bitlk(cd, params);
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1081,7 +1128,7 @@ static void crypt_free_type(struct crypt_device *cd)
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.hash_device);
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.fec_device);
|
||||
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
|
||||
free(cd->u.verity.root_hash);
|
||||
free(CONST_CAST(void*)cd->u.verity.root_hash);
|
||||
free(cd->u.verity.uuid);
|
||||
device_free(cd, cd->u.verity.fec_device);
|
||||
} else if (isINTEGRITY(cd->type)) {
|
||||
@@ -1090,6 +1137,9 @@ static void crypt_free_type(struct crypt_device *cd)
|
||||
free(CONST_CAST(void*)cd->u.integrity.params.journal_crypt);
|
||||
crypt_free_volume_key(cd->u.integrity.journal_crypt_key);
|
||||
crypt_free_volume_key(cd->u.integrity.journal_mac_key);
|
||||
} else if (isBITLK(cd->type)) {
|
||||
free(cd->u.bitlk.cipher_spec);
|
||||
BITLK_bitlk_metadata_free(&cd->u.bitlk.params);
|
||||
} else if (!cd->type) {
|
||||
free(cd->u.none.active_name);
|
||||
cd->u.none.active_name = NULL;
|
||||
@@ -1242,6 +1292,13 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
|
||||
} else if (isTCRYPT(cd->type) && single_segment(&dmd) && tgt->type == DM_CRYPT) {
|
||||
r = TCRYPT_init_by_name(cd, name, dmd.uuid, tgt, &cd->device,
|
||||
&cd->u.tcrypt.params, &cd->u.tcrypt.hdr);
|
||||
} else if (isBITLK(cd->type)) {
|
||||
r = _crypt_load_bitlk(cd, NULL);
|
||||
if (r < 0) {
|
||||
log_dbg(cd, "BITLK device header not available.");
|
||||
crypt_set_null_type(cd);
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
out:
|
||||
dm_targets_free(cd, &dmd);
|
||||
@@ -1264,6 +1321,7 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
|
||||
r = dm_query_device(cd, name,
|
||||
DM_ACTIVE_DEVICE |
|
||||
DM_ACTIVE_VERITY_HASH_DEVICE |
|
||||
DM_ACTIVE_VERITY_ROOT_HASH |
|
||||
DM_ACTIVE_VERITY_PARAMS, &dmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -1295,6 +1353,7 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
|
||||
cd->u.verity.hdr.fec_roots = tgt->u.verity.vp->fec_roots;
|
||||
MOVE_REF(cd->u.verity.fec_device, tgt->u.verity.fec_device);
|
||||
MOVE_REF(cd->metadata_device, tgt->u.verity.hash_device);
|
||||
MOVE_REF(cd->u.verity.root_hash, tgt->u.verity.root_hash);
|
||||
}
|
||||
out:
|
||||
dm_targets_free(cd, &dmd);
|
||||
@@ -1408,6 +1467,8 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||
(*cd)->type = strdup(CRYPT_TCRYPT);
|
||||
else if (!strncmp(CRYPT_INTEGRITY, dmd.uuid, sizeof(CRYPT_INTEGRITY)-1))
|
||||
(*cd)->type = strdup(CRYPT_INTEGRITY);
|
||||
else if (!strncmp(CRYPT_BITLK, dmd.uuid, sizeof(CRYPT_BITLK)-1))
|
||||
(*cd)->type = strdup(CRYPT_BITLK);
|
||||
else
|
||||
log_dbg(NULL, "Unknown UUID set, some parameters are not set.");
|
||||
} else
|
||||
@@ -1419,7 +1480,7 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Try to initialise basic parameters from active device */
|
||||
/* Try to initialize basic parameters from active device */
|
||||
|
||||
if (tgt->type == DM_CRYPT || tgt->type == DM_LINEAR)
|
||||
r = _init_by_name_crypt(*cd, name);
|
||||
@@ -2085,6 +2146,7 @@ static int _crypt_format_integrity(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params)
|
||||
{
|
||||
int r;
|
||||
uint32_t integrity_tag_size;
|
||||
char *integrity = NULL, *journal_integrity = NULL, *journal_crypt = NULL;
|
||||
struct volume_key *journal_crypt_key = NULL, *journal_mac_key = NULL;
|
||||
|
||||
@@ -2141,6 +2203,14 @@ static int _crypt_format_integrity(struct crypt_device *cd,
|
||||
goto err;
|
||||
}
|
||||
|
||||
integrity_tag_size = INTEGRITY_hash_tag_size(integrity);
|
||||
if (integrity_tag_size > 0 && params->tag_size && integrity_tag_size != params->tag_size)
|
||||
log_std(cd, _("WARNING: Requested tag size %d bytes differs from %s size output (%d bytes).\n"),
|
||||
params->tag_size, integrity, integrity_tag_size);
|
||||
|
||||
if (params->tag_size)
|
||||
integrity_tag_size = params->tag_size;
|
||||
|
||||
cd->u.integrity.journal_crypt_key = journal_crypt_key;
|
||||
cd->u.integrity.journal_mac_key = journal_mac_key;
|
||||
cd->u.integrity.params.journal_size = params->journal_size;
|
||||
@@ -2149,7 +2219,7 @@ static int _crypt_format_integrity(struct crypt_device *cd,
|
||||
cd->u.integrity.params.interleave_sectors = params->interleave_sectors;
|
||||
cd->u.integrity.params.buffer_sectors = params->buffer_sectors;
|
||||
cd->u.integrity.params.sector_size = params->sector_size;
|
||||
cd->u.integrity.params.tag_size = params->tag_size;
|
||||
cd->u.integrity.params.tag_size = integrity_tag_size;
|
||||
cd->u.integrity.params.integrity = integrity;
|
||||
cd->u.integrity.params.journal_integrity = journal_integrity;
|
||||
cd->u.integrity.params.journal_crypt = journal_crypt;
|
||||
@@ -2696,7 +2766,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
||||
* explicit size stored in metadata (length != "dynamic")
|
||||
*/
|
||||
|
||||
/* Device context type must be initialised */
|
||||
/* Device context type must be initialized */
|
||||
if (!cd || !cd->type || !name)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -2750,6 +2820,12 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (MISALIGNED(new_size, device_block_size(cd, crypt_data_device(cd)) >> SECTOR_SHIFT)) {
|
||||
log_err(cd, _("Device size is not aligned to device logical block size."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dmd.uuid = crypt_get_uuid(cd);
|
||||
dmd.size = new_size;
|
||||
dmd.flags = dmdq.flags | CRYPT_ACTIVATE_REFRESH;
|
||||
@@ -2891,8 +2967,8 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
else
|
||||
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
|
||||
|
||||
crypt_memzero(&hdr1, sizeof(hdr1));
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
crypt_safe_memzero(&hdr1, sizeof(hdr1));
|
||||
crypt_safe_memzero(&hdr2, sizeof(hdr2));
|
||||
} else if (isLUKS2(cd->type) && (!requested_type || isLUKS2(requested_type))) {
|
||||
r = LUKS2_hdr_restore(cd, &cd->u.luks2.hdr, backup_file);
|
||||
if (r)
|
||||
@@ -2927,7 +3003,7 @@ void crypt_free(struct crypt_device *cd)
|
||||
free(CONST_CAST(void*)cd->pbkdf.hash);
|
||||
|
||||
/* Some structures can contain keys (TCRYPT), wipe it */
|
||||
crypt_memzero(cd, sizeof(*cd));
|
||||
crypt_safe_memzero(cd, sizeof(*cd));
|
||||
free(cd);
|
||||
}
|
||||
|
||||
@@ -3136,7 +3212,7 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
r = dm_resume_and_reinstate_key(cd, name, vk);
|
||||
if (r)
|
||||
if (r < 0)
|
||||
log_err(cd, _("Error during resuming device %s."), name);
|
||||
out:
|
||||
crypt_safe_free(passphrase_read);
|
||||
@@ -3167,6 +3243,65 @@ int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
|
||||
keyfile, keyfile_size, keyfile_offset);
|
||||
}
|
||||
|
||||
int crypt_resume_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size)
|
||||
{
|
||||
struct volume_key *vk = NULL;
|
||||
int r;
|
||||
|
||||
if (!name || !volume_key)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(cd, "Resuming volume %s by volume key.", name);
|
||||
|
||||
if ((r = onlyLUKS(cd)))
|
||||
return r;
|
||||
|
||||
r = dm_status_suspended(cd, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!r) {
|
||||
log_err(cd, _("Volume %s is not suspended."), name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vk = crypt_alloc_volume_key(volume_key_size, volume_key);
|
||||
if (!vk)
|
||||
return -ENOMEM;
|
||||
|
||||
if (isLUKS1(cd->type))
|
||||
r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
|
||||
else if (isLUKS2(cd->type))
|
||||
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||
else
|
||||
r = -EINVAL;
|
||||
if (r == -EPERM || r == -ENOENT)
|
||||
log_err(cd, _("Volume key does not match the volume."));
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = 0;
|
||||
|
||||
if (crypt_use_keyring_for_vk(cd)) {
|
||||
r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr, vk, CRYPT_DEFAULT_SEGMENT);
|
||||
if (!r)
|
||||
r = crypt_volume_key_load_in_keyring(cd, vk);
|
||||
}
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = dm_resume_and_reinstate_key(cd, name, vk);
|
||||
if (r < 0)
|
||||
log_err(cd, _("Error during resuming device %s."), name);
|
||||
out:
|
||||
if (r < 0)
|
||||
crypt_drop_keyring_key(cd, vk);
|
||||
crypt_free_volume_key(vk);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keyslot manipulation
|
||||
*/
|
||||
@@ -3610,7 +3745,7 @@ static int _create_device_with_integrity(struct crypt_device *cd,
|
||||
|
||||
device_check = dmd->flags & CRYPT_ACTIVATE_SHARED ? DEV_OK : DEV_EXCL;
|
||||
|
||||
r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi);
|
||||
r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi, 0);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -3632,6 +3767,27 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int kernel_keyring_support(void)
|
||||
{
|
||||
static unsigned _checked = 0;
|
||||
|
||||
if (!_checked) {
|
||||
_kernel_keyring_supported = keyring_check();
|
||||
_checked = 1;
|
||||
}
|
||||
|
||||
return _kernel_keyring_supported;
|
||||
}
|
||||
|
||||
static int dmcrypt_keyring_bug(void)
|
||||
{
|
||||
uint64_t kversion;
|
||||
|
||||
if (kernel_version(&kversion))
|
||||
return 1;
|
||||
return kversion < version(4,15,0,0);
|
||||
}
|
||||
|
||||
int create_or_reload_device(struct crypt_device *cd, const char *name,
|
||||
const char *type, struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
@@ -3706,7 +3862,7 @@ static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct
|
||||
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
|
||||
if (r < 0)
|
||||
return r;
|
||||
vk = vk->next;
|
||||
vk = crypt_volume_key_next(vk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -3819,7 +3975,7 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd,
|
||||
if (crypt_use_keyring_for_vk(cd))
|
||||
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot activate device."));
|
||||
@@ -3963,8 +4119,12 @@ static int _activate_by_passphrase(struct crypt_device *cd,
|
||||
} else if (isLUKS2(cd->type)) {
|
||||
r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags);
|
||||
keyslot = r;
|
||||
} else if (isBITLK(cd->type)) {
|
||||
r = BITLK_activate(cd, name, passphrase, passphrase_size,
|
||||
&cd->u.bitlk.params, flags);
|
||||
keyslot = 0;
|
||||
} else {
|
||||
log_err(cd, _("Device type is not properly initialised."));
|
||||
log_err(cd, _("Device type is not properly initialized."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
@@ -4103,7 +4263,6 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
|
||||
return crypt_activate_by_keyfile_device_offset(cd, name, keyslot, keyfile,
|
||||
keyfile_size, keyfile_offset, flags);
|
||||
}
|
||||
|
||||
int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
@@ -4198,25 +4357,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
if (!r && name)
|
||||
r = LUKS2_activate(cd, name, vk, flags);
|
||||
} else if (isVERITY(cd->type)) {
|
||||
/* volume_key == root hash */
|
||||
if (!volume_key || !volume_key_size) {
|
||||
log_err(cd, _("Incorrect root hash specified for verity device."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = VERITY_activate(cd, name, volume_key, volume_key_size, cd->u.verity.fec_device,
|
||||
&cd->u.verity.hdr, flags|CRYPT_ACTIVATE_READONLY);
|
||||
|
||||
if (r == -EPERM) {
|
||||
free(cd->u.verity.root_hash);
|
||||
cd->u.verity.root_hash = NULL;
|
||||
} if (!r) {
|
||||
cd->u.verity.root_hash_size = volume_key_size;
|
||||
if (!cd->u.verity.root_hash)
|
||||
cd->u.verity.root_hash = malloc(volume_key_size);
|
||||
if (cd->u.verity.root_hash)
|
||||
memcpy(cd->u.verity.root_hash, volume_key, volume_key_size);
|
||||
}
|
||||
r = crypt_activate_by_signed_key(cd, name, volume_key, volume_key_size, NULL, 0, flags);
|
||||
} else if (isTCRYPT(cd->type)) {
|
||||
if (!name)
|
||||
return 0;
|
||||
@@ -4232,9 +4373,10 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
}
|
||||
r = INTEGRITY_activate(cd, name, &cd->u.integrity.params, vk,
|
||||
cd->u.integrity.journal_crypt_key,
|
||||
cd->u.integrity.journal_mac_key, flags);
|
||||
cd->u.integrity.journal_mac_key, flags,
|
||||
cd->u.integrity.sb_flags);
|
||||
} else {
|
||||
log_err(cd, _("Device type is not properly initialised."));
|
||||
log_err(cd, _("Device type is not properly initialized."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
@@ -4245,6 +4387,77 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_activate_by_signed_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
uint32_t flags)
|
||||
{
|
||||
char description[512];
|
||||
int r;
|
||||
|
||||
if (!cd || !isVERITY(cd->type))
|
||||
return -EINVAL;
|
||||
|
||||
if (!volume_key || !volume_key_size || (!name && signature)) {
|
||||
log_err(cd, _("Incorrect root hash specified for verity device."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg(cd, "%s volume %s by signed key.", name ? "Activating" : "Checking", name ?: "");
|
||||
|
||||
if (cd->u.verity.hdr.flags & CRYPT_VERITY_ROOT_HASH_SIGNATURE && !signature) {
|
||||
log_err(cd, _("Root hash signature required."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = _activate_check_status(cd, name, flags & CRYPT_ACTIVATE_REFRESH);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (signature && !kernel_keyring_support()) {
|
||||
log_err(cd, _("Kernel keyring missing: required for passing signature to kernel."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* volume_key == root hash */
|
||||
free(CONST_CAST(void*)cd->u.verity.root_hash);
|
||||
cd->u.verity.root_hash = NULL;
|
||||
|
||||
if (signature) {
|
||||
r = snprintf(description, sizeof(description)-1, "cryptsetup:%s%s%s",
|
||||
crypt_get_uuid(cd) ?: "", crypt_get_uuid(cd) ? "-" : "", name);
|
||||
if (r < 0)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(cd, "Adding signature into keyring %s", description);
|
||||
r = keyring_add_key_in_thread_keyring(USER_KEY, description, signature, signature_size);
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to load key in kernel keyring."));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = VERITY_activate(cd, name, volume_key, volume_key_size,
|
||||
signature ? description : NULL,
|
||||
cd->u.verity.fec_device,
|
||||
&cd->u.verity.hdr, flags | CRYPT_ACTIVATE_READONLY);
|
||||
|
||||
if (!r) {
|
||||
cd->u.verity.root_hash_size = volume_key_size;
|
||||
cd->u.verity.root_hash = malloc(volume_key_size);
|
||||
if (cd->u.verity.root_hash)
|
||||
memcpy(CONST_CAST(void*)cd->u.verity.root_hash, volume_key, volume_key_size);
|
||||
}
|
||||
|
||||
if (signature)
|
||||
crypt_drop_keyring_key_by_description(cd, description, USER_KEY);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t flags)
|
||||
{
|
||||
struct crypt_device *fake_cd = NULL;
|
||||
@@ -4284,7 +4497,7 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
|
||||
if (isLUKS2(cd->type))
|
||||
hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||
|
||||
if (!strncmp(CRYPT_LUKS2, dmd.uuid ?: "", sizeof(CRYPT_LUKS2)-1) || hdr2)
|
||||
if ((dmd.uuid && !strncmp(CRYPT_LUKS2, dmd.uuid, sizeof(CRYPT_LUKS2)-1)) || hdr2)
|
||||
r = LUKS2_deactivate(cd, name, hdr2, &dmd, flags);
|
||||
else if (isTCRYPT(cd->type))
|
||||
r = TCRYPT_deactivate(cd, name, flags);
|
||||
@@ -4404,7 +4617,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
struct volume_key *vk = NULL;
|
||||
int key_len, r = -EINVAL;
|
||||
|
||||
if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !passphrase))
|
||||
if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !isVERITY(cd->type) && !passphrase))
|
||||
return -EINVAL;
|
||||
|
||||
if (isLUKS2(cd->type) && keyslot != CRYPT_ANY_SLOT)
|
||||
@@ -4434,10 +4647,18 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
passphrase, passphrase_size, &vk);
|
||||
} else if (isTCRYPT(cd->type)) {
|
||||
r = TCRYPT_get_volume_key(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params, &vk);
|
||||
} else if (isVERITY(cd->type)) {
|
||||
/* volume_key == root hash */
|
||||
if (cd->u.verity.root_hash) {
|
||||
memcpy(volume_key, cd->u.verity.root_hash, cd->u.verity.root_hash_size);
|
||||
*volume_key_size = cd->u.verity.root_hash_size;
|
||||
r = 0;
|
||||
} else
|
||||
log_err(cd, _("Cannot retrieve root hash for verity device."));
|
||||
} else
|
||||
log_err(cd, _("This operation is not supported for %s crypt device."), cd->type ?: "(none)");
|
||||
|
||||
if (r >= 0) {
|
||||
if (r >= 0 && vk) {
|
||||
memcpy(volume_key, vk->key, vk->keylength);
|
||||
*volume_key_size = vk->keylength;
|
||||
}
|
||||
@@ -4464,6 +4685,9 @@ int crypt_volume_key_verify(struct crypt_device *cd,
|
||||
r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
|
||||
else if (isLUKS2(cd->type))
|
||||
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||
else
|
||||
r = -EINVAL;
|
||||
|
||||
|
||||
if (r == -EPERM)
|
||||
log_err(cd, _("Volume key does not match the volume."));
|
||||
@@ -4502,6 +4726,20 @@ int crypt_memory_lock(struct crypt_device *cd, int lock)
|
||||
return lock ? crypt_memlock_inc(cd) : crypt_memlock_dec(cd);
|
||||
}
|
||||
|
||||
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags)
|
||||
{
|
||||
if (cd)
|
||||
cd->compatibility = flags;
|
||||
}
|
||||
|
||||
uint32_t crypt_get_compatibility(struct crypt_device *cd)
|
||||
{
|
||||
if (cd)
|
||||
return cd->compatibility;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reporting
|
||||
*/
|
||||
@@ -4621,6 +4859,8 @@ int crypt_dump(struct crypt_device *cd)
|
||||
return TCRYPT_dump(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
|
||||
else if (isINTEGRITY(cd->type))
|
||||
return INTEGRITY_dump(cd, crypt_data_device(cd), 0);
|
||||
else if (isBITLK(cd->type))
|
||||
return BITLK_dump(cd, crypt_data_device(cd), &cd->u.bitlk.params);
|
||||
|
||||
log_err(cd, _("Dump operation is not supported for this device type."));
|
||||
return -EINVAL;
|
||||
@@ -4639,6 +4879,8 @@ const char *crypt_get_cipher_spec(struct crypt_device *cd)
|
||||
return cd->u.plain.cipher_spec;
|
||||
else if (isLOOPAES(cd->type))
|
||||
return cd->u.loopaes.cipher_spec;
|
||||
else if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.cipher_spec;
|
||||
else if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.cipher_spec;
|
||||
|
||||
@@ -4669,6 +4911,9 @@ const char *crypt_get_cipher(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return cd->u.tcrypt.params.cipher;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.cipher;
|
||||
|
||||
if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.cipher;
|
||||
|
||||
@@ -4699,6 +4944,9 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return cd->u.tcrypt.params.mode;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.cipher_mode;
|
||||
|
||||
if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.cipher_mode;
|
||||
|
||||
@@ -4773,6 +5021,9 @@ const char *crypt_get_uuid(struct crypt_device *cd)
|
||||
if (isVERITY(cd->type))
|
||||
return cd->u.verity.uuid;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.guid;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -4833,6 +5084,9 @@ int crypt_get_volume_key_size(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return cd->u.tcrypt.params.key_size;
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.key_size / 8;
|
||||
|
||||
if (!cd->type && !_init_by_name_crypt_none(cd))
|
||||
return cd->u.none.key_size;
|
||||
|
||||
@@ -5014,6 +5268,9 @@ uint64_t crypt_get_data_offset(struct crypt_device *cd)
|
||||
if (isTCRYPT(cd->type))
|
||||
return TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
|
||||
|
||||
if (isBITLK(cd->type))
|
||||
return cd->u.bitlk.params.volume_header_size / SECTOR_SIZE;
|
||||
|
||||
return cd->data_offset;
|
||||
}
|
||||
|
||||
@@ -5133,7 +5390,7 @@ int crypt_get_verity_info(struct crypt_device *cd,
|
||||
vp->data_size = cd->u.verity.hdr.data_size;
|
||||
vp->hash_area_offset = cd->u.verity.hdr.hash_area_offset;
|
||||
vp->hash_type = cd->u.verity.hdr.hash_type;
|
||||
vp->flags = cd->u.verity.hdr.flags & CRYPT_VERITY_NO_HEADER;
|
||||
vp->flags = cd->u.verity.hdr.flags & (CRYPT_VERITY_NO_HEADER | CRYPT_VERITY_ROOT_HASH_SIGNATURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5585,7 +5842,7 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
|
||||
|
||||
r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, ¶ms);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Failed to initialise default LUKS2 keyslot parameters."));
|
||||
log_err(cd, _("Failed to initialize default LUKS2 keyslot parameters."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5613,32 +5870,11 @@ out:
|
||||
* Keyring handling
|
||||
*/
|
||||
|
||||
static int kernel_keyring_support(void)
|
||||
{
|
||||
static unsigned _checked = 0;
|
||||
|
||||
if (!_checked) {
|
||||
_kernel_keyring_supported = keyring_check();
|
||||
_checked = 1;
|
||||
}
|
||||
|
||||
return _kernel_keyring_supported;
|
||||
}
|
||||
|
||||
static int dmcrypt_keyring_bug(void)
|
||||
{
|
||||
uint64_t kversion;
|
||||
|
||||
if (kernel_version(&kversion))
|
||||
return 1;
|
||||
return kversion < version(4,15,0,0);
|
||||
}
|
||||
|
||||
int crypt_use_keyring_for_vk(struct crypt_device *cd)
|
||||
{
|
||||
uint32_t dmc_flags;
|
||||
|
||||
/* dm backend must be initialised */
|
||||
/* dm backend must be initialized */
|
||||
if (!cd || !isLUKS2(cd->type))
|
||||
return 0;
|
||||
|
||||
@@ -5759,7 +5995,7 @@ int crypt_activate_by_keyring(struct crypt_device *cd,
|
||||
|
||||
r = _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
|
||||
|
||||
crypt_memzero(passphrase, passphrase_size);
|
||||
crypt_safe_memzero(passphrase, passphrase_size);
|
||||
free(passphrase);
|
||||
|
||||
return r;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -301,8 +300,8 @@ static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
|
||||
}
|
||||
|
||||
crypt_cipher_destroy(cipher);
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -369,8 +368,8 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
|
||||
crypt_cipher_destroy(cipher);
|
||||
}
|
||||
|
||||
crypt_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
crypt_safe_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_safe_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -420,8 +419,8 @@ out:
|
||||
if (cipher[j])
|
||||
crypt_cipher_destroy(cipher[j]);
|
||||
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -474,13 +473,13 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
crypt_safe_memzero(&hdr2, sizeof(hdr2));
|
||||
return r;
|
||||
}
|
||||
|
||||
static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
unsigned char pool[TCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile)
|
||||
unsigned char pool[VCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile, int keyfiles_pool_length)
|
||||
{
|
||||
unsigned char *data;
|
||||
int i, j, fd, data_size, r = -EIO;
|
||||
@@ -512,12 +511,12 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
pool[j++] += (unsigned char)(crc >> 16);
|
||||
pool[j++] += (unsigned char)(crc >> 8);
|
||||
pool[j++] += (unsigned char)(crc);
|
||||
j %= TCRYPT_KEY_POOL_LEN;
|
||||
j %= keyfiles_pool_length;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
crypt_memzero(&crc, sizeof(crc));
|
||||
crypt_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
crypt_safe_memzero(&crc, sizeof(crc));
|
||||
crypt_safe_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
free(data);
|
||||
|
||||
return r;
|
||||
@@ -527,29 +526,39 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params)
|
||||
{
|
||||
unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size;
|
||||
unsigned char pwd[VCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size, max_passphrase_size;
|
||||
char *key;
|
||||
unsigned int i, skipped = 0, iterations;
|
||||
int r = -EPERM;
|
||||
int r = -EPERM, keyfiles_pool_length;
|
||||
|
||||
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
|
||||
return -ENOMEM;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_VERA_MODES &&
|
||||
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 = TCRYPT_KEY_POOL_LEN;
|
||||
passphrase_size = max_passphrase_size;
|
||||
else
|
||||
passphrase_size = params->passphrase_size;
|
||||
|
||||
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded."),
|
||||
TCRYPT_KEY_POOL_LEN);
|
||||
if (params->passphrase_size > max_passphrase_size) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%zu) exceeded."),
|
||||
max_passphrase_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Calculate pool content from keyfiles */
|
||||
for (i = 0; i < params->keyfiles_count; i++) {
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i], keyfiles_pool_length);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
@@ -619,9 +628,9 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
params->cipher, params->mode, params->key_size);
|
||||
}
|
||||
out:
|
||||
crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
crypt_safe_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
if (key)
|
||||
crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
crypt_safe_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
free(key);
|
||||
return r;
|
||||
}
|
||||
@@ -747,7 +756,7 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (strstr(params->mode, "-tcrypt")) {
|
||||
log_err(cd, _("Kernel doesn't support activation for this TCRYPT legacy mode."));
|
||||
log_err(cd, _("Kernel does not support activation for this TCRYPT legacy mode."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -859,7 +868,7 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
|
||||
if (r < 0 &&
|
||||
(dm_flags(cd, DM_CRYPT, &dmc_flags) || ((dmc_flags & req_flags) != req_flags))) {
|
||||
log_err(cd, _("Kernel doesn't support TCRYPT compatible mapping."));
|
||||
log_err(cd, _("Kernel does not support TCRYPT compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#define TCRYPT_LRW_IKEY_LEN 16
|
||||
#define TCRYPT_KEY_POOL_LEN 64
|
||||
#define VCRYPT_KEY_POOL_LEN 128
|
||||
#define TCRYPT_KEYFILE_LEN 1048576
|
||||
|
||||
#define TCRYPT_HDR_FLAG_SYSTEM (1 << 0)
|
||||
|
||||
11
lib/utils.c
11
lib/utils.c
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -130,7 +129,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
/* read error */
|
||||
return -1;
|
||||
}
|
||||
@@ -142,7 +141,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
bytes -= bytes_r;
|
||||
}
|
||||
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
return bytes == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -181,7 +180,7 @@ int crypt_keyfile_device_read(struct crypt_device *cd, const char *keyfile,
|
||||
key_size = DEFAULT_KEYFILE_SIZE_MAXKB * 1024 + 1;
|
||||
unlimited_read = 1;
|
||||
/* use 4k for buffer (page divisor but avoid huge pages) */
|
||||
buflen = 4096 - sizeof(struct safe_allocation);
|
||||
buflen = 4096 - sizeof(size_t); // sizeof(struct safe_allocation);
|
||||
} else
|
||||
buflen = key_size;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library, cipher benchmark
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -48,6 +48,12 @@ 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)
|
||||
@@ -71,9 +77,9 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
|
||||
if (r == -ERANGE)
|
||||
log_dbg(cd, "Measured cipher runtime is too low.");
|
||||
else if (r == -ENOTSUP || r == -ENOENT)
|
||||
log_dbg(cd, "Cannot initialise cipher %s, mode %s.", cipher, cipher_mode);
|
||||
|
||||
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);
|
||||
out:
|
||||
free(buffer);
|
||||
free(key);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkid probe utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -307,3 +307,17 @@ int blk_supported(void)
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
off_t blk_get_offset(struct blkid_handle *h)
|
||||
{
|
||||
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);
|
||||
} else if (blk_is_partition(h) && !blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
|
||||
offset_value = strtoll(offset, NULL, 10);
|
||||
#endif
|
||||
return offset_value;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkid probe utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -59,4 +59,6 @@ int blk_do_wipe(struct blkid_handle *h);
|
||||
|
||||
int blk_supported(void);
|
||||
|
||||
off_t blk_get_offset(struct blkid_handle *h);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -149,79 +149,6 @@ int crypt_parse_pbkdf(const char *s, const char **pbkdf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replacement for memset(s, 0, n) on stack that can be optimized out
|
||||
* Also used in safe allocations for explicit memory wipe.
|
||||
*/
|
||||
void crypt_memzero(void *s, size_t n)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
|
||||
while(n--)
|
||||
*p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
crypt_memzero(&alloc->data, size);
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
void crypt_safe_free(void *data)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
crypt_memzero(data, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
void *crypt_safe_realloc(void *data, size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
void *new_data;
|
||||
|
||||
new_data = crypt_safe_alloc(size);
|
||||
|
||||
if (new_data && data) {
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
if (size > alloc->size)
|
||||
size = alloc->size;
|
||||
|
||||
memcpy(new_data, data, size);
|
||||
}
|
||||
|
||||
crypt_safe_free(data);
|
||||
return new_data;
|
||||
}
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
{
|
||||
char buf[3] = "xx\0", *endp, *bytes;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -29,14 +29,6 @@
|
||||
#define MAX_CIPHER_LEN_STR "31"
|
||||
#define MAX_KEYFILES 32
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
/* Not to be used directly */
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
int crypt_parse_name_and_mode(const char *s, char *cipher,
|
||||
int *key_nums, char *cipher_mode);
|
||||
int crypt_parse_hash_integrity_mode(const char *s, char *integrity);
|
||||
@@ -44,12 +36,6 @@ int crypt_parse_integrity_mode(const char *s, char *integrity,
|
||||
int *integrity_key_size);
|
||||
int crypt_parse_pbkdf(const char *s, const char **pbkdf);
|
||||
|
||||
void *crypt_safe_alloc(size_t size);
|
||||
void crypt_safe_free(void *data);
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
void crypt_memzero(void *s, size_t n);
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
|
||||
|
||||
#endif /* _UTILS_CRYPT_H */
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -145,7 +144,7 @@ static int device_read_test(int devfd)
|
||||
if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize)
|
||||
r = 0;
|
||||
|
||||
crypt_memzero(buffer, sizeof(buffer));
|
||||
crypt_safe_memzero(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -185,7 +184,7 @@ static int device_ready(struct crypt_device *cd, struct device *device)
|
||||
}
|
||||
|
||||
if (devfd < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied."),
|
||||
log_err(cd, _("Device %s does not exist or access denied."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Metadata on-disk locking for processes serialization
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Metadata on-disk locking for processes serialization
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -63,8 +63,14 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
|
||||
#define DM_DEFERRED_SUPPORTED (1 << 15) /* deferred removal of device */
|
||||
#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 */
|
||||
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
|
||||
enum tdirection { TARGET_SET = 1, TARGET_QUERY };
|
||||
|
||||
int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags);
|
||||
@@ -109,6 +115,7 @@ struct dm_target {
|
||||
|
||||
const char *root_hash;
|
||||
uint32_t root_hash_size;
|
||||
const char *root_hash_sig_key_desc;
|
||||
|
||||
uint64_t hash_offset; /* hash offset in blocks (not header) */
|
||||
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
|
||||
@@ -137,10 +144,14 @@ struct dm_target {
|
||||
struct volume_key *journal_crypt_key;
|
||||
|
||||
struct device *meta_device;
|
||||
|
||||
bool fix_padding;
|
||||
} integrity;
|
||||
struct {
|
||||
uint64_t offset;
|
||||
} linear;
|
||||
struct {
|
||||
} zero;
|
||||
} u;
|
||||
|
||||
char *params;
|
||||
@@ -174,9 +185,10 @@ int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg
|
||||
uint32_t tag_size, uint32_t sector_size);
|
||||
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||
uint64_t hash_blocks, struct crypt_params_verity *vp);
|
||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
const char *root_hash, uint32_t root_hash_size, const char *root_hash_sig_key_desc,
|
||||
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp);
|
||||
int dm_integrity_target_set(struct crypt_device *cd,
|
||||
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *meta_device,
|
||||
struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
|
||||
struct volume_key *vk,
|
||||
@@ -184,6 +196,7 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
|
||||
const struct crypt_params_integrity *ip);
|
||||
int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, uint64_t data_offset);
|
||||
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size);
|
||||
|
||||
int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags);
|
||||
int dm_status_device(struct crypt_device *cd, const char *name);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kernel keyring utilities
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -25,15 +25,14 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "utils_keyring.h"
|
||||
|
||||
#ifndef HAVE_KEY_SERIAL_T
|
||||
#define HAVE_KEY_SERIAL_T
|
||||
#include <stdint.h>
|
||||
typedef int32_t key_serial_t;
|
||||
#endif
|
||||
|
||||
#include "utils_crypt.h"
|
||||
#include "utils_keyring.h"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
@@ -178,7 +177,7 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
if (ret < 0) {
|
||||
err = errno;
|
||||
if (buf)
|
||||
crypt_memzero(buf, len);
|
||||
crypt_safe_memzero(buf, len);
|
||||
free(buf);
|
||||
return -err;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kernel keyring syscall wrappers
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2020 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -252,7 +252,12 @@ static char *_sysfs_backing_file(const char *loop)
|
||||
|
||||
char *crypt_loop_backing_file(const char *loop)
|
||||
{
|
||||
char *bf = _sysfs_backing_file(loop);
|
||||
char *bf;
|
||||
|
||||
if (!crypt_loop_device(loop))
|
||||
return NULL;
|
||||
|
||||
bf = _sysfs_backing_file(loop);
|
||||
return bf ?: _ioctl_backing_file(loop);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* utils_pbkdf - PBKDF settings for libcryptsetup
|
||||
*
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
102
lib/utils_safe_memory.c
Normal file
102
lib/utils_safe_memory.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* utils_safe_memory - safe memory helpers
|
||||
*
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Replacement for memset(s, 0, n) on stack that can be optimized out
|
||||
* Also used in safe allocations for explicit memory wipe.
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(data, size);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)data;
|
||||
|
||||
while(size--)
|
||||
*p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
crypt_safe_memzero(&alloc->data, size);
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
void crypt_safe_free(void *data)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
crypt_safe_memzero(data, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
void *crypt_safe_realloc(void *data, size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
void *new_data;
|
||||
|
||||
new_data = crypt_safe_alloc(size);
|
||||
|
||||
if (new_data && data) {
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
if (size > alloc->size)
|
||||
size = alloc->size;
|
||||
|
||||
memcpy(new_data, data, size);
|
||||
}
|
||||
|
||||
crypt_safe_free(data);
|
||||
return new_data;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generic wrapper for storage functions
|
||||
* (experimental only)
|
||||
*
|
||||
* Copyright (C) 2018, Ondrej Kozina
|
||||
* Copyright (C) 2018-2020, Ondrej Kozina
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -108,7 +107,7 @@ static int crypt_storage_dmcrypt_init(
|
||||
r = device_block_adjust(cd, device, DEV_OK,
|
||||
device_offset, &dmd.size, &dmd.flags);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied."),
|
||||
log_err(cd, _("Device %s does not exist or access denied."),
|
||||
device_path(device));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generic wrapper for storage functions
|
||||
* (experimental only)
|
||||
*
|
||||
* Copyright (C) 2018, Ondrej Kozina
|
||||
* Copyright (C) 2018-2020, Ondrej Kozina
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_wipe - wipe a device
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2020 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
@@ -56,7 +55,7 @@ static int crypt_wipe_special(struct crypt_device *cd, int fd, size_t bsize,
|
||||
size_t alignment, char *buffer,
|
||||
uint64_t offset, size_t size)
|
||||
{
|
||||
int r;
|
||||
int r = 0;
|
||||
unsigned int i;
|
||||
ssize_t written;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2004 Phil Karn, KA9Q
|
||||
* libcryptsetup modifications
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2002, Phil Karn, KA9Q
|
||||
* libcryptsetup modifications
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2002, Phil Karn, KA9Q
|
||||
* libcryptsetup modifications
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
@@ -66,7 +65,7 @@ int VERITY_read_sb(struct crypt_device *cd,
|
||||
sizeof(struct verity_sb), device_path(device), sb_offset);
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device %s doesn't use on-disk header."),
|
||||
log_err(cd, _("Verity device %s does not use on-disk header."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -169,7 +168,7 @@ int VERITY_write_sb(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device %s doesn't use on-disk header."),
|
||||
log_err(cd, _("Verity device %s does not use on-disk header."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -235,6 +234,7 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
const char *signature_description,
|
||||
struct device *fec_device,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags)
|
||||
@@ -252,6 +252,11 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
name ?: "[none]", verity_hdr->hash_name);
|
||||
|
||||
if (verity_hdr->flags & CRYPT_VERITY_CHECK_HASH) {
|
||||
if (signature_description) {
|
||||
log_err(cd, _("Root hash signature verification is not supported."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg(cd, "Verification of data in userspace required.");
|
||||
r = VERITY_verify(cd, verity_hdr, root_hash, root_hash_size);
|
||||
|
||||
@@ -291,7 +296,8 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
|
||||
r = dm_verity_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
|
||||
crypt_metadata_device(cd), fec_device, root_hash,
|
||||
root_hash_size, VERITY_hash_offset_block(verity_hdr),
|
||||
root_hash_size, signature_description,
|
||||
VERITY_hash_offset_block(verity_hdr),
|
||||
VERITY_hash_blocks(cd, verity_hdr), verity_hdr);
|
||||
|
||||
if (r)
|
||||
@@ -299,7 +305,11 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
|
||||
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd);
|
||||
if (r < 0 && (dm_flags(cd, DM_VERITY, &dmv_flags) || !(dmv_flags & DM_VERITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-verity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-verity mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r < 0 && signature_description && !(dmv_flags & DM_VERITY_SIGNATURE_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel does not support dm-verity signature option."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r < 0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -46,6 +46,7 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
const char *signature_description,
|
||||
struct device *fec_device,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags);
|
||||
@@ -57,7 +58,7 @@ int VERITY_verify(struct crypt_device *cd,
|
||||
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
char *root_hash,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
int VERITY_FEC_process(struct crypt_device *cd,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* dm-verity Forward Error Correction (FEC) support
|
||||
*
|
||||
* Copyright (C) 2015 Google, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "verity.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -102,7 +102,7 @@ static int hash_levels(size_t hash_block_size, size_t digest_size,
|
||||
off_t *hash_level_block, off_t *hash_level_size)
|
||||
{
|
||||
size_t hash_per_block_bits;
|
||||
off_t s;
|
||||
off_t s, s_shift;
|
||||
int i;
|
||||
|
||||
if (!digest_size)
|
||||
@@ -124,7 +124,10 @@ static int hash_levels(size_t hash_block_size, size_t digest_size,
|
||||
if (hash_level_block)
|
||||
hash_level_block[i] = *hash_position;
|
||||
// verity position of block data_file_blocks at level i
|
||||
s = (data_file_blocks + ((off_t)1 << ((i + 1) * hash_per_block_bits)) - 1) >> ((i + 1) * hash_per_block_bits);
|
||||
s_shift = (i + 1) * hash_per_block_bits;
|
||||
if (s_shift > 63)
|
||||
return -EINVAL;
|
||||
s = (data_file_blocks + ((off_t)1 << s_shift) - 1) >> ((i + 1) * hash_per_block_bits);
|
||||
if (hash_level_size)
|
||||
hash_level_size[i] = s;
|
||||
if ((*hash_position + s) < *hash_position ||
|
||||
@@ -418,7 +421,7 @@ int VERITY_verify(struct crypt_device *cd,
|
||||
/* Create verity hash */
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
char *root_hash,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
unsigned pgsize = (unsigned)crypt_getpagesize();
|
||||
@@ -439,7 +442,7 @@ int VERITY_create(struct crypt_device *cd,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
VERITY_hash_offset_block(verity_hdr),
|
||||
root_hash,
|
||||
CONST_CAST(char*)root_hash,
|
||||
root_hash_size,
|
||||
verity_hdr->salt,
|
||||
verity_hdr->salt_size);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* cryptsetup volume key implementation
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -47,7 +47,7 @@ struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key)
|
||||
if (key)
|
||||
memcpy(&vk->key, key, keylength);
|
||||
else
|
||||
crypt_memzero(&vk->key, keylength);
|
||||
crypt_safe_memzero(&vk->key, keylength);
|
||||
}
|
||||
|
||||
return vk;
|
||||
@@ -120,7 +120,7 @@ void crypt_free_volume_key(struct volume_key *vk)
|
||||
struct volume_key *vk_next;
|
||||
|
||||
while (vk) {
|
||||
crypt_memzero(vk->key, vk->keylength);
|
||||
crypt_safe_memzero(vk->key, vk->keylength);
|
||||
vk->keylength = 0;
|
||||
free(CONST_CAST(void*)vk->key_description);
|
||||
vk_next = vk->next;
|
||||
|
||||
@@ -285,9 +285,9 @@ Please attach the output of the failed command with the
|
||||
.SH AUTHORS
|
||||
Cryptsetup-reencrypt was written by Milan Broz <gmazyland@gmail.com>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012-2019 Milan Broz
|
||||
Copyright \(co 2012-2020 Milan Broz
|
||||
.br
|
||||
Copyright \(co 2012-2019 Red Hat, Inc.
|
||||
Copyright \(co 2012-2020 Red Hat, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
@@ -12,7 +12,7 @@ and can hence offer more features than plain dm-crypt. On the other
|
||||
hand, the header is visible and vulnerable to damage.
|
||||
|
||||
In addition, cryptsetup provides limited support for the use of
|
||||
loop-AES volumes and for TrueCrypt compatible volumes.
|
||||
loop-AES volumes, TrueCrypt, VeraCrypt and BitLocker compatible volumes.
|
||||
|
||||
.SH PLAIN DM-CRYPT OR LUKS?
|
||||
.PP
|
||||
@@ -84,6 +84,8 @@ For backward compatibility there are \fBopen\fR command aliases:
|
||||
\fBloopaesOpen\fR: open \-\-type loopaes
|
||||
.br
|
||||
\fBtcryptOpen\fR: open \-\-type tcrypt
|
||||
.br
|
||||
\fBbitlkOpen\fR: open \-\-type bitlk
|
||||
|
||||
\fB<options>\fR are type specific and are described below
|
||||
for individual device types. For \fBcreate\fR, the order of the <name>
|
||||
@@ -161,7 +163,7 @@ above in LUKS2 metadata (only after successful refresh operation).
|
||||
in dm-crypt driver.
|
||||
|
||||
.PP
|
||||
\fIreencrypt\fR <device> or --active-name <name>
|
||||
\fIreencrypt\fR <device> or --active-name <name> [<new_name>]
|
||||
.IP
|
||||
Run resilient reencryption (LUKS2 device only).
|
||||
|
||||
@@ -191,6 +193,10 @@ If the reencryption process was interrupted abruptly (reencryption process crash
|
||||
it may require recovery. The recovery is currently run automatically on next activation (action \fIopen\fR)
|
||||
when needed.
|
||||
|
||||
Optional parameter <new_name> takes effect only with \-\-encrypt option and it activates device <new_name>
|
||||
immediately after encryption initialization gets finished. That's useful when device needs to be ready
|
||||
as soon as possible and mounted (used) before full data area encryption is completed.
|
||||
|
||||
Action supports following additional \fB<options>\fR [\-\-encrypt, \-\-decrypt, \-\-device\-size,
|
||||
\-\-resilience, \-\-resilience-hash, \-\-hotzone-size, \-\-init\-only, \-\-resume\-only,
|
||||
\-\-reduce\-device\-size].
|
||||
@@ -484,14 +490,18 @@ master key is dumped to a file instead of standard output. Beware that the
|
||||
master key cannot be changed without reencryption and can be used to decrypt
|
||||
the data stored in the LUKS container without a passphrase and even without the
|
||||
LUKS header. This means that if the master key is compromised, the whole device
|
||||
has to be erased to prevent further access. Use this option carefully.
|
||||
has to be erased or reencrypted to prevent further access. Use this option carefully.
|
||||
|
||||
To dump the master key, a passphrase has to be supplied,
|
||||
either interactively or via \-\-key\-file.
|
||||
|
||||
To dump unbound key (LUKS2 format only), \-\-unbound parameter, specific \-\-key-slot
|
||||
id and proper passphrase has to be supplied, either interactively or via \-\-key\-file.
|
||||
Optional \-\-master\-key\-file parameter enables unbound keyslot dump to a file.
|
||||
|
||||
\fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
|
||||
\-\-keyfile\-offset, \-\-keyfile\-size, \-\-header, \-\-disable\-locks,
|
||||
\-\-master\-key\-file, \-\-type].
|
||||
\-\-master\-key\-file, \-\-type, \-\-unbound, \-\-key-slot].
|
||||
|
||||
\fBWARNING:\fR If \-\-dump\-master\-key is used with \-\-key\-file
|
||||
and the argument to \-\-key\-file is '-', no validation question
|
||||
@@ -739,6 +749,47 @@ TrueCrypt.
|
||||
|
||||
Please note that cryptsetup does not use TrueCrypt code, please report
|
||||
all problems related to this compatibility extension to the cryptsetup project.
|
||||
|
||||
.SH BITLK (Windows BitLocker-compatible) EXTENSION (EXPERIMENTAL)
|
||||
cryptsetup supports mapping of BitLocker and BitLocker to Go encrypted partition
|
||||
using a native Linux kernel API.
|
||||
Header formatting and BITLK header changes are not supported, cryptsetup
|
||||
never changes BITLK header on-device.
|
||||
|
||||
\fBWARNING:\fR This extension is EXPERIMENTAL.
|
||||
|
||||
BITLK extension requires kernel userspace crypto API to be available
|
||||
(for details see TCRYPT section).
|
||||
|
||||
Cryptsetup should recognize all BITLK header variants, except legacy
|
||||
header used in Windows Vista systems and partially decrypted BitLocker devices.
|
||||
Activation of legacy devices encrypted in CBC mode requires at least
|
||||
Linux kernel version 5.3 and for devices using Elephant diffuser kernel 5.6.
|
||||
|
||||
The \fBbitlkDump\fR command should work for all recognized BITLK devices
|
||||
and doesn't require superuser privilege.
|
||||
|
||||
For unlocking with the \fBopen\fR a password or a recovery passphrase must
|
||||
be provided. Other unlocking methods (TPM, SmartCard) are not supported.
|
||||
|
||||
.PP
|
||||
\fIopen\fR \-\-type bitlk <device> <name>
|
||||
.br
|
||||
\fIbitlkOpen\fR <device> <name> (\fBold syntax\fR)
|
||||
.IP
|
||||
Opens the BITLK (a BitLocker-compatible) <device> and sets up
|
||||
a mapping <name>.
|
||||
|
||||
\fB<options>\fR can be [\-\-key\-file, \-\-readonly, \-\-test\-passphrase,
|
||||
\-\-allow-discards].
|
||||
|
||||
.PP
|
||||
\fIbitlkDump\fR <device>
|
||||
.IP
|
||||
Dump the header information of a BITLK device.
|
||||
|
||||
Please note that cryptsetup does not use any Windows BitLocker code, please report
|
||||
all problems related to this compatibility extension to the cryptsetup project.
|
||||
.SH MISCELLANEOUS
|
||||
.PP
|
||||
\fIrepair\fR <device>
|
||||
@@ -1124,6 +1175,7 @@ e.g. 12345678-1234-1234-1234-123456789abc.
|
||||
.B "\-\-allow\-discards\fR"
|
||||
Allow the use of discard (TRIM) requests for the device.
|
||||
This option is only relevant for \fIopen\fR action.
|
||||
This is also not supported for LUKS2 devices with data integrity protection.
|
||||
|
||||
\fBWARNING:\fR This command can have a negative security impact
|
||||
because it can make filesystem-level operations visible on
|
||||
@@ -1189,7 +1241,7 @@ with the \-\-header option. Use with care.
|
||||
.TP
|
||||
.B "\-\-header\-backup\-file <file>"
|
||||
Specify file with header backup for \fIluksHeaderBackup\fR or
|
||||
\fIluksHeaderBackup\fR actions.
|
||||
\fIluksHeaderRestore\fR actions.
|
||||
.TP
|
||||
.B "\-\-force\-password"
|
||||
Do not use password quality checking for new LUKS passwords.
|
||||
@@ -1320,8 +1372,9 @@ integrity tag.
|
||||
.TP
|
||||
.B "\-\-unbound"
|
||||
|
||||
Creates new LUKS2 unbound keyslot. See \fIluksAddKey\fR action for more
|
||||
details.
|
||||
Creates new or dumps existing LUKS2 unbound keyslot. See \fIluksAddKey\fR or
|
||||
\fIluksDump\fR actions for more details.
|
||||
|
||||
.TP
|
||||
.B "\-\-tcrypt\-hidden"
|
||||
.B "\-\-tcrypt\-system"
|
||||
@@ -1572,6 +1625,9 @@ for integrity protected devices.
|
||||
If you want to format LUKS2 device with data integrity protection,
|
||||
use \fI\-\-integrity\fR option.
|
||||
|
||||
Since dm-integrity doesn't support discards (TRIM), dm-crypt device on top of it
|
||||
inherits this, so integrity protection mode doesn't support discards either.
|
||||
|
||||
Some integrity modes requires two independent keys (key for encryption
|
||||
and for authentication). Both these keys are stored in one LUKS keyslot.
|
||||
|
||||
@@ -1632,9 +1688,9 @@ Copyright \(co 2004-2006 Clemens Fruhwirth
|
||||
.br
|
||||
Copyright \(co 2012-2014 Arno Wagner
|
||||
.br
|
||||
Copyright \(co 2009-2019 Red Hat, Inc.
|
||||
Copyright \(co 2009-2020 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2009-2019 Milan Broz
|
||||
Copyright \(co 2009-2020 Milan Broz
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
@@ -33,7 +33,7 @@ Open a mapping with <name> backed by device <device>.
|
||||
\fB<options>\fR can be [\-\-data\-device, \-\-batch\-mode, \-\-journal\-watermark,
|
||||
\-\-journal\-commit\-time, \-\-buffer\-sectors, \-\-integrity, \-\-integrity\-key\-size,
|
||||
\-\-integrity\-key\-file, \-\-integrity\-no\-journal, \-\-integrity\-recalculate,
|
||||
\-\-integrity\-recovery\-mode]
|
||||
\-\-integrity\-recovery\-mode, \-\-allow\-discards]
|
||||
|
||||
.PP
|
||||
\fIclose\fR <name>
|
||||
@@ -165,8 +165,8 @@ The file with the integrity key.
|
||||
.TP
|
||||
.B "\-\-journal\-crypt ALGORITHM"
|
||||
Encryption algorithm for journal data area.
|
||||
You can use a block cipher here such as cbc(aes) or
|
||||
a stream cipher, for example, chacha20 or ctr(aes).
|
||||
You can use a block cipher here such as cbc-aes or
|
||||
a stream cipher, for example, chacha20 or ctr-aes.
|
||||
.TP
|
||||
.B "\-\-journal\-crypt\-key\-size BYTES"
|
||||
The size of the journal encryption key.
|
||||
@@ -174,6 +174,10 @@ The size of the journal encryption key.
|
||||
.B "\-\-journal\-crypt\-key\-file FILE"
|
||||
The file with the journal encryption key.
|
||||
.TP
|
||||
.B "\-\-allow\-discards\fR"
|
||||
Allow the use of discard (TRIM) requests for the device.
|
||||
This option is available since the Linux kernel version 5.7.
|
||||
.TP
|
||||
The dm-integrity target is available since Linux kernel version 4.12.
|
||||
.TP
|
||||
\fBNOTE:\fR
|
||||
@@ -223,9 +227,9 @@ Please attach the output of the failed command with the
|
||||
The integritysetup tool is written by Milan Broz <gmazyland@gmail.com>
|
||||
and is part of the cryptsetup project.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2016-2019 Red Hat, Inc.
|
||||
Copyright \(co 2016-2020 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2016-2019 Milan Broz
|
||||
Copyright \(co 2016-2020 Milan Broz
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user