mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 00:10:04 +01:00
Compare commits
196 Commits
v2.5.0-rc1
...
v2.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b08212ea45 | ||
|
|
5a976ad1d9 | ||
|
|
0e4182874b | ||
|
|
487e85fdec | ||
|
|
32344d5a84 | ||
|
|
ebb16a511c | ||
|
|
51200eb6da | ||
|
|
119c57e00e | ||
|
|
700b0f6e36 | ||
|
|
8fff498062 | ||
|
|
2ef2f6017d | ||
|
|
cdfa213ad0 | ||
|
|
dab00bfd4f | ||
|
|
c018558f2d | ||
|
|
3633b81909 | ||
|
|
b23a02b05c | ||
|
|
347c39ca97 | ||
|
|
2d1f1833e8 | ||
|
|
7f09ab67e2 | ||
|
|
f5fb1f1b94 | ||
|
|
005141554f | ||
|
|
cd8f80b7ee | ||
|
|
c7bbae01a6 | ||
|
|
257bc80ae9 | ||
|
|
6c2e64bf75 | ||
|
|
942cea1803 | ||
|
|
e7eab5fec2 | ||
|
|
b0779c6529 | ||
|
|
37d045df00 | ||
|
|
4b95f36804 | ||
|
|
faf3b27f51 | ||
|
|
c85d1351ea | ||
|
|
3b18fe2b23 | ||
|
|
e96588b8b5 | ||
|
|
c31494abc6 | ||
|
|
819902a33a | ||
|
|
395beb635c | ||
|
|
81c56a8395 | ||
|
|
3333f3e9bb | ||
|
|
b086430877 | ||
|
|
01f3f3e66c | ||
|
|
e37d8bdf91 | ||
|
|
8b4a5e5931 | ||
|
|
33d8d19408 | ||
|
|
9bb98d49c0 | ||
|
|
1c5fd5ae10 | ||
|
|
3d1b965c46 | ||
|
|
2770273582 | ||
|
|
f6b6e41951 | ||
|
|
03059fae75 | ||
|
|
ba9757b14b | ||
|
|
cd5bd1c773 | ||
|
|
a5c7bba6ee | ||
|
|
4bce6d5962 | ||
|
|
cb9deaf354 | ||
|
|
0ce5de9c1c | ||
|
|
35071c6d50 | ||
|
|
af6ea01997 | ||
|
|
1d5d6d73a5 | ||
|
|
1ffc9d967c | ||
|
|
1f4c7a83f9 | ||
|
|
f312ba6256 | ||
|
|
5186f49613 | ||
|
|
616d3cd493 | ||
|
|
cd2e22cb87 | ||
|
|
54073ef65f | ||
|
|
3e7c1e46fd | ||
|
|
ea05e4307e | ||
|
|
f35b9cc99b | ||
|
|
d4888fba86 | ||
|
|
f9e778a2cd | ||
|
|
69025faa24 | ||
|
|
871000fa05 | ||
|
|
cb53c643c2 | ||
|
|
f771f9a694 | ||
|
|
9009a2de26 | ||
|
|
6a279e21c9 | ||
|
|
124367f365 | ||
|
|
55c39d7d16 | ||
|
|
f7e2ed956b | ||
|
|
0e6264c53c | ||
|
|
01c16111d7 | ||
|
|
49ab658c9c | ||
|
|
888c6321df | ||
|
|
20f8c09195 | ||
|
|
57d4c677bd | ||
|
|
cde7b90735 | ||
|
|
3e4c69a017 | ||
|
|
19c15a652f | ||
|
|
2390395150 | ||
|
|
9a9ddc7d22 | ||
|
|
3616da631f | ||
|
|
b380fa7494 | ||
|
|
23f49eca43 | ||
|
|
00baa92756 | ||
|
|
8bbb018a01 | ||
|
|
c464d61995 | ||
|
|
d260ca6680 | ||
|
|
d05a2a6c99 | ||
|
|
758a2974f5 | ||
|
|
4b5e814094 | ||
|
|
98f5e0538a | ||
|
|
f03180d06a | ||
|
|
39b94ae530 | ||
|
|
3690d5f532 | ||
|
|
e595940637 | ||
|
|
dab939c3c9 | ||
|
|
cc276527c7 | ||
|
|
27429daf5d | ||
|
|
b20821a520 | ||
|
|
46b465ff2e | ||
|
|
d8fd9caa6a | ||
|
|
dad11f97ce | ||
|
|
c06e853938 | ||
|
|
c35e4479d5 | ||
|
|
8585fb29eb | ||
|
|
97b3926655 | ||
|
|
a3f248df9b | ||
|
|
e1a84607cc | ||
|
|
2f4267ba81 | ||
|
|
99e8ee6b7e | ||
|
|
f58aff21a9 | ||
|
|
de8a27ae02 | ||
|
|
b9b08eba7c | ||
|
|
82b56300cd | ||
|
|
9f8fe3da16 | ||
|
|
50803ebacb | ||
|
|
5fce0c2ad1 | ||
|
|
2e29eb7906 | ||
|
|
b867f0b578 | ||
|
|
1745fd5aea | ||
|
|
90ad841a45 | ||
|
|
0397cac878 | ||
|
|
033ff34109 | ||
|
|
0d61e4c20f | ||
|
|
b4863897fe | ||
|
|
eac02f5605 | ||
|
|
94e8a7ca96 | ||
|
|
b183bb25e2 | ||
|
|
09ac5321f4 | ||
|
|
c1302555b7 | ||
|
|
01c032df04 | ||
|
|
88d9524e6c | ||
|
|
4b47091b85 | ||
|
|
b9bf657449 | ||
|
|
21d87a246e | ||
|
|
db65a5ceac | ||
|
|
132027bafa | ||
|
|
f6fd73aea5 | ||
|
|
5b001b7962 | ||
|
|
429afe8fc3 | ||
|
|
abfb5e374f | ||
|
|
f8c79f9a95 | ||
|
|
190e4fc033 | ||
|
|
093adfc5f9 | ||
|
|
a009614191 | ||
|
|
75111d382b | ||
|
|
1cc6c82f21 | ||
|
|
2c555bd4a0 | ||
|
|
3f3f5a6aab | ||
|
|
c6ed1becd7 | ||
|
|
766ac108ec | ||
|
|
94e5d227ce | ||
|
|
f96e19147c | ||
|
|
05dbf04d82 | ||
|
|
b9b7c3a9bd | ||
|
|
17e6d2053a | ||
|
|
912109ae66 | ||
|
|
25b877a403 | ||
|
|
8270b72bfc | ||
|
|
9c0cdcc2f9 | ||
|
|
1e2cb2d419 | ||
|
|
3e178caeaf | ||
|
|
803957cd3e | ||
|
|
bf4bfeac8a | ||
|
|
090dca635a | ||
|
|
0369ffdcc1 | ||
|
|
648a85ed3a | ||
|
|
8f3884e0d7 | ||
|
|
289d5e5891 | ||
|
|
b37d04975d | ||
|
|
6578dac2f9 | ||
|
|
dc5f284e42 | ||
|
|
32149e4ee7 | ||
|
|
0e4857ee81 | ||
|
|
06dd06ea27 | ||
|
|
03eb8f860a | ||
|
|
fbcef71c41 | ||
|
|
8315ada3b0 | ||
|
|
782dae9292 | ||
|
|
96c0544527 | ||
|
|
cb7e2c6433 | ||
|
|
f0da65cc63 | ||
|
|
a76c96d361 | ||
|
|
3106b4e2c1 | ||
|
|
5d711c000f |
2
.github/workflows/cibuild-setup-ubuntu.sh
vendored
2
.github/workflows/cibuild-setup-ubuntu.sh
vendored
@@ -4,7 +4,7 @@ set -ex
|
||||
|
||||
PACKAGES=(
|
||||
git make autoconf automake autopoint pkg-config libtool libtool-bin
|
||||
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
|
||||
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
|
||||
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
|
||||
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
|
||||
asciidoctor
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -58,3 +58,4 @@ tests/unit-utils-io
|
||||
tests/vectors-test
|
||||
tests/test-symbols-list.h
|
||||
tests/all-symbols-test
|
||||
tests/fuzz/LUKS2.pb*
|
||||
|
||||
@@ -18,3 +18,5 @@ include:
|
||||
- local: .gitlab/ci/compilation-gcc.gitlab-ci.yml
|
||||
- local: .gitlab/ci/compilation-clang.gitlab-ci.yml
|
||||
- local: .gitlab/ci/alpinelinux.yml
|
||||
- local: .gitlab/ci/ubuntu-32bit.yml
|
||||
- local: .gitlab/ci/cifuzz.yml
|
||||
|
||||
@@ -23,11 +23,11 @@ test-main-commit-job-alpinelinux:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "0"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
@@ -44,6 +44,8 @@ test-mergerq-job-alpinelinux:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "0"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
|
||||
@@ -27,6 +27,8 @@ test-main-commit-centos-stream9:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
@@ -46,6 +48,8 @@ test-mergerq-centos-stream9:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
|
||||
@@ -4,7 +4,7 @@ set -ex
|
||||
|
||||
PACKAGES=(
|
||||
git make autoconf automake autopoint pkg-config libtool libtool-bin
|
||||
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
|
||||
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
|
||||
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
|
||||
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
|
||||
asciidoctor
|
||||
|
||||
46
.gitlab/ci/cifuzz.yml
Normal file
46
.gitlab/ci/cifuzz.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
cifuzz:
|
||||
variables:
|
||||
OSS_FUZZ_PROJECT_NAME: cryptsetup
|
||||
CFL_PLATFORM: gitlab
|
||||
CIFUZZ_DEBUG: "True"
|
||||
FUZZ_SECONDS: 300 # 5 minutes per fuzzer
|
||||
ARCHITECTURE: "x86_64"
|
||||
DRY_RUN: "False"
|
||||
LOW_DISK_SPACE: "True"
|
||||
BAD_BUILD_CHECK: "True"
|
||||
LANGUAGE: "c"
|
||||
DOCKER_HOST: "tcp://docker:2375"
|
||||
DOCKER_IN_DOCKER: "true"
|
||||
DOCKER_DRIVER: overlay2
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
image:
|
||||
name: gcr.io/oss-fuzz-base/cifuzz-base
|
||||
entrypoint: [""]
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
stage: test
|
||||
parallel:
|
||||
matrix:
|
||||
- SANITIZER: [address, undefined, memory]
|
||||
rules:
|
||||
# Default code change.
|
||||
# - if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
# variables:
|
||||
# MODE: "code-change"
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $BUILD_AND_RUN_FUZZERS != null
|
||||
before_script:
|
||||
# Get gitlab's container id.
|
||||
- export CFL_CONTAINER_ID=`cut -c9- < /proc/1/cpuset`
|
||||
script:
|
||||
# Will build and run the fuzzers.
|
||||
# We use a hack to override CI_JOB_ID, because otherwise a bad path is used
|
||||
# in GitLab CI environment
|
||||
- CI_JOB_ID="$CI_PROJECT_NAMESPACE/$CI_PROJECT_TITLE" python3 "/opt/oss-fuzz/infra/cifuzz/cifuzz_combined_entrypoint.py"
|
||||
artifacts:
|
||||
# Upload artifacts when a crash makes the job fail.
|
||||
when: always
|
||||
paths:
|
||||
- artifacts/
|
||||
@@ -3,12 +3,15 @@
|
||||
- .dump_kernel_log
|
||||
before_script:
|
||||
- >
|
||||
sudo apt-get -y install -y -qq git gcc make
|
||||
autoconf automake autopoint pkg-config libtool libtool-bin gettext
|
||||
libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
|
||||
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev
|
||||
libpwquality-dev sharutils dmsetup jq xxd expect keyutils
|
||||
netcat passwd openssh-client sshpass asciidoctor
|
||||
[ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
|
||||
sudo apt-get -y install -y -qq swtpm meson ninja-build python3-jinja2
|
||||
gperf libcap-dev tpm2-tss-engine-dev libmount-dev swtpm-tools
|
||||
- >
|
||||
sudo apt-get -y install -y -qq git gcc make autoconf automake autopoint
|
||||
pkgconf libtool libtool-bin gettext libssl-dev libdevmapper-dev
|
||||
libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev
|
||||
tar libargon2-0-dev libpwquality-dev sharutils dmsetup jq xxd expect
|
||||
keyutils netcat passwd openssh-client sshpass asciidoctor
|
||||
- sudo apt-get -y build-dep cryptsetup
|
||||
- sudo -E git clean -xdf
|
||||
- ./autogen.sh
|
||||
@@ -19,7 +22,7 @@ test-mergerq-job-debian:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- debian10
|
||||
- debian11
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
@@ -38,7 +41,7 @@ test-main-commit-job-debian:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- debian10
|
||||
- debian11
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
|
||||
@@ -3,7 +3,12 @@
|
||||
- .dump_kernel_log
|
||||
before_script:
|
||||
- >
|
||||
sudo dnf -y -q install
|
||||
[ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
|
||||
sudo dnf -y -q install
|
||||
swtpm meson ninja-build python3-jinja2 gperf libcap-devel tpm2-tss-devel
|
||||
libmount-devel swtpm-tools
|
||||
- >
|
||||
sudo dnf -y -q install
|
||||
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
|
||||
libargon2-devel libblkid-devel libpwquality-devel libselinux-devel
|
||||
libssh-devel libtool libuuid-devel make popt-devel
|
||||
|
||||
@@ -27,6 +27,8 @@ test-main-commit-rhel8:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
@@ -46,6 +48,8 @@ test-main-commit-rhel9:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
@@ -67,10 +71,13 @@ test-main-commit-rhel8-fips:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- fips-mode-setup --check || exit 1
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
@@ -87,10 +94,13 @@ test-main-commit-rhel9-fips:
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- fips-mode-setup --check || exit 1
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
41
.gitlab/ci/ubuntu-32bit.yml
Normal file
41
.gitlab/ci/ubuntu-32bit.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
test-mergerq-job-ubuntu-32bit:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- ubuntu-bionic-32bit
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-main-commit-job-ubuntu-32bit:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- ubuntu-bionic-32bit
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
43
FAQ.md
43
FAQ.md
@@ -1192,7 +1192,7 @@
|
||||
|
||||
More references can be found at the end of this document. Note that
|
||||
these are estimates from the defender side, so assuming something is
|
||||
easier than it actually is is fine. An attacker may still have
|
||||
easier than it actually is fine. An attacker may still have
|
||||
significantly higher cost than estimated here.
|
||||
|
||||
LUKS1 used SHA1 (since version 1.7.0 it uses SHA256) for hashing per
|
||||
@@ -1864,11 +1864,11 @@
|
||||
|
||||
This basically means that if you already have a slot-key, and you have
|
||||
set the PBKDF2 iteration count to 1 (it is > 10'000 normally), you could
|
||||
(maybe) derive a different passphrase that gives you the the same
|
||||
slot-key. But if you have the slot-key, you can already unlock the
|
||||
key-slot and get the volume key, breaking everything. So basically,
|
||||
this SHA-1 vulnerability allows you to open a LUKS1 container with high
|
||||
effort when you already have it open.
|
||||
(maybe) derive a different passphrase that gives you the same slot-key.
|
||||
But if you have the slot-key, you can already unlock the key-slot and
|
||||
get the volume key, breaking everything. So basically, this SHA-1
|
||||
vulnerability allows you to open a LUKS1 container with high effort when
|
||||
you already have it open.
|
||||
|
||||
The real problem here is people that do not understand crypto and claim
|
||||
things are broken just because some mechanism is used that has been
|
||||
@@ -2506,6 +2506,31 @@ offset length name data type description
|
||||
individually created (and hence has its own volume key). In this case,
|
||||
changing the default passphrase will make it secure again.
|
||||
|
||||
* **6.16 How to convert the printed volume key to a raw one?**
|
||||
A volume key printed via something like:
|
||||
```
|
||||
cryptsetup --dump-volume-key luksDump /dev/<device> >volume-key
|
||||
```
|
||||
(i.e. without using `--volume-key-file`), which gives something like:
|
||||
```
|
||||
LUKS header information for /dev/<device>
|
||||
Cipher name: aes
|
||||
Cipher mode: xts-plain64
|
||||
Payload offset: 32768
|
||||
UUID: 6e914442-e8b5-4eb5-98c4-5bf0cf17ecad
|
||||
MK bits: 512
|
||||
MK dump: e0 3f 15 c2 0f e5 80 ab 35 b4 10 03 ae 30 b9 5d
|
||||
4c 0d 28 9e 1b 0f e3 b0 50 57 ef d4 4d 53 a0 12
|
||||
b7 4e 43 a1 20 7e c5 02 1f f1 f5 08 04 3c f5 20
|
||||
a6 0b 23 f6 7b 53 55 aa 22 d8 aa 02 e0 2f d5 04
|
||||
```
|
||||
can be converted to the raw volume key for example via:
|
||||
```
|
||||
sed -E -n '/^MK dump:\t/,/^[^\t]/{0,/^MK dump:\t/s/^MK dump://; /^([^\t].*)?$/q; s/\t+//p;};' volume-key | xxd -r -p
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
# 7. Interoperability with other Disk Encryption Tools
|
||||
|
||||
@@ -3014,9 +3039,9 @@ offset length name data type description
|
||||
currently associated with any data/crypt segment (encrypted area) in the
|
||||
LUKS2 'Segments' section (displayed by luksDump).
|
||||
|
||||
This is a bit of a more general idea. It basically allows to use a keyslot
|
||||
as a container for a key to be used in other things than decrypting a
|
||||
data segment.
|
||||
This is a bit of a more general idea. It basically allows one to use a
|
||||
keyslot as a container for a key to be used in other things than decrypting
|
||||
a data segment.
|
||||
|
||||
As of April 2020, the following uses are defined:
|
||||
|
||||
|
||||
13
Makefile.am
13
Makefile.am
@@ -1,5 +1,5 @@
|
||||
EXTRA_DIST = README.md COPYING.LGPL FAQ.md docs misc autogen.sh
|
||||
SUBDIRS = po tests
|
||||
SUBDIRS = po tests tests/fuzz
|
||||
CLEANFILES =
|
||||
DISTCLEAN_TARGETS =
|
||||
|
||||
@@ -14,8 +14,14 @@ AM_CPPFLAGS = \
|
||||
-DVERSION=\""$(VERSION)"\" \
|
||||
-DEXTERNAL_LUKS2_TOKENS_PATH=\"${EXTERNAL_LUKS2_TOKENS_PATH}\"
|
||||
AM_CFLAGS = -Wall
|
||||
AM_CXXFLAGS = -Wall
|
||||
AM_LDFLAGS =
|
||||
|
||||
if ENABLE_FUZZ_TARGETS
|
||||
AM_CFLAGS += -fsanitize=fuzzer-no-link
|
||||
AM_CXXFLAGS += -fsanitize=fuzzer-no-link
|
||||
endif
|
||||
|
||||
LDADD = $(LTLIBINTL)
|
||||
|
||||
tmpfilesddir = @DEFAULT_TMPFILESDIR@
|
||||
@@ -64,3 +70,8 @@ uninstall-local:
|
||||
|
||||
check-programs: libcryptsetup.la
|
||||
$(MAKE) -C tests $@
|
||||
|
||||
if ENABLE_FUZZ_TARGETS
|
||||
fuzz-targets: libcryptsetup.la libcrypto_backend.la
|
||||
$(MAKE) -C tests/fuzz $@
|
||||
endif
|
||||
|
||||
22
README.md
22
README.md
@@ -6,7 +6,7 @@ What the ...?
|
||||
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
|
||||
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
|
||||
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
|
||||
**TrueCrypt** (including **VeraCrypt** extension), **BitLocker** and **FileVault2** 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
|
||||
@@ -45,22 +45,16 @@ Download
|
||||
--------
|
||||
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
|
||||
**The latest stable release candidate cryptsetup version is 2.5.0-rc1**
|
||||
* [cryptsetup-2.5.0-rc1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0-rc1.tar.xz)
|
||||
* Signature [cryptsetup-2.5.0-rc1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0-rc1.tar.sign)
|
||||
**The latest stable cryptsetup release version is 2.6.0**
|
||||
* [cryptsetup-2.6.0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.0.tar.xz)
|
||||
* Signature [cryptsetup-2.6.0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.0.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.5.0-rc1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/v2.5.0-rc1-ReleaseNotes).
|
||||
|
||||
**The latest stable cryptsetup version is 2.4.3**
|
||||
* [cryptsetup-2.4.3.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.3.tar.xz)
|
||||
* Signature [cryptsetup-2.4.3.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.3.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.4.3 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/v2.4.3-ReleaseNotes).
|
||||
* [Cryptsetup 2.6.0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/v2.6.0-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 2.3.7](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.7.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.7.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.7-ReleaseNotes).
|
||||
* [Version 2.5.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/v2.5.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).
|
||||
|
||||
@@ -74,7 +74,7 @@ autopoint --force $AP_OPTS
|
||||
libtoolize --force --copy
|
||||
aclocal -I m4 $AL_OPTS
|
||||
autoheader $AH_OPTS
|
||||
automake --add-missing --copy --gnu $AM_OPTS
|
||||
automake --force-missing --add-missing --copy --gnu $AM_OPTS
|
||||
autoconf $AC_OPTS
|
||||
|
||||
echo
|
||||
|
||||
34
configure.ac
34
configure.ac
@@ -1,9 +1,9 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[2.5.0-rc1])
|
||||
AC_INIT([cryptsetup],[2.6.0])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=20:0:8
|
||||
LIBCRYPTSETUP_VERSION_INFO=21:0:9
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
@@ -28,6 +28,7 @@ AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_MKDIR_P
|
||||
@@ -150,6 +151,7 @@ if test "x$enable_external_tokens" = "xyes"; then
|
||||
AC_SUBST(DL_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
fi
|
||||
AM_CONDITIONAL(EXTERNAL_TOKENS, test "x$enable_external_tokens" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE([ssh-token],
|
||||
AS_HELP_STRING([--disable-ssh-token], [disable LUKS2 ssh-token]),
|
||||
@@ -213,6 +215,17 @@ if test "x$enable_pwquality" = "xyes"; then
|
||||
PWQUALITY_STATIC_LIBS="$PWQUALITY_LIBS -lcrack -lz"
|
||||
fi
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl fuzzers, it requires own static library compilation later
|
||||
AC_ARG_ENABLE([fuzz-targets],
|
||||
AS_HELP_STRING([--enable-fuzz-targets], [enable building fuzz targets]))
|
||||
AM_CONDITIONAL(ENABLE_FUZZ_TARGETS, test "x$enable_fuzz_targets" = "xyes")
|
||||
|
||||
if test "x$enable_fuzz_targets" = "xyes"; then
|
||||
AX_CHECK_COMPILE_FLAG([-fsanitize=fuzzer-no-link],,
|
||||
AC_MSG_ERROR([Required compiler options not supported; use clang.]), [-Werror])
|
||||
fi
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl passwdqc library (cryptsetup CLI only)
|
||||
AC_ARG_ENABLE([passwdqc],
|
||||
@@ -617,6 +630,22 @@ AC_SUBST([LIBSSH_LIBS])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
|
||||
|
||||
dnl Set Requires.private for libcryptsetup.pc
|
||||
dnl pwquality is used only by tools
|
||||
PKGMODULES="uuid devmapper json-c"
|
||||
case $with_crypto_backend in
|
||||
gcrypt) PKGMODULES+=" libgcrypt" ;;
|
||||
openssl) PKGMODULES+=" openssl" ;;
|
||||
nss) PKGMODULES+=" nss" ;;
|
||||
nettle) PKGMODULES+=" nettle" ;;
|
||||
esac
|
||||
if test "x$enable_libargon2" = "xyes"; then
|
||||
PKGMODULES+=" libargon2"
|
||||
fi
|
||||
if test "x$enable_blkid" = "xyes"; then
|
||||
PKGMODULES+=" blkid"
|
||||
fi
|
||||
AC_SUBST([PKGMODULES])
|
||||
dnl ==========================================================================
|
||||
AC_ARG_ENABLE([dev-random],
|
||||
AS_HELP_STRING([--enable-dev-random], [use /dev/random by default for key generation (otherwise use /dev/urandom)]))
|
||||
@@ -739,5 +768,6 @@ lib/libcryptsetup.pc
|
||||
po/Makefile.in
|
||||
scripts/cryptsetup.conf
|
||||
tests/Makefile
|
||||
tests/fuzz/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
2012-03-16 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --keyfile-offset and --new-keyfile-offset parameters to API and CLI.
|
||||
* Add repair command and crypt_repair() for known LUKS metadata problems repair.
|
||||
* Allow to specify --align-payload only for luksFormat.
|
||||
* Allow one to specify --align-payload only for luksFormat.
|
||||
|
||||
2012-03-16 Milan Broz <mbroz@redhat.com>
|
||||
* Unify password verification option.
|
||||
@@ -228,7 +228,7 @@
|
||||
* Fix password callback call.
|
||||
* Fix default plain password entry from terminal in activate_by_passphrase.
|
||||
* Add --dump-master-key option for luksDump to allow volume key dump.
|
||||
* Allow to activate by internally cached volume key
|
||||
* Allow one to activate by internally cached volume key
|
||||
(format/activate without keyslots active - used for temporary devices).
|
||||
* Initialize volume key from active device in crypt_init_by_name()
|
||||
* Fix cryptsetup binary exitcodes.
|
||||
|
||||
@@ -85,7 +85,7 @@ Libcryptsetup API additions:
|
||||
|
||||
* Fix optional password callback handling.
|
||||
|
||||
* Allow to activate by internally cached volume key immediately after
|
||||
* Allow one to activate by internally cached volume key immediately after
|
||||
crypt_format() without active slot (for temporary devices with
|
||||
on-disk metadata)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ Changes since version 1.4.1
|
||||
* Fix header check to support old (cryptsetup 1.0.0) header alignment.
|
||||
(Regression in 1.4.0)
|
||||
|
||||
* Allow to specify --align-payload only for luksFormat.
|
||||
* Allow one to specify --align-payload only for luksFormat.
|
||||
|
||||
* Add --master-key-file option to luksOpen (open using volume key).
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Changes since version 1.4.2
|
||||
Device-mapper now retry removal if device is busy.
|
||||
|
||||
* Allow "private" activation (skip some udev global rules) flag.
|
||||
Cryptsetup library API now allows to specify CRYPT_ACTIVATE_PRIVATE,
|
||||
Cryptsetup library API now allows one to specify CRYPT_ACTIVATE_PRIVATE,
|
||||
which means that some udev rules are not processed.
|
||||
(Used for temporary devices, like internal keyslot mappings where
|
||||
it is not desirable to run any device scans.)
|
||||
|
||||
@@ -4,7 +4,7 @@ Cryptsetup 1.6.0 Release Notes
|
||||
Changes since version 1.6.0-rc1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Change LUKS default cipher to to use XTS encryption mode,
|
||||
* Change LUKS default cipher to use XTS encryption mode,
|
||||
aes-xts-plain64 (i.e. using AES128-XTS).
|
||||
|
||||
XTS mode becomes standard in hard disk encryption.
|
||||
@@ -209,7 +209,7 @@ Important changes
|
||||
|
||||
WARNING: these tests do not use dmcrypt, only crypto API.
|
||||
You have to benchmark the whole device stack and you can get completely
|
||||
different results. But is is usable for basic comparison.
|
||||
different results. But it is usable for basic comparison.
|
||||
(Note for example AES-NI decryption optimization effect in example above.)
|
||||
|
||||
Features
|
||||
|
||||
@@ -8,7 +8,7 @@ Changes since version 1.6.1
|
||||
* Fix cipher specification string parsing (found by gcc -fsanitize=address option).
|
||||
|
||||
* Try to map TCRYPT system encryption through partition
|
||||
(allows to activate mapping when other partition on the same device is mounted).
|
||||
(allows one to activate mapping when other partition on the same device is mounted).
|
||||
|
||||
* Print a warning if system encryption is used and device is a partition.
|
||||
(TCRYPT system encryption uses whole device argument.)
|
||||
|
||||
@@ -25,7 +25,7 @@ Changes since version 1.6.3
|
||||
|
||||
Please refer to cryptsetup FAQ for detail how to fix this situation.
|
||||
|
||||
* Allow to use --disable-gcrypt-pbkdf2 during configuration
|
||||
* Allow one to use --disable-gcrypt-pbkdf2 during configuration
|
||||
to force use internal PBKDF2 code.
|
||||
|
||||
* Require gcrypt 1.6.1 for imported implementation of PBKDF2
|
||||
|
||||
@@ -38,7 +38,7 @@ Changes since version 1.6.4
|
||||
The command "cryptsetup status" will print basic info, even if you
|
||||
do not provide detached header argument.
|
||||
|
||||
* Allow to specify ECB mode in cryptsetup benchmark.
|
||||
* Allow one to specify ECB mode in cryptsetup benchmark.
|
||||
|
||||
* Add some LUKS images for regression testing.
|
||||
Note that if image with Whirlpool fails, the most probable cause is that
|
||||
|
||||
@@ -35,14 +35,14 @@ Changes since version 1.6.6
|
||||
* Support permanent device decryption for cryptsetup-reencrypt.
|
||||
To remove LUKS encryption from a device, you can now use --decrypt option.
|
||||
|
||||
* Allow to use --header option in all LUKS commands.
|
||||
* Allow one to use --header option in all LUKS commands.
|
||||
The --header always takes precedence over positional device argument.
|
||||
|
||||
* Allow luksSuspend without need to specify a detached header.
|
||||
|
||||
* Detect if O_DIRECT is usable on a device allocation.
|
||||
There are some strange storage stack configurations which wrongly allows
|
||||
to open devices with direct-io but fails on all IO operations later.
|
||||
one to open devices with direct-io but fails on all IO operations later.
|
||||
|
||||
Cryptsetup now tries to read the device first sector to ensure it can use
|
||||
direct-io.
|
||||
|
||||
@@ -30,7 +30,7 @@ Changes since version 1.6.7
|
||||
cryptsetup resize will try to resize underlying loop device as well.
|
||||
(It can be used to grow up file-backed device in one step.)
|
||||
|
||||
* Cryptsetup now allows to use empty password through stdin pipe.
|
||||
* Cryptsetup now allows one to use empty password through stdin pipe.
|
||||
(Intended only for testing in scripts.)
|
||||
|
||||
Cryptsetup API NOTE:
|
||||
|
||||
@@ -3,7 +3,7 @@ Cryptsetup 1.7.4 Release Notes
|
||||
|
||||
Changes since version 1.7.3
|
||||
|
||||
* Allow to specify LUKS1 hash algorithm in Python luksFormat wrapper.
|
||||
* Allow one to specify LUKS1 hash algorithm in Python luksFormat wrapper.
|
||||
|
||||
* Use LUKS1 compiled-in defaults also in Python wrapper.
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ Changes since version 2.0.1
|
||||
|
||||
* Add LUKS2 specific options for cryptsetup-reencrypt.
|
||||
Tokens and persistent flags are now transferred during reencryption;
|
||||
change of PBKDF keyslot parameters is now supported and allows
|
||||
change of PBKDF keyslot parameters is now supported and allows one
|
||||
to set precalculated values (no benchmarks).
|
||||
|
||||
* Do not allow LUKS2 --persistent and --test-passphrase cryptsetup flags
|
||||
|
||||
@@ -28,7 +28,7 @@ Changes since version 2.0.2
|
||||
|
||||
* New API extensions for unbound keyslots (LUKS2 only)
|
||||
crypt_keyslot_get_key_size() and crypt_volume_key_get()
|
||||
These functions allow to get key and key size for unbound keyslots.
|
||||
These functions allow one to get key and key size for unbound keyslots.
|
||||
|
||||
* New enum value CRYPT_SLOT_UNBOUND for keyslot status (LUKS2 only).
|
||||
|
||||
|
||||
@@ -170,21 +170,21 @@ These new calls are now exported, for details see libcryptsetup.h:
|
||||
|
||||
* crypt_get_metadata_size
|
||||
* crypt_set_metadata_size
|
||||
allows to set/get area sizes in LUKS header
|
||||
allows one to set/get area sizes in LUKS header
|
||||
(according to specification).
|
||||
|
||||
* crypt_get_default_type
|
||||
get default compiled-in LUKS type (version).
|
||||
|
||||
* crypt_get_pbkdf_type_params
|
||||
allows to get compiled-in PBKDF parameters.
|
||||
allows one to get compiled-in PBKDF parameters.
|
||||
|
||||
* crypt_keyslot_set_encryption
|
||||
* crypt_keyslot_get_encryption
|
||||
allows to set/get per-keyslot encryption algorithm for LUKS2.
|
||||
allows one to set/get per-keyslot encryption algorithm for LUKS2.
|
||||
|
||||
* crypt_keyslot_get_pbkdf
|
||||
allows to get PBKDF parameters per-keyslot.
|
||||
allows one to get PBKDF parameters per-keyslot.
|
||||
|
||||
and these new defines:
|
||||
* CRYPT_LOG_DEBUG_JSON (message type for JSON debug)
|
||||
|
||||
@@ -9,7 +9,7 @@ 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.
|
||||
one to access this proprietary disk encryption.
|
||||
|
||||
Changes since version 2.2.2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -18,7 +18,7 @@ Changes since version 2.3.1
|
||||
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).
|
||||
area on disk (LUKS2 allows one to store arbitrary keys).
|
||||
|
||||
* Rephrase some error messages and remove redundant end-of-lines.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Cryptsetup 2.5.0-rc1 Release Notes
|
||||
==================================
|
||||
Stable release candidate with new features and bug fixes.
|
||||
Cryptsetup 2.5.0 Release Notes
|
||||
==============================
|
||||
Stable release with new features and bug fixes.
|
||||
|
||||
Changes since version 2.4.3
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -125,6 +125,11 @@ LUKS volume reencryption changes
|
||||
|
||||
* Support all options allowed with luksFormat with encrypt action.
|
||||
|
||||
* Add prompt if LUKS2 decryption is run with a detached header.
|
||||
|
||||
* Add warning for reencryption of file image and mention
|
||||
the possible use of --force-offline-reencrypt option.
|
||||
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
@@ -258,6 +263,11 @@ Other changes
|
||||
|
||||
* Reimplement BASE64 with simplified code instead of coreutils version.
|
||||
|
||||
* Fix regression when warning messages were not displayed
|
||||
if some kernel feature is not supported (2.4.2).
|
||||
|
||||
* Add support for --key-slot option in luksResume action.
|
||||
|
||||
Libcryptsetup API extensions and changes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
236
docs/v2.6.0-ReleaseNotes
Normal file
236
docs/v2.6.0-ReleaseNotes
Normal file
@@ -0,0 +1,236 @@
|
||||
Cryptsetup 2.6.0 Release Notes
|
||||
==============================
|
||||
Stable release with new features and bug fixes.
|
||||
|
||||
Changes since version 2.5.0
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Introduce support for handling macOS FileVault2 devices (FVAULT2).
|
||||
|
||||
Cryptsetup now supports the mapping of FileVault2 full-disk encryption
|
||||
by Apple for the macOS operating system using a native Linux kernel.
|
||||
You can open an existing USB FileVault portable device and (with
|
||||
the hfsplus filesystem driver) access the native data read/write.
|
||||
|
||||
Cryptsetup supports only (legacy) FileVault2 based on Core Storage
|
||||
and HFS+ filesystem (introduced in MacOS X 10.7 Lion).
|
||||
It does NOT support the new version of FileVault based on the APFS
|
||||
filesystem used in recent macOS versions.
|
||||
|
||||
Header formatting and changes are not supported; cryptsetup never
|
||||
changes the metadata on the device.
|
||||
|
||||
FVAULT2 extension requires kernel userspace crypto API and kernel
|
||||
driver for HFS+ (hfsplus) filesystem (available on most systems today).
|
||||
|
||||
Example of using FileVault2 formatted USB device:
|
||||
|
||||
A typical encrypted device contains three partitions; the FileVault
|
||||
encrypted partition is here sda2:
|
||||
|
||||
$ lsblk -o NAME,FSTYPE,LABEL /dev/sda
|
||||
NAME FSTYPE LABEL
|
||||
sda
|
||||
|-sda1 vfat EFI
|
||||
|-sda2
|
||||
`-sda3 hfsplus Boot OS X
|
||||
|
||||
Note: blkid does not recognize FileVault2 format yet.
|
||||
|
||||
To dump metadata information about the device, you can use
|
||||
the fvault2Dump command:
|
||||
|
||||
$ cryptsetup fvault2Dump /dev/sda2
|
||||
Header information for FVAULT2 device /dev/sda2.
|
||||
Physical volume UUID: 6f353c05-daae-4e76-a0ee-6a9569a22d81
|
||||
Family UUID: f82cceb0-a788-4815-945a-53d57fcd55a8
|
||||
Logical volume offset: 67108864 [bytes]
|
||||
Logical volume size: 3288334336 [bytes]
|
||||
Cipher: aes
|
||||
Cipher mode: xts-plain64
|
||||
PBKDF2 iterations: 97962
|
||||
PBKDF2 salt: 173a4ec7447662ec79ca7a47df6c2a01
|
||||
|
||||
To activate the device, use open --type fvault2 option:
|
||||
|
||||
$ cryptsetup open --type fvault2 /dev/sda2 test
|
||||
Enter passphrase for /dev/sda2: ...
|
||||
|
||||
And check the status of the active device:
|
||||
|
||||
$ cryptsetup status test
|
||||
/dev/mapper/test is active.
|
||||
type: FVAULT2
|
||||
cipher: aes-xts-plain64
|
||||
keysize: 256 bits
|
||||
key location: dm-crypt
|
||||
device: /dev/sda2
|
||||
sector size: 512
|
||||
offset: 131072 sectors
|
||||
size: 6422528 sectors
|
||||
mode: read/write
|
||||
|
||||
Now, if the kernel contains hfsplus filesystem driver, you can mount
|
||||
decrypted content:
|
||||
|
||||
$ mount /dev/mapper/test /mnt/test
|
||||
|
||||
For more info about implementation, please refer to the master thesis
|
||||
by Pavel Tobias, which was the source for this extension.
|
||||
https://is.muni.cz/th/p0aok/?lang=en
|
||||
|
||||
* libcryptsetup: no longer use global memory locking through mlockall()
|
||||
|
||||
For many years, libcryptsetup locked all memory (including dependent
|
||||
library address space) to prevent swapping sensitive content outside
|
||||
of RAM.
|
||||
|
||||
This strategy no longer works as the locking of basic libraries exceeds
|
||||
the memory locking limit if running as a non-root user.
|
||||
|
||||
Libcryptsetup now locks only memory ranges containing sensitive
|
||||
material (keys) through crypt_safe_alloc() calls.
|
||||
|
||||
This change solves many reported mysterious problems of unexpected
|
||||
failures. If the initial lock was still under the limit and succeeded,
|
||||
some following memory allocation could fail later as it exceeded
|
||||
the locking limit. If the initial locking fails, memory locking
|
||||
was quietly ignored completely.
|
||||
|
||||
The whole crypt_memory_lock() API call is deprecated; it no longer
|
||||
calls memlockall().
|
||||
|
||||
* libcryptsetup: process priority is increased only for key derivation
|
||||
(PBKDF) calls.
|
||||
|
||||
Increasing priority was tight to memory locking and works only if
|
||||
running under superuser.
|
||||
Only PBKDF calls and benchmarking now increase the process priority.
|
||||
|
||||
* Add new LUKS keyslot context handling functions and API.
|
||||
|
||||
In practice, the luksAddKey action does two operations.
|
||||
It unlocks the existing device volume key and stores the unlocked
|
||||
volume key in a new keyslot.
|
||||
Previously the options were limited to key files and passphrases.
|
||||
|
||||
Newly available methods (keyslot contexts) are passphrase, keyfile,
|
||||
key (binary representation), and LUKS2 token.
|
||||
|
||||
To unlock a keyslot user may:
|
||||
- provide existing passphrase via interactive prompt (default method)
|
||||
- use --key-file option to provide a file with a valid passphrase
|
||||
- provide volume key directly via --volume-key-file
|
||||
- unlock keyslot via all available LUKS2 tokens by --token-only
|
||||
- unlock keyslot via specific token with --token-id
|
||||
- unlock keyslot via specific token type by --token-type
|
||||
|
||||
To provide the passphrase for a new keyslot, a user may:
|
||||
- provide existing passphrase via interactive prompt (default method)
|
||||
- use --new-keyfile to read the passphrase from the file
|
||||
- use --new-token-id to select LUKS2 token to get passphrase
|
||||
for new keyslot. The new keyslot is assigned to the selected token
|
||||
id if the operation is successful.
|
||||
|
||||
* The volume key may now be extracted using a passphrase, keyfile, or
|
||||
token. For LUKS devices, it also returns the volume key after
|
||||
a successful crypt_format call.
|
||||
|
||||
* Fix --disable-luks2-reencryption configuration option.
|
||||
|
||||
* cryptsetup: Print a better error message and warning if the format
|
||||
produces an image without space available for data.
|
||||
|
||||
Activation now fails early with a more descriptive message.
|
||||
|
||||
* Print error if anti-forensic LUKS2 hash setting is not available.
|
||||
If the specified hash was not available, activation quietly failed.
|
||||
|
||||
* Fix internal crypt segment compare routine if the user
|
||||
specified cipher in kernel format (capi: prefix).
|
||||
|
||||
* cryptsetup: Add token unassign action.
|
||||
|
||||
This action allows removing token binding on specific keyslot.
|
||||
|
||||
* veritysetup: add support for --use-tasklets option.
|
||||
|
||||
This option sets try_verify_in_tasklet kernel dm-verity option
|
||||
(available since Linux kernel 6.0) to allow some performance
|
||||
improvement on specific systems.
|
||||
|
||||
* Provide pkgconfig Require.private settings.
|
||||
|
||||
While we do not completely provide static build on udev systems,
|
||||
it helps produce statically linked binaries in certain situations.
|
||||
|
||||
* Always update automake library files if autogen.sh is run.
|
||||
|
||||
For several releases, we distributed older automake scripts by mistake.
|
||||
|
||||
* reencryption: Fix user defined moved segment size in LUKS2 decryption.
|
||||
|
||||
The --hotzone-size argument was ignored in cases where the actual data
|
||||
size was less than the original LUKS2 data offset.
|
||||
|
||||
* Delegate FIPS mode detection to configured crypto backend.
|
||||
System FIPS mode check no longer depends on /etc/system-fips file.
|
||||
|
||||
* tests: externally provided systemd plugin is now optionally compiled
|
||||
from systemd git and tested with cryptsetup
|
||||
|
||||
* tests: initial integration to OSS-fuzz project with basic crypt_load()
|
||||
test for LUKS2 and JSON mutated fuzzing.
|
||||
|
||||
For more info, see README in tests/fuzz directory.
|
||||
|
||||
* Update documentation, including FAQ and man pages.
|
||||
|
||||
Libcryptsetup API extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The libcryptsetup API is backward compatible with existing symbols.
|
||||
|
||||
New symbols:
|
||||
crypt_keyslot_context_init_by_passphrase
|
||||
crypt_keyslot_context_init_by_keyfile
|
||||
crypt_keyslot_context_init_by_token
|
||||
crypt_keyslot_context_init_by_volume_key
|
||||
crypt_keyslot_context_get_error
|
||||
crypt_keyslot_context_set_pin
|
||||
crypt_keyslot_context_get_type
|
||||
crypt_keyslot_context_free
|
||||
crypt_keyslot_add_by_keyslot_context
|
||||
crypt_volume_key_get_by_keyslot_context
|
||||
|
||||
New defines:
|
||||
CRYPT_FVAULT2 "FVAULT2" (FileVault2 compatible mode)
|
||||
|
||||
Keyslot context types:
|
||||
CRYPT_KC_TYPE_PASSPHRASE
|
||||
CRYPT_KC_TYPE_KEYFILE
|
||||
CRYPT_KC_TYPE_TOKEN
|
||||
CRYPT_KC_TYPE_KEY
|
||||
|
||||
CRYPT_ACTIVATE_TASKLETS (dm-verity: use tasklets activation flag)
|
||||
|
||||
WARNING!
|
||||
~~~~~~~~
|
||||
The next version of cryptsetup will change the encryption mode and key
|
||||
derivation option for the PLAIN format.
|
||||
|
||||
This change will cause backward incompatibility.
|
||||
For this reason, the user will have to specify the exact parameters
|
||||
for cipher, key size, and key derivation parameters for plain format.
|
||||
|
||||
The default encryption mode will be AES-XTS with 512bit key (AES-256).
|
||||
The CBC mode is no longer considered the best default, as it allows easy
|
||||
bit-flipped ciphertext modification attacks and performance problems.
|
||||
|
||||
For the passphrase hashing in plain mode, the encryption key is directly
|
||||
derived through iterative hashing from a user-provided passphrase
|
||||
(except a keyfile that is not hashed).
|
||||
|
||||
The default hash is RIPEMD160, which is no longer the best default
|
||||
option. The exact change will be yet discussed but should include
|
||||
the possibility of using a password-based key derivation function
|
||||
instead of iterative hashing.
|
||||
@@ -53,8 +53,6 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/utils_loop.h \
|
||||
lib/utils_devpath.c \
|
||||
lib/utils_wipe.c \
|
||||
lib/utils_fips.c \
|
||||
lib/utils_fips.h \
|
||||
lib/utils_device.c \
|
||||
lib/utils_keyring.c \
|
||||
lib/utils_keyring.h \
|
||||
@@ -75,6 +73,8 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/loopaes/loopaes.c \
|
||||
lib/tcrypt/tcrypt.h \
|
||||
lib/tcrypt/tcrypt.c \
|
||||
lib/keyslot_context.h \
|
||||
lib/keyslot_context.c \
|
||||
lib/luks1/af.h \
|
||||
lib/luks1/af.c \
|
||||
lib/luks1/keyencryption.c \
|
||||
@@ -106,4 +106,6 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/utils_blkid.c \
|
||||
lib/utils_blkid.h \
|
||||
lib/bitlk/bitlk.h \
|
||||
lib/bitlk/bitlk.c
|
||||
lib/bitlk/bitlk.c \
|
||||
lib/fvault2/fvault2.h \
|
||||
lib/fvault2/fvault2.c
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "crypto_backend.h"
|
||||
|
||||
|
||||
@@ -97,12 +97,71 @@ static const uint32_t crc32_tab[] = {
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
static const uint32_t crc32c_tab[] = {
|
||||
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL,
|
||||
0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL,
|
||||
0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L,
|
||||
0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
|
||||
0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L,
|
||||
0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL,
|
||||
0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L,
|
||||
0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
|
||||
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
|
||||
0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L,
|
||||
0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L,
|
||||
0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
|
||||
0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL,
|
||||
0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L,
|
||||
0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L,
|
||||
0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
|
||||
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL,
|
||||
0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
|
||||
0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L,
|
||||
0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
|
||||
0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL,
|
||||
0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L,
|
||||
0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL,
|
||||
0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
|
||||
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL,
|
||||
0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL,
|
||||
0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
|
||||
0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
|
||||
0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L,
|
||||
0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL,
|
||||
0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL,
|
||||
0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
|
||||
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L,
|
||||
0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL,
|
||||
0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L,
|
||||
0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
|
||||
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L,
|
||||
0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL,
|
||||
0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L,
|
||||
0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
|
||||
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L,
|
||||
0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L,
|
||||
0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L,
|
||||
0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
|
||||
0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
|
||||
0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L,
|
||||
0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L,
|
||||
0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
|
||||
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL,
|
||||
0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L,
|
||||
0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L,
|
||||
0xAD7D5351L
|
||||
};
|
||||
|
||||
/*
|
||||
* This a generic crc32() function, it takes seed as an argument,
|
||||
* and does __not__ xor at the end. Then individual users can do
|
||||
* whatever they need.
|
||||
*/
|
||||
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
|
||||
static uint32_t compute_crc32(
|
||||
const uint32_t *crc32_tab,
|
||||
uint32_t seed,
|
||||
const unsigned char *buf,
|
||||
size_t len)
|
||||
{
|
||||
uint32_t crc = seed;
|
||||
const unsigned char *p = buf;
|
||||
@@ -112,3 +171,13 @@ uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
|
||||
{
|
||||
return compute_crc32(crc32_tab, seed, buf, len);
|
||||
}
|
||||
|
||||
uint32_t crypt_crc32c(uint32_t seed, const unsigned char *buf, size_t len)
|
||||
{
|
||||
return compute_crc32(crc32c_tab, seed, buf, len);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef _CRYPTO_BACKEND_H
|
||||
#define _CRYPTO_BACKEND_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@@ -88,6 +89,7 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
|
||||
|
||||
/* CRC32 */
|
||||
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
|
||||
uint32_t crypt_crc32c(uint32_t seed, const unsigned char *buf, size_t len);
|
||||
|
||||
/* Base64 */
|
||||
int crypt_base64_encode(char **out, size_t *out_length, const char *in, size_t in_length);
|
||||
@@ -152,4 +154,7 @@ static inline void crypt_backend_memzero(void *s, size_t n)
|
||||
/* Memcmp helper (memcmp in constant time) */
|
||||
int crypt_backend_memeq(const void *m1, const void *m2, size_t n);
|
||||
|
||||
/* crypto backend running in FIPS mode */
|
||||
bool crypt_fips_mode(void);
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_H */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <gcrypt.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
@@ -555,3 +554,20 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
|
||||
{
|
||||
return crypt_internal_memeq(m1, m2, n);
|
||||
}
|
||||
|
||||
#if !ENABLE_FIPS
|
||||
bool crypt_fips_mode(void) { return false; }
|
||||
#else
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
static bool fips_mode = false, fips_checked = false;
|
||||
|
||||
if (fips_checked)
|
||||
return fips_mode;
|
||||
|
||||
fips_mode = gcry_fips_mode_active();
|
||||
fips_checked = true;
|
||||
|
||||
return fips_mode;
|
||||
}
|
||||
#endif /* ENABLE FIPS */
|
||||
|
||||
@@ -421,3 +421,8 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
|
||||
{
|
||||
return crypt_internal_memeq(m1, m2, n);
|
||||
}
|
||||
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -453,3 +453,8 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
|
||||
/* The logic is inverse to memcmp... */
|
||||
return !memeql_sec(m1, m2, n);
|
||||
}
|
||||
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -400,3 +400,8 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
|
||||
{
|
||||
return NSS_SecureMemcmp(m1, m2, n);
|
||||
}
|
||||
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -812,3 +812,29 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
|
||||
{
|
||||
return CRYPTO_memcmp(m1, m2, n);
|
||||
}
|
||||
|
||||
#if !ENABLE_FIPS
|
||||
bool crypt_fips_mode(void) { return false; }
|
||||
#else
|
||||
static bool openssl_fips_mode(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
return EVP_default_properties_is_fips_enabled(NULL);
|
||||
#else
|
||||
return FIPS_mode();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
static bool fips_mode = false, fips_checked = false;
|
||||
|
||||
if (fips_checked)
|
||||
return fips_mode;
|
||||
|
||||
fips_mode = openssl_fips_mode();
|
||||
fips_checked = true;
|
||||
|
||||
return fips_mode;
|
||||
}
|
||||
#endif /* ENABLE FIPS */
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <endian.h>
|
||||
|
||||
|
||||
1057
lib/fvault2/fvault2.c
Normal file
1057
lib/fvault2/fvault2.c
Normal file
File diff suppressed because it is too large
Load Diff
80
lib/fvault2/fvault2.h
Normal file
80
lib/fvault2/fvault2.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* FVAULT2 (FileVault2-compatible) volume handling
|
||||
*
|
||||
* Copyright (C) 2021-2022 Pavel Tobias
|
||||
*
|
||||
* 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_FVAULT2_H
|
||||
#define _CRYPTSETUP_FVAULT2_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define FVAULT2_WRAPPED_KEY_SIZE 24
|
||||
#define FVAULT2_PBKDF2_SALT_SIZE 16
|
||||
#define FVAULT2_UUID_LEN 37
|
||||
|
||||
struct crypt_device;
|
||||
struct volume_key;
|
||||
|
||||
struct fvault2_params {
|
||||
const char *cipher;
|
||||
const char *cipher_mode;
|
||||
uint16_t key_size;
|
||||
uint32_t pbkdf2_iters;
|
||||
char pbkdf2_salt[FVAULT2_PBKDF2_SALT_SIZE];
|
||||
char wrapped_kek[FVAULT2_WRAPPED_KEY_SIZE];
|
||||
char wrapped_vk[FVAULT2_WRAPPED_KEY_SIZE];
|
||||
char family_uuid[FVAULT2_UUID_LEN];
|
||||
char ph_vol_uuid[FVAULT2_UUID_LEN];
|
||||
uint64_t log_vol_off;
|
||||
uint64_t log_vol_size;
|
||||
};
|
||||
|
||||
int FVAULT2_read_metadata(
|
||||
struct crypt_device *cd,
|
||||
struct fvault2_params *params);
|
||||
|
||||
int FVAULT2_get_volume_key(
|
||||
struct crypt_device *cd,
|
||||
const char *passphrase,
|
||||
size_t passphrase_len,
|
||||
const struct fvault2_params *params,
|
||||
struct volume_key **vol_key);
|
||||
|
||||
int FVAULT2_dump(
|
||||
struct crypt_device *cd,
|
||||
struct device *device,
|
||||
const struct fvault2_params *params);
|
||||
|
||||
int FVAULT2_activate_by_passphrase(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *passphrase,
|
||||
size_t passphrase_len,
|
||||
const struct fvault2_params *params,
|
||||
uint32_t flags);
|
||||
|
||||
int FVAULT2_activate_by_volume_key(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *key,
|
||||
size_t key_size,
|
||||
const struct fvault2_params *params,
|
||||
uint32_t flags);
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "bitops.h"
|
||||
@@ -38,7 +39,6 @@
|
||||
#include "utils_crypt.h"
|
||||
#include "utils_loop.h"
|
||||
#include "utils_dm.h"
|
||||
#include "utils_fips.h"
|
||||
#include "utils_keyring.h"
|
||||
#include "utils_io.h"
|
||||
#include "crypto_backend/crypto_backend.h"
|
||||
@@ -178,8 +178,7 @@ int init_crypto(struct crypt_device *ctx);
|
||||
|
||||
int crypt_get_debug_level(void);
|
||||
|
||||
int crypt_memlock_inc(struct crypt_device *ctx);
|
||||
int crypt_memlock_dec(struct crypt_device *ctx);
|
||||
void crypt_process_priority(struct crypt_device *cd, int *priority, bool raise);
|
||||
|
||||
int crypt_metadata_locking_enabled(void);
|
||||
|
||||
|
||||
488
lib/keyslot_context.c
Normal file
488
lib/keyslot_context.c
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup, keyslot unlock helpers
|
||||
*
|
||||
* Copyright (C) 2022 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 Ondrej Kozina
|
||||
*
|
||||
* 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 <errno.h>
|
||||
|
||||
#include "luks1/luks.h"
|
||||
#include "luks2/luks2.h"
|
||||
#include "keyslot_context.h"
|
||||
|
||||
static int get_luks2_key_by_passphrase(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
int segment,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
|
||||
assert(r_vk);
|
||||
|
||||
r = LUKS2_keyslot_open(cd, keyslot, segment, kc->u.p.passphrase, kc->u.p.passphrase_size, r_vk);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_luks1_volume_key_by_passphrase(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
|
||||
assert(r_vk);
|
||||
|
||||
r = LUKS_open_key_with_hdr(keyslot, kc->u.p.passphrase, kc->u.p.passphrase_size,
|
||||
crypt_get_hdr(cd, CRYPT_LUKS1), r_vk, cd);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_luks2_volume_key_by_passphrase(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
return get_luks2_key_by_passphrase(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk);
|
||||
}
|
||||
|
||||
static int get_passphrase_by_passphrase(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const char **r_passphrase,
|
||||
size_t *r_passphrase_size)
|
||||
{
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
|
||||
assert(r_passphrase);
|
||||
assert(r_passphrase_size);
|
||||
|
||||
*r_passphrase = kc->u.p.passphrase;
|
||||
*r_passphrase_size = kc->u.p.passphrase_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_passphrase_by_keyfile(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const char **r_passphrase,
|
||||
size_t *r_passphrase_size)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
|
||||
assert(r_passphrase);
|
||||
assert(r_passphrase_size);
|
||||
|
||||
if (!kc->i_passphrase) {
|
||||
r = crypt_keyfile_device_read(cd, kc->u.kf.keyfile,
|
||||
&kc->i_passphrase, &kc->i_passphrase_size,
|
||||
kc->u.kf.keyfile_offset, kc->u.kf.keyfile_size, 0);
|
||||
if (r < 0) {
|
||||
kc->error = r;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
*r_passphrase = kc->i_passphrase;
|
||||
*r_passphrase_size = kc->i_passphrase_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_luks2_key_by_keyfile(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
int segment,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
const char *passphrase;
|
||||
size_t passphrase_size;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
|
||||
assert(r_vk);
|
||||
|
||||
r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = LUKS2_keyslot_open(cd, keyslot, segment, passphrase, passphrase_size, r_vk);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_luks2_volume_key_by_keyfile(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
return get_luks2_key_by_keyfile(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk);
|
||||
}
|
||||
|
||||
static int get_luks1_volume_key_by_keyfile(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
const char *passphrase;
|
||||
size_t passphrase_size;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
|
||||
assert(r_vk);
|
||||
|
||||
r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = LUKS_open_key_with_hdr(keyslot, passphrase, passphrase_size,
|
||||
crypt_get_hdr(cd, CRYPT_LUKS1), r_vk, cd);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_key_by_key(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot __attribute__((unused)),
|
||||
int segment __attribute__((unused)),
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEY);
|
||||
assert(r_vk);
|
||||
|
||||
if (!kc->u.k.volume_key) {
|
||||
kc->error = -ENOENT;
|
||||
return kc->error;
|
||||
}
|
||||
|
||||
*r_vk = crypt_alloc_volume_key(kc->u.k.volume_key_size, kc->u.k.volume_key);
|
||||
if (!*r_vk) {
|
||||
kc->error = -ENOMEM;
|
||||
return kc->error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_volume_key_by_key(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot __attribute__((unused)),
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
|
||||
}
|
||||
|
||||
static int get_luks2_key_by_token(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot __attribute__((unused)),
|
||||
int segment,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN);
|
||||
assert(r_vk);
|
||||
|
||||
r = LUKS2_token_unlock_key(cd, crypt_get_hdr(cd, CRYPT_LUKS2), kc->u.t.id, kc->u.t.type,
|
||||
kc->u.t.pin, kc->u.t.pin_size, segment, kc->u.t.usrptr, r_vk);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_luks2_volume_key_by_token(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot __attribute__((unused)),
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
return get_luks2_key_by_token(cd, kc, -2 /* unused */, CRYPT_DEFAULT_SEGMENT, r_vk);
|
||||
}
|
||||
|
||||
static int get_passphrase_by_token(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const char **r_passphrase,
|
||||
size_t *r_passphrase_size)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN);
|
||||
assert(r_passphrase);
|
||||
assert(r_passphrase_size);
|
||||
|
||||
if (!kc->i_passphrase) {
|
||||
r = LUKS2_token_unlock_passphrase(cd, crypt_get_hdr(cd, CRYPT_LUKS2), kc->u.t.id,
|
||||
kc->u.t.type, kc->u.t.pin, kc->u.t.pin_size,
|
||||
kc->u.t.usrptr, &kc->i_passphrase, &kc->i_passphrase_size);
|
||||
if (r < 0) {
|
||||
kc->error = r;
|
||||
return r;
|
||||
}
|
||||
kc->u.t.id = r;
|
||||
}
|
||||
|
||||
*r_passphrase = kc->i_passphrase;
|
||||
*r_passphrase_size = kc->i_passphrase_size;
|
||||
|
||||
return kc->u.t.id;
|
||||
}
|
||||
|
||||
static void unlock_method_init_internal(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc);
|
||||
|
||||
kc->error = 0;
|
||||
kc->i_passphrase = NULL;
|
||||
kc->i_passphrase_size = 0;
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size)
|
||||
{
|
||||
assert(kc);
|
||||
|
||||
kc->type = CRYPT_KC_TYPE_KEY;
|
||||
kc->u.k.volume_key = volume_key;
|
||||
kc->u.k.volume_key_size = volume_key_size;
|
||||
kc->get_luks2_key = get_key_by_key;
|
||||
kc->get_luks2_volume_key = get_volume_key_by_key;
|
||||
kc->get_luks1_volume_key = get_volume_key_by_key;
|
||||
kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */
|
||||
unlock_method_init_internal(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size)
|
||||
{
|
||||
assert(kc);
|
||||
|
||||
kc->type = CRYPT_KC_TYPE_PASSPHRASE;
|
||||
kc->u.p.passphrase = passphrase;
|
||||
kc->u.p.passphrase_size = passphrase_size;
|
||||
kc->get_luks2_key = get_luks2_key_by_passphrase;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase;
|
||||
kc->get_luks1_volume_key = get_luks1_volume_key_by_passphrase;
|
||||
kc->get_passphrase = get_passphrase_by_passphrase;
|
||||
unlock_method_init_internal(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset)
|
||||
{
|
||||
assert(kc);
|
||||
|
||||
kc->type = CRYPT_KC_TYPE_KEYFILE;
|
||||
kc->u.kf.keyfile = keyfile;
|
||||
kc->u.kf.keyfile_size = keyfile_size;
|
||||
kc->u.kf.keyfile_offset = keyfile_offset;
|
||||
kc->get_luks2_key = get_luks2_key_by_keyfile;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile;
|
||||
kc->get_luks1_volume_key = get_luks1_volume_key_by_keyfile;
|
||||
kc->get_passphrase = get_passphrase_by_keyfile;
|
||||
unlock_method_init_internal(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
void *usrptr)
|
||||
{
|
||||
assert(kc);
|
||||
|
||||
kc->type = CRYPT_KC_TYPE_TOKEN;
|
||||
kc->u.t.id = token;
|
||||
kc->u.t.type = type;
|
||||
kc->u.t.pin = pin;
|
||||
kc->u.t.pin_size = pin_size;
|
||||
kc->u.t.usrptr = usrptr;
|
||||
kc->get_luks2_key = get_luks2_key_by_token;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_token;
|
||||
kc->get_luks1_volume_key = NULL; /* LUKS1 is not supported */
|
||||
kc->get_passphrase = get_passphrase_by_token;
|
||||
unlock_method_init_internal(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
if (!kc)
|
||||
return;
|
||||
|
||||
crypt_safe_free(kc->i_passphrase);
|
||||
kc->i_passphrase = NULL;
|
||||
kc->i_passphrase_size = 0;
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
crypt_keyslot_context_destroy_internal(kc);
|
||||
free(kc);
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc || !passphrase)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_passphrase_init_internal(tmp, passphrase, passphrase_size);
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc || !keyfile)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_keyfile_init_internal(tmp, keyfile, keyfile_size, keyfile_offset);
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_token(struct crypt_device *cd,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin, size_t pin_size,
|
||||
void *usrptr,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN))
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_token_init_internal(tmp, token, type, pin, pin_size, usrptr);
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_key_init_internal(tmp, volume_key, volume_key_size);
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
return kc ? kc->error : -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_set_pin(struct crypt_device *cd,
|
||||
const char *pin, size_t pin_size,
|
||||
struct crypt_keyslot_context *kc)
|
||||
{
|
||||
if (!kc || kc->type != CRYPT_KC_TYPE_TOKEN)
|
||||
return -EINVAL;
|
||||
|
||||
kc->u.t.pin = pin;
|
||||
kc->u.t.pin_size = pin_size;
|
||||
kc->error = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc)
|
||||
{
|
||||
return kc ? kc->type : -EINVAL;
|
||||
}
|
||||
|
||||
const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc);
|
||||
|
||||
switch (kc->type) {
|
||||
case CRYPT_KC_TYPE_PASSPHRASE:
|
||||
return "passphrase";
|
||||
case CRYPT_KC_TYPE_KEYFILE:
|
||||
return "keyfile";
|
||||
case CRYPT_KC_TYPE_TOKEN:
|
||||
return "token";
|
||||
case CRYPT_KC_TYPE_KEY:
|
||||
return "key";
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
111
lib/keyslot_context.h
Normal file
111
lib/keyslot_context.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup, keyslot unlock helpers
|
||||
*
|
||||
* Copyright (C) 2022 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 Ondrej Kozina
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef KEYSLOT_CONTEXT_H
|
||||
#define KEYSLOT_CONTEXT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
typedef int (*keyslot_context_get_key) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
int segment,
|
||||
struct volume_key **r_vk);
|
||||
|
||||
typedef int (*keyslot_context_get_volume_key) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot,
|
||||
struct volume_key **r_vk);
|
||||
|
||||
typedef int (*keyslot_context_get_passphrase) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const char **r_passphrase,
|
||||
size_t *r_passphrase_size);
|
||||
|
||||
/* crypt_keyslot_context */
|
||||
struct crypt_keyslot_context {
|
||||
int type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
const char *passphrase;
|
||||
size_t passphrase_size;
|
||||
} p;
|
||||
struct {
|
||||
const char *keyfile;
|
||||
uint64_t keyfile_offset;
|
||||
size_t keyfile_size;
|
||||
} kf;
|
||||
struct {
|
||||
int id;
|
||||
const char *type;
|
||||
const char *pin;
|
||||
size_t pin_size;
|
||||
void *usrptr;
|
||||
} t;
|
||||
struct {
|
||||
const char *volume_key;
|
||||
size_t volume_key_size;
|
||||
} k;
|
||||
} u;
|
||||
|
||||
int error;
|
||||
|
||||
char *i_passphrase;
|
||||
size_t i_passphrase_size;
|
||||
|
||||
keyslot_context_get_key get_luks2_key;
|
||||
keyslot_context_get_volume_key get_luks1_volume_key;
|
||||
keyslot_context_get_volume_key get_luks2_volume_key;
|
||||
keyslot_context_get_passphrase get_passphrase;
|
||||
};
|
||||
|
||||
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *method);
|
||||
|
||||
void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size);
|
||||
|
||||
void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size);
|
||||
|
||||
void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset);
|
||||
|
||||
void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
void *usrptr);
|
||||
|
||||
const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc);
|
||||
|
||||
#endif /* KEYSLOT_CONTEXT_H */
|
||||
@@ -46,6 +46,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
struct crypt_device; /* crypt device handle */
|
||||
struct crypt_keyslot_context;
|
||||
|
||||
/**
|
||||
* Initialize crypt device handle and check if the provided device exists.
|
||||
@@ -344,6 +345,7 @@ void crypt_set_iteration_time(struct crypt_device *cd, uint64_t iteration_time_m
|
||||
|
||||
/**
|
||||
* Helper to lock/unlock memory to avoid swap sensitive data to disk.
|
||||
* \b Deprecated, only for backward compatibility. Memory with keys are locked automatically.
|
||||
*
|
||||
* @param cd crypt device handle, can be @e NULL
|
||||
* @param lock 0 to unlock otherwise lock memory
|
||||
@@ -353,7 +355,7 @@ void crypt_set_iteration_time(struct crypt_device *cd, uint64_t iteration_time_m
|
||||
* @note Only root can do this.
|
||||
* @note It locks/unlocks all process memory, not only crypt context.
|
||||
*/
|
||||
int crypt_memory_lock(struct crypt_device *cd, int lock);
|
||||
int crypt_memory_lock(struct crypt_device *cd, int lock) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* Set global lock protection for on-disk metadata (file-based locking).
|
||||
@@ -427,6 +429,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
|
||||
#define CRYPT_INTEGRITY "INTEGRITY"
|
||||
/** BITLK (BitLocker-compatible mode) */
|
||||
#define CRYPT_BITLK "BITLK"
|
||||
/** FVAULT2 (FileVault2-compatible mode) */
|
||||
#define CRYPT_FVAULT2 "FVAULT2"
|
||||
|
||||
/** LUKS any version */
|
||||
#define CRYPT_LUKS NULL
|
||||
@@ -1106,6 +1110,187 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
|
||||
size_t passphrase_size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* @defgroup crypt-keyslot-context Crypt keyslot context
|
||||
* @addtogroup crypt-keyslot-context
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Release crypt keyslot context and used memory.
|
||||
*
|
||||
* @param kc crypt keyslot context
|
||||
*/
|
||||
void crypt_keyslot_context_free(struct crypt_keyslot_context *kc);
|
||||
|
||||
/**
|
||||
* Initialize keyslot context via passphrase.
|
||||
*
|
||||
* @param cd crypt device handle initialized to LUKS device context
|
||||
* @param passphrase passphrase for a keyslot
|
||||
* @param passphrase_size size of passphrase
|
||||
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_PASSPHRASE
|
||||
*
|
||||
* @return zero on success or negative errno otherwise.
|
||||
*/
|
||||
int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
struct crypt_keyslot_context **kc);
|
||||
|
||||
/**
|
||||
* Initialize keyslot context via key file path.
|
||||
*
|
||||
* @param cd crypt device handle initialized to LUKS device context
|
||||
*
|
||||
* @param keyfile key file with passphrase for a keyslot
|
||||
* @param keyfile_size number of bytes to read from keyfile, @e 0 is unlimited
|
||||
* @param keyfile_offset number of bytes to skip at start of keyfile
|
||||
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEYFILE
|
||||
*
|
||||
* @return zero on success or negative errno otherwise.
|
||||
*/
|
||||
int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset,
|
||||
struct crypt_keyslot_context **kc);
|
||||
|
||||
/**
|
||||
* Initialize keyslot context via LUKS2 token.
|
||||
*
|
||||
* @param cd crypt device handle initialized to LUKS2 device context
|
||||
*
|
||||
* @param token token providing passphrase for a keyslot or CRYPT_ANY_TOKEN
|
||||
* @param type restrict type of token, if @e NULL all types are allowed
|
||||
* @param pin passphrase (or PIN) to unlock token (may be binary data)
|
||||
* @param pin_size size of @e pin
|
||||
* @param usrptr provided identification in callback
|
||||
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_TOKEN
|
||||
*
|
||||
* @return zero on success or negative errno otherwise.
|
||||
*/
|
||||
int crypt_keyslot_context_init_by_token(struct crypt_device *cd,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin, size_t pin_size,
|
||||
void *usrptr,
|
||||
struct crypt_keyslot_context **kc);
|
||||
|
||||
/**
|
||||
* Initialize keyslot context via key.
|
||||
*
|
||||
* @param cd crypt device handle initialized to LUKS device context
|
||||
*
|
||||
* @param volume_key provided volume key or @e NULL if used after crypt_format
|
||||
* or with CRYPT_VOLUME_KEY_NO_SEGMENT flag
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEY
|
||||
*
|
||||
* @return zero on success or negative errno otherwise.
|
||||
*/
|
||||
int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
struct crypt_keyslot_context **kc);
|
||||
|
||||
/**
|
||||
* Get error code per keyslot context from last failed call.
|
||||
*
|
||||
* @note If @link crypt_keyslot_add_by_keyslot_context @endlink passed with
|
||||
* no negative return code. The return value of this function is undefined.
|
||||
*
|
||||
* @param kc keyslot context involved in failed @link crypt_keyslot_add_by_keyslot_context @endlink
|
||||
*
|
||||
* @return Negative errno if keyslot context caused a failure, zero otherwise.
|
||||
*/
|
||||
int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc);
|
||||
|
||||
/**
|
||||
* Set new pin to token based keyslot context.
|
||||
*
|
||||
* @note Use when @link crypt_keyslot_add_by_keyslot_context @endlink failed
|
||||
* and token keyslot context returned -ENOANO error code via
|
||||
* @link crypt_keyslot_context_get_error @endlink.
|
||||
*
|
||||
* @param cd crypt device handle initialized to LUKS2 device context
|
||||
* @param pin passphrase (or PIN) to unlock token (may be binary data)
|
||||
* @param pin_size size of @e pin
|
||||
* @param kc LUKS2 keyslot context (only @link CRYPT_KC_TYPE_TOKEN @endlink is allowed)
|
||||
*
|
||||
* @return zero on success or negative errno otherwise
|
||||
*/
|
||||
int crypt_keyslot_context_set_pin(struct crypt_device *cd,
|
||||
const char *pin, size_t pin_size,
|
||||
struct crypt_keyslot_context *kc);
|
||||
|
||||
/**
|
||||
* @defgroup crypt-keyslot-context-types Crypt keyslot context
|
||||
* @addtogroup crypt-keyslot-context-types
|
||||
* @{
|
||||
*/
|
||||
/** keyslot context initialized by passphrase (@link crypt_keyslot_context_init_by_passphrase @endlink) */
|
||||
#define CRYPT_KC_TYPE_PASSPHRASE INT16_C(1)
|
||||
/** keyslot context initialized by keyfile (@link crypt_keyslot_context_init_by_keyfile @endlink) */
|
||||
#define CRYPT_KC_TYPE_KEYFILE INT16_C(2)
|
||||
/** keyslot context initialized by token (@link crypt_keyslot_context_init_by_token @endlink) */
|
||||
#define CRYPT_KC_TYPE_TOKEN INT16_C(3)
|
||||
/** keyslot context initialized by volume key or unbound key (@link crypt_keyslot_context_init_by_volume_key @endlink) */
|
||||
#define CRYPT_KC_TYPE_KEY INT16_C(4)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Get type identifier for crypt keyslot context.
|
||||
*
|
||||
* @param kc keyslot context
|
||||
*
|
||||
* @return crypt keyslot context type id (see @link crypt-keyslot-context-types @endlink) or negative errno otherwise.
|
||||
*/
|
||||
int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Add key slot by volume key provided by keyslot context (kc). New
|
||||
* keyslot will be protected by passphrase provided by new keyslot context (new_kc).
|
||||
* See @link crypt-keyslot-context @endlink for context initialization routines.
|
||||
*
|
||||
* @pre @e cd contains initialized and formatted LUKS device context.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot_existing existing keyslot or CRYPT_ANY_SLOT to get volume key from.
|
||||
* @param kc keyslot context providing volume key.
|
||||
* @param keyslot_new new keyslot or CRYPT_ANY_SLOT (first free number is used).
|
||||
* @param new_kc keyslot context providing passphrase for new keyslot.
|
||||
* @param flags key flags to set
|
||||
*
|
||||
* @return allocated key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note new_kc can not be @e CRYPT_KC_TYPE_KEY type keyslot context.
|
||||
*
|
||||
* @note For kc parameter with type @e CRYPT_KC_TYPE_KEY the keyslot_existing
|
||||
* parameter is ignored.
|
||||
*
|
||||
* @note in case there is no active LUKS keyslot to get existing volume key from, one of following must apply:
|
||||
* @li @e cd must be device handle used in crypt_format() by current process (it holds reference to generated volume key)
|
||||
* @li kc must be of @e CRYPT_KC_TYPE_KEY type with valid volume key.
|
||||
*
|
||||
* @note With CRYPT_VOLUME_KEY_NO_SEGMENT flag raised and kc of type @e CRYPT_KC_TYPE_KEY with @e volume_key set to @e NULL
|
||||
* the new volume_key will be generated and stored in new keyslot. The keyslot will become unbound (unusable to
|
||||
* dm-crypt device activation).
|
||||
*
|
||||
* @warning CRYPT_VOLUME_KEY_SET flag force updates volume key. It is @b not @b reencryption!
|
||||
* By doing so you will most probably destroy your ciphertext data device. It's supposed
|
||||
* to be used only in wrapped keys scheme for key refresh process where real (inner) volume
|
||||
* key stays untouched. It may be involed on active @e keyslot which makes the (previously
|
||||
* unbound) keyslot new regular keyslot.
|
||||
*/
|
||||
int crypt_keyslot_add_by_keyslot_context(struct crypt_device *cd,
|
||||
int keyslot_existing,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot_new,
|
||||
struct crypt_keyslot_context *new_kc,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Destroy (and disable) key slot.
|
||||
*
|
||||
@@ -1182,6 +1367,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (UINT32_C(1) << 25)
|
||||
/** dm-integrity: reset automatic recalculation */
|
||||
#define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
|
||||
/** dm-verity: try to use tasklets */
|
||||
#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -1471,6 +1658,9 @@ 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.
|
||||
* @note For LUKS devices, if passphrase is @e NULL and volume key is cached in
|
||||
* device context it returns the volume key generated in preceding
|
||||
* @link crypt_format @endlink call.
|
||||
*/
|
||||
int crypt_volume_key_get(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -1479,6 +1669,41 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size);
|
||||
|
||||
/**
|
||||
* Get volume key from crypt device by keyslot context.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
|
||||
* @param volume_key buffer for volume key
|
||||
* @param volume_key_size on input, size of buffer @e volume_key,
|
||||
* on output size of @e volume_key
|
||||
* @param kc keyslot context used to unlock volume key
|
||||
*
|
||||
* @return unlocked key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note See @link crypt-keyslot-context-types @endlink for info on keyslot
|
||||
* context initialization.
|
||||
* @note For TCRYPT cipher chain is the volume key concatenated
|
||||
* for all ciphers in chain (kc may be NULL).
|
||||
* @note For VERITY the volume key means root hash used for activation
|
||||
* (kc may be NULL).
|
||||
* @note For LUKS devices, if kc is @e NULL and volume key is cached in
|
||||
* device context it returns the volume key generated in preceding
|
||||
* @link crypt_format @endlink call.
|
||||
* @note @link CRYPT_KC_TYPE_TOKEN @endlink keyslot context is usable only with LUKS2 devices.
|
||||
* @note @link CRYPT_KC_TYPE_KEY @endlink keyslot context can not be used.
|
||||
* @note To get LUKS2 unbound key, keyslot parameter must not be @e CRYPT_ANY_SLOT.
|
||||
* @note EPERM errno means provided keyslot context could not unlock any (or selected)
|
||||
* keyslot.
|
||||
* @note ENOENT errno means no LUKS keyslot is available to retrieve volume key from
|
||||
* and there's no cached volume key in device handle.
|
||||
*/
|
||||
int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
char *volume_key,
|
||||
size_t *volume_key_size,
|
||||
struct crypt_keyslot_context *kc);
|
||||
|
||||
/**
|
||||
* Verify that provided volume key is valid for crypt device.
|
||||
*
|
||||
|
||||
@@ -8,3 +8,4 @@ Description: cryptsetup library
|
||||
Version: @LIBCRYPTSETUP_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lcryptsetup
|
||||
Requires.private: @PKGMODULES@
|
||||
|
||||
@@ -151,3 +151,17 @@ CRYPTSETUP_2.5 {
|
||||
crypt_get_subsystem;
|
||||
crypt_resume_by_token_pin;
|
||||
} CRYPTSETUP_2.4;
|
||||
|
||||
CRYPTSETUP_2.6 {
|
||||
global:
|
||||
crypt_keyslot_context_free;
|
||||
crypt_keyslot_context_init_by_passphrase;
|
||||
crypt_keyslot_context_init_by_keyfile;
|
||||
crypt_keyslot_context_init_by_token;
|
||||
crypt_keyslot_context_init_by_volume_key;
|
||||
crypt_keyslot_context_get_error;
|
||||
crypt_keyslot_context_set_pin;
|
||||
crypt_keyslot_context_get_type;
|
||||
crypt_keyslot_add_by_keyslot_context;
|
||||
crypt_volume_key_get_by_keyslot_context;
|
||||
} CRYPTSETUP_2.5;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
# include <sys/sysmacros.h> /* for major, minor */
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include "internal.h"
|
||||
|
||||
#define DM_CRYPT_TARGET "crypt"
|
||||
@@ -205,6 +204,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
|
||||
if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
|
||||
_dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch))
|
||||
_dm_flags |= DM_VERITY_TASKLETS_SUPPORTED;
|
||||
|
||||
_dm_verity_checked = true;
|
||||
}
|
||||
|
||||
@@ -473,27 +475,22 @@ static size_t int_log10(uint64_t x)
|
||||
return r;
|
||||
}
|
||||
|
||||
#define CLEN 64 /* 2*MAX_CIPHER_LEN */
|
||||
#define CLENS "63" /* for sscanf length + '\0' */
|
||||
#define CAPIL 144 /* should be enough to fit whole capi string */
|
||||
#define CAPIS "143" /* for sscanf of crypto API string + 16 + \0 */
|
||||
|
||||
static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
|
||||
static int cipher_dm2c(const char *org_c, const char *org_i, unsigned tag_size,
|
||||
char *c_dm, int c_dm_size,
|
||||
char *i_dm, int i_dm_size)
|
||||
{
|
||||
int c_size = 0, i_size = 0, i;
|
||||
char cipher[CLEN], mode[CLEN], iv[CLEN+1], tmp[CLEN];
|
||||
char capi[CAPIL];
|
||||
char cipher[MAX_CAPI_ONE_LEN], mode[MAX_CAPI_ONE_LEN], iv[MAX_CAPI_ONE_LEN+1],
|
||||
tmp[MAX_CAPI_ONE_LEN], capi[MAX_CAPI_LEN];
|
||||
|
||||
if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
|
||||
return -EINVAL;
|
||||
|
||||
i = sscanf(org_c, "%" CLENS "[^-]-%" CLENS "s", cipher, tmp);
|
||||
i = sscanf(org_c, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", cipher, tmp);
|
||||
if (i != 2)
|
||||
return -EINVAL;
|
||||
|
||||
i = sscanf(tmp, "%" CLENS "[^-]-%" CLENS "s", mode, iv);
|
||||
i = sscanf(tmp, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", mode, iv);
|
||||
if (i == 1) {
|
||||
memset(iv, 0, sizeof(iv));
|
||||
strncpy(iv, mode, sizeof(iv)-1);
|
||||
@@ -540,75 +537,6 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
|
||||
{
|
||||
char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN];
|
||||
char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1];
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (!c_dm)
|
||||
return -EINVAL;
|
||||
|
||||
/* legacy mode */
|
||||
if (strncmp(c_dm, "capi:", 4)) {
|
||||
if (!(*org_c = strdup(c_dm)))
|
||||
return -ENOMEM;
|
||||
*org_i = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* modes with capi: prefix */
|
||||
i = sscanf(c_dm, "capi:%" CAPIS "[^-]-%" CLENS "s", tmp, iv);
|
||||
if (i != 2)
|
||||
return -EINVAL;
|
||||
|
||||
len = strlen(tmp);
|
||||
if (len < 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (tmp[len-1] == ')')
|
||||
tmp[len-1] = '\0';
|
||||
|
||||
if (sscanf(tmp, "rfc4309(%" CAPIS "s", capi) == 1) {
|
||||
if (!(*org_i = strdup("aead")))
|
||||
return -ENOMEM;
|
||||
} else if (sscanf(tmp, "rfc7539(%" CAPIS "[^,],%" CLENS "s", capi, auth) == 2) {
|
||||
if (!(*org_i = strdup(auth)))
|
||||
return -ENOMEM;
|
||||
} else if (sscanf(tmp, "authenc(%" CLENS "[^,],%" CAPIS "s", auth, capi) == 2) {
|
||||
if (!(*org_i = strdup(auth)))
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
if (i_dm) {
|
||||
if (!(*org_i = strdup(i_dm)))
|
||||
return -ENOMEM;
|
||||
} else
|
||||
*org_i = NULL;
|
||||
memset(capi, 0, sizeof(capi));
|
||||
strncpy(capi, tmp, sizeof(capi)-1);
|
||||
}
|
||||
|
||||
i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher);
|
||||
if (i == 2)
|
||||
i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
|
||||
else
|
||||
i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
|
||||
if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) {
|
||||
free(*org_i);
|
||||
*org_i = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(*org_c = strdup(dmcrypt_tmp))) {
|
||||
free(*org_i);
|
||||
*org_i = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *_uf(char *buf, size_t buf_size, const char *s, unsigned u)
|
||||
{
|
||||
size_t r = snprintf(buf, buf_size, " %s:%u", s, u);
|
||||
@@ -626,7 +554,7 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
|
||||
if (!tgt)
|
||||
return NULL;
|
||||
|
||||
r = cipher_c2dm(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size,
|
||||
r = cipher_dm2c(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size,
|
||||
cipher_dm, sizeof(cipher_dm), integrity_dm, sizeof(integrity_dm));
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
@@ -734,6 +662,8 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_TASKLETS)
|
||||
num_options++;
|
||||
|
||||
max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256;
|
||||
fec_features = crypt_safe_alloc(max_fec_size);
|
||||
@@ -764,13 +694,14 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
} else
|
||||
*verity_verify_args = '\0';
|
||||
|
||||
if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 */
|
||||
r = snprintf(features, sizeof(features), " %d%s%s%s%s%s", num_options,
|
||||
if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 + 22 */
|
||||
r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
|
||||
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
|
||||
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "",
|
||||
(flags & CRYPT_ACTIVATE_TASKLETS) ? " try_verify_in_tasklet" : "");
|
||||
if (r < 0 || (size_t)r >= sizeof(features))
|
||||
goto out;
|
||||
} else
|
||||
@@ -1670,16 +1601,94 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
return -ENOTSUP;
|
||||
|
||||
r = _dm_create_device(cd, name, type, dmd);
|
||||
|
||||
if (r < 0 && dm_flags(cd, dmd->segment.type, &dmt_flags))
|
||||
if (!r || r == -EEXIST)
|
||||
goto out;
|
||||
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
|
||||
if (dm_flags(cd, dmd->segment.type, &dmt_flags))
|
||||
goto out;
|
||||
|
||||
if ((dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
|
||||
check_retry(cd, &dmd->flags, dmt_flags)) {
|
||||
log_dbg(cd, "Retrying open without incompatible options.");
|
||||
r = _dm_create_device(cd, name, type, dmd);
|
||||
if (!r || r == -EEXIST)
|
||||
goto out;
|
||||
}
|
||||
|
||||
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_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) &&
|
||||
!(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED)) {
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd->flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
|
||||
CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
|
||||
CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
|
||||
CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) &&
|
||||
!(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED)) {
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd->flags & CRYPT_ACTIVATE_TASKLETS &&
|
||||
!(dmt_flags & DM_VERITY_TASKLETS_SUPPORTED)) {
|
||||
log_err(cd, _("Requested dm-verity tasklets option is not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
|
||||
!(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED)) {
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd->segment.type == DM_VERITY &&
|
||||
dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED)) {
|
||||
log_err(cd, _("Requested dm-verity FEC options are not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd->segment.type == DM_CRYPT) {
|
||||
if (dmd->segment.u.crypt.integrity && !(dmt_flags & DM_INTEGRITY_SUPPORTED)) {
|
||||
log_err(cd, _("Requested data integrity options are not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
if (dmd->segment.u.crypt.sector_size != SECTOR_SIZE && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED)) {
|
||||
log_err(cd, _("Requested sector_size option is not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) &&
|
||||
!(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED)) {
|
||||
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE_RESET) &&
|
||||
!(dmt_flags & DM_INTEGRITY_RESET_RECALC_SUPPORTED)) {
|
||||
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (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."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
if (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."));
|
||||
r = -EINVAL;
|
||||
}
|
||||
out:
|
||||
/*
|
||||
* Print warning if activating dm-crypt cipher_null device unless it's reencryption helper or
|
||||
* keyslot encryption helper device (LUKS1 cipher_null devices).
|
||||
@@ -1688,54 +1697,6 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
crypt_is_cipher_null(dmd->segment.u.crypt.cipher))
|
||||
log_dbg(cd, "Activated dm-crypt device with cipher_null. Device is not encrypted.");
|
||||
|
||||
if (r == -EINVAL &&
|
||||
dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) &&
|
||||
!(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
|
||||
if (r == -EINVAL &&
|
||||
dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) &&
|
||||
!(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
|
||||
CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
|
||||
CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
|
||||
CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) &&
|
||||
!(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
|
||||
!(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_VERITY &&
|
||||
dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity FEC options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_CRYPT) {
|
||||
if (dmd->segment.u.crypt.integrity && !(dmt_flags & DM_INTEGRITY_SUPPORTED))
|
||||
log_err(cd, _("Requested data integrity options are not supported."));
|
||||
if (dmd->segment.u.crypt.sector_size != SECTOR_SIZE && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED))
|
||||
log_err(cd, _("Requested sector_size option is not supported."));
|
||||
}
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) &&
|
||||
!(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_RECALCULATE_RESET) &&
|
||||
!(dmt_flags & DM_INTEGRITY_RESET_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."));
|
||||
out:
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
@@ -2030,9 +1991,7 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
|
||||
|
||||
/* cipher */
|
||||
if (get_flags & DM_ACTIVE_CRYPT_CIPHER) {
|
||||
r = cipher_dm2c(CONST_CAST(char**)&cipher,
|
||||
CONST_CAST(char**)&integrity,
|
||||
rcipher, rintegrity);
|
||||
r = crypt_capi_to_cipher(&cipher, &integrity, rcipher, rintegrity);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
}
|
||||
@@ -2265,6 +2224,8 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
*act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
|
||||
else if (!strcasecmp(arg, "check_at_most_once"))
|
||||
*act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
|
||||
else if (!strcasecmp(arg, "try_verify_in_tasklet"))
|
||||
*act_flags |= CRYPT_ACTIVATE_TASKLETS;
|
||||
else if (!strcasecmp(arg, "use_fec_from_device")) {
|
||||
str = strsep(¶ms, " ");
|
||||
str2 = crypt_lookup_dev(str);
|
||||
@@ -2736,7 +2697,7 @@ static int _dm_query_device(struct crypt_device *cd, const char *name,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Never allow to return empty key */
|
||||
/* Never allow one to return empty key */
|
||||
if ((get_flags & DM_ACTIVE_CRYPT_KEY) && dmi.suspended) {
|
||||
log_dbg(cd, "Cannot read volume key while suspended.");
|
||||
r = -EINVAL;
|
||||
@@ -2818,7 +2779,8 @@ int dm_query_device(struct crypt_device *cd, const char *name,
|
||||
return r;
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
@@ -2864,7 +2826,8 @@ static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_
|
||||
#endif
|
||||
}
|
||||
|
||||
int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
|
||||
int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix,
|
||||
char **names, size_t names_length)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
struct dm_info dmi;
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "luks.h"
|
||||
@@ -232,11 +231,12 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
hdr_size = LUKS_device_sectors(&hdr) << SECTOR_SHIFT;
|
||||
buffer_size = size_round_up(hdr_size, crypt_getpagesize());
|
||||
|
||||
buffer = crypt_safe_alloc(buffer_size);
|
||||
buffer = malloc(buffer_size);
|
||||
if (!buffer || hdr_size < LUKS_ALIGN_KEYSLOTS || hdr_size > buffer_size) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
memset(buffer, 0, buffer_size);
|
||||
|
||||
log_dbg(ctx, "Storing backup of header (%zu bytes) and keyslot area (%zu bytes).",
|
||||
sizeof(hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);
|
||||
@@ -280,7 +280,8 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
r = 0;
|
||||
out:
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_free(buffer);
|
||||
crypt_safe_memzero(buffer, buffer_size);
|
||||
free(buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -308,7 +309,7 @@ int LUKS_hdr_restore(
|
||||
goto out;
|
||||
}
|
||||
|
||||
buffer = crypt_safe_alloc(buffer_size);
|
||||
buffer = malloc(buffer_size);
|
||||
if (!buffer) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
@@ -379,7 +380,8 @@ int LUKS_hdr_restore(
|
||||
r = LUKS_read_phdr(hdr, 1, 0, ctx);
|
||||
out:
|
||||
device_sync(ctx, device);
|
||||
crypt_safe_free(buffer);
|
||||
crypt_safe_memzero(buffer, buffer_size);
|
||||
free(buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1227,6 +1229,10 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
|
||||
uint64_t offset, length;
|
||||
size_t wipe_block;
|
||||
|
||||
r = LUKS_check_device_size(ctx, hdr, 1);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Wipe complete header, keyslots and padding areas with zeroes. */
|
||||
offset = 0;
|
||||
length = (uint64_t)hdr->payloadOffset * SECTOR_SIZE;
|
||||
|
||||
@@ -121,6 +121,7 @@ struct luks2_hdr {
|
||||
uint8_t salt2[LUKS2_SALT_L];
|
||||
char uuid[LUKS2_UUID_L];
|
||||
void *jobj;
|
||||
void *jobj_rollback;
|
||||
};
|
||||
|
||||
struct luks2_keyslot_params {
|
||||
@@ -167,6 +168,7 @@ int LUKS2_hdr_version_unlocked(struct crypt_device *cd,
|
||||
int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair);
|
||||
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr);
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr);
|
||||
int LUKS2_hdr_rollback(struct crypt_device *cd, struct luks2_hdr *hdr);
|
||||
int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr);
|
||||
int LUKS2_hdr_dump_json(struct crypt_device *cd, struct luks2_hdr *hdr, const char **json);
|
||||
|
||||
@@ -283,13 +285,13 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
|
||||
uint32_t flags,
|
||||
void *usrptr);
|
||||
|
||||
int LUKS2_token_unlock_volume_key(struct crypt_device *cd,
|
||||
int LUKS2_token_unlock_key(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
uint32_t flags,
|
||||
int segment,
|
||||
void *usrptr,
|
||||
struct volume_key **vk);
|
||||
|
||||
@@ -300,6 +302,16 @@ int LUKS2_token_keyring_get(struct luks2_hdr *hdr,
|
||||
int LUKS2_token_keyring_json(char *buffer, size_t buffer_size,
|
||||
const struct crypt_token_params_luks2_keyring *keyring_params);
|
||||
|
||||
int LUKS2_token_unlock_passphrase(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
void *usrptr,
|
||||
char **passphrase,
|
||||
size_t *passphrase_size);
|
||||
|
||||
void crypt_token_unload_external_all(struct crypt_device *cd);
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "luks2_internal.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -189,6 +189,8 @@ void keyring_dump(struct crypt_device *cd, const char *json);
|
||||
|
||||
int keyring_validate(struct crypt_device *cd, const char *json);
|
||||
|
||||
void keyring_buffer_free(void *buffer, size_t buffer_size);
|
||||
|
||||
struct crypt_token_handler_v2 {
|
||||
const char *name;
|
||||
crypt_token_open_func open;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include "luks2_internal.h"
|
||||
#include <uuid/uuid.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct area {
|
||||
uint64_t offset;
|
||||
@@ -363,6 +362,10 @@ int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
wipe_block = 4096;
|
||||
}
|
||||
|
||||
r = device_check_size(cd, crypt_metadata_device(cd), length, 1);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
log_dbg(cd, "Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
|
||||
offset, length + offset);
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "luks2_internal.h"
|
||||
#include "../integrity/integrity.h"
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
@@ -1110,6 +1109,33 @@ int LUKS2_hdr_validate(struct crypt_device *cd, json_object *hdr_jobj, uint64_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool hdr_json_free(json_object **jobj)
|
||||
{
|
||||
assert(jobj);
|
||||
|
||||
if (json_object_put(*jobj))
|
||||
*jobj = NULL;
|
||||
|
||||
return (*jobj == NULL);
|
||||
}
|
||||
|
||||
static int hdr_update_copy_for_rollback(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
json_object **jobj_copy;
|
||||
|
||||
assert(hdr);
|
||||
assert(hdr->jobj);
|
||||
|
||||
jobj_copy = (json_object **)&hdr->jobj_rollback;
|
||||
|
||||
if (!hdr_json_free(jobj_copy)) {
|
||||
log_dbg(cd, "LUKS2 rollback metadata copy still in use");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return json_object_copy(hdr->jobj, jobj_copy) ? -ENOMEM : 0;
|
||||
}
|
||||
|
||||
/* FIXME: should we expose do_recovery parameter explicitly? */
|
||||
int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
|
||||
{
|
||||
@@ -1141,6 +1167,9 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
|
||||
} else
|
||||
device_read_unlock(cd, crypt_metadata_device(cd));
|
||||
|
||||
if (!r && (r = hdr_update_copy_for_rollback(cd, hdr)))
|
||||
log_dbg(cd, "Failed to update rollback LUKS2 metadata.");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1153,18 +1182,50 @@ static int hdr_cleanup_and_validate(struct crypt_device *cd, struct luks2_hdr *h
|
||||
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
|
||||
r = LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
|
||||
|
||||
if (!r && (r = hdr_update_copy_for_rollback(cd, hdr)))
|
||||
log_dbg(cd, "Failed to update rollback LUKS2 metadata.");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
|
||||
r = LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
|
||||
|
||||
if (!r && (r = hdr_update_copy_for_rollback(cd, hdr)))
|
||||
log_dbg(cd, "Failed to update rollback LUKS2 metadata.");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS2_hdr_rollback(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
json_object **jobj_copy;
|
||||
|
||||
assert(hdr->jobj_rollback);
|
||||
|
||||
log_dbg(cd, "Rolling back in-memory LUKS2 json metadata.");
|
||||
|
||||
jobj_copy = (json_object **)&hdr->jobj;
|
||||
|
||||
if (!hdr_json_free(jobj_copy)) {
|
||||
log_dbg(cd, "LUKS2 header still in use");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return json_object_copy(hdr->jobj_rollback, jobj_copy) ? -ENOMEM : 0;
|
||||
}
|
||||
|
||||
int LUKS2_hdr_uuid(struct crypt_device *cd, struct luks2_hdr *hdr, const char *uuid)
|
||||
@@ -1201,10 +1262,19 @@ int LUKS2_hdr_labels(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
|
||||
void LUKS2_hdr_free(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
if (json_object_put(hdr->jobj))
|
||||
hdr->jobj = NULL;
|
||||
else if (hdr->jobj)
|
||||
json_object **jobj;
|
||||
|
||||
assert(hdr);
|
||||
|
||||
jobj = (json_object **)&hdr->jobj;
|
||||
|
||||
if (!hdr_json_free(jobj))
|
||||
log_dbg(cd, "LUKS2 header still in use");
|
||||
|
||||
jobj = (json_object **)&hdr->jobj_rollback;
|
||||
|
||||
if (!hdr_json_free(jobj))
|
||||
log_dbg(cd, "LUKS2 rollback metadata copy still in use");
|
||||
}
|
||||
|
||||
static uint64_t LUKS2_keyslots_size_jobj(json_object *jobj)
|
||||
@@ -1246,7 +1316,7 @@ int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
hdr_size = LUKS2_hdr_and_areas_size(hdr);
|
||||
buffer_size = size_round_up(hdr_size, crypt_getpagesize());
|
||||
|
||||
buffer = crypt_safe_alloc(buffer_size);
|
||||
buffer = malloc(buffer_size);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1257,23 +1327,22 @@ int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to acquire read lock on device %s."),
|
||||
device_path(crypt_metadata_device(cd)));
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
goto out;
|
||||
}
|
||||
|
||||
devfd = device_open_locked(cd, device, O_RDONLY);
|
||||
if (devfd < 0) {
|
||||
device_read_unlock(cd, device);
|
||||
log_err(cd, _("Device %s is not a valid LUKS device."), device_path(device));
|
||||
crypt_safe_free(buffer);
|
||||
return devfd == -1 ? -EINVAL : devfd;
|
||||
r = (devfd == -1) ? -EINVAL : devfd;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), buffer, hdr_size, 0) < hdr_size) {
|
||||
device_read_unlock(cd, device);
|
||||
crypt_safe_free(buffer);
|
||||
return -EIO;
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
device_read_unlock(cd, device);
|
||||
@@ -1284,8 +1353,8 @@ int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
log_err(cd, _("Requested header backup file %s already exists."), backup_file);
|
||||
else
|
||||
log_err(cd, _("Cannot create header backup file %s."), backup_file);
|
||||
crypt_safe_free(buffer);
|
||||
return -EINVAL;
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ret = write_buffer(fd, buffer, buffer_size);
|
||||
close(fd);
|
||||
@@ -1294,8 +1363,9 @@ int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
r = -EIO;
|
||||
} else
|
||||
r = 0;
|
||||
|
||||
crypt_safe_free(buffer);
|
||||
out:
|
||||
crypt_safe_memzero(buffer, buffer_size);
|
||||
free(buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1306,8 +1376,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
int r, fd, devfd = -1, diff_uuid = 0;
|
||||
ssize_t ret, buffer_size = 0;
|
||||
char *buffer = NULL, msg[1024];
|
||||
struct luks2_hdr hdr_file;
|
||||
struct luks2_hdr tmp_hdr = {};
|
||||
struct luks2_hdr hdr_file = {}, tmp_hdr = {};
|
||||
uint32_t reqs = 0;
|
||||
|
||||
r = device_alloc(cd, &backup_device, backup_file);
|
||||
@@ -1340,7 +1409,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
}
|
||||
|
||||
buffer_size = LUKS2_hdr_and_areas_size(&hdr_file);
|
||||
buffer = crypt_safe_alloc(buffer_size);
|
||||
buffer = malloc(buffer_size);
|
||||
if (!buffer) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
@@ -1440,10 +1509,9 @@ out:
|
||||
LUKS2_hdr_free(cd, &tmp_hdr);
|
||||
crypt_safe_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_safe_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_free(buffer);
|
||||
|
||||
crypt_safe_memzero(buffer, buffer_size);
|
||||
free(buffer);
|
||||
device_sync(cd, device);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
/* Serialize memory-hard keyslot access: optional workaround for parallel processing */
|
||||
#define MIN_MEMORY_FOR_SERIALIZE_LOCK_KB 32*1024 /* 32MB */
|
||||
|
||||
/* coverity[ -taint_source : arg-0 ] */
|
||||
static int luks2_encrypt_to_storage(char *src, size_t srcLength,
|
||||
const char *cipher, const char *cipher_mode,
|
||||
struct volume_key *vk, unsigned int sector,
|
||||
@@ -275,7 +276,11 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
r = AF_split(cd, volume_key, AfKey, volume_key_len, LUKS_STRIPES, af_hash);
|
||||
r = crypt_hash_size(af_hash);
|
||||
if (r < 0)
|
||||
log_err(cd, _("Hash algorithm %s is not available."), af_hash);
|
||||
else
|
||||
r = AF_split(cd, volume_key, AfKey, volume_key_len, LUKS_STRIPES, af_hash);
|
||||
|
||||
if (r == 0) {
|
||||
log_dbg(cd, "Updating keyslot area [0x%04" PRIx64 "].", area_offset);
|
||||
@@ -379,8 +384,13 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
|
||||
derived_key, (unsigned)(area_offset / SECTOR_SIZE), cd);
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
r = AF_merge(AfKey, volume_key, volume_key_len, LUKS_STRIPES, af_hash);
|
||||
if (r == 0) {
|
||||
r = crypt_hash_size(af_hash);
|
||||
if (r < 0)
|
||||
log_err(cd, _("Hash algorithm %s is not available."), af_hash);
|
||||
else
|
||||
r = AF_merge(AfKey, volume_key, volume_key_len, LUKS_STRIPES, af_hash);
|
||||
}
|
||||
out:
|
||||
free(salt);
|
||||
crypt_free_volume_key(derived_key);
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "luks2_internal.h"
|
||||
#include "utils_device_locking.h"
|
||||
|
||||
@@ -513,7 +511,8 @@ static json_object *reencrypt_make_hot_segments_forward(struct crypt_device *cd,
|
||||
|
||||
if (tmp < device_size) {
|
||||
fixed_length = device_size - tmp;
|
||||
jobj_old_seg = reencrypt_make_segment_old(cd, hdr, rh, data_offset + data_shift_value(&rh->rp), rh->offset + rh->length, rh->fixed_length ? &fixed_length : NULL);
|
||||
jobj_old_seg = reencrypt_make_segment_old(cd, hdr, rh, data_offset + data_shift_value(&rh->rp),
|
||||
rh->offset + rh->length, rh->fixed_length ? &fixed_length : NULL);
|
||||
if (!jobj_old_seg)
|
||||
goto err;
|
||||
json_object_object_add_by_uint(jobj_segs_hot, sg, jobj_old_seg);
|
||||
@@ -668,7 +667,8 @@ static json_object *reencrypt_make_hot_segments_backward(struct crypt_device *cd
|
||||
|
||||
if (tmp < device_size) {
|
||||
fixed_length = device_size - tmp;
|
||||
jobj_new_seg = reencrypt_make_segment_new(cd, hdr, rh, data_offset, rh->offset + rh->length, rh->offset + rh->length, rh->fixed_length ? &fixed_length : NULL);
|
||||
jobj_new_seg = reencrypt_make_segment_new(cd, hdr, rh, data_offset, rh->offset + rh->length,
|
||||
rh->offset + rh->length, rh->fixed_length ? &fixed_length : NULL);
|
||||
if (!jobj_new_seg)
|
||||
goto err;
|
||||
json_object_object_add_by_uint(jobj_segs_hot, sg, jobj_new_seg);
|
||||
@@ -846,6 +846,50 @@ void LUKS2_reencrypt_free(struct crypt_device *cd, struct luks2_reencrypt *rh)
|
||||
crypt_unlock_internal(cd, rh->reenc_lock);
|
||||
free(rh);
|
||||
}
|
||||
|
||||
int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
const struct reenc_protection *rp,
|
||||
int reencrypt_keyslot,
|
||||
uint64_t *r_length)
|
||||
{
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
int r;
|
||||
uint64_t dummy, area_length;
|
||||
|
||||
assert(hdr);
|
||||
assert(rp);
|
||||
assert(r_length);
|
||||
|
||||
if (rp->type <= REENC_PROTECTION_NONE) {
|
||||
*r_length = LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rp->type == REENC_PROTECTION_DATASHIFT) {
|
||||
*r_length = rp->p.ds.data_shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = LUKS2_keyslot_area(hdr, reencrypt_keyslot, &dummy, &area_length);
|
||||
if (r < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rp->type == REENC_PROTECTION_JOURNAL) {
|
||||
*r_length = area_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rp->type == REENC_PROTECTION_CHECKSUM) {
|
||||
*r_length = (area_length / rp->p.csum.hash_size) * rp->p.csum.block_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static size_t reencrypt_get_alignment(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr)
|
||||
@@ -892,7 +936,8 @@ static void _load_backup_segments(struct luks2_hdr *hdr,
|
||||
rh->jobj_segment_moved = NULL;
|
||||
}
|
||||
|
||||
static int reencrypt_offset_backward_moved(struct luks2_hdr *hdr, json_object *jobj_segments, uint64_t *reencrypt_length, uint64_t data_shift, uint64_t *offset)
|
||||
static int reencrypt_offset_backward_moved(struct luks2_hdr *hdr, json_object *jobj_segments,
|
||||
uint64_t *reencrypt_length, uint64_t data_shift, uint64_t *offset)
|
||||
{
|
||||
uint64_t tmp, linear_length = 0;
|
||||
int sg, segs = json_segments_count(jobj_segments);
|
||||
@@ -1474,7 +1519,8 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
else
|
||||
crash_iv_offset = json_segment_get_iv_offset(json_segments_get_segment(rh->jobj_segs_hot, rseg));
|
||||
|
||||
log_dbg(cd, "crash_offset: %" PRIu64 ", crash_length: %" PRIu64 ", crash_iv_offset: %" PRIu64, data_offset + rh->offset, rh->length, crash_iv_offset);
|
||||
log_dbg(cd, "crash_offset: %" PRIu64 ", crash_length: %" PRIu64 ", crash_iv_offset: %" PRIu64,
|
||||
data_offset + rh->offset, rh->length, crash_iv_offset);
|
||||
|
||||
r = crypt_storage_wrapper_init(cd, &cw2, crypt_data_device(cd),
|
||||
data_offset + rh->offset, crash_iv_offset, new_sector_size,
|
||||
@@ -1842,7 +1888,9 @@ static int reencrypt_assign_segments(struct crypt_device *cd,
|
||||
return commit ? LUKS2_hdr_write(cd, hdr) : 0;
|
||||
}
|
||||
|
||||
static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t dev_size, uint64_t data_shift, bool move_first_segment, crypt_reencrypt_direction_info di)
|
||||
static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
uint64_t dev_size, uint64_t data_shift, bool move_first_segment,
|
||||
crypt_reencrypt_direction_info di)
|
||||
{
|
||||
int r;
|
||||
uint64_t first_segment_offset, first_segment_length,
|
||||
@@ -1912,7 +1960,6 @@ static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_
|
||||
static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
uint64_t dev_size,
|
||||
uint64_t data_shift,
|
||||
uint64_t moved_segment_length,
|
||||
crypt_reencrypt_direction_info di)
|
||||
{
|
||||
@@ -1922,7 +1969,7 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
|
||||
data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT;
|
||||
json_object *jobj_segment_first = NULL, *jobj_segment_second = NULL, *jobj_segments;
|
||||
|
||||
if (!data_shift || di == CRYPT_REENCRYPT_BACKWARD)
|
||||
if (di == CRYPT_REENCRYPT_BACKWARD)
|
||||
return -ENOTSUP;
|
||||
|
||||
/*
|
||||
@@ -1930,12 +1977,11 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
|
||||
* [encrypted first segment (max data shift size)][gap (data shift size)][second encrypted data segment]
|
||||
*/
|
||||
first_segment_offset = 0;
|
||||
if (dev_size > data_shift) {
|
||||
first_segment_length = moved_segment_length;
|
||||
first_segment_length = moved_segment_length;
|
||||
if (dev_size > moved_segment_length) {
|
||||
second_segment_offset = data_offset + first_segment_length;
|
||||
second_segment_length = 0;
|
||||
} else
|
||||
first_segment_length = dev_size;
|
||||
}
|
||||
|
||||
jobj_segments = json_object_new_object();
|
||||
if (!jobj_segments)
|
||||
@@ -1951,7 +1997,7 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
if (dev_size > data_shift) {
|
||||
if (dev_size > moved_segment_length) {
|
||||
jobj_segment_second = json_segment_create_crypt(second_segment_offset,
|
||||
crypt_get_iv_offset(cd) + (first_segment_length >> SECTOR_SHIFT),
|
||||
second_segment_length ? &second_segment_length : NULL,
|
||||
@@ -2406,7 +2452,10 @@ static int reencrypt_make_backup_segments(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
|
||||
if (params->flags & CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT) {
|
||||
json_object_copy(LUKS2_get_segment_jobj(hdr, 0), &jobj_segment_bcp);
|
||||
if (json_object_copy(LUKS2_get_segment_jobj(hdr, 0), &jobj_segment_bcp)) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
r = LUKS2_segment_set_flag(jobj_segment_bcp, "backup-moved-segment");
|
||||
if (r)
|
||||
goto err;
|
||||
@@ -2431,8 +2480,12 @@ static int reencrypt_make_backup_segments(struct crypt_device *cd,
|
||||
json_segment_get_cipher(jobj_tmp),
|
||||
json_segment_get_sector_size(jobj_tmp),
|
||||
0);
|
||||
} else
|
||||
json_object_copy(LUKS2_get_segment_jobj(hdr, CRYPT_DEFAULT_SEGMENT), &jobj_segment_old);
|
||||
} else {
|
||||
if (json_object_copy(LUKS2_get_segment_jobj(hdr, CRYPT_DEFAULT_SEGMENT), &jobj_segment_old)) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else if (params->mode == CRYPT_REENCRYPT_ENCRYPT) {
|
||||
r = LUKS2_get_data_size(hdr, &tmp, NULL);
|
||||
if (r)
|
||||
@@ -2640,71 +2693,37 @@ static int reencrypt_verify_datashift_params(struct crypt_device *cd,
|
||||
|
||||
static int reencrypt_verify_resilience_params(struct crypt_device *cd,
|
||||
const struct crypt_params_reencrypt *params,
|
||||
uint32_t sector_size)
|
||||
uint32_t sector_size, bool move_first_segment)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* no change requested */
|
||||
if (!params || !params->resilience)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(params->resilience, "journal"))
|
||||
return 0;
|
||||
return (params->data_shift || move_first_segment) ? -EINVAL : 0;
|
||||
else if (!strcmp(params->resilience, "none"))
|
||||
return 0;
|
||||
return (params->data_shift || move_first_segment) ? -EINVAL : 0;
|
||||
else if (!strcmp(params->resilience, "datashift"))
|
||||
return reencrypt_verify_datashift_params(cd, params, sector_size);
|
||||
else if (!strcmp(params->resilience, "checksum"))
|
||||
else if (!strcmp(params->resilience, "checksum")) {
|
||||
if (params->data_shift || move_first_segment)
|
||||
return -EINVAL;
|
||||
return reencrypt_verify_checksum_params(cd, params);
|
||||
else if (!strcmp(params->resilience, "datashift-checksum")) {
|
||||
r = reencrypt_verify_datashift_params(cd, params, sector_size);
|
||||
return r ?: reencrypt_verify_checksum_params(cd, params);
|
||||
} else if (!strcmp(params->resilience, "datashift-journal"))
|
||||
} else if (!strcmp(params->resilience, "datashift-checksum")) {
|
||||
if (!move_first_segment ||
|
||||
reencrypt_verify_datashift_params(cd, params, sector_size))
|
||||
return -EINVAL;
|
||||
return reencrypt_verify_checksum_params(cd, params);
|
||||
} else if (!strcmp(params->resilience, "datashift-journal")) {
|
||||
if (!move_first_segment)
|
||||
return -EINVAL;
|
||||
return reencrypt_verify_datashift_params(cd, params, sector_size);
|
||||
}
|
||||
|
||||
log_err(cd, _("Unsupported resilience mode %s"), params->resilience);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
const struct reenc_protection *rp,
|
||||
int reencrypt_keyslot,
|
||||
uint64_t *r_length)
|
||||
{
|
||||
int r;
|
||||
uint64_t dummy, area_length;
|
||||
|
||||
assert(hdr);
|
||||
assert(rp);
|
||||
assert(r_length);
|
||||
|
||||
if (rp->type <= REENC_PROTECTION_NONE) {
|
||||
*r_length = LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rp->type == REENC_PROTECTION_DATASHIFT) {
|
||||
*r_length = rp->p.ds.data_shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = LUKS2_keyslot_area(hdr, reencrypt_keyslot, &dummy, &area_length);
|
||||
if (r < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rp->type == REENC_PROTECTION_JOURNAL) {
|
||||
*r_length = area_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rp->type == REENC_PROTECTION_CHECKSUM) {
|
||||
*r_length = (area_length / rp->p.csum.hash_size) * rp->p.csum.block_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd,
|
||||
const char *name,
|
||||
struct luks2_hdr *hdr,
|
||||
@@ -2742,6 +2761,8 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg(cd, "Initializing decryption with datashift.");
|
||||
|
||||
data_shift = params->data_shift << SECTOR_SHIFT;
|
||||
|
||||
/*
|
||||
@@ -2761,10 +2782,12 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd,
|
||||
moved_segment_length = data_shift < LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH ?
|
||||
data_shift : LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH;
|
||||
|
||||
r = reencrypt_set_decrypt_shift_segments(cd, hdr,
|
||||
data_size, data_shift,
|
||||
moved_segment_length,
|
||||
params->direction);
|
||||
if (moved_segment_length > data_size)
|
||||
moved_segment_length = data_size;
|
||||
|
||||
r = reencrypt_set_decrypt_shift_segments(cd, hdr, data_size,
|
||||
moved_segment_length,
|
||||
params->direction);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
@@ -2774,9 +2797,11 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = reencrypt_verify_resilience_params(cd, params, sector_size);
|
||||
if (r < 0)
|
||||
r = reencrypt_verify_resilience_params(cd, params, sector_size, true);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Invalid reencryption resilience parameters."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = LUKS2_keyslot_reencrypt_allocate(cd, hdr, reencrypt_keyslot,
|
||||
params, reencrypt_get_alignment(cd, hdr));
|
||||
@@ -2888,8 +2913,8 @@ out:
|
||||
log_err(cd, _("Failed to resume device %s."), name);
|
||||
|
||||
device_release_excl(cd, crypt_data_device(cd));
|
||||
if (r < 0 && crypt_load(cd, CRYPT_LUKS2, NULL) < 0)
|
||||
log_dbg(cd, "Cannot reload context after failure.");
|
||||
if (r < 0 && LUKS2_hdr_rollback(cd, hdr) < 0)
|
||||
log_dbg(cd, "Failed to rollback LUKS2 metadata after failure.");
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -3039,7 +3064,7 @@ static int reencrypt_init(struct crypt_device *cd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = reencrypt_verify_resilience_params(cd, params, check_sector_size);
|
||||
r = reencrypt_verify_resilience_params(cd, params, check_sector_size, move_first_segment);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -3096,8 +3121,8 @@ static int reencrypt_init(struct crypt_device *cd,
|
||||
r = reencrypt_keyslot;
|
||||
out:
|
||||
device_release_excl(cd, crypt_data_device(cd));
|
||||
if (r < 0 && crypt_load(cd, CRYPT_LUKS2, NULL) < 0)
|
||||
log_dbg(cd, "Cannot reload context after failure.");
|
||||
if (r < 0 && LUKS2_hdr_rollback(cd, hdr) < 0)
|
||||
log_dbg(cd, "Failed to rollback LUKS2 metadata after failure.");
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -3371,12 +3396,12 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
|
||||
|
||||
log_dbg(cd, "Loading LUKS2 reencryption context.");
|
||||
|
||||
|
||||
old_sector_size = reencrypt_get_sector_size_old(hdr);
|
||||
new_sector_size = reencrypt_get_sector_size_new(hdr);
|
||||
sector_size = new_sector_size > old_sector_size ? new_sector_size : old_sector_size;
|
||||
|
||||
r = reencrypt_verify_resilience_params(cd, params, sector_size);
|
||||
r = reencrypt_verify_resilience_params(cd, params, sector_size,
|
||||
LUKS2_get_segment_id_by_flag(hdr, "backup-moved-segment") >= 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
#include "luks2_internal.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define MAX_STR 64
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dlfcn.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "luks2_internal.h"
|
||||
|
||||
@@ -38,6 +37,7 @@ static struct crypt_token_handler_internal token_handlers[LUKS2_TOKENS_MAX] = {
|
||||
.u = {
|
||||
.v1 = { .name = LUKS2_TOKEN_KEYRING,
|
||||
.open = keyring_open,
|
||||
.buffer_free = keyring_buffer_free,
|
||||
.validate = keyring_validate,
|
||||
.dump = keyring_dump }
|
||||
}
|
||||
@@ -423,7 +423,8 @@ static const char *token_json_to_string(json_object *jobj_token)
|
||||
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
|
||||
}
|
||||
|
||||
static int token_is_usable(struct luks2_hdr *hdr, json_object *jobj_token, int segment, crypt_keyslot_priority minimal_priority)
|
||||
static int token_is_usable(struct luks2_hdr *hdr, json_object *jobj_token, int segment,
|
||||
crypt_keyslot_priority minimal_priority, bool requires_keyslot)
|
||||
{
|
||||
crypt_keyslot_priority keyslot_priority;
|
||||
json_object *jobj_array;
|
||||
@@ -440,7 +441,13 @@ static int token_is_usable(struct luks2_hdr *hdr, json_object *jobj_token, int s
|
||||
|
||||
/* no assigned keyslot returns -ENOENT even for CRYPT_ANY_SEGMENT */
|
||||
len = json_object_array_length(jobj_array);
|
||||
if (len <= 0)
|
||||
if (len < 0)
|
||||
return -ENOENT;
|
||||
|
||||
if (!requires_keyslot)
|
||||
return 0;
|
||||
|
||||
if (!len)
|
||||
return -ENOENT;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
@@ -471,7 +478,7 @@ static int translate_errno(struct crypt_device *cd, int ret_val, const char *typ
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int LUKS2_token_open(struct crypt_device *cd,
|
||||
static int token_open(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int token,
|
||||
json_object *jobj_token,
|
||||
@@ -482,7 +489,8 @@ static int LUKS2_token_open(struct crypt_device *cd,
|
||||
size_t pin_size,
|
||||
char **buffer,
|
||||
size_t *buffer_len,
|
||||
void *usrptr)
|
||||
void *usrptr,
|
||||
bool requires_keyslot)
|
||||
{
|
||||
const struct crypt_token_handler_v2 *h;
|
||||
json_object *jobj_type;
|
||||
@@ -499,10 +507,11 @@ static int LUKS2_token_open(struct crypt_device *cd,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
r = token_is_usable(hdr, jobj_token, segment, priority);
|
||||
r = token_is_usable(hdr, jobj_token, segment, priority, requires_keyslot);
|
||||
if (r < 0) {
|
||||
if (r == -ENOENT)
|
||||
log_dbg(cd, "Token %d unusable for segment %d with desired keyslot priority %d.", token, segment, priority);
|
||||
log_dbg(cd, "Token %d unusable for segment %d with desired keyslot priority %d.",
|
||||
token, segment, priority);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -594,7 +603,8 @@ static int LUKS2_keyslot_open_by_token(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
if (keyslot_priority < priority)
|
||||
continue;
|
||||
log_dbg(cd, "Trying to open keyslot %u with token %d (type %s).", num, token, json_object_get_string(jobj_type));
|
||||
log_dbg(cd, "Trying to open keyslot %u with token %d (type %s).",
|
||||
num, token, json_object_get_string(jobj_type));
|
||||
r = LUKS2_keyslot_open(cd, num, segment, buffer, buffer_len, vk);
|
||||
/* short circuit on fatal error */
|
||||
if (r < 0 && r != -EPERM && r != -ENOENT)
|
||||
@@ -615,7 +625,7 @@ static bool token_is_blocked(int token, uint32_t *block_list)
|
||||
/* it is safe now, but have assert in case LUKS2_TOKENS_MAX grows */
|
||||
assert(token >= 0 && (size_t)token < BITFIELD_SIZE(block_list));
|
||||
|
||||
return (*block_list & (1 << token));
|
||||
return (*block_list & (UINT32_C(1) << token));
|
||||
}
|
||||
|
||||
static void token_block(int token, uint32_t *block_list)
|
||||
@@ -623,7 +633,7 @@ static void token_block(int token, uint32_t *block_list)
|
||||
/* it is safe now, but have assert in case LUKS2_TOKENS_MAX grows */
|
||||
assert(token >= 0 && (size_t)token < BITFIELD_SIZE(block_list));
|
||||
|
||||
*block_list |= (1 << token);
|
||||
*block_list |= (UINT32_C(1) << token);
|
||||
}
|
||||
|
||||
static int token_open_priority(struct crypt_device *cd,
|
||||
@@ -650,7 +660,7 @@ static int token_open_priority(struct crypt_device *cd,
|
||||
token = atoi(slot);
|
||||
if (token_is_blocked(token, block_list))
|
||||
continue;
|
||||
r = LUKS2_token_open(cd, hdr, token, val, type, segment, priority, pin, pin_size, &buffer, &buffer_size, usrptr);
|
||||
r = token_open(cd, hdr, token, val, type, segment, priority, pin, pin_size, &buffer, &buffer_size, usrptr, true);
|
||||
if (!r) {
|
||||
r = LUKS2_keyslot_open_by_token(cd, hdr, token, segment, priority,
|
||||
buffer, buffer_size, vk);
|
||||
@@ -669,7 +679,8 @@ static int token_open_priority(struct crypt_device *cd,
|
||||
return *stored_retval;
|
||||
}
|
||||
|
||||
static int token_open_any(struct crypt_device *cd, struct luks2_hdr *hdr, const char *type, int segment, const char *pin, size_t pin_size, void *usrptr, struct volume_key **vk)
|
||||
static int token_open_any(struct crypt_device *cd, struct luks2_hdr *hdr, const char *type, int segment,
|
||||
const char *pin, size_t pin_size, void *usrptr, struct volume_key **vk)
|
||||
{
|
||||
json_object *jobj_tokens;
|
||||
int r, retval = -ENOENT;
|
||||
@@ -681,41 +692,42 @@ static int token_open_any(struct crypt_device *cd, struct luks2_hdr *hdr, const
|
||||
if (!type)
|
||||
usrptr = NULL;
|
||||
|
||||
r = token_open_priority(cd, hdr, jobj_tokens, type, segment, CRYPT_SLOT_PRIORITY_PREFER, pin, pin_size, usrptr, &retval, &blocked, vk);
|
||||
r = token_open_priority(cd, hdr, jobj_tokens, type, segment, CRYPT_SLOT_PRIORITY_PREFER,
|
||||
pin, pin_size, usrptr, &retval, &blocked, vk);
|
||||
if (break_loop_retval(r))
|
||||
return r;
|
||||
|
||||
return token_open_priority(cd, hdr, jobj_tokens, type, segment, CRYPT_SLOT_PRIORITY_NORMAL, pin, pin_size, usrptr, &retval, &blocked, vk);
|
||||
return token_open_priority(cd, hdr, jobj_tokens, type, segment, CRYPT_SLOT_PRIORITY_NORMAL,
|
||||
pin, pin_size, usrptr, &retval, &blocked, vk);
|
||||
}
|
||||
|
||||
int LUKS2_token_unlock_volume_key(struct crypt_device *cd,
|
||||
int LUKS2_token_unlock_key(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
uint32_t flags,
|
||||
int segment,
|
||||
void *usrptr,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
json_object *jobj_token;
|
||||
int segment, r = -ENOENT;
|
||||
int r = -ENOENT;
|
||||
|
||||
assert(vk);
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY)
|
||||
segment = CRYPT_ANY_SEGMENT;
|
||||
else {
|
||||
if (segment == CRYPT_DEFAULT_SEGMENT)
|
||||
segment = LUKS2_get_default_segment(hdr);
|
||||
if (segment < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (segment < 0 && segment != CRYPT_ANY_SEGMENT)
|
||||
return -EINVAL;
|
||||
|
||||
if (token >= 0 && token < LUKS2_TOKENS_MAX) {
|
||||
if ((jobj_token = LUKS2_get_token_jobj(hdr, token))) {
|
||||
r = LUKS2_token_open(cd, hdr, token, jobj_token, type, segment, CRYPT_SLOT_PRIORITY_IGNORE, pin, pin_size, &buffer, &buffer_size, usrptr);
|
||||
r = token_open(cd, hdr, token, jobj_token, type, segment, CRYPT_SLOT_PRIORITY_IGNORE,
|
||||
pin, pin_size, &buffer, &buffer_size, usrptr, true);
|
||||
if (!r) {
|
||||
r = LUKS2_keyslot_open_by_token(cd, hdr, token, segment, CRYPT_SLOT_PRIORITY_IGNORE,
|
||||
buffer, buffer_size, vk);
|
||||
@@ -726,7 +738,7 @@ int LUKS2_token_unlock_volume_key(struct crypt_device *cd,
|
||||
/*
|
||||
* return priorities (ordered form least to most significant):
|
||||
* ENOENT - unusable for activation (no token handler, invalid token metadata, not assigned to volume segment, etc)
|
||||
* EPERM - usable but token provided passphrase did not not unlock any assigned keyslot
|
||||
* EPERM - usable but token provided passphrase did not unlock any assigned keyslot
|
||||
* EAGAIN - usable but not ready (token HW is missing)
|
||||
* ENOANO - ready, but token pin is wrong or missing
|
||||
*
|
||||
@@ -751,10 +763,15 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
|
||||
void *usrptr)
|
||||
{
|
||||
bool use_keyring;
|
||||
int keyslot, r;
|
||||
int keyslot, r, segment;
|
||||
struct volume_key *vk = NULL;
|
||||
|
||||
r = LUKS2_token_unlock_volume_key(cd, hdr, token, type, pin, pin_size, flags, usrptr, &vk);
|
||||
if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY)
|
||||
segment = CRYPT_ANY_SEGMENT;
|
||||
else
|
||||
segment = CRYPT_DEFAULT_SEGMENT;
|
||||
|
||||
r = LUKS2_token_unlock_key(cd, hdr, token, type, pin, pin_size, segment, usrptr, &vk);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -871,6 +888,10 @@ int LUKS2_token_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
json_object *jobj_tokens;
|
||||
int r = 0;
|
||||
|
||||
if ((keyslot < 0 && keyslot != CRYPT_ANY_SLOT) || keyslot >= LUKS2_KEYSLOTS_MAX ||
|
||||
(token < 0 && token != CRYPT_ANY_TOKEN) || token >= LUKS2_TOKENS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (token == CRYPT_ANY_TOKEN) {
|
||||
json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
|
||||
|
||||
@@ -953,3 +974,70 @@ int LUKS2_token_assignment_copy(struct crypt_device *cd,
|
||||
|
||||
return commit ? LUKS2_hdr_write(cd, hdr) : 0;
|
||||
}
|
||||
|
||||
int LUKS2_token_unlock_passphrase(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
void *usrptr,
|
||||
char **passphrase,
|
||||
size_t *passphrase_size)
|
||||
{
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
json_object *jobj_token, *jobj_tokens;
|
||||
int r = -ENOENT, retval = -ENOENT;
|
||||
|
||||
if (!hdr)
|
||||
return -EINVAL;
|
||||
|
||||
if (token >= 0 && token < LUKS2_TOKENS_MAX) {
|
||||
if ((jobj_token = LUKS2_get_token_jobj(hdr, token)))
|
||||
r = token_open(cd, hdr, token, jobj_token, type, CRYPT_ANY_SEGMENT, CRYPT_SLOT_PRIORITY_IGNORE,
|
||||
pin, pin_size, &buffer, &buffer_size, usrptr, false);
|
||||
} else if (token == CRYPT_ANY_TOKEN) {
|
||||
json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
|
||||
|
||||
if (!type)
|
||||
usrptr = NULL;
|
||||
|
||||
json_object_object_foreach(jobj_tokens, slot, val) {
|
||||
token = atoi(slot);
|
||||
r = token_open(cd, hdr, token, val, type, CRYPT_ANY_SEGMENT, CRYPT_SLOT_PRIORITY_IGNORE,
|
||||
pin, pin_size, &buffer, &buffer_size, usrptr, false);
|
||||
|
||||
/*
|
||||
* return priorities (ordered form least to most significant):
|
||||
* ENOENT - unusable for activation (no token handler, invalid token metadata, etc)
|
||||
* EAGAIN - usable but not ready (token HW is missing)
|
||||
* ENOANO - ready, but token pin is wrong or missing
|
||||
*
|
||||
* success (>= 0) or any other negative errno short-circuits token activation loop
|
||||
* immediately
|
||||
*/
|
||||
if (break_loop_retval(r))
|
||||
goto out;
|
||||
|
||||
update_return_errno(r, &retval);
|
||||
}
|
||||
r = retval;
|
||||
} else
|
||||
r = -EINVAL;
|
||||
out:
|
||||
if (!r) {
|
||||
*passphrase = crypt_safe_alloc(buffer_size);
|
||||
if (*passphrase) {
|
||||
memcpy(*passphrase, buffer, buffer_size);
|
||||
*passphrase_size = buffer_size;
|
||||
} else
|
||||
r = -ENOMEM;
|
||||
LUKS2_token_buffer_free(cd, token, buffer, buffer_size);
|
||||
}
|
||||
|
||||
if (!r)
|
||||
return token;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "luks2_internal.h"
|
||||
|
||||
int keyring_open(struct crypt_device *cd,
|
||||
@@ -139,3 +137,8 @@ int LUKS2_token_keyring_get(struct luks2_hdr *hdr,
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
void keyring_buffer_free(void *buffer, size_t buffer_len __attribute__((unused)))
|
||||
{
|
||||
crypt_safe_free(buffer);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -171,6 +170,7 @@ err:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* coverity[ -taint_source : arg-1 ] */
|
||||
int crypt_random_get(struct crypt_device *ctx, char *buf, size_t len, int quality)
|
||||
{
|
||||
int status, rng_type;
|
||||
|
||||
804
lib/setup.c
804
lib/setup.c
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "tcrypt.h"
|
||||
|
||||
56
lib/utils.c
56
lib/utils.c
@@ -59,43 +59,33 @@ uint64_t crypt_getphysmemory_kb(void)
|
||||
return phys_memory_kb;
|
||||
}
|
||||
|
||||
/* MEMLOCK */
|
||||
#define DEFAULT_PROCESS_PRIORITY -18
|
||||
|
||||
static int _priority;
|
||||
static int _memlock_count = 0;
|
||||
|
||||
// return 1 if memory is locked
|
||||
int crypt_memlock_inc(struct crypt_device *ctx)
|
||||
void crypt_process_priority(struct crypt_device *cd, int *priority, bool raise)
|
||||
{
|
||||
if (!_memlock_count++) {
|
||||
log_dbg(ctx, "Locking memory.");
|
||||
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
|
||||
log_dbg(ctx, "Cannot lock memory with mlockall.");
|
||||
_memlock_count--;
|
||||
return 0;
|
||||
}
|
||||
errno = 0;
|
||||
if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno)
|
||||
log_err(ctx, _("Cannot get process priority."));
|
||||
int _priority, new_priority;
|
||||
|
||||
if (raise) {
|
||||
_priority = getpriority(PRIO_PROCESS, 0);
|
||||
if (_priority < 0)
|
||||
_priority = 0;
|
||||
if (priority)
|
||||
*priority = _priority;
|
||||
|
||||
/*
|
||||
* Do not bother checking CAP_SYS_NICE as device activation
|
||||
* requires CAP_SYSADMIN later anyway.
|
||||
*/
|
||||
if (getuid() || geteuid())
|
||||
new_priority = 0;
|
||||
else
|
||||
if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY))
|
||||
log_dbg(ctx, "setpriority %d failed: %s",
|
||||
DEFAULT_PROCESS_PRIORITY, strerror(errno));
|
||||
}
|
||||
return _memlock_count ? 1 : 0;
|
||||
}
|
||||
new_priority = -18;
|
||||
|
||||
int crypt_memlock_dec(struct crypt_device *ctx)
|
||||
{
|
||||
if (_memlock_count && (!--_memlock_count)) {
|
||||
log_dbg(ctx, "Unlocking memory.");
|
||||
if (munlockall() == -1)
|
||||
log_err(ctx, _("Cannot unlock memory."));
|
||||
if (setpriority(PRIO_PROCESS, 0, new_priority))
|
||||
log_dbg(cd, "Cannot raise process priority.");
|
||||
} else {
|
||||
_priority = priority ? *priority : 0;
|
||||
if (setpriority(PRIO_PROCESS, 0, _priority))
|
||||
log_dbg(ctx, "setpriority %d failed: %s", _priority, strerror(errno));
|
||||
log_dbg(cd, "Cannot reset process priority.");
|
||||
}
|
||||
return _memlock_count ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Keyfile processing */
|
||||
@@ -179,7 +169,7 @@ int crypt_keyfile_device_read(struct crypt_device *cd, const char *keyfile,
|
||||
key_size = DEFAULT_KEYFILE_SIZE_MAXKB * 1024 + 1;
|
||||
unlimited_read = 1;
|
||||
/* use 4k for buffer (page divisor but avoid huge pages) */
|
||||
buflen = 4096 - sizeof(size_t); // sizeof(struct safe_allocation);
|
||||
buflen = 4096 - 16; /* sizeof(struct safe_allocation); */
|
||||
} else
|
||||
buflen = key_size;
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
r = -ENOMEM;
|
||||
if (posix_memalign(&buffer, crypt_getpagesize(), buffer_size))
|
||||
goto out;
|
||||
memset(buffer, 0, buffer_size);
|
||||
|
||||
r = crypt_cipher_ivsize(cipher, cipher_mode);
|
||||
if (r >= 0 && iv_size != (size_t)r) {
|
||||
@@ -98,7 +99,7 @@ int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
||||
int (*progress)(uint32_t time_ms, void *usrptr),
|
||||
void *usrptr)
|
||||
{
|
||||
int r;
|
||||
int r, priority;
|
||||
const char *kdf_opt;
|
||||
|
||||
if (!pbkdf || (!password && password_size))
|
||||
@@ -112,10 +113,12 @@ int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
||||
|
||||
log_dbg(cd, "Running %s(%s) benchmark.", pbkdf->type, kdf_opt);
|
||||
|
||||
crypt_process_priority(cd, &priority, true);
|
||||
r = crypt_pbkdf_perf(pbkdf->type, pbkdf->hash, password, password_size,
|
||||
salt, salt_size, volume_key_size, pbkdf->time_ms,
|
||||
pbkdf->max_memory_kb, pbkdf->parallel_threads,
|
||||
&pbkdf->iterations, &pbkdf->max_memory_kb, progress, usrptr);
|
||||
crypt_process_priority(cd, &priority, false);
|
||||
|
||||
if (!r)
|
||||
log_dbg(cd, "Benchmark returns %s(%s) %u iterations, %u memory, %u threads (for %zu-bits key).",
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "libcryptsetup.h"
|
||||
#include "utils_crypt.h"
|
||||
|
||||
#define MAX_CAPI_LEN_STR "143" /* for sscanf of crypto API string + 16 + \0 */
|
||||
|
||||
int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums,
|
||||
char *cipher_mode)
|
||||
{
|
||||
@@ -266,3 +268,80 @@ bool crypt_is_cipher_null(const char *cipher_spec)
|
||||
return false;
|
||||
return (strstr(cipher_spec, "cipher_null") || !strcmp(cipher_spec, "null"));
|
||||
}
|
||||
|
||||
int crypt_capi_to_cipher(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
|
||||
{
|
||||
char cipher[MAX_CAPI_ONE_LEN], mode[MAX_CAPI_ONE_LEN], iv[MAX_CAPI_ONE_LEN],
|
||||
auth[MAX_CAPI_ONE_LEN], tmp[MAX_CAPI_LEN], dmcrypt_tmp[MAX_CAPI_LEN*2],
|
||||
capi[MAX_CAPI_LEN+1];
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (!c_dm)
|
||||
return -EINVAL;
|
||||
|
||||
/* legacy mode */
|
||||
if (strncmp(c_dm, "capi:", 4)) {
|
||||
if (!(*org_c = strdup(c_dm)))
|
||||
return -ENOMEM;
|
||||
if (i_dm) {
|
||||
if (!(*org_i = strdup(i_dm))) {
|
||||
free(*org_c);
|
||||
*org_c = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else
|
||||
*org_i = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* modes with capi: prefix */
|
||||
i = sscanf(c_dm, "capi:%" MAX_CAPI_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", tmp, iv);
|
||||
if (i != 2)
|
||||
return -EINVAL;
|
||||
|
||||
len = strlen(tmp);
|
||||
if (len < 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (tmp[len-1] == ')')
|
||||
tmp[len-1] = '\0';
|
||||
|
||||
if (sscanf(tmp, "rfc4309(%" MAX_CAPI_LEN_STR "s", capi) == 1) {
|
||||
if (!(*org_i = strdup("aead")))
|
||||
return -ENOMEM;
|
||||
} else if (sscanf(tmp, "rfc7539(%" MAX_CAPI_LEN_STR "[^,],%" MAX_CAPI_ONE_LEN_STR "s", capi, auth) == 2) {
|
||||
if (!(*org_i = strdup(auth)))
|
||||
return -ENOMEM;
|
||||
} else if (sscanf(tmp, "authenc(%" MAX_CAPI_ONE_LEN_STR "[^,],%" MAX_CAPI_LEN_STR "s", auth, capi) == 2) {
|
||||
if (!(*org_i = strdup(auth)))
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
if (i_dm) {
|
||||
if (!(*org_i = strdup(i_dm)))
|
||||
return -ENOMEM;
|
||||
} else
|
||||
*org_i = NULL;
|
||||
memset(capi, 0, sizeof(capi));
|
||||
strncpy(capi, tmp, sizeof(capi)-1);
|
||||
}
|
||||
|
||||
i = sscanf(capi, "%" MAX_CAPI_ONE_LEN_STR "[^(](%" MAX_CAPI_ONE_LEN_STR "[^)])", mode, cipher);
|
||||
if (i == 2)
|
||||
i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
|
||||
else
|
||||
i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
|
||||
if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) {
|
||||
free(*org_i);
|
||||
*org_i = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(*org_c = strdup(dmcrypt_tmp))) {
|
||||
free(*org_i);
|
||||
*org_i = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,9 +27,12 @@
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
#define MAX_CIPHER_LEN 32
|
||||
#define MAX_CIPHER_LEN_STR "31"
|
||||
#define MAX_KEYFILES 32
|
||||
#define MAX_CIPHER_LEN 32
|
||||
#define MAX_CIPHER_LEN_STR "31"
|
||||
#define MAX_KEYFILES 32
|
||||
#define MAX_CAPI_ONE_LEN 2 * MAX_CIPHER_LEN
|
||||
#define MAX_CAPI_ONE_LEN_STR "63" /* for sscanf length + '\0' */
|
||||
#define MAX_CAPI_LEN 144 /* should be enough to fit whole capi string */
|
||||
|
||||
int crypt_parse_name_and_mode(const char *s, char *cipher,
|
||||
int *key_nums, char *cipher_mode);
|
||||
@@ -46,4 +49,6 @@ void crypt_log_hex(struct crypt_device *cd,
|
||||
|
||||
bool crypt_is_cipher_null(const char *cipher_spec);
|
||||
|
||||
int crypt_capi_to_cipher(char **org_c, char **org_i, const char *c_dm, const char *i_dm);
|
||||
|
||||
#endif /* _UTILS_CRYPT_H */
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
@@ -623,7 +622,10 @@ size_t device_optimal_encryption_sector_size(struct crypt_device *cd, struct dev
|
||||
phys_block_size = device_block_phys_size_fd(fd);
|
||||
close(fd);
|
||||
|
||||
if (device->block_size >= phys_block_size || phys_block_size <= SECTOR_SIZE || phys_block_size > MAX_SECTOR_SIZE || MISALIGNED(phys_block_size, device->block_size))
|
||||
if (device->block_size >= phys_block_size ||
|
||||
phys_block_size <= SECTOR_SIZE ||
|
||||
phys_block_size > MAX_SECTOR_SIZE ||
|
||||
MISALIGNED(phys_block_size, device->block_size))
|
||||
return device->block_size;
|
||||
|
||||
return phys_block_size;
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
# include <sys/sysmacros.h> /* for major, minor */
|
||||
#endif
|
||||
#include <libgen.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "utils_device_locking.h"
|
||||
@@ -106,7 +105,7 @@ static int open_lock_dir(struct crypt_device *cd, const char *dir, const char *b
|
||||
lockdfd = openat(dirfd, base, O_RDONLY | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
|
||||
if (lockdfd < 0) {
|
||||
if (errno == ENOENT) {
|
||||
log_dbg(cd, _("Locking directory %s/%s will be created with default compiled-in permissions."), dir, base);
|
||||
log_dbg(cd, "Locking directory %s/%s will be created with default compiled-in permissions.", dir, base);
|
||||
|
||||
/* success or failure w/ errno == EEXIST either way just try to open the 'base' directory again */
|
||||
if (mkdirat(dirfd, base, DEFAULT_LUKS2_LOCK_DIR_PERMS) && errno != EEXIST)
|
||||
|
||||
@@ -75,6 +75,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
|
||||
#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */
|
||||
#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */
|
||||
#define DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */
|
||||
#define DM_VERITY_TASKLETS_SUPPORTED (1 << 28) /* dm-verity tasklets supported */
|
||||
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
|
||||
enum tdirection { TARGET_EMPTY = 0, TARGET_SET, TARGET_QUERY };
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2022 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
|
||||
* 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 <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "utils_fips.h"
|
||||
|
||||
#if !ENABLE_FIPS
|
||||
bool crypt_fips_mode(void) { return false; }
|
||||
#else
|
||||
static bool fips_checked = false;
|
||||
static bool fips_mode = false;
|
||||
|
||||
static bool kernel_fips_mode(void)
|
||||
{
|
||||
int fd;
|
||||
char buf[1] = "";
|
||||
|
||||
if ((fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY)) >= 0) {
|
||||
while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return (buf[0] == '1');
|
||||
}
|
||||
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
if (fips_checked)
|
||||
return fips_mode;
|
||||
|
||||
fips_mode = kernel_fips_mode() && !access("/etc/system-fips", F_OK);
|
||||
fips_checked = true;
|
||||
|
||||
return fips_mode;
|
||||
}
|
||||
#endif /* ENABLE_FIPS */
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2022 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_FIPS_H
|
||||
#define _UTILS_FIPS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool crypt_fips_mode(void);
|
||||
|
||||
#endif /* _UTILS_FIPS_H */
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "utils_io.h"
|
||||
|
||||
/* coverity[ -taint_source : arg-1 ] */
|
||||
static ssize_t _read_buffer(int fd, void *buf, size_t length, volatile int *quit)
|
||||
{
|
||||
size_t read_size = 0;
|
||||
|
||||
@@ -163,7 +163,7 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
ret = keyctl_read(kid, NULL, 0);
|
||||
if (ret > 0) {
|
||||
len = ret;
|
||||
buf = malloc(len);
|
||||
buf = crypt_safe_alloc(len);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -173,9 +173,7 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
|
||||
if (ret < 0) {
|
||||
err = errno;
|
||||
if (buf)
|
||||
crypt_safe_memzero(buf, len);
|
||||
free(buf);
|
||||
crypt_safe_free(buf);
|
||||
return -err;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,17 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[0];
|
||||
size_t size;
|
||||
bool locked;
|
||||
char data[0] __attribute__((aligned(8)));
|
||||
};
|
||||
#define OVERHEAD offsetof(struct safe_allocation, data)
|
||||
|
||||
/*
|
||||
* Replacement for memset(s, 0, n) on stack that can be optimized out
|
||||
@@ -34,6 +38,9 @@ struct safe_allocation {
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(data, size);
|
||||
#else
|
||||
@@ -49,15 +56,19 @@ void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
|
||||
if (!size || size > (SIZE_MAX - OVERHEAD))
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
alloc = malloc(size + OVERHEAD);
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
crypt_safe_memzero(alloc, size + OVERHEAD);
|
||||
alloc->size = size;
|
||||
crypt_safe_memzero(&alloc->data, size);
|
||||
|
||||
/* Ignore failure if it is over limit. */
|
||||
if (!mlock(alloc, size + OVERHEAD))
|
||||
alloc->locked = true;
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
@@ -72,11 +83,16 @@ void crypt_safe_free(void *data)
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
p = (char *)data - offsetof(struct safe_allocation, data);
|
||||
p = (char *)data - OVERHEAD;
|
||||
alloc = (struct safe_allocation *)p;
|
||||
|
||||
crypt_safe_memzero(data, alloc->size);
|
||||
|
||||
if (alloc->locked) {
|
||||
munlock(alloc, alloc->size + OVERHEAD);
|
||||
alloc->locked = false;
|
||||
}
|
||||
|
||||
s = (volatile size_t *)&alloc->size;
|
||||
*s = 0x55aa55aa;
|
||||
free(alloc);
|
||||
@@ -92,7 +108,7 @@ void *crypt_safe_realloc(void *data, size_t size)
|
||||
|
||||
if (new_data && data) {
|
||||
|
||||
p = (char *)data - offsetof(struct safe_allocation, data);
|
||||
p = (char *)data - OVERHEAD;
|
||||
alloc = (struct safe_allocation *)p;
|
||||
|
||||
if (size > alloc->size)
|
||||
|
||||
53
m4/ax_check_compile_flag.m4
Normal file
53
m4/ax_check_compile_flag.m4
Normal file
@@ -0,0 +1,53 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check whether the given FLAG works with the current language's compiler
|
||||
# or gives an error. (Warnings, however, are ignored)
|
||||
#
|
||||
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||
# success/failure.
|
||||
#
|
||||
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||
# force the compiler to issue an error when a bad flag is given.
|
||||
#
|
||||
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 6
|
||||
|
||||
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
||||
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
|
||||
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||
[AS_VAR_SET(CACHEVAR,[no])])
|
||||
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||
AS_VAR_IF(CACHEVAR,yes,
|
||||
[m4_default([$2], :)],
|
||||
[m4_default([$3], :)])
|
||||
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||
])dnl AX_CHECK_COMPILE_FLAGS
|
||||
@@ -29,6 +29,7 @@ ADOCFILES = $(ADOCFILES_COMMON) \
|
||||
man/cryptsetup-config.8.adoc \
|
||||
man/cryptsetup-tcryptDump.8.adoc \
|
||||
man/cryptsetup-bitlkDump.8.adoc \
|
||||
man/cryptsetup-fvault2Dump.8.adoc \
|
||||
man/cryptsetup-repair.8.adoc \
|
||||
man/cryptsetup-benchmark.8.adoc \
|
||||
man/cryptsetup-ssh.8.adoc \
|
||||
@@ -64,6 +65,7 @@ CRYPTSETUP_MANPAGES = \
|
||||
man/cryptsetup-config.8 \
|
||||
man/cryptsetup-tcryptDump.8 \
|
||||
man/cryptsetup-bitlkDump.8 \
|
||||
man/cryptsetup-fvault2Dump.8 \
|
||||
man/cryptsetup-repair.8 \
|
||||
man/cryptsetup-benchmark.8
|
||||
|
||||
@@ -74,6 +76,7 @@ CRYPTSETUP_MANLINKS = \
|
||||
man/cryptsetup-loopaesOpen.8 \
|
||||
man/cryptsetup-tcryptOpen.8 \
|
||||
man/cryptsetup-bitlkOpen.8 \
|
||||
man/cryptsetup-fvault2Open.8 \
|
||||
man/cryptsetup-luksErase.8
|
||||
|
||||
VERITYSETUP_MANPAGES = man/veritysetup.8
|
||||
|
||||
@@ -33,7 +33,7 @@ ifdef::ACTION_ISLUKS[]
|
||||
Print more information on command execution.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_ISLUKS,ACTION_LUKSDUMP,ACTION_CONVERT,ACTION_REPAIR,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSKILLSLOT,ACTION_ISLUKS,ACTION_LUKSDUMP,ACTION_LUKSUUID,ACTION_CONVERT,ACTION_REPAIR,ACTION_REENCRYPT[]
|
||||
*--type <device-type>*::
|
||||
ifndef::ACTION_REENCRYPT[]
|
||||
Specifies required device type, for more info read _BASIC ACTIONS_ section in *cryptsetup*(8).
|
||||
@@ -45,7 +45,7 @@ endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_TCRYPTDUMP,ACTION_BENCHMARK,ACTION_REENCRYPT[]
|
||||
*--hash, -h* _<hash-spec>_::
|
||||
ifdef::ACTION_OPEN[]
|
||||
ifdef::ACTION_OPEN,ACTION_TCRYPTDUMP[]
|
||||
Specifies the passphrase hash. Applies to _plain_ and _loopaes_ device types only.
|
||||
+
|
||||
For _tcrypt_ device type, it restricts checked PBKDF2 variants when looking for header.
|
||||
@@ -54,7 +54,7 @@ ifdef::ACTION_LUKSFORMAT[]
|
||||
Specifies the hash used in the LUKS key setup scheme and volume key
|
||||
digest.
|
||||
endif::[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN,ACTION_TCRYPTDUMP[]
|
||||
The specified hash is used for PBKDF2 and AF splitter.
|
||||
endif::[]
|
||||
ifdef::ACTION_REENCRYPT[]
|
||||
@@ -67,25 +67,21 @@ for new LUKS1 device header.
|
||||
*LUKS2:* Ignored unless new keyslot pbkdf algorithm is set to PBKDF2 (see --pbkdf).
|
||||
endif::[]
|
||||
+
|
||||
The specified hash name is passed to the compiled-in crypto backend.
|
||||
Different backends may support different hashes.
|
||||
ifdef::ACTION_LUKSFORMAT[]
|
||||
The hash algorithm must provide at least 160 bits of output.
|
||||
endif::[]
|
||||
Do not use a non-crypto hash like *xxhash* as this breaks
|
||||
security.
|
||||
+
|
||||
Do not use a non-crypto hash like *xxhash* as this breaks security.
|
||||
Use _cryptsetup --help_ to show the defaults.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT,ACTION_TCRYPTDUMP,ACTION_BENCHMARK[]
|
||||
*--cipher, -c* _<cipher-spec>_::
|
||||
ifdef::ACTION_OPEN[]
|
||||
ifdef::ACTION_OPEN,ACTION_TCRYPTDUMP[]
|
||||
Set the cipher specification string for _plain_ device type.
|
||||
+
|
||||
For _tcrypt_ device type it restricts checked cipher chains when looking for header.
|
||||
endif::[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN,ACTION_TCRYPTDUMP[]
|
||||
Set the cipher specification string.
|
||||
endif::[]
|
||||
ifdef::ACTION_REENCRYPT[]
|
||||
@@ -100,6 +96,7 @@ In reencrypt mode, if no new cipher specification is requested, the existing cip
|
||||
in use. Unless the existing cipher was "cipher_null". In that case default cipher would
|
||||
be applied as in encrypt mode.
|
||||
endif::[]
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT[]
|
||||
+
|
||||
_cryptsetup --help_ shows the compiled-in defaults.
|
||||
+
|
||||
@@ -110,12 +107,10 @@ of the IV generation. For example, ESSIV needs a hash function, while
|
||||
For XTS mode you can optionally set a key size of 512 bits with the -s
|
||||
option. Key size for XTS mode is twice that for other modes for the same
|
||||
security level.
|
||||
+
|
||||
XTS mode requires kernel 2.6.24 or later and plain64 requires kernel
|
||||
2.6.33 or later. More information can be found in the FAQ.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_REPAIR,ACTION_TCRYPTDUMP,ACTION_REENCRYPT[]
|
||||
*--verify-passphrase, -y*::
|
||||
When interactively asking for a passphrase, ask for it twice and
|
||||
complain if both inputs do not match.
|
||||
@@ -125,28 +120,27 @@ endif::[]
|
||||
Ignored on input from file or stdin.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_TCRYPTDUMP,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_TCRYPTDUMP,ACTION_REENCRYPT,ACTION_REPAIR,ACTION_BITLKDUMP[]
|
||||
*--key-file, -d* _name_::
|
||||
Read the passphrase from file.
|
||||
+
|
||||
If the name given is "-", then the passphrase will be read from stdin.
|
||||
In this case, reading will not stop at newline characters.
|
||||
+
|
||||
ifdef::ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY[]
|
||||
The passphrase supplied via --key-file is always the passphrase for existing
|
||||
keyslot requested by the command.
|
||||
+
|
||||
If you want to set a new passphrase via key file, you have to use a
|
||||
positional argument or parameter --new-keyfile.
|
||||
+
|
||||
endif::[]
|
||||
ifdef::ACTION_OPEN[]
|
||||
*NOTE:* With _plain_ device type, the passphrase obtained via --key-file option is
|
||||
passed directly in dm-crypt. Unlike the interactive mode (stdin)
|
||||
where digest (--hash option) of the passphrase is passed in dm-crypt instead.
|
||||
+
|
||||
endif::[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN[]
|
||||
With LUKS, the passphrase supplied via --key-file is always the existing
|
||||
passphrase requested by a command, except in the case of _luksFormat_
|
||||
where --key-file is equivalent to the positional key file argument.
|
||||
+
|
||||
If you want to set a new passphrase via key file, you have to use a
|
||||
positional argument to _luksAddKey_.
|
||||
+
|
||||
endif::[]
|
||||
ifndef::ACTION_REENCRYPT[]
|
||||
See section _NOTES ON PASSPHRASE PROCESSING_ in *cryptsetup*(8) for more information.
|
||||
endif::[]
|
||||
@@ -160,12 +154,12 @@ passphrases.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_REENCRYPT,ACTION_REPAIR,ACTION_BITLKDUMP[]
|
||||
*--keyfile-offset* _value_::
|
||||
Skip _value_ bytes at the beginning of the key file.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_REENCRYPT,ACTION_REPAIR,ACTION_BITLKDUMP[]
|
||||
*--keyfile-size, -l* _value_::
|
||||
Read a maximum of _value_ bytes from the key file. The default is to
|
||||
read the whole file up to the compiled-in maximum that can be queried
|
||||
@@ -176,16 +170,27 @@ This option is useful to cut trailing newlines, for example. If
|
||||
--keyfile-offset is also given, the size count starts after the offset.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
*--new-keyfile* _name_::
|
||||
Read the passphrase for a new keyslot from file.
|
||||
+
|
||||
If the name given is "-", then the passphrase will be read from stdin.
|
||||
In this case, reading will not stop at newline characters.
|
||||
+
|
||||
This is alternative method to positional argument when adding new
|
||||
passphrase via kefile.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY[]
|
||||
*--new-keyfile-offset* _value_::
|
||||
Skip _value_ bytes at the start when adding a new passphrase from key
|
||||
file with _luksAddKey_.
|
||||
file.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY[]
|
||||
*--new-keyfile-size* _value_::
|
||||
Read a maximum of _value_ bytes when adding a new passphrase from key
|
||||
file with _luksAddKey_. The default is to read the whole file up to
|
||||
file. The default is to read the whole file up to
|
||||
the compiled-in maximum length that can be queried with --help.
|
||||
Supplying more than the compiled in maximum aborts the operation. When
|
||||
--new-keyfile-offset is also given, reading starts after the offset.
|
||||
@@ -198,7 +203,7 @@ Use a volume key stored in a file.
|
||||
endif::[]
|
||||
ifdef::ACTION_FORMAT[]
|
||||
+
|
||||
For _luksFormat_ this allows creating a LUKS header with this specific
|
||||
This allows creating a LUKS header with this specific
|
||||
volume key. If the volume key was taken from an existing LUKS header and
|
||||
all other parameters are the same, then the new header decrypts the data
|
||||
encrypted with the header the volume key was taken from. +
|
||||
@@ -207,8 +212,9 @@ ifdef::ACTION_LUKSDUMP,ACTION_BITLKDUMP[]
|
||||
The volume key is stored in a file instead of being printed out to standard output. +
|
||||
endif::[]
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
For _luksAddKey_ this allows adding a new passphrase without having to
|
||||
know an existing one. +
|
||||
This allows adding a new keyslot without having to know passphrase to existing one.
|
||||
It may be also used when no keyslot is active.
|
||||
+
|
||||
endif::[]
|
||||
ifdef::ACTION_OPEN[]
|
||||
This allows one to open _luks_ and _bitlk_ device types without giving a passphrase. +
|
||||
@@ -263,8 +269,8 @@ See *NOTES ON RANDOM NUMBER GENERATORS* in *cryptsetup*(8) for more
|
||||
information. Use _cryptsetup --help_ to show the compiled-in default random
|
||||
number generator.
|
||||
+
|
||||
*WARNING:* In a low-entropy situation (e.g. in an embedded system), both
|
||||
selections are problematic. Using /dev/urandom can lead to weak keys.
|
||||
*WARNING:* In a low-entropy situation (e.g. in an embedded system) and older
|
||||
kernels, both selections are problematic. Using /dev/urandom can lead to weak keys.
|
||||
Using /dev/random can block a long time, potentially forever, if not
|
||||
enough entropy can be harvested by the kernel.
|
||||
endif::[]
|
||||
@@ -280,9 +286,20 @@ it is requested.
|
||||
Reencrypt only the LUKS1 header and keyslots. Skips data in-place reencryption.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSDUMP,ACTION_TOKEN,ACTION_CONFIG,ACTION_TOKEN,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSDUMP,ACTION_LUKSRESUME,ACTION_TOKEN,ACTION_CONFIG,ACTION_TOKEN,ACTION_REPAIR,ACTION_REENCRYPT[]
|
||||
*--key-slot, -S <0-N>*::
|
||||
ifndef::ACTION_OPEN[]
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
When used together with parameter --new-key-slot this option allows you to specify which
|
||||
key slot is selected for unlocking volume key.
|
||||
+
|
||||
*NOTE:* This option is ignored if existing volume key gets unlocked
|
||||
via LUKS2 token (--token-id, --token-type or --token-only parameters) or
|
||||
when volume key is provided directly via --volume-key-file parameter.
|
||||
+
|
||||
*NOTE:* To maintain backward compatibility, without --new-key-slot parameter,
|
||||
this option allows you to specify which key slot is selected for the new key.
|
||||
endif::[]
|
||||
ifndef::ACTION_OPEN,ACTION_LUKSADDKEY[]
|
||||
For LUKS operations that add key material, this option allows you to
|
||||
specify which key slot is selected for the new key.
|
||||
endif::[]
|
||||
@@ -303,18 +320,40 @@ size and key size, but a valid key slot ID can always be between 0 and
|
||||
31 for LUKS2.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
*--new-key-slot <0-N>*::
|
||||
This option allows you to specify which key slot is selected for
|
||||
the new key.
|
||||
+
|
||||
*NOTE:* When used this option affects --key-slot option.
|
||||
+
|
||||
The maximum number of key slots depends on the LUKS version. LUKS1 can have up
|
||||
to 8 key slots. LUKS2 can have up to 32 key slots based on key slot area
|
||||
size and key size, but a valid key slot ID can always be between 0 and
|
||||
31 for LUKS2.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT,ACTION_BENCHMARK,ACTION_LUKSADDKEY[]
|
||||
*--key-size, -s* _bits_::
|
||||
ifndef::ACTION_LUKSADDKEY[]
|
||||
Sets key size in _bits_. The argument has to be a multiple of 8. The
|
||||
possible key-sizes are limited by the cipher and mode used.
|
||||
+
|
||||
See /proc/crypto for more information. Note that key-size in
|
||||
/proc/crypto is stated in bytes.
|
||||
+
|
||||
endif::[]
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
Provide volume key size in _bits_. The argument has to be a multiple of 8.
|
||||
+
|
||||
This option is required when parameter --volume-key-file is used to provide
|
||||
current volume key. Also, it is used when new unbound keyslot is created by
|
||||
specifying --unbound parameter.
|
||||
endif::[]
|
||||
ifdef::ACTION_OPEN[]
|
||||
This option can be used for _plain_ device type only.
|
||||
endif::[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN,ACTION_LUKSADDKEY[]
|
||||
This option can be used for _open --type plain_ or _luksFormat_. All
|
||||
other LUKS actions will use the key-size specified in the LUKS header.
|
||||
Use _cryptsetup --help_ to show the compiled-in defaults.
|
||||
@@ -350,7 +389,7 @@ endif::[]
|
||||
+
|
||||
ifndef::ACTION_OPEN[]
|
||||
The --offset option sets the data offset (payload) of data
|
||||
device and must be be aligned to 4096-byte sectors (must be multiple of
|
||||
device and must be aligned to 4096-byte sectors (must be multiple of
|
||||
8). This option cannot be combined with --align-payload option.
|
||||
endif::[]
|
||||
endif::[]
|
||||
@@ -465,7 +504,7 @@ new LUKS header.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT,ACTION_BENCHMARK[]
|
||||
*--pbkdf-memory <number>*::
|
||||
Set the memory cost for PBKDF (for Argon2i/id the number represents
|
||||
kilobytes). Note that it is maximal value, PBKDF benchmark or
|
||||
@@ -473,7 +512,7 @@ available physical memory can decrease it. This option is not
|
||||
available for PBKDF2.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT,ACTION_BENCHMARK[]
|
||||
*--pbkdf-parallel <number>*::
|
||||
Set the parallel cost for PBKDF (number of threads, up to 4). Note
|
||||
that it is maximal value, it is decreased automatically if CPU online
|
||||
@@ -520,18 +559,18 @@ numbers are represented in a string format due to need of full 64bit
|
||||
unsigned integers.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_RESIZE[]
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_REENCRYPT,ACTION_REPAIR,ACTION_LUKSRESUME,ACTION_RESIZE,ACTION_TCRYPTDUMP,ACTION_BITLKDUMP[]
|
||||
*--timeout, -t <number of seconds>*::
|
||||
The number of seconds to wait before timeout on passphrase input via
|
||||
terminal. It is relevant every time a passphrase is asked, for example
|
||||
for _open_, _luksFormat_ or _luksAddKey_. It has no effect if used in
|
||||
conjunction with --key-file. +
|
||||
terminal. It is relevant every time a passphrase is asked.
|
||||
It has no effect if used in conjunction with --key-file.
|
||||
+
|
||||
This option is useful when the system should not stall if the user
|
||||
does not input a passphrase, e.g. during boot. The default is a value
|
||||
of 0 seconds, which means to wait forever.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_REENCRYPT[]
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSRESUME,ACTION_REENCRYPT[]
|
||||
*--tries, -T*::
|
||||
How often the input of the passphrase shall be retried. The default is 3 tries.
|
||||
endif::[]
|
||||
@@ -629,7 +668,7 @@ Do not activate the device, just verify passphrase. The device mapping name is
|
||||
not mandatory if this option is used.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_STATUS,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSSUSPEND,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_TOKEN,ACTION_CONVERT,ACTION_CONFIG,ACTION_REENCRYPT,ACTION_CLOSE[]
|
||||
ifndef::ACTION_BENCHMARK,ACTION_BITLKDUMP[]
|
||||
*--header <device or file storing the LUKS header>*::
|
||||
ifndef::ACTION_OPEN[]
|
||||
Use a detached (separated) metadata device or file where the LUKS
|
||||
@@ -670,6 +709,9 @@ to a detached file. The passed future file must not exist at the time
|
||||
of initializing the decryption operation. This frees space in head of data
|
||||
device so that data can be moved at original LUKS2 header location. Later on
|
||||
decryption operation continues as if the ordinary detached header was passed.
|
||||
+
|
||||
*WARNING:* Never put exported header file in a filesystem on top of device
|
||||
you are about to decrypt! It would cause a deadlock.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
@@ -715,12 +757,12 @@ Removes a previously configured deferred device removal in _close_
|
||||
command.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_TOKEN[]
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSRESUME,ACTION_RESIZE,ACTION_TOKEN[]
|
||||
*--disable-external-tokens*::
|
||||
Disable loading of plugins for external LUKS2 tokens.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSSUSPEND,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_TOKEN,ACTION_REENCRYPT[]
|
||||
ifndef::ACTION_BENCHMARK,ACTION_BITLKDUMP,ACTION_TCRYPTDUMP[]
|
||||
*--disable-locks*::
|
||||
Disable lock protection for metadata on disk. This option is valid
|
||||
only for LUKS2 and ignored for other formats.
|
||||
@@ -739,8 +781,7 @@ endif::[]
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_REFRESH,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_TOKEN,ACTION_REENCRYPT[]
|
||||
*--disable-keyring*::
|
||||
Do not load volume key in kernel keyring and store it directly in the
|
||||
dm-crypt target instead. This option is supported only for the LUKS2
|
||||
format.
|
||||
dm-crypt target instead. This option is supported only for the LUKS2 type.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_TOKEN[]
|
||||
@@ -756,23 +797,49 @@ slot is never used, if not explicitly requested by _--key-slot_
|
||||
option.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME,ACTION_TOKEN[]
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME,ACTION_TOKEN,ACTION_LUKSADDKEY[]
|
||||
*--token-id*::
|
||||
ifndef::ACTION_TOKEN,ACTION_LUKSADDKEY[]
|
||||
Specify what token to use. If omitted, all available tokens will be checked
|
||||
before proceeding further with passphrase prompt.
|
||||
endif::[]
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
Specify what token to use when unlocking existing keyslot to get volume key.
|
||||
endif::[]
|
||||
ifdef::ACTION_TOKEN[]
|
||||
Specify token number. If omitted, first unused token id is used when adding or importing
|
||||
new token.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME[]
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
*--new-token-id*::
|
||||
Specify what token to use to get the passphrase for a new keyslot.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME,ACTION_LUKSADDKEY[]
|
||||
*--token-only*::
|
||||
ifndef::ACTION_LUKSADDKEY[]
|
||||
Do not proceed further with action if token based keyslot unlock failed. Without the
|
||||
option, action asks for passphrase to proceed further.
|
||||
endif::[]
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
Use only LUKS2 tokens to unlock existing volume key.
|
||||
+
|
||||
*NOTE*: To create a new keyslot using passphrase provided by a token use --new-token-id parameter.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME[]
|
||||
*--token-type*::
|
||||
Restrict tokens eligible for operation to specific token type (name).
|
||||
ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME,ACTION_LUKSADDKEY[]
|
||||
*--token-type* _type_::
|
||||
ifndef::ACTION_LUKSADDKEY[]
|
||||
Restrict tokens eligible for operation to specific token _type_.
|
||||
Mostly useful when no --token-id is specified.
|
||||
endif::[]
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
Specify what token type (all _type_ tokens) to use when unlocking existing keyslot to get volume key.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT[]
|
||||
ifndef::ACTION_REENCRYPT[]
|
||||
@@ -819,7 +886,7 @@ Reencrypt device with new encryption sector size enforced.
|
||||
+
|
||||
*WARNING:* Increasing encryption sector size may break hosted filesystem. Do not
|
||||
run reencryption with --force-offline-reencrypt if unsure what block size
|
||||
was filesystem formated with.
|
||||
was filesystem formatted with.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
@@ -834,7 +901,7 @@ use it only for accessing incompatible existing disk images from other
|
||||
systems that require this option.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_REFRESH[]
|
||||
ifdef::ACTION_OPEN,ACTION_REFRESH[]
|
||||
*--persistent*::
|
||||
If used with LUKS2 devices and activation commands like _open_ or
|
||||
_refresh_, the specified activation flags are persistently written
|
||||
@@ -880,6 +947,14 @@ option).
|
||||
For more info, see _AUTHENTICATED DISK ENCRYPTION_ section in *cryptsetup*(8).
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSFORMAT[]
|
||||
*--integrity-legacy-padding*::
|
||||
Use inefficient legacy padding.
|
||||
+
|
||||
*WARNING*: Do not use this option until you need compatibility with specific
|
||||
old kernel.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_LUKSFORMAT,ACTION_REENCRYPT[]
|
||||
*--luks2-metadata-size <size>*::
|
||||
This option can be used to enlarge the LUKS2 metadata (JSON) area. The
|
||||
@@ -928,17 +1003,21 @@ aligned to page size and page-cache initiates read of a sector with
|
||||
invalid integrity tag.
|
||||
endif::[]
|
||||
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSADDKEY,ACTION_LUKSDUMP[]
|
||||
ifdef::ACTION_OPEN,ACTION_LUKSADDKEY,ACTION_LUKSDUMP,ACTION_TOKEN[]
|
||||
*--unbound*::
|
||||
ifndef::ACTION_OPEN[]
|
||||
Creates new or dumps existing LUKS2 unbound keyslot.
|
||||
+
|
||||
ifdef::ACTION_LUKSADDKEY[]
|
||||
Creates new LUKS2 unbound keyslot.
|
||||
endif::[]
|
||||
ifdef::ACTION_LUKSDUMP[]
|
||||
Dumps existing LUKS2 unbound keyslot.
|
||||
endif::[]
|
||||
ifdef::ACTION_OPEN[]
|
||||
Allowed only only together with --test-passphrase parameter, it allows
|
||||
to test passphrase for unbound LUKS2 keyslot. Otherwise, unbound keyslot
|
||||
passphrase can be tested only when specific keyslot is selected via
|
||||
--key-slot parameter.
|
||||
Allowed only together with --test-passphrase parameter, it allows one to test
|
||||
passphrase for unbound LUKS2 keyslot. Otherwise, unbound keyslot passphrase
|
||||
can be tested only when specific keyslot is selected via --key-slot parameter.
|
||||
endif::[]
|
||||
ifdef::ACTION_TOKEN[]
|
||||
Creates new LUKS2 keyring token assigned to no keyslot. Usable only with _add_ action.
|
||||
endif::[]
|
||||
endif::[]
|
||||
|
||||
|
||||
@@ -20,7 +20,10 @@ Benchmarks ciphers and KDF (key derivation function). Without
|
||||
parameters, it tries to measure few common configurations.
|
||||
|
||||
To benchmark other ciphers or modes, you need to specify *--cipher* and
|
||||
*--key-size* options or *--hash* for KDF test.
|
||||
*--key-size* options.
|
||||
|
||||
To benchmark PBKDF you need to specify *--pbkdf* or *--hash* with optional
|
||||
cost parameters *--iter-time*, *--pbkdf-memory* or *--pbkdf-parallel*.
|
||||
|
||||
*NOTE:* This benchmark uses memory only and is only informative. You
|
||||
cannot directly predict real storage encryption speed from it.
|
||||
@@ -31,7 +34,8 @@ are configuring kernel yourself, enable "User-space interface for
|
||||
symmetric key cipher algorithms" in "Cryptographic API" section
|
||||
(CRYPTO_USER_API_SKCIPHER .config option).
|
||||
|
||||
*<options>* can be [--cipher, --key-size, --hash].
|
||||
*<options>* can be [--cipher, --key-size, --hash, --pbkdf, --iter-time,
|
||||
--pbkdf-memory, --pbkdf-parallel].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -18,7 +18,17 @@ cryptsetup-bitlkDump - dump the header information of a BITLK (BitLocker compati
|
||||
|
||||
Dump the header information of a BITLK (BitLocker compatible) device.
|
||||
|
||||
*<options>* can be [--dump-volume-key --volume-key-file].
|
||||
If the --dump-volume-key option is used, the BITLK device volume key
|
||||
is dumped instead of header information. You have to provide password
|
||||
or keyfile to dump volume key.
|
||||
|
||||
Beware that the volume key can be used to decrypt the data stored in
|
||||
the container without a passphrase.
|
||||
This means that if the volume key is compromised, the whole device has
|
||||
to be erased to prevent further access. Use this option carefully.
|
||||
|
||||
*<options>* can be [--dump-volume-key, --volume-key-file, --key-file,
|
||||
--keyfile-offset, --keyfile-size, --timeout].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -20,11 +20,11 @@ Removes the existing mapping <name> and wipes the key from kernel
|
||||
memory.
|
||||
|
||||
For backward compatibility, there are *close* command aliases: *remove*,
|
||||
*plainClose*, *luksClose*, *loopaesClose*, *tcryptClose* (all behave
|
||||
exactly the same, device type is determined automatically from the active
|
||||
device).
|
||||
*plainClose*, *luksClose*, *loopaesClose*, *tcryptClose*, *bitlkClose*
|
||||
(all behave exactly the same, device type is determined automatically
|
||||
from the active device).
|
||||
|
||||
*<options>* can be [--deferred] or [--cancel-deferred]
|
||||
*<options>* can be [--deferred, --cancel-deferred, --header, --disable-locks].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -24,7 +24,7 @@ prefer, ignore) for keyslot (specified by _--key-slot_) or _--label_ and
|
||||
_--subsystem_.
|
||||
|
||||
*<options>* can be [--priority, --label, --subsystem, --key-slot,
|
||||
--header].
|
||||
--header, --disable-locks].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -31,7 +31,7 @@ _luks2_.
|
||||
of a crash during conversion or if a media error occurs. Always create a
|
||||
header backup before performing this operation!
|
||||
|
||||
*<options>* can be [--header, --type].
|
||||
*<options>* can be [--header, --type, --disable-locks].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -22,5 +22,7 @@ You do not need to provide any password for this operation.
|
||||
|
||||
*WARNING:* This operation is irreversible.
|
||||
|
||||
*<options>* can be [--header, --disable-locks].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
34
man/cryptsetup-fvault2Dump.8.adoc
Normal file
34
man/cryptsetup-fvault2Dump.8.adoc
Normal file
@@ -0,0 +1,34 @@
|
||||
= cryptsetup-fvault2Dump(8)
|
||||
:doctype: manpage
|
||||
:manmanual: Maintenance Commands
|
||||
:mansource: cryptsetup {release-version}
|
||||
:man-linkstyle: pass:[blue R < >]
|
||||
:COMMON_OPTIONS:
|
||||
:ACTION_BITLKDUMP:
|
||||
|
||||
== Name
|
||||
|
||||
cryptsetup-fvault2Dump - dump the header information of a FVAULT2 (FileVault2 compatible) device
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
*cryptsetup _fvault2Dump_ [<options>] <device>*
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
Dump the header information of a FVAULT2 (FileVault2 compatible) device.
|
||||
|
||||
If the --dump-volume-key option is used, the FVAULT2 device volume key
|
||||
is dumped instead of header information. You have to provide password
|
||||
or keyfile to dump volume key.
|
||||
|
||||
Beware that the volume key can be used to decrypt the data stored in
|
||||
the container without a passphrase.
|
||||
This means that if the volume key is compromised, the whole device has
|
||||
to be erased to prevent further access. Use this option carefully.
|
||||
|
||||
*<options>* can be [--dump-volume-key, --volume-key-file, --key-file,
|
||||
--keyfile-offset, --keyfile-size, --timeout].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
@@ -16,11 +16,14 @@ cryptsetup-isLuks - check if a device is a LUKS device
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
Returns true, if <device> is a LUKS device, false otherwise. Use option
|
||||
-v to get human-readable feedback. 'Command successful.' means the
|
||||
device is a LUKS device.
|
||||
Returns true, if <device> is a LUKS device, false otherwise.
|
||||
|
||||
Use option -v to get human-readable feedback.
|
||||
'Command successful.' means the device is a LUKS device.
|
||||
|
||||
By specifying --type you may query for specific LUKS version.
|
||||
|
||||
*<options>* can be [--header, --type, --disable-locks].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -16,10 +16,12 @@ cryptsetup-luksAddKey - add a new passphrase
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
Adds a new passphrase. An existing passphrase must be supplied
|
||||
interactively or via --key-file. The new passphrase to be added can be
|
||||
specified interactively or read from the file given as the positional
|
||||
argument.
|
||||
Adds a keyslot protected by a new passphrase. An existing passphrase
|
||||
must be supplied interactively, via --key-file or LUKS2 token (plugin).
|
||||
Alternatively to existing passphrase user may pass directly volume key
|
||||
(via --volume-key-file). The new passphrase to be added can be specified
|
||||
interactively, read from the file given as the positional argument (also
|
||||
via --new-keyfile parameter) or via LUKS2 token.
|
||||
|
||||
*NOTE:* with --unbound option the action creates new unbound LUKS2
|
||||
keyslot. The keyslot cannot be used for device activation. If you don't
|
||||
@@ -31,10 +33,39 @@ that supports per-keyslot parameters. For LUKS1, PBKDF type and hash
|
||||
algorithm is always the same for all keyslots.
|
||||
|
||||
*<options>* can be [--key-file, --keyfile-offset, --keyfile-size,
|
||||
--new-keyfile-offset, --new-keyfile-size, --key-slot, --volume-key-file,
|
||||
--force-password, --hash, --header, --disable-locks, --iter-time,
|
||||
--pbkdf, --pbkdf-force-iterations, --pbkdf-memory, --pbkdf-parallel,
|
||||
--unbound, --type, --keyslot-cipher, --keyslot-key-size].
|
||||
--new-keyfile, --new-keyfile-offset, --new-keyfile-size, --key-slot,
|
||||
--new-key-slot, --volume-key-file, --force-password, --hash, --header,
|
||||
--disable-locks, --iter-time, --pbkdf, --pbkdf-force-iterations,
|
||||
--pbkdf-memory, --pbkdf-parallel, --unbound, --type, --keyslot-cipher,
|
||||
--keyslot-key-size, --key-size, --timeout, --token-id, --token-type,
|
||||
--token-only, --new-token-id, --verify-passphrase].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
|
||||
== EXAMPLES
|
||||
|
||||
*NOTE*: When not specified otherwise interactive passphrase prompt is always default method.
|
||||
|
||||
Add new keyslot using interactive passphrase prompt for both existing and new passphrase:
|
||||
|
||||
*cryptsetup luksAddKey /dev/device*
|
||||
|
||||
Add new keyslot using LUKS2 tokens to unlock existing keyslot with interactive passphrase prompt for new passphrase:
|
||||
|
||||
*cryptsetup luksAddKey --token-only /dev/device*
|
||||
|
||||
Add new keyslot using LUKS2 systemd-tpm2 tokens to unlock existing keyslot with interactive passphrase prompt for new passphrase (systemd-tpm2 token plugin must be available):
|
||||
|
||||
*cryptsetup luksAddKey --token-type systemd-tpm2 /dev/device*
|
||||
|
||||
Add new keyslot using interactive passphrase prompt for existing keyslot, reading new passphrase from key_file:
|
||||
|
||||
*cryptsetup luksAddKey --new-keyfile key_file /dev/device* or
|
||||
*cryptsetup luksAddKey /dev/device key_file*
|
||||
|
||||
Add new keyslot using volume stored in volume_key_file and LUKS2 token in slot 5 to get new keyslot passphrase (token in slot 5 must exist
|
||||
and respective token plugin must be available):
|
||||
|
||||
*cryptsetup luksAddKey --volume-key-file volume_key_file --new-token-id 5 /dev/device*
|
||||
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -40,7 +40,7 @@ algorithm is always the same for all keyslots.
|
||||
--new-keyfile-offset, --iter-time, --pbkdf, --pbkdf-force-iterations,
|
||||
--pbkdf-memory, --pbkdf-parallel, --new-keyfile-size, --key-slot,
|
||||
--force-password, --hash, --header, --disable-locks, --type,
|
||||
--keyslot-cipher, --keyslot-key-size].
|
||||
--keyslot-cipher, --keyslot-key-size, --timeout, --verify-passphrase].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -35,7 +35,7 @@ been wiped and make the LUKS container inaccessible.
|
||||
*<options>* can be [--key-file, --keyfile-offset, --keyfile-size,
|
||||
--key-slot, --hash, --header, --disable-locks, --iter-time, --pbkdf,
|
||||
--pbkdf-force-iterations, --pbkdf-memory, --pbkdf-parallel,
|
||||
--keyslot-cipher, --keyslot-key-size].
|
||||
--keyslot-cipher, --keyslot-key-size, --timeout, --verify-passphrase].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
@@ -35,12 +35,12 @@ To dump unbound key (LUKS2 format only), --unbound parameter, specific
|
||||
interactively or via --key-file. Optional --volume-key-file parameter
|
||||
enables unbound keyslot dump to a file.
|
||||
|
||||
To dump LUKS2 JSON metadata (without basic heade information like UUID)
|
||||
To dump LUKS2 JSON metadata (without basic header information like UUID)
|
||||
use --dump-json-metadata option.
|
||||
|
||||
*<options>* can be [--dump-volume-key, --dump-json-metadata, --key-file,
|
||||
--keyfile-offset, --keyfile-size, --header, --disable-locks,
|
||||
--volume-key-file, --type, --unbound, --key-slot].
|
||||
--volume-key-file, --type, --unbound, --key-slot, --timeout].
|
||||
|
||||
*WARNING:* If --dump-volume-key is used with --key-file and the argument
|
||||
to --key-file is '-', no validation question will be asked and no
|
||||
|
||||
@@ -28,19 +28,20 @@ You cannot call luksFormat on a device or filesystem that is mapped or
|
||||
in use, e.g., mounted filesystem, used in LVM, active RAID member, etc. The
|
||||
device or filesystem has to be un-mounted in order to call luksFormat.
|
||||
|
||||
To use LUKS2, specify _--type luks2_.
|
||||
To use specific version of LUKS format, use _--type luks1_ or _type luks2_.
|
||||
|
||||
*<options>* can be [--hash, --cipher, --verify-passphrase, --key-size,
|
||||
--key-slot, --key-file (takes precedence over optional second argument),
|
||||
--keyfile-offset, --keyfile-size, --use-random | --use-urandom, --uuid,
|
||||
--keyfile-offset, --keyfile-size, --use-random, --use-urandom, --uuid,
|
||||
--volume-key-file, --iter-time, --header, --pbkdf-force-iterations,
|
||||
--force-password, --disable-locks].
|
||||
--force-password, --disable-locks, --timeout, --type, --offset,
|
||||
--align-payload (deprecated)].
|
||||
|
||||
For LUKS2, additional *<options>* can be [--integrity,
|
||||
--integrity-no-wipe, --sector-size, --label, --subsystem, --pbkdf,
|
||||
--pbkdf-memory, --pbkdf-parallel, --disable-locks, --disable-keyring,
|
||||
--luks2-metadata-size, --luks2-keyslots-size, --keyslot-cipher,
|
||||
--keyslot-key-size].
|
||||
--keyslot-key-size, --integrity-legacy-padding].
|
||||
|
||||
*WARNING:* Doing a luksFormat on an existing LUKS container will make
|
||||
all data in the old container permanently irretrievable unless you have a
|
||||
|
||||
@@ -17,9 +17,11 @@ cryptsetup-luksHeaderBackup - store a binary backup of the LUKS header and keysl
|
||||
== DESCRIPTION
|
||||
|
||||
Stores a binary backup of the LUKS header and keyslot area. +
|
||||
Note: Using '-' as filename writes the header backup to a file named
|
||||
*NOTE:* Using '-' as filename writes the header backup to a file named
|
||||
'-'.
|
||||
|
||||
*<options>* can be [--header, --header-backup-file, --disable-locks].
|
||||
|
||||
*WARNING:* This backup file and a passphrase valid at the time of backup
|
||||
allows decryption of the LUKS data area, even if the passphrase was
|
||||
later changed or removed from the LUKS device. Also note that with a
|
||||
|
||||
@@ -18,8 +18,9 @@ cryptsetup-luksHeaderRestore - restore a binary backup of the LUKS header and ke
|
||||
|
||||
Restores a binary backup of the LUKS header and keyslot area from the
|
||||
specified file. +
|
||||
Note: Using '-' as filename reads the header backup from a file named
|
||||
'-'.
|
||||
*NOTE:* Using '-' as filename reads the header backup from a file named '-'.
|
||||
|
||||
*<options>* can be [--header, --header-backup-file, --disable-locks].
|
||||
|
||||
*WARNING:* Header and keyslots will be replaced, only the passphrases
|
||||
from the backup will work afterward.
|
||||
|
||||
@@ -24,7 +24,7 @@ so. Removing the last passphrase makes a LUKS container permanently
|
||||
inaccessible.
|
||||
|
||||
*<options>* can be [--key-file, --keyfile-offset, --keyfile-size,
|
||||
--header, --disable-locks, --type].
|
||||
--header, --disable-locks, --type, --verify-passphrase, --timeout].
|
||||
|
||||
*WARNING:* If you read the passphrase from stdin (without further
|
||||
argument or with '-' as an argument to --key-file), batch-mode (-q) will
|
||||
|
||||
@@ -21,7 +21,7 @@ be removed can be specified interactively, as the positional argument or
|
||||
via --key-file.
|
||||
|
||||
*<options>* can be [--key-file, --keyfile-offset, --keyfile-size,
|
||||
--header, --disable-locks, --type]
|
||||
--header, --disable-locks, --type, --timeout, --verify-passphrase].
|
||||
|
||||
*WARNING:* If you read the passphrase from stdin (without further
|
||||
argument or with '-' as an argument to --key-file), batch-mode (-q) will
|
||||
|
||||
@@ -20,9 +20,10 @@ Resumes a suspended device and reinstates the encryption key. Prompts
|
||||
interactively for a passphrase if no token is usable (LUKS2 only) or
|
||||
--key-file is not given.
|
||||
|
||||
*<options>* can be [--key-file, --keyfile-size, --header,
|
||||
--disable-keyring, --disable-locks, --token-id, --token-only,
|
||||
--token-type, --type]
|
||||
*<options>* can be [--key-file, --keyfile-size, --keyfile-offset,
|
||||
--key-slot, --header, --disable-keyring, --disable-locks, --token-id,
|
||||
--token-only, --token-type, --disable-external-tokens, --type, --tries,
|
||||
--timeout, --verify-passphrase].
|
||||
|
||||
include::man/common_options.adoc[]
|
||||
include::man/common_footer.adoc[]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user