Merge ~vpa1977/ubuntu/+source/cryptsetup:merge-lp2004423-lunar into ubuntu/+source/cryptsetup:ubuntu/devel

Proposed by Vladimir Petko
Status: Superseded
Proposed branch: ~vpa1977/ubuntu/+source/cryptsetup:merge-lp2004423-lunar
Merge into: ubuntu/+source/cryptsetup:ubuntu/devel
Diff against target: 60499 lines (+25488/-8727) (has conflicts)
230 files modified
.github/workflows/cibuild-setup-ubuntu.sh (+1/-1)
.gitignore (+1/-0)
.gitlab-ci.yml (+3/-0)
.gitlab/ci/alpinelinux.yml (+4/-2)
.gitlab/ci/centos.yml (+4/-0)
.gitlab/ci/cibuild-setup-ubuntu.sh (+1/-1)
.gitlab/ci/cifuzz.yml (+46/-0)
.gitlab/ci/compilation-various-disables.yml (+21/-0)
.gitlab/ci/debian.yml (+11/-8)
.gitlab/ci/fedora.yml (+6/-1)
.gitlab/ci/rhel.yml (+10/-0)
.gitlab/ci/ubuntu-32bit.yml (+41/-0)
FAQ.md (+25/-0)
Makefile.am (+12/-1)
README.md (+93/-61)
autogen.sh (+1/-1)
configure.ac (+32/-2)
debian/README.Debian (+1/-1)
debian/changelog (+83/-0)
debian/clean (+5/-0)
debian/control (+11/-2)
debian/copyright (+26/-17)
debian/cryptsetup-bin.manpages (+2/-0)
debian/doc/crypttab.xml (+16/-2)
debian/functions (+4/-0)
debian/initramfs/hooks/cryptgnupg-sc (+11/-1)
debian/libcryptsetup12.symbols (+11/-0)
debian/patches/decrease_memlock_ulimit.patch (+20/-0)
debian/rules (+4/-0)
debian/upstream/metadata (+3/-2)
dev/null (+0/-55)
docs/examples/crypt_log_usage.c (+1/-1)
docs/examples/crypt_luks_usage.c (+1/-1)
docs/v2.6.0-ReleaseNotes (+236/-0)
docs/v2.6.1-ReleaseNotes (+50/-0)
lib/Makemodule.am (+5/-3)
lib/bitlk/bitlk.c (+87/-41)
lib/bitlk/bitlk.h (+3/-3)
lib/crypt_plain.c (+2/-2)
lib/crypto_backend/argon2_generic.c (+2/-2)
lib/crypto_backend/base64.c (+1/-2)
lib/crypto_backend/cipher_check.c (+2/-2)
lib/crypto_backend/cipher_generic.c (+2/-2)
lib/crypto_backend/crc32.c (+70/-1)
lib/crypto_backend/crypto_backend.h (+9/-3)
lib/crypto_backend/crypto_backend_internal.h (+2/-2)
lib/crypto_backend/crypto_cipher_kernel.c (+2/-2)
lib/crypto_backend/crypto_gcrypt.c (+19/-3)
lib/crypto_backend/crypto_kernel.c (+7/-2)
lib/crypto_backend/crypto_nettle.c (+7/-2)
lib/crypto_backend/crypto_nss.c (+7/-2)
lib/crypto_backend/crypto_openssl.c (+37/-2)
lib/crypto_backend/crypto_storage.c (+1/-1)
lib/crypto_backend/pbkdf2_generic.c (+2/-2)
lib/crypto_backend/pbkdf_check.c (+2/-2)
lib/crypto_backend/utf8.c (+1/-2)
lib/fvault2/fvault2.c (+1057/-0)
lib/fvault2/fvault2.h (+80/-0)
lib/integrity/integrity.c (+1/-1)
lib/integrity/integrity.h (+1/-1)
lib/internal.h (+4/-5)
lib/keyslot_context.c (+488/-0)
lib/keyslot_context.h (+111/-0)
lib/libcryptsetup.h (+228/-3)
lib/libcryptsetup.pc.in (+1/-0)
lib/libcryptsetup.sym (+14/-0)
lib/libcryptsetup_macros.h (+2/-2)
lib/libcryptsetup_symver.h (+3/-3)
lib/libdevmapper.c (+30/-91)
lib/loopaes/loopaes.c (+2/-2)
lib/loopaes/loopaes.h (+2/-2)
lib/luks1/af.c (+1/-1)
lib/luks1/af.h (+1/-1)
lib/luks1/keyencryption.c (+2/-2)
lib/luks1/keymanage.c (+19/-8)
lib/luks1/luks.h (+1/-1)
lib/luks2/luks2.h (+16/-4)
lib/luks2/luks2_digest.c (+2/-2)
lib/luks2/luks2_digest_pbkdf2.c (+2/-2)
lib/luks2/luks2_disk_metadata.c (+2/-4)
lib/luks2/luks2_internal.h (+4/-2)
lib/luks2/luks2_json_format.c (+6/-3)
lib/luks2/luks2_json_metadata.c (+94/-26)
lib/luks2/luks2_keyslot.c (+2/-2)
lib/luks2/luks2_keyslot_luks2.c (+19/-5)
lib/luks2/luks2_keyslot_reenc.c (+2/-2)
lib/luks2/luks2_luks1_convert.c (+3/-3)
lib/luks2/luks2_reencrypt.c (+82/-67)
lib/luks2/luks2_reencrypt_digest.c (+3/-4)
lib/luks2/luks2_segment.c (+2/-2)
lib/luks2/luks2_token.c (+116/-28)
lib/luks2/luks2_token_keyring.c (+7/-4)
lib/random.c (+2/-2)
lib/setup.c (+594/-390)
lib/tcrypt/tcrypt.c (+2/-3)
lib/tcrypt/tcrypt.h (+2/-2)
lib/utils.c (+27/-37)
lib/utils_benchmark.c (+8/-5)
lib/utils_blkid.c (+1/-1)
lib/utils_blkid.h (+1/-1)
lib/utils_crypt.c (+81/-2)
lib/utils_crypt.h (+10/-5)
lib/utils_device.c (+6/-4)
lib/utils_device_locking.c (+3/-4)
lib/utils_device_locking.h (+2/-2)
lib/utils_devpath.c (+2/-2)
lib/utils_dm.h (+3/-2)
lib/utils_io.c (+3/-2)
lib/utils_io.h (+2/-2)
lib/utils_keyring.c (+4/-6)
lib/utils_keyring.h (+2/-2)
lib/utils_loop.c (+2/-2)
lib/utils_loop.h (+2/-2)
lib/utils_pbkdf.c (+2/-2)
lib/utils_safe_memory.c (+25/-9)
lib/utils_storage_wrappers.c (+1/-1)
lib/utils_storage_wrappers.h (+1/-1)
lib/utils_wipe.c (+4/-4)
lib/verity/rs.h (+1/-1)
lib/verity/rs_decode_char.c (+1/-1)
lib/verity/rs_encode_char.c (+1/-1)
lib/verity/verity.c (+1/-1)
lib/verity/verity.h (+1/-1)
lib/verity/verity_fec.c (+1/-1)
lib/verity/verity_hash.c (+1/-1)
lib/volumekey.c (+1/-1)
m4/ax_check_compile_flag.m4 (+53/-0)
man/Makemodule.am (+3/-0)
man/common_options.adoc (+109/-27)
man/cryptsetup-fvault2Dump.8.adoc (+34/-0)
man/cryptsetup-luksAddKey.8.adoc (+39/-9)
man/cryptsetup-open.8.adoc (+21/-4)
man/cryptsetup-token.8.adoc (+5/-2)
man/cryptsetup.8.adoc (+45/-1)
man/veritysetup.8.adoc (+5/-1)
po/LINGUAS (+2/-0)
po/POTFILES.in (+1/-1)
po/cryptsetup.pot (+699/-621)
po/cs.po (+750/-651)
po/de.po (+749/-652)
po/fr.po (+749/-652)
po/ja.po (+736/-717)
po/ka.po (+3756/-0)
po/pl.po (+700/-613)
po/ro.po (+3874/-0)
po/ru.po (+749/-651)
po/sr.po (+1315/-1039)
po/sv.po (+1315/-1045)
po/uk.po (+748/-651)
src/cryptsetup.c (+389/-72)
src/cryptsetup.h (+2/-3)
src/cryptsetup_arg_list.h (+9/-3)
src/cryptsetup_args.h (+7/-3)
src/integritysetup.c (+2/-2)
src/integritysetup_arg_list.h (+2/-2)
src/integritysetup_args.h (+2/-2)
src/utils_arg_macros.h (+2/-2)
src/utils_arg_names.h (+6/-2)
src/utils_args.c (+2/-2)
src/utils_blockdev.c (+2/-2)
src/utils_luks.c (+3/-3)
src/utils_luks.h (+3/-3)
src/utils_password.c (+4/-5)
src/utils_progress.c (+2/-2)
src/utils_reencrypt.c (+40/-8)
src/utils_reencrypt_luks1.c (+8/-8)
src/utils_tools.c (+19/-14)
src/veritysetup.c (+9/-5)
src/veritysetup_arg_list.h (+4/-2)
src/veritysetup_args.h (+3/-2)
tests/Makefile.am (+38/-9)
tests/Makefile.localtest (+8/-0)
tests/align-test (+28/-2)
tests/align-test2 (+17/-1)
tests/all-symbols-test.c (+1/-1)
tests/api-test-2.c (+344/-62)
tests/api-test.c (+263/-13)
tests/api_test.h (+23/-4)
tests/bitlk-compat-test (+3/-3)
tests/compat-test (+50/-15)
tests/compat-test2 (+131/-31)
tests/crypto-vectors.c (+1/-1)
tests/device-test (+17/-1)
tests/differ.c (+1/-1)
tests/discards-test (+16/-0)
tests/fake_systemd_tpm_path.c (+17/-0)
tests/fuzz/FuzzerInterface.h (+81/-0)
tests/fuzz/LUKS2.proto (+379/-0)
tests/fuzz/LUKS2_plain_JSON.proto (+190/-0)
tests/fuzz/Makefile.am (+122/-0)
tests/fuzz/README.md (+66/-0)
tests/fuzz/crypt2_load_fuzz.cc (+112/-0)
tests/fuzz/crypt2_load_fuzz.dict (+130/-0)
tests/fuzz/crypt2_load_ondisk_fuzz.cc (+64/-0)
tests/fuzz/crypt2_load_ondisk_fuzz.dict (+9/-0)
tests/fuzz/crypt2_load_proto_fuzz.cc (+30/-7)
tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc (+51/-0)
tests/fuzz/crypt2_load_proto_plain_json_fuzz.dict (+72/-0)
tests/fuzz/json_proto_converter.cc (+87/-0)
tests/fuzz/json_proto_converter.h (+43/-0)
tests/fuzz/oss-fuzz-build.sh (+152/-0)
tests/fuzz/plain_json_proto_to_luks2.cc (+75/-0)
tests/fuzz/plain_json_proto_to_luks2_converter.cc (+153/-0)
tests/fuzz/plain_json_proto_to_luks2_converter.h (+58/-0)
tests/fuzz/proto_to_luks2.cc (+75/-0)
tests/fuzz/proto_to_luks2_converter.cc (+604/-0)
tests/fuzz/proto_to_luks2_converter.h (+91/-0)
tests/fuzz/unpoison-mutated-buffers-from-libfuzzer.patch (+29/-0)
tests/fvault2-compat-test (+134/-0)
tests/keyring-compat-test (+18/-2)
tests/loopaes-test (+16/-0)
tests/luks1-compat-test (+27/-12)
tests/luks2-integrity-test (+16/-0)
tests/luks2-reencryption-mangle-test (+2/-1)
tests/luks2-reencryption-test (+43/-19)
tests/mode-test (+20/-2)
tests/password-hash-test (+16/-0)
tests/reencryption-compat-test (+42/-2)
tests/ssh-test-plugin (+27/-2)
tests/systemd-test-plugin (+150/-0)
tests/tcrypt-compat-test (+3/-3)
tests/test_utils.c (+66/-9)
tests/unit-utils-crypt.c (+1/-1)
tests/unit-utils-io.c (+1/-1)
tests/unit-wipe.c (+1/-1)
tests/verity-compat-test (+6/-0)
tokens/ssh/cryptsetup-ssh.c (+2/-2)
tokens/ssh/libcryptsetup-token-ssh.c (+8/-2)
tokens/ssh/ssh-utils.c (+2/-2)
tokens/ssh/ssh-utils.h (+2/-2)
Conflict in debian/changelog
Conflict in debian/patches/decrease_memlock_ulimit.patch
Reviewer Review Type Date Requested Status
git-ubuntu import Pending
Review via email: mp+437183@code.launchpad.net

This proposal has been superseded by a proposal from 2023-02-13.

Description of the change

  * Merge with Debian unstable (LP: #2004423). Remaining changes:
   - debian/control:
      + Recommend plymouth.
      + Depend on busybox-initramfs instead of busybox | busybox-static.
      + Move cryptsetup-initramfs back to cryptsetup's Recommends.
      + Do not build cryptsetup-suspend binary package on i386.
    - Fix cryptroot-unlock for busybox compatibility.
    - Fix warning and error when running on ZFS on root
      - d/functions: Return an empty devno for ZFS devices as they don't have
        major:minor device numbers.
      - d/initramfs/hooks/cryptroot: Ignore and don't print an error message
        when devices don't have a devno.
    - debian/patches/decrease_memlock_ulimit.patch
      Fixed FTBFS due to a restricted build environment
    - Fix cryptroot-* autopkgtests on Ubuntu. (LP: #1983522)
      + debian/tests/utils/mock.pm: return from consume() function if select()
        times out or fails
      + debian/tests/utils/cryptroot-common: fix apt source and kernel package
        names for Ubuntu
      + debian/tests/cryptroot-sysvinit.d: use systemd-sysv init for Ubuntu
        cryptroot-sysvinit package test
      + debian/tests/cryptroot-nested.d: fix cryptsetup-nested test, add
        workaround for LP1831747 by adding a e2fsprogs dependency
      + debian/tests/initramfs-hook: fix test's initramfs layout for Ubuntu and
        allow blowfish test use 64Mb of provisioned space (drop --size)
      + debian/tests/control: disable cryptdisks test

PPA: ppa:vpa1977/cryptsetup-review-comments

Package Test Results:

autopkgtest [16:57:03]: @@@@@@@@@@@@@@@@@@@@ summary
hint-testsuite-triggers SKIP unknown restriction hint-testsuite-triggers
hint-testsuite-triggers SKIP unknown restriction hint-testsuite-triggers
upstream-testsuite PASS
ssh-test-plugin PASS
cryptdisks.init PASS
initramfs-hook PASS
cryptroot-lvm PASS
cryptroot-legacy PASS
cryptroot-md PASS
cryptroot-nested PASS
cryptroot-sysvinit PASS
qemu-system-x86_64: terminating on signal 15 from pid 1553342 (/usr/bin/pyt)

To post a comment you must log in.

Unmerged commits

a930e85... by Vladimir Petko

update-maintainer

8cdbacc... by Vladimir Petko

changelog

c6e9d40... by Vladimir Petko

merge-changelogs

b50d064... by Vladimir Petko

refresh patch

2d43026... by Vladimir Petko

  * Fix cryptroot-* autopkgtests on Ubuntu. (LP: #1983522)

    - debian/tests/control: enable cryptroot-lvm

8c5bf17... by Vladimir Petko

    - debian/tests/utils/cryptroot-common: fix apt source and kernel package
      names for Ubuntu
    - debian/tests/cryptroot-sysvinit.d: use systemd-sysv init for Ubuntu
      cryptroot-sysvinit package test
    - debian/tests/cryptroot-nested.d: fix cryptsetup-nested test, add
      workaround for LP1831747 by adding a e2fsprogs dependency
    - debian/tests/initramfs-hook: fix test's initramfs layout for Ubuntu and
      allow blowfish test use 64Mb of provisioned space (drop --size)

71bc417... by Vladimir Petko

    - debian/tests/utils/mock.pm: return from consume() function if select()
      times out or fails

9463315... by Vladimir Petko

    - Fix cryptroot-unlock for busybox compatibility.

59550be... by Vladimir Petko

    - debian/patches/decrease_memlock_ulimit.patch
      Fixed FTBFS due to a restricted build environment

fa40a7d... by Vladimir Petko

      - d/initramfs/hooks/cryptroot: Ignore and don't print an error message
        when devices don't have a devno.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.github/workflows/cibuild-setup-ubuntu.sh b/.github/workflows/cibuild-setup-ubuntu.sh
2index 85c15e5..2c0adb2 100755
3--- a/.github/workflows/cibuild-setup-ubuntu.sh
4+++ b/.github/workflows/cibuild-setup-ubuntu.sh
5@@ -4,7 +4,7 @@ set -ex
6
7 PACKAGES=(
8 git make autoconf automake autopoint pkg-config libtool libtool-bin
9- gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
10+ gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
11 libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
12 sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
13 asciidoctor
14diff --git a/.gitignore b/.gitignore
15index db7afde..41715d1 100644
16--- a/.gitignore
17+++ b/.gitignore
18@@ -58,3 +58,4 @@ tests/unit-utils-io
19 tests/vectors-test
20 tests/test-symbols-list.h
21 tests/all-symbols-test
22+tests/fuzz/LUKS2.pb*
23diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
24index 5481515..3153145 100644
25--- a/.gitlab-ci.yml
26+++ b/.gitlab-ci.yml
27@@ -15,6 +15,9 @@ include:
28 - local: .gitlab/ci/annocheck.yml
29 - local: .gitlab/ci/csmock.yml
30 - local: .gitlab/ci/gitlab-shared-docker.yml
31+ - local: .gitlab/ci/compilation-various-disables.yml
32 - local: .gitlab/ci/compilation-gcc.gitlab-ci.yml
33 - local: .gitlab/ci/compilation-clang.gitlab-ci.yml
34 - local: .gitlab/ci/alpinelinux.yml
35+ - local: .gitlab/ci/ubuntu-32bit.yml
36+ - local: .gitlab/ci/cifuzz.yml
37diff --git a/.gitlab/ci/alpinelinux.yml b/.gitlab/ci/alpinelinux.yml
38index 130c897..81bd6cb 100644
39--- a/.gitlab/ci/alpinelinux.yml
40+++ b/.gitlab/ci/alpinelinux.yml
41@@ -23,11 +23,11 @@ test-main-commit-job-alpinelinux:
42 variables:
43 RUN_SSH_PLUGIN_TEST: "0"
44 rules:
45+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
46+ when: never
47 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
48 when: never
49 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
50- rules:
51- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
52 script:
53 - make -j
54 - make -j -C tests check-programs
55@@ -44,6 +44,8 @@ test-mergerq-job-alpinelinux:
56 variables:
57 RUN_SSH_PLUGIN_TEST: "0"
58 rules:
59+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
60+ when: never
61 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
62 when: never
63 - if: $CI_PIPELINE_SOURCE == "merge_request_event"
64diff --git a/.gitlab/ci/centos.yml b/.gitlab/ci/centos.yml
65index 2c607cf..6f5559c 100644
66--- a/.gitlab/ci/centos.yml
67+++ b/.gitlab/ci/centos.yml
68@@ -27,6 +27,8 @@ test-main-commit-centos-stream9:
69 variables:
70 RUN_SSH_PLUGIN_TEST: "1"
71 rules:
72+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
73+ when: never
74 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
75 when: never
76 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
77@@ -46,6 +48,8 @@ test-mergerq-centos-stream9:
78 variables:
79 RUN_SSH_PLUGIN_TEST: "1"
80 rules:
81+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
82+ when: never
83 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
84 when: never
85 - if: $CI_PIPELINE_SOURCE == "merge_request_event"
86diff --git a/.gitlab/ci/cibuild-setup-ubuntu.sh b/.gitlab/ci/cibuild-setup-ubuntu.sh
87index a966fde..07b0990 100755
88--- a/.gitlab/ci/cibuild-setup-ubuntu.sh
89+++ b/.gitlab/ci/cibuild-setup-ubuntu.sh
90@@ -4,7 +4,7 @@ set -ex
91
92 PACKAGES=(
93 git make autoconf automake autopoint pkg-config libtool libtool-bin
94- gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
95+ gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
96 libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
97 sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
98 asciidoctor
99diff --git a/.gitlab/ci/cifuzz.yml b/.gitlab/ci/cifuzz.yml
100new file mode 100644
101index 0000000..063b912
102--- /dev/null
103+++ b/.gitlab/ci/cifuzz.yml
104@@ -0,0 +1,46 @@
105+cifuzz:
106+ variables:
107+ OSS_FUZZ_PROJECT_NAME: cryptsetup
108+ CFL_PLATFORM: gitlab
109+ CIFUZZ_DEBUG: "True"
110+ FUZZ_SECONDS: 300 # 5 minutes per fuzzer
111+ ARCHITECTURE: "x86_64"
112+ DRY_RUN: "False"
113+ LOW_DISK_SPACE: "True"
114+ BAD_BUILD_CHECK: "True"
115+ LANGUAGE: "c"
116+ DOCKER_HOST: "tcp://docker:2375"
117+ DOCKER_IN_DOCKER: "true"
118+ DOCKER_DRIVER: overlay2
119+ DOCKER_TLS_CERTDIR: ""
120+ image:
121+ name: gcr.io/oss-fuzz-base/cifuzz-base
122+ entrypoint: [""]
123+ services:
124+ - docker:dind
125+
126+ stage: test
127+ parallel:
128+ matrix:
129+ - SANITIZER: [address, undefined, memory]
130+ rules:
131+ # Default code change.
132+ # - if: $CI_PIPELINE_SOURCE == "merge_request_event"
133+ # variables:
134+ # MODE: "code-change"
135+ - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
136+ when: never
137+ - if: $BUILD_AND_RUN_FUZZERS != null
138+ before_script:
139+ # Get gitlab's container id.
140+ - export CFL_CONTAINER_ID=`cut -c9- < /proc/1/cpuset`
141+ script:
142+ # Will build and run the fuzzers.
143+ # We use a hack to override CI_JOB_ID, because otherwise a bad path is used
144+ # in GitLab CI environment
145+ - CI_JOB_ID="$CI_PROJECT_NAMESPACE/$CI_PROJECT_TITLE" python3 "/opt/oss-fuzz/infra/cifuzz/cifuzz_combined_entrypoint.py"
146+ artifacts:
147+ # Upload artifacts when a crash makes the job fail.
148+ when: always
149+ paths:
150+ - artifacts/
151diff --git a/.gitlab/ci/compilation-various-disables.yml b/.gitlab/ci/compilation-various-disables.yml
152new file mode 100644
153index 0000000..1414f9e
154--- /dev/null
155+++ b/.gitlab/ci/compilation-various-disables.yml
156@@ -0,0 +1,21 @@
157+test-gcc-disable-compiles:
158+ extends:
159+ - .gitlab-shared-gcc
160+ parallel:
161+ matrix:
162+ - DISABLE_FLAGS: [
163+ "--disable-keyring",
164+ "--disable-external-tokens --disable-ssh-token",
165+ "--disable-luks2-reencryption",
166+ "--disable-cryptsetup --disable-veritysetup --disable-integritysetup",
167+ "--disable-kernel_crypto",
168+ "--disable-selinux",
169+ "--disable-udev",
170+ "--disable-internal-argon2",
171+ "--disable-blkid"
172+ ]
173+ script:
174+ - export CFLAGS="-Wall -Werror"
175+ - ./configure $DISABLE_FLAGS
176+ - make -j
177+ - make -j check-programs
178diff --git a/.gitlab/ci/debian.yml b/.gitlab/ci/debian.yml
179index fbc8c26..fad9d97 100644
180--- a/.gitlab/ci/debian.yml
181+++ b/.gitlab/ci/debian.yml
182@@ -3,12 +3,15 @@
183 - .dump_kernel_log
184 before_script:
185 - >
186- sudo apt-get -y install -y -qq git gcc make
187- autoconf automake autopoint pkg-config libtool libtool-bin gettext
188- libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
189- libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev
190- libpwquality-dev sharutils dmsetup jq xxd expect keyutils
191- netcat passwd openssh-client sshpass asciidoctor
192+ [ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
193+ sudo apt-get -y install -y -qq swtpm meson ninja-build python3-jinja2
194+ gperf libcap-dev tpm2-tss-engine-dev libmount-dev swtpm-tools
195+ - >
196+ sudo apt-get -y install -y -qq git gcc make autoconf automake autopoint
197+ pkgconf libtool libtool-bin gettext libssl-dev libdevmapper-dev
198+ libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev
199+ tar libargon2-0-dev libpwquality-dev sharutils dmsetup jq xxd expect
200+ keyutils netcat passwd openssh-client sshpass asciidoctor
201 - sudo apt-get -y build-dep cryptsetup
202 - sudo -E git clean -xdf
203 - ./autogen.sh
204@@ -19,7 +22,7 @@ test-mergerq-job-debian:
205 - .debian-prep
206 tags:
207 - libvirt
208- - debian10
209+ - debian11
210 stage: test
211 interruptible: true
212 variables:
213@@ -38,7 +41,7 @@ test-main-commit-job-debian:
214 - .debian-prep
215 tags:
216 - libvirt
217- - debian10
218+ - debian11
219 stage: test
220 interruptible: true
221 variables:
222diff --git a/.gitlab/ci/fedora.yml b/.gitlab/ci/fedora.yml
223index 39f8e31..7fd9c7e 100644
224--- a/.gitlab/ci/fedora.yml
225+++ b/.gitlab/ci/fedora.yml
226@@ -3,7 +3,12 @@
227 - .dump_kernel_log
228 before_script:
229 - >
230- sudo dnf -y -q install
231+ [ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
232+ sudo dnf -y -q install
233+ swtpm meson ninja-build python3-jinja2 gperf libcap-devel tpm2-tss-devel
234+ libmount-devel swtpm-tools
235+ - >
236+ sudo dnf -y -q install
237 autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
238 libargon2-devel libblkid-devel libpwquality-devel libselinux-devel
239 libssh-devel libtool libuuid-devel make popt-devel
240diff --git a/.gitlab/ci/rhel.yml b/.gitlab/ci/rhel.yml
241index 77657b5..f71533c 100644
242--- a/.gitlab/ci/rhel.yml
243+++ b/.gitlab/ci/rhel.yml
244@@ -27,6 +27,8 @@ test-main-commit-rhel8:
245 variables:
246 RUN_SSH_PLUGIN_TEST: "1"
247 rules:
248+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
249+ when: never
250 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
251 when: never
252 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
253@@ -46,6 +48,8 @@ test-main-commit-rhel9:
254 variables:
255 RUN_SSH_PLUGIN_TEST: "1"
256 rules:
257+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
258+ when: never
259 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
260 when: never
261 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
262@@ -67,10 +71,13 @@ test-main-commit-rhel8-fips:
263 variables:
264 RUN_SSH_PLUGIN_TEST: "1"
265 rules:
266+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
267+ when: never
268 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
269 when: never
270 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
271 script:
272+ - fips-mode-setup --check || exit 1
273 - make -j
274 - make -j -C tests check-programs
275 - sudo -E make check
276@@ -87,10 +94,13 @@ test-main-commit-rhel9-fips:
277 variables:
278 RUN_SSH_PLUGIN_TEST: "1"
279 rules:
280+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
281+ when: never
282 - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
283 when: never
284 - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
285 script:
286+ - fips-mode-setup --check || exit 1
287 - make -j
288 - make -j -C tests check-programs
289 - sudo -E make check
290diff --git a/.gitlab/ci/ubuntu-32bit.yml b/.gitlab/ci/ubuntu-32bit.yml
291new file mode 100644
292index 0000000..f51c059
293--- /dev/null
294+++ b/.gitlab/ci/ubuntu-32bit.yml
295@@ -0,0 +1,41 @@
296+test-mergerq-job-ubuntu-32bit:
297+ extends:
298+ - .debian-prep
299+ tags:
300+ - libvirt
301+ - ubuntu-bionic-32bit
302+ stage: test
303+ interruptible: true
304+ variables:
305+ RUN_SSH_PLUGIN_TEST: "1"
306+ rules:
307+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
308+ when: never
309+ - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
310+ when: never
311+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
312+ script:
313+ - make -j
314+ - make -j -C tests check-programs
315+ - sudo -E make check
316+
317+test-main-commit-job-ubuntu-32bit:
318+ extends:
319+ - .debian-prep
320+ tags:
321+ - libvirt
322+ - ubuntu-bionic-32bit
323+ stage: test
324+ interruptible: true
325+ variables:
326+ RUN_SSH_PLUGIN_TEST: "1"
327+ rules:
328+ - if: $RUN_SYSTEMD_PLUGIN_TEST != null
329+ when: never
330+ - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
331+ when: never
332+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
333+ script:
334+ - make -j
335+ - make -j -C tests check-programs
336+ - sudo -E make check
337diff --git a/FAQ.md b/FAQ.md
338index efa26bd..74ad955 100644
339--- a/FAQ.md
340+++ b/FAQ.md
341@@ -2506,6 +2506,31 @@ offset length name data type description
342 individually created (and hence has its own volume key). In this case,
343 changing the default passphrase will make it secure again.
344
345+ * **6.16 How to convert the printed volume key to a raw one?**
346+ A volume key printed via something like:
347+```
348+ cryptsetup --dump-volume-key luksDump /dev/<device> >volume-key
349+```
350+(i.e. without using `--volume-key-file`), which gives something like:
351+```
352+LUKS header information for /dev/<device>
353+Cipher name: aes
354+Cipher mode: xts-plain64
355+Payload offset: 32768
356+UUID: 6e914442-e8b5-4eb5-98c4-5bf0cf17ecad
357+MK bits: 512
358+MK dump: e0 3f 15 c2 0f e5 80 ab 35 b4 10 03 ae 30 b9 5d
359+ 4c 0d 28 9e 1b 0f e3 b0 50 57 ef d4 4d 53 a0 12
360+ b7 4e 43 a1 20 7e c5 02 1f f1 f5 08 04 3c f5 20
361+ a6 0b 23 f6 7b 53 55 aa 22 d8 aa 02 e0 2f d5 04
362+```
363+can be converted to the raw volume key for example via:
364+```
365+ sed -E -n '/^MK dump:\t/,/^[^\t]/{0,/^MK dump:\t/s/^MK dump://; /^([^\t].*)?$/q; s/\t+//p;};' volume-key | xxd -r -p
366+```
367+
368+
369+
370
371 # 7. Interoperability with other Disk Encryption Tools
372
373diff --git a/Makefile.am b/Makefile.am
374index c2ccb5e..fb7cb18 100644
375--- a/Makefile.am
376+++ b/Makefile.am
377@@ -1,5 +1,5 @@
378 EXTRA_DIST = README.md COPYING.LGPL FAQ.md docs misc autogen.sh
379-SUBDIRS = po tests
380+SUBDIRS = po tests tests/fuzz
381 CLEANFILES =
382 DISTCLEAN_TARGETS =
383
384@@ -14,8 +14,14 @@ AM_CPPFLAGS = \
385 -DVERSION=\""$(VERSION)"\" \
386 -DEXTERNAL_LUKS2_TOKENS_PATH=\"${EXTERNAL_LUKS2_TOKENS_PATH}\"
387 AM_CFLAGS = -Wall
388+AM_CXXFLAGS = -Wall
389 AM_LDFLAGS =
390
391+if ENABLE_FUZZ_TARGETS
392+AM_CFLAGS += -fsanitize=fuzzer-no-link
393+AM_CXXFLAGS += -fsanitize=fuzzer-no-link
394+endif
395+
396 LDADD = $(LTLIBINTL)
397
398 tmpfilesddir = @DEFAULT_TMPFILESDIR@
399@@ -64,3 +70,8 @@ uninstall-local:
400
401 check-programs: libcryptsetup.la
402 $(MAKE) -C tests $@
403+
404+if ENABLE_FUZZ_TARGETS
405+fuzz-targets: libcryptsetup.la libcrypto_backend.la
406+ $(MAKE) -C tests/fuzz $@
407+endif
408diff --git a/README.md b/README.md
409index b944304..daec8f7 100644
410--- a/README.md
411+++ b/README.md
412@@ -2,113 +2,145 @@
413
414 What the ...?
415 =============
416-**Cryptsetup** is a utility used to conveniently set up disk encryption based
417-on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
418+**Cryptsetup** is an open-source utility used to conveniently set up disk encryption based
419+on the [dm-crypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
420
421-These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
422-**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
423+These formats are supported:
424+ * **plain** volumes,
425+ * **LUKS** volumes,
426+ * **loop-AES**,
427+ * **TrueCrypt** (including **VeraCrypt** extension),
428+ * **BitLocker**, and
429+ * **FileVault2**.
430
431 The project also includes a **veritysetup** utility used to conveniently setup
432-[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
433-and **integritysetup** to setup
434-[DMIntegrity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMIntegrity) block integrity kernel module.
435+[dm-verity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity)
436+block integrity checking kernel module and **integritysetup** to setup
437+[dm-integrity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMIntegrity)
438+block integrity kernel module.
439
440 LUKS Design
441 -----------
442-**LUKS** is the standard for Linux hard disk encryption. By providing a standard on-disk-format, it does not
443-only facilitate compatibility among distributions, but also provides secure management of multiple user passwords.
444-LUKS stores all necessary setup information in the partition header, enabling to transport or migrate data seamlessly.
445+**LUKS** is the standard for Linux disk encryption. By providing a standard on-disk format,
446+it does not only facilitate compatibility among distributions, but also provides secure management
447+of multiple user passwords. LUKS stores all necessary setup information in the partition header,
448+enabling to transport or migrate data seamlessly.
449
450-### Specifications
451+### Specification and documentation
452
453-Last version of the LUKS2 format specification is
454-[available here](https://gitlab.com/cryptsetup/LUKS2-docs).
455-
456-Last version of the LUKS1 format specification is
457-[available here](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
458-
459-Why LUKS?
460----------
461- * compatibility via standardization,
462- * secure against low entropy attacks,
463- * support for multiple keys,
464- * effective passphrase revocation,
465- * free.
466-
467-[Project home page](https://gitlab.com/cryptsetup/cryptsetup/).
468------------------
469-
470-[Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
471---------------------------------
472+ * The latest version of the
473+ [LUKS2 format specification](https://gitlab.com/cryptsetup/LUKS2-docs).
474+ * The latest version of the
475+ [LUKS1 format specification](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
476+ * [Project home page](https://gitlab.com/cryptsetup/cryptsetup/).
477+ * [Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
478
479 Download
480 --------
481-All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
482+All release tarballs and release notes are hosted on
483+[kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
484
485-**The latest stable cryptsetup version is 2.5.0**
486- * [cryptsetup-2.5.0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.xz)
487- * Signature [cryptsetup-2.5.0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.sign)
488+**The latest stable cryptsetup release version is 2.6.1**
489+ * [cryptsetup-2.6.1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.xz)
490+ * Signature [cryptsetup-2.6.1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.sign)
491 _(You need to decompress file first to check signature.)_
492- * [Cryptsetup 2.5.0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/v2.5.0-ReleaseNotes).
493+ * [Cryptsetup 2.6.1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/v2.6.1-ReleaseNotes).
494
495 Previous versions
496- * [Version 2.4.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.3.tar.xz) -
497- [Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.3.tar.sign) -
498- [Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/v2.4.3-ReleaseNotes).
499+ * [Version 2.5.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.xz) -
500+ [Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.sign) -
501+ [Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/v2.5.0-ReleaseNotes).
502 * [Version 1.7.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.xz) -
503 [Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.sign) -
504 [Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.5-ReleaseNotes).
505
506-Source and API docs
507--------------------
508-For development version code, please refer to [source](https://gitlab.com/cryptsetup/cryptsetup/tree/master) page,
509-mirror on [kernel.org](https://git.kernel.org/cgit/utils/cryptsetup/cryptsetup.git/) or [GitHub](https://github.com/mbroz/cryptsetup).
510+Source and API documentation
511+----------------------------
512+For development version code, please refer to
513+[source](https://gitlab.com/cryptsetup/cryptsetup/tree/master) page,
514+mirror on [kernel.org](https://git.kernel.org/cgit/utils/cryptsetup/cryptsetup.git/) or
515+[GitHub](https://github.com/mbroz/cryptsetup).
516
517-For libcryptsetup documentation see [libcryptsetup API](https://mbroz.fedorapeople.org/libcryptsetup_API/) page.
518+For libcryptsetup documentation see
519+[libcryptsetup API](https://mbroz.fedorapeople.org/libcryptsetup_API/) page.
520
521-The libcryptsetup API/ABI changes are tracked in [compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).
522+The libcryptsetup API/ABI changes are tracked in
523+[compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).
524
525-NLS PO files are maintained by [TranslationProject](https://translationproject.org/domain/cryptsetup.html).
526+NLS PO files are maintained by
527+[TranslationProject](https://translationproject.org/domain/cryptsetup.html).
528
529 Required packages
530 -----------------
531-All distributions provide cryptsetup as distro package. If you need to compile cryptsetup yourself, some packages are required for compilation. Please always prefer distro specific build tools to manually configuring cryptsetup.
532+All distributions provide cryptsetup as distro package. If you need to compile cryptsetup yourself,
533+some packages are required for compilation.
534+Please always prefer distro specific build tools to manually configuring cryptsetup.
535
536 Here is the list of packages needed for the compilation of project for particular distributions:
537- * For Fedora: `git gcc make autoconf automake gettext-devel pkgconfig openssl-devel popt-devel device-mapper-devel libuuid-devel json-c-devel libblkid-devel findutils libtool libssh-devel tar`. Optionally `libargon2-devel libpwquality-devel`. To run the internal testsuite you also need to install `sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openssh-clients openssh sshpass`.
538
539- * For Debian and Ubuntu: `git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev libjson-c-dev libssh-dev libblkid-dev tar`. Optionally `libargon2-0-dev libpwquality-dev`. To run the internal testsuite you also need to install `sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass`
540+**For Fedora**:
541+```
542+git gcc make autoconf automake gettext-devel pkgconfig openssl-devel popt-devel device-mapper-devel
543+libuuid-devel json-c-devel libblkid-devel findutils libtool libssh-devel tar
544+
545+Optionally: libargon2-devel libpwquality-devel
546+```
547+To run the internal testsuite (make check) you also need to install
548+```
549+sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openssh-clients openssh sshpass
550+```
551+
552+**For Debian and Ubuntu**:
553+```
554+git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev
555+libpopt-dev uuid-dev libsepol1-dev libjson-c-dev libssh-dev libblkid-dev tar
556+
557+Optionally: libargon2-0-dev libpwquality-dev
558+```
559+To run the internal testsuite (make check) you also need to install
560+```
561+sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
562+```
563
564 Note that the list could change as the distributions evolve.
565
566 Compilation
567 -----------
568-The cryptsetup project uses **automake** and **autoconf** system to generate all needed files for compilation. If you check it from the git snapshot, use ``./autogen.sh && ./configure && make`` to compile the project. If you use downloaded released ``*.tar.xz`` archive, the configure script is already pre-generated (no need to run ``autoconf.sh``).
569-See ``./configure --help`` and use ``--disable-*`` and ``--enable-*`` options.
570+The cryptsetup project uses **automake** and **autoconf** system to generate all needed files
571+for compilation. If you check it from the git snapshot, use **./autogen.sh && ./configure && make**
572+to compile the project. If you use downloaded released **tar.xz** archive, the configure script
573+is already pre-generated (no need to run **autoconf.sh**).
574+See **./configure --help** and use **--disable-[feature]** and **--enable-[feature]** options.
575
576-For running the test suite that come with the project, type ``make check``.
577+For running the test suite that come with the project, type **make check**.
578 Note that most tests will need root user privileges and run many dangerous storage fail simulations.
579-Do **not** run tests with root privilege on production systems! Some tests will need scsi_debug kernel module to be available.
580+Do **not** run tests with root privilege on production systems! Some tests will need scsi_debug
581+kernel module to be available.
582
583-For more details, please refer to [automake](https://www.gnu.org/software/automake/manual/automake.html) and [autoconf](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf.html) manuals.
584+For more details, please refer to [automake](https://www.gnu.org/software/automake/manual/automake.html)
585+and [autoconf](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf.html) manuals.
586
587 Help!
588 -----
589-
590 ### Documentation
591+Please read the following documentation before posting questions in the mailing list...
592+You will be able to ask better questions and better understand the answers.
593
594-Please read the following documentation before posting questions in the mailing list. You will be able to ask better questions and better understand the answers.
595-
596-* [FAQ](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
597-* LUKS Specifications
598+* [Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions),
599+* [LUKS Specifications](#specification-and-documentation), and
600 * manuals (aka man page, man pages, man-page)
601
602-The FAQ is online and in the source code for the project. The Specifications are referenced above in this document. The man pages are in source and should be available after installation using standard man commands. e.g. man cryptsetup
603+The FAQ is online and in the source code for the project. The Specifications are referenced above
604+in this document. The man pages are in source and should be available after installation using
605+standard man commands, e.g. **man cryptsetup**.
606
607 ### Mailing List
608
609-For cryptsetup and LUKS related questions, please use the cryptsetup mailing list [cryptsetup@lists.linux.dev](mailto:cryptsetup@lists.linux.dev), hosted at [kernel.org subspace](https://subspace.kernel.org/lists.linux.dev.html).
610-To subscribe send an empty mail to [cryptsetup+subscribe@lists.linux.dev](mailto:cryptsetup+subscribe@lists.linux.dev).
611+For cryptsetup and LUKS related questions, please use the cryptsetup mailing list
612+[cryptsetup@lists.linux.dev](mailto:cryptsetup@lists.linux.dev),
613+hosted at [kernel.org subspace](https://subspace.kernel.org/lists.linux.dev.html).
614+To subscribe send an empty mail to
615+[cryptsetup+subscribe@lists.linux.dev](mailto:cryptsetup+subscribe@lists.linux.dev).
616
617 You can also browse and/or search the mailing [list archive](https://lore.kernel.org/cryptsetup/).
618 News (NNTP), Atom feed and git access to public inbox is available through [lore.kernel.org](https://lore.kernel.org) service.
619diff --git a/autogen.sh b/autogen.sh
620index 1b77be6..c111f79 100755
621--- a/autogen.sh
622+++ b/autogen.sh
623@@ -74,7 +74,7 @@ autopoint --force $AP_OPTS
624 libtoolize --force --copy
625 aclocal -I m4 $AL_OPTS
626 autoheader $AH_OPTS
627-automake --add-missing --copy --gnu $AM_OPTS
628+automake --force-missing --add-missing --copy --gnu $AM_OPTS
629 autoconf $AC_OPTS
630
631 echo
632diff --git a/configure.ac b/configure.ac
633index 0175ee5..ccf2112 100644
634--- a/configure.ac
635+++ b/configure.ac
636@@ -1,9 +1,9 @@
637 AC_PREREQ([2.67])
638-AC_INIT([cryptsetup],[2.5.0])
639+AC_INIT([cryptsetup],[2.6.1])
640
641 dnl library version from <major>.<minor>.<release>[-<suffix>]
642 LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
643-LIBCRYPTSETUP_VERSION_INFO=20:0:8
644+LIBCRYPTSETUP_VERSION_INFO=21:0:9
645
646 AM_SILENT_RULES([yes])
647 AC_CONFIG_SRCDIR(src/cryptsetup.c)
648@@ -28,6 +28,7 @@ AC_USE_SYSTEM_EXTENSIONS
649 AC_PROG_CC
650 AM_PROG_CC_C_O
651 AC_PROG_CPP
652+AC_PROG_CXX
653 AC_PROG_INSTALL
654 AC_PROG_MAKE_SET
655 AC_PROG_MKDIR_P
656@@ -150,6 +151,7 @@ if test "x$enable_external_tokens" = "xyes"; then
657 AC_SUBST(DL_LIBS, $LIBS)
658 LIBS=$saved_LIBS
659 fi
660+AM_CONDITIONAL(EXTERNAL_TOKENS, test "x$enable_external_tokens" = "xyes")
661
662 AC_ARG_ENABLE([ssh-token],
663 AS_HELP_STRING([--disable-ssh-token], [disable LUKS2 ssh-token]),
664@@ -214,6 +216,17 @@ if test "x$enable_pwquality" = "xyes"; then
665 fi
666
667 dnl ==========================================================================
668+dnl fuzzers, it requires own static library compilation later
669+AC_ARG_ENABLE([fuzz-targets],
670+ AS_HELP_STRING([--enable-fuzz-targets], [enable building fuzz targets]))
671+AM_CONDITIONAL(ENABLE_FUZZ_TARGETS, test "x$enable_fuzz_targets" = "xyes")
672+
673+if test "x$enable_fuzz_targets" = "xyes"; then
674+ AX_CHECK_COMPILE_FLAG([-fsanitize=fuzzer-no-link],,
675+ AC_MSG_ERROR([Required compiler options not supported; use clang.]), [-Werror])
676+fi
677+
678+dnl ==========================================================================
679 dnl passwdqc library (cryptsetup CLI only)
680 AC_ARG_ENABLE([passwdqc],
681 AS_HELP_STRING([--enable-passwdqc@<:@=CONFIG_PATH@:>@],
682@@ -617,6 +630,22 @@ AC_SUBST([LIBSSH_LIBS])
683 AC_SUBST([LIBCRYPTSETUP_VERSION])
684 AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
685
686+dnl Set Requires.private for libcryptsetup.pc
687+dnl pwquality is used only by tools
688+PKGMODULES="uuid devmapper json-c"
689+case $with_crypto_backend in
690+ gcrypt) PKGMODULES+=" libgcrypt" ;;
691+ openssl) PKGMODULES+=" openssl" ;;
692+ nss) PKGMODULES+=" nss" ;;
693+ nettle) PKGMODULES+=" nettle" ;;
694+esac
695+if test "x$enable_libargon2" = "xyes"; then
696+ PKGMODULES+=" libargon2"
697+fi
698+if test "x$enable_blkid" = "xyes"; then
699+ PKGMODULES+=" blkid"
700+fi
701+AC_SUBST([PKGMODULES])
702 dnl ==========================================================================
703 AC_ARG_ENABLE([dev-random],
704 AS_HELP_STRING([--enable-dev-random], [use /dev/random by default for key generation (otherwise use /dev/urandom)]))
705@@ -739,5 +768,6 @@ lib/libcryptsetup.pc
706 po/Makefile.in
707 scripts/cryptsetup.conf
708 tests/Makefile
709+tests/fuzz/Makefile
710 ])
711 AC_OUTPUT
712diff --git a/debian/README.Debian b/debian/README.Debian
713index a0ef9ad..99633bf 100644
714--- a/debian/README.Debian
715+++ b/debian/README.Debian
716@@ -63,7 +63,7 @@ that may be written to disk when memory is swapped to disk.
717 sure to place the source device (here `/dev/sde9`) with your swap devices:
718
719 # <target name> <source device> <key file> <options>
720- cswap1 /dev/sde9 /dev/urandom swap,cipher=aes-xts-plain64,size=256,hash=sha1
721+ cswap1 /dev/sde9 /dev/urandom plain,cipher=aes-xts-plain64,size=256,swap
722
723 Now you need to change the swap devices in `/etc/fstab` to the encrypted swap
724 device names (`/dev/mapper/cswap1` in this example).
725diff --git a/debian/changelog b/debian/changelog
726index f24081f..ed8fb12 100644
727--- a/debian/changelog
728+++ b/debian/changelog
729@@ -1,3 +1,86 @@
730+<<<<<<< debian/changelog
731+=======
732+cryptsetup (2:2.6.1-1ubuntu1) lunar; urgency=medium
733+
734+ * Merge with Debian unstable (LP: #2004423). Remaining changes:
735+ - debian/control:
736+ + Recommend plymouth.
737+ + Depend on busybox-initramfs instead of busybox | busybox-static.
738+ + Move cryptsetup-initramfs back to cryptsetup's Recommends.
739+ + Do not build cryptsetup-suspend binary package on i386.
740+ - Fix cryptroot-unlock for busybox compatibility.
741+ - Fix warning and error when running on ZFS on root
742+ - d/functions: Return an empty devno for ZFS devices as they don't have
743+ major:minor device numbers.
744+ - d/initramfs/hooks/cryptroot: Ignore and don't print an error message
745+ when devices don't have a devno.
746+ - debian/patches/decrease_memlock_ulimit.patch
747+ Fixed FTBFS due to a restricted build environment
748+ - Fix cryptroot-* autopkgtests on Ubuntu. (LP: #1983522)
749+ + debian/tests/utils/mock.pm: return from consume() function if select()
750+ times out or fails
751+ + debian/tests/utils/cryptroot-common: fix apt source and kernel package
752+ names for Ubuntu
753+ + debian/tests/cryptroot-sysvinit.d: use systemd-sysv init for Ubuntu
754+ cryptroot-sysvinit package test
755+ + debian/tests/cryptroot-nested.d: fix cryptsetup-nested test, add
756+ workaround for LP1831747 by adding a e2fsprogs dependency
757+ + debian/tests/initramfs-hook: fix test's initramfs layout for Ubuntu and
758+ allow blowfish test use 64Mb of provisioned space (drop --size)
759+ + debian/tests/control: disable cryptdisks test
760+
761+ -- Vladimir Petko <vladimir.petko@canonical.com> Mon, 13 Feb 2023 15:57:18 +1300
762+
763+cryptsetup (2:2.6.1-1) unstable; urgency=medium
764+
765+ * New upstream bugfix release.
766+ * d/README.Debian: Explicitly set cswap1's device type to 'plain'.
767+ (Closes: #1025136)
768+ * d/control: Update standards version to 4.6.2, no changes needed.
769+ * d/clean: Add some gitignore(5)'d files. (Closes: #1026838)
770+ * cryptgnupg-sc hook: Look terminfo file in /usr/share/terminfo in adition
771+ to /lib/terminfo, see #1028202. (Closes: 1028234)
772+ * d/copyright: Bump copyright years.
773+
774+ -- Guilhem Moulin <guilhem@debian.org> Fri, 10 Feb 2023 00:50:42 +0100
775+
776+cryptsetup (2:2.6.0-2) unstable; urgency=low
777+
778+ * libcryptsetup-dev: Add 'Depends: libargon2-dev, libblkid-dev,
779+ libdevmapper-dev, libjson-c-dev, libssl-dev, uuid-dev' to account for
780+ libcryptsetup.pc's Requires.private. Closes: #1025054.
781+
782+ -- Guilhem Moulin <guilhem@debian.org> Tue, 29 Nov 2022 15:42:25 +0100
783+
784+cryptsetup (2:2.6.0-1) unstable; urgency=low
785+
786+ * New upstream release 2.6.0.
787+
788+ -- Guilhem Moulin <guilhem@debian.org> Tue, 29 Nov 2022 01:20:38 +0100
789+
790+cryptsetup (2:2.6.0~rc0-1) experimental; urgency=medium
791+
792+ * New upstream release candidate 2.6.0, introducing support for handling
793+ macOS FileVault2 devices (FVAULT2). The new version of FileVault based on
794+ the APFS filesystem used in recent macOS versions is currently not
795+ supported: only the (legacy) FileVault2 format based on Core Storage and
796+ HFS+ filesystem (introduced in MacOS X 10.7 Lion) is supported. Moreover
797+ header formatting and changes are not supported; cryptsetup never changes
798+ the metadata on the device.
799+ Closes: #923513.
800+ * Update d/copyright for 2:2.6.0~rc0-1.
801+ * Ship cryptsetup-fvault2Dump(8) and cryptsetup-fvault2Open(8) to
802+ cryptsetup-bin binary package.
803+ * Update d/libcryptsetup12.symbols for 2:2.6.0~rc0-1.
804+ * Add 'fvault2' flag to crypttab(5) to force detection of Apple's FileVault2
805+ volumes.
806+ * d/rules: Add new target execute_before_dh_auto_test so blhc ignores
807+ compilations of tests/*.c.
808+ * d/u/metadata: Set 'Security-Contact' upstream metadata field.
809+
810+ -- Guilhem Moulin <guilhem@debian.org> Sat, 19 Nov 2022 17:30:40 +0100
811+
812+>>>>>>> debian/changelog
813 cryptsetup (2:2.5.0-6ubuntu3) lunar; urgency=medium
814
815 * Fix cryptroot-lvm autopkgtest on Ubuntu. (LP: #1983522)
816diff --git a/debian/clean b/debian/clean
817index 8f6ae6f..f1aea9d 100644
818--- a/debian/clean
819+++ b/debian/clean
820@@ -3,3 +3,8 @@ debian/doc/*.[0-9]
821 debian/doc/variables.xml
822 debian/scripts/passdev
823 debian/scripts/suspend/cryptsetup-suspend
824+# `make clean` doesn't remove all gitignore(5)'d files, instead
825+# .gitlab/ci/debian.yml runs `git clean -xdf`
826+man/*.8
827+po/*.gmo
828+po/stamp-po
829diff --git a/debian/control b/debian/control
830index 981726e..d218d7a 100644
831--- a/debian/control
832+++ b/debian/control
833@@ -32,7 +32,7 @@ Build-Depends: asciidoctor <!nodoc>,
834 uuid-dev,
835 xsltproc <!nodoc>,
836 xxd <!nocheck>
837-Standards-Version: 4.6.1
838+Standards-Version: 4.6.2
839 Homepage: https://gitlab.com/cryptsetup/cryptsetup
840 Vcs-Browser: https://salsa.debian.org/cryptsetup-team/cryptsetup
841 Vcs-Git: https://salsa.debian.org/cryptsetup-team/cryptsetup.git -b debian/latest
842@@ -161,7 +161,16 @@ Package: libcryptsetup-dev
843 Section: libdevel
844 Architecture: linux-any
845 Multi-Arch: same
846-Depends: libcryptsetup12 (= ${binary:Version}), ${misc:Depends}
847+# XXX [#1025065] ideal we would have "Depends: libcryptsetup12
848+# (= ${binary:Version}), ${misc:Depends}, ${pkgconf:Depends}"
849+Depends: libargon2-dev,
850+ libblkid-dev,
851+ libcryptsetup12 (= ${binary:Version}),
852+ libdevmapper-dev,
853+ libjson-c-dev,
854+ libssl-dev,
855+ uuid-dev,
856+ ${misc:Depends}
857 Description: disk encryption support - development files
858 Cryptsetup provides an interface for configuring encryption on block
859 devices (such as /home or swap partitions), using the Linux kernel
860diff --git a/debian/copyright b/debian/copyright
861index b8047db..5e9553d 100644
862--- a/debian/copyright
863+++ b/debian/copyright
864@@ -6,8 +6,8 @@ Upstream-Name: cryptsetup
865 Files: *
866 Copyright: © 2004 Christophe Saout <christophe@saout.de>
867 © 2004-2008 Clemens Fruhwirth <clemens@endorphin.org>
868- © 2008-2022 Red Hat, Inc.
869- © 2008-2022 Milan Broz <gmazyland@gmail.com>
870+ © 2008-2023 Red Hat, Inc.
871+ © 2008-2023 Milan Broz <gmazyland@gmail.com>
872 License: GPL-2+ with OpenSSL exception
873
874 Files: debian/*
875@@ -15,7 +15,7 @@ Copyright: © 2004-2005 Wesley W. Terpstra <terpstra@debian.org>
876 © 2005-2006 Michael Gebetsroither <michael.geb@gmx.at>
877 © 2006-2008 David Härdeman <david@hardeman.nu>
878 © 2005-2015 Jonas Meurer <jonas@freesources.org>
879- © 2016-2022 Guilhem Moulin <guilhem@debian.org>
880+ © 2016-2023 Guilhem Moulin <guilhem@debian.org>
881 License: GPL-2+
882
883 Files: debian/scripts/suspend/cryptsetup-suspend.c
884@@ -61,47 +61,56 @@ Copyright: © 2021-2022 Guilhem Moulin <guilhem@debian.org>
885 License: GPL-3+
886
887 Files: docs/examples/* tests/all-symbols-test.c
888-Copyright: © 2011-2022 Red Hat, Inc.
889+Copyright: © 2011-2023 Red Hat, Inc.
890 License: LGPL-2.1+
891
892 Files: lib/bitlk/*
893-Copyright: © 2019-2022 Red Hat, Inc.
894- © 2019-2022 Milan Broz <gmazyland@gmail.com>
895- © 2019-2022 Vojtech Trefny
896+Copyright: © 2019-2023 Red Hat, Inc.
897+ © 2019-2023 Milan Broz <gmazyland@gmail.com>
898+ © 2019-2023 Vojtech Trefny
899 License: LGPL-2.1+
900
901 Files: tokens/ssh/*
902-Copyright: © 2016-2022 Milan Broz <gmazyland@gmail.com>
903- © 2020-2022 Vojtech Trefny
904+Copyright: © 2016-2023 Milan Broz <gmazyland@gmail.com>
905+ © 2020-2023 Vojtech Trefny
906 License: LGPL-2.1+
907
908 Files: tokens/ssh/cryptsetup-ssh.c
909-Copyright: © 2016-2022 Milan Broz <gmazyland@gmail.com>
910- © 2021-2022 Vojtech Trefny
911+Copyright: © 2016-2023 Milan Broz <gmazyland@gmail.com>
912+ © 2021-2023 Vojtech Trefny
913 License: GPL-2+
914
915 Files: lib/crypto_backend/* lib/integrity/* lib/loopaes/* lib/tcrypt/* lib/verity/*
916-Copyright: © 2009-2022 Red Hat, Inc.
917- © 2010-2022 Milan Broz <gmazyland@gmail.com>
918+Copyright: © 2009-2023 Red Hat, Inc.
919+ © 2010-2023 Milan Broz <gmazyland@gmail.com>
920 License: LGPL-2.1+
921
922 Files: lib/crypto_backend/base64.c
923 Copyright: © 2010 Lennart Poettering
924- © 2021-2022 Milan Broz <gmazyland@gmail.com>
925+ © 2021-2023 Milan Broz <gmazyland@gmail.com>
926 License: LGPL-2.1+
927
928 Files: lib/crypto_backend/utf8.c
929 Copyright: © 2010 Lennart Poettering
930- © 2021-2022 Vojtech Trefny
931+ © 2021-2023 Vojtech Trefny
932 © 1999 Tom Tromey
933 © 2000 Red Hat, Inc.
934 License: GPL-2+
935
936 Files: lib/crypto_backend/crypto_openssl.c
937-Copyright: © 2009-2022 Red Hat, Inc.
938- © 2010-2022 Milan Broz <gmazyland@gmail.com>
939+Copyright: © 2009-2023 Red Hat, Inc.
940+ © 2010-2023 Milan Broz <gmazyland@gmail.com>
941 License: LGPL-2.1+ with OpenSSL exception
942
943+Files: lib/fvault2/fvault2.c lib/fvault2/fvault2.h
944+Copyright: © 2021-2022 Pavel Tobias
945+License: LGPL-2.1+ with OpenSSL exception
946+
947+Files: lib/keyslot_context.c lib/keyslot_context.h
948+Copyright: © 2022-2023 Red Hat, Inc.
949+ © 2022-2023 Ondrej Kozina <okozina@redhat.com>
950+License: GPL-2+
951+
952 Files: lib/crypto_backend/argon2/*
953 Copyright: © 2015 Daniel Dinu
954 © 2015 Dmitry Khovratovich
955diff --git a/debian/cryptsetup-bin.manpages b/debian/cryptsetup-bin.manpages
956index 3d1724d..759911e 100644
957--- a/debian/cryptsetup-bin.manpages
958+++ b/debian/cryptsetup-bin.manpages
959@@ -11,6 +11,8 @@ usr/share/man/man8/cryptsetup-config.8
960 usr/share/man/man8/cryptsetup-convert.8
961 usr/share/man/man8/cryptsetup-create.8
962 usr/share/man/man8/cryptsetup-erase.8
963+usr/share/man/man8/cryptsetup-fvault2Dump.8
964+usr/share/man/man8/cryptsetup-fvault2Open.8
965 usr/share/man/man8/cryptsetup-isLuks.8
966 usr/share/man/man8/cryptsetup-loopaesOpen.8
967 usr/share/man/man8/cryptsetup-luksAddKey.8
968diff --git a/debian/doc/crypttab.xml b/debian/doc/crypttab.xml
969index 9327157..c6077a7 100644
970--- a/debian/doc/crypttab.xml
971+++ b/debian/doc/crypttab.xml
972@@ -81,8 +81,9 @@
973 <simpara>
974 The fourth field, <emphasis>options</emphasis>, is an optional comma-separated
975 list of options and/or flags describing the device type (<emphasis>luks</emphasis>,
976- <emphasis>tcrypt</emphasis>, <emphasis>bitlk</emphasis>, or <emphasis>plain</emphasis>
977- which is also the default) and cryptsetup options associated with the encryption process.
978+ <emphasis>tcrypt</emphasis>, <emphasis>bitlk</emphasis>, <emphasis>fvault2</emphasis>,
979+ or <emphasis>plain</emphasis> which is also the default) and cryptsetup options
980+ associated with the encryption process.
981 The supported options are described below.
982 For plain dm-crypt devices the <emphasis>cipher</emphasis>, <emphasis>hash</emphasis>
983 and <emphasis>size</emphasis> options are required.
984@@ -298,6 +299,19 @@
985 </varlistentry>
986
987 <varlistentry>
988+ <term><emphasis>fvault2</emphasis></term>
989+ <listitem>
990+ <simpara>
991+ Force Apple's FileVault2 mode.
992+ Only the (legacy) FileVault2 format based on Core Storage and HFS+
993+ filesystem (introduced in MacOS X 10.7 Lion) is currently supported;
994+ the new version of FileVault based on the APFS filesystem used in
995+ recent macOS versions is not supported.
996+ </simpara>
997+ </listitem>
998+ </varlistentry>
999+
1000+ <varlistentry>
1001 <term><emphasis>tcrypt</emphasis></term>
1002 <listitem>
1003 <simpara>Use TrueCrypt encryption mode. When this mode is used, the
1004diff --git a/debian/functions b/debian/functions
1005index 35fd321..73f5f2a 100644
1006--- a/debian/functions
1007+++ b/debian/functions
1008@@ -68,6 +68,7 @@ crypttab_parse_options() {
1009 CRYPTTAB_OPTION_tcrypt \
1010 CRYPTTAB_OPTION_veracrypt \
1011 CRYPTTAB_OPTION_bitlk \
1012+ CRYPTTAB_OPTION_fvault2 \
1013 CRYPTTAB_OPTION_swap \
1014 CRYPTTAB_OPTION_tmp \
1015 CRYPTTAB_OPTION_check \
1016@@ -241,6 +242,7 @@ crypttab_validate_option() {
1017 veracrypt) ;;
1018 tcrypthidden) ;;
1019 bitlk) ;;
1020+ fvault2) ;;
1021 same-cpu-crypt) ;;
1022 submit-from-crypt-cpus) ;;
1023 no-read-workqueue) ;;
1024@@ -311,6 +313,8 @@ _get_crypt_type() {
1025 t="plain"
1026 elif [ "${CRYPTTAB_OPTION_bitlk-}" = "yes" ]; then
1027 t="bitlk"
1028+ elif [ "${CRYPTTAB_OPTION_fvault2-}" = "yes" ]; then
1029+ t="fvault2"
1030 elif [ -n "${CRYPTTAB_OPTION_header+x}" ]; then
1031 # detached headers are only supported for LUKS devices
1032 if [ -e "$CRYPTTAB_OPTION_header" ] && /sbin/cryptsetup isLuks -- "$CRYPTTAB_OPTION_header"; then
1033diff --git a/debian/initramfs/hooks/cryptgnupg-sc b/debian/initramfs/hooks/cryptgnupg-sc
1034index 752474a..9e45000 100644
1035--- a/debian/initramfs/hooks/cryptgnupg-sc
1036+++ b/debian/initramfs/hooks/cryptgnupg-sc
1037@@ -72,6 +72,16 @@ if [ ! -x "$DESTDIR/usr/bin/pinentry" ]; then
1038 copy_exec "$pinentry"
1039 ln -s "$pinentry" "$DESTDIR/usr/bin/pinentry"
1040 fi
1041-[ -f "$DESTDIR/lib/terminfo/l/linux" ] || copy_file terminfo /lib/terminfo/l/linux || RV=$?
1042+
1043+# #1028202: ncurses-base: move terminfo files from /lib/terminfo to
1044+# /usr/share/terminfo
1045+for d in "/usr/share/terminfo" "/lib/terminfo"; do
1046+ if [ -f "$d/l/linux" ]; then
1047+ if [ ! -f "$DESTDIR$d/l/linux" ]; then
1048+ copy_file terminfo "$d/l/linux" || RV=$?
1049+ fi
1050+ break
1051+ fi
1052+done
1053
1054 exit $RV
1055diff --git a/debian/libcryptsetup12.symbols b/debian/libcryptsetup12.symbols
1056index f6303a1..f124910 100644
1057--- a/debian/libcryptsetup12.symbols
1058+++ b/debian/libcryptsetup12.symbols
1059@@ -3,6 +3,7 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER#
1060 CRYPTSETUP_2.0@CRYPTSETUP_2.0 2:2.0
1061 CRYPTSETUP_2.4@CRYPTSETUP_2.4 2:2.4
1062 CRYPTSETUP_2.5@CRYPTSETUP_2.5 2:2.5
1063+ CRYPTSETUP_2.6@CRYPTSETUP_2.6 2:2.6
1064 crypt_activate_by_keyfile@CRYPTSETUP_2.0 2:1.4
1065 crypt_activate_by_keyfile_offset@CRYPTSETUP_2.0 2:1.4.3
1066 crypt_activate_by_keyring@CRYPTSETUP_2.0 2:2.0
1067@@ -59,10 +60,19 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER#
1068 crypt_keyslot_add_by_key@CRYPTSETUP_2.0 2:2.0
1069 crypt_keyslot_add_by_keyfile@CRYPTSETUP_2.0 2:1.4
1070 crypt_keyslot_add_by_keyfile_offset@CRYPTSETUP_2.0 2:1.4.3
1071+ crypt_keyslot_add_by_keyslot_context@CRYPTSETUP_2.6 2:2.6
1072 crypt_keyslot_add_by_passphrase@CRYPTSETUP_2.0 2:1.4
1073 crypt_keyslot_add_by_volume_key@CRYPTSETUP_2.0 2:1.4
1074 crypt_keyslot_area@CRYPTSETUP_2.0 2:1.6
1075 crypt_keyslot_change_by_passphrase@CRYPTSETUP_2.0 2:1.6
1076+ crypt_keyslot_context_free@CRYPTSETUP_2.6 2:2.6
1077+ crypt_keyslot_context_get_error@CRYPTSETUP_2.6 2:2.6
1078+ crypt_keyslot_context_get_type@CRYPTSETUP_2.6 2:2.6
1079+ crypt_keyslot_context_init_by_keyfile@CRYPTSETUP_2.6 2:2.6
1080+ crypt_keyslot_context_init_by_passphrase@CRYPTSETUP_2.6 2:2.6
1081+ crypt_keyslot_context_init_by_token@CRYPTSETUP_2.6 2:2.6
1082+ crypt_keyslot_context_init_by_volume_key@CRYPTSETUP_2.6 2:2.6
1083+ crypt_keyslot_context_set_pin@CRYPTSETUP_2.6 2:2.6
1084 crypt_keyslot_destroy@CRYPTSETUP_2.0 2:1.4
1085 crypt_keyslot_get_encryption@CRYPTSETUP_2.0 2:2.1
1086 crypt_keyslot_get_key_size@CRYPTSETUP_2.0 2:2.0.3
1087@@ -123,6 +133,7 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER#
1088 crypt_token_status@CRYPTSETUP_2.0 2:2.0
1089 crypt_token_unassign_keyslot@CRYPTSETUP_2.0 2:2.0
1090 crypt_volume_key_get@CRYPTSETUP_2.0 2:1.4
1091+ crypt_volume_key_get_by_keyslot_context@CRYPTSETUP_2.6 2:2.6
1092 crypt_volume_key_keyring@CRYPTSETUP_2.0 2:2.0
1093 crypt_volume_key_verify@CRYPTSETUP_2.0 2:1.4
1094 crypt_wipe@CRYPTSETUP_2.0 2:2.0
1095diff --git a/debian/patches/decrease_memlock_ulimit.patch b/debian/patches/decrease_memlock_ulimit.patch
1096index be9b6ab..30b264a 100644
1097--- a/debian/patches/decrease_memlock_ulimit.patch
1098+++ b/debian/patches/decrease_memlock_ulimit.patch
1099@@ -8,6 +8,7 @@ Author: Guilherme G. Piccoli <gpiccoli@canonical.com>
1100 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891473
1101 Last-Update: 2020-09-09
1102
1103+<<<<<<< debian/patches/decrease_memlock_ulimit.patch
1104 Index: cryptsetup-2.3.3/tests/compat-test
1105 ===================================================================
1106 --- cryptsetup-2.3.3.orig/tests/compat-test
1107@@ -15,6 +16,13 @@ Index: cryptsetup-2.3.3/tests/compat-test
1108 @@ -45,6 +45,10 @@ TEST_UUID="12345678-1234-1234-1234-12345
1109 LOOPDEV=$(losetup -f 2>/dev/null)
1110 [ -f /etc/system-fips ] && FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
1111+=======
1112+--- a/tests/compat-test
1113++++ b/tests/compat-test
1114+@@ -47,6 +47,10 @@
1115+ LOOPDEV=$(losetup -f 2>/dev/null)
1116+ FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
1117+>>>>>>> debian/patches/decrease_memlock_ulimit.patch
1118
1119 +# Circumvent test failure due to Bionic builder; we need to decrease
1120 +# the memlock limit here to mimic Xenial builder (see LP #1891473).
1121@@ -23,11 +31,17 @@ Index: cryptsetup-2.3.3/tests/compat-test
1122 function remove_mapping()
1123 {
1124 [ -b /dev/mapper/$DEV_NAME3 ] && dmsetup remove --retry $DEV_NAME3 >/dev/null 2>&1
1125+<<<<<<< debian/patches/decrease_memlock_ulimit.patch
1126 Index: cryptsetup-2.3.3/tests/luks2-validation-test
1127 ===================================================================
1128 --- cryptsetup-2.3.3.orig/tests/luks2-validation-test
1129 +++ cryptsetup-2.3.3/tests/luks2-validation-test
1130 @@ -21,6 +21,10 @@ FAILS=0
1131+=======
1132+--- a/tests/luks2-validation-test
1133++++ b/tests/luks2-validation-test
1134+@@ -21,6 +21,10 @@
1135+>>>>>>> debian/patches/decrease_memlock_ulimit.patch
1136
1137 [ -z "$srcdir" ] && srcdir="."
1138
1139@@ -38,11 +52,17 @@ Index: cryptsetup-2.3.3/tests/luks2-validation-test
1140 function remove_mapping()
1141 {
1142 rm -rf $IMG $TST_IMGS >/dev/null 2>&1
1143+<<<<<<< debian/patches/decrease_memlock_ulimit.patch
1144 Index: cryptsetup-2.3.3/tests/tcrypt-compat-test
1145 ===================================================================
1146 --- cryptsetup-2.3.3.orig/tests/tcrypt-compat-test
1147 +++ cryptsetup-2.3.3/tests/tcrypt-compat-test
1148 @@ -13,6 +13,10 @@ PIM=1234
1149+=======
1150+--- a/tests/tcrypt-compat-test
1151++++ b/tests/tcrypt-compat-test
1152+@@ -16,6 +16,10 @@
1153+>>>>>>> debian/patches/decrease_memlock_ulimit.patch
1154
1155 [ -z "$srcdir" ] && srcdir="."
1156
1157diff --git a/debian/rules b/debian/rules
1158index a8761cd..08074b4 100755
1159--- a/debian/rules
1160+++ b/debian/rules
1161@@ -55,6 +55,10 @@ endif
1162 # generate gettext po files (for luksformat)
1163 $(MAKE) -C debian/scripts/po all luksformat.pot
1164
1165+execute_before_dh_auto_test:
1166+ # tests/fake_token_path.so is built without global $(CFLAGS)
1167+ @echo "blhc: ignore-line-regexp: gcc\\s.*\\s\\.\\./tests/[0-9A-Za-z_-]+\\.c\\s.*"
1168+
1169 execute_after_dh_auto_install:
1170 # install gettext po files (for luksformat)
1171 $(MAKE) -C debian/scripts/po DESTDIR=$(CURDIR)/debian/cryptsetup-bin install
1172diff --git a/debian/upstream/metadata b/debian/upstream/metadata
1173index 639d138..abb325c 100644
1174--- a/debian/upstream/metadata
1175+++ b/debian/upstream/metadata
1176@@ -1,5 +1,6 @@
1177-Bug-Database: https://gitlab.com/cryptsetup/cryptsetup/issues
1178-Bug-Submit: https://gitlab.com/cryptsetup/cryptsetup/issues/new
1179+Bug-Database: https://gitlab.com/cryptsetup/cryptsetup/-/issues
1180+Bug-Submit: https://gitlab.com/cryptsetup/cryptsetup/-/issues/new
1181 Repository: https://gitlab.com/cryptsetup/cryptsetup.git
1182 Repository-Browse: https://gitlab.com/cryptsetup/cryptsetup
1183 FAQ: https://gitlab.com/cryptsetup/cryptsetup/-/wikis/FrequentlyAskedQuestions
1184+Security-Contact: https://gitlab.com/cryptsetup/cryptsetup/-/blob/HEAD/SECURITY.md
1185diff --git a/docs/examples/crypt_log_usage.c b/docs/examples/crypt_log_usage.c
1186index aced85c..3d08c34 100644
1187--- a/docs/examples/crypt_log_usage.c
1188+++ b/docs/examples/crypt_log_usage.c
1189@@ -1,7 +1,7 @@
1190 /*
1191 * libcryptsetup API log example
1192 *
1193- * Copyright (C) 2011-2022 Red Hat, Inc. All rights reserved.
1194+ * Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
1195 *
1196 * This file is free software; you can redistribute it and/or
1197 * modify it under the terms of the GNU Lesser General Public
1198diff --git a/docs/examples/crypt_luks_usage.c b/docs/examples/crypt_luks_usage.c
1199index acde553..d7779bd 100644
1200--- a/docs/examples/crypt_luks_usage.c
1201+++ b/docs/examples/crypt_luks_usage.c
1202@@ -1,7 +1,7 @@
1203 /*
1204 * libcryptsetup API - using LUKS device example
1205 *
1206- * Copyright (C) 2011-2022 Red Hat, Inc. All rights reserved.
1207+ * Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
1208 *
1209 * This file is free software; you can redistribute it and/or
1210 * modify it under the terms of the GNU Lesser General Public
1211diff --git a/docs/v2.6.0-ReleaseNotes b/docs/v2.6.0-ReleaseNotes
1212new file mode 100644
1213index 0000000..6303945
1214--- /dev/null
1215+++ b/docs/v2.6.0-ReleaseNotes
1216@@ -0,0 +1,236 @@
1217+Cryptsetup 2.6.0 Release Notes
1218+==============================
1219+Stable release with new features and bug fixes.
1220+
1221+Changes since version 2.5.0
1222+~~~~~~~~~~~~~~~~~~~~~~~~~~~
1223+
1224+* Introduce support for handling macOS FileVault2 devices (FVAULT2).
1225+
1226+ Cryptsetup now supports the mapping of FileVault2 full-disk encryption
1227+ by Apple for the macOS operating system using a native Linux kernel.
1228+ You can open an existing USB FileVault portable device and (with
1229+ the hfsplus filesystem driver) access the native data read/write.
1230+
1231+ Cryptsetup supports only (legacy) FileVault2 based on Core Storage
1232+ and HFS+ filesystem (introduced in MacOS X 10.7 Lion).
1233+ It does NOT support the new version of FileVault based on the APFS
1234+ filesystem used in recent macOS versions.
1235+
1236+ Header formatting and changes are not supported; cryptsetup never
1237+ changes the metadata on the device.
1238+
1239+ FVAULT2 extension requires kernel userspace crypto API and kernel
1240+ driver for HFS+ (hfsplus) filesystem (available on most systems today).
1241+
1242+ Example of using FileVault2 formatted USB device:
1243+
1244+ A typical encrypted device contains three partitions; the FileVault
1245+ encrypted partition is here sda2:
1246+
1247+ $ lsblk -o NAME,FSTYPE,LABEL /dev/sda
1248+ NAME FSTYPE LABEL
1249+ sda
1250+ |-sda1 vfat EFI
1251+ |-sda2
1252+ `-sda3 hfsplus Boot OS X
1253+
1254+ Note: blkid does not recognize FileVault2 format yet.
1255+
1256+ To dump metadata information about the device, you can use
1257+ the fvault2Dump command:
1258+
1259+ $ cryptsetup fvault2Dump /dev/sda2
1260+ Header information for FVAULT2 device /dev/sda2.
1261+ Physical volume UUID: 6f353c05-daae-4e76-a0ee-6a9569a22d81
1262+ Family UUID: f82cceb0-a788-4815-945a-53d57fcd55a8
1263+ Logical volume offset: 67108864 [bytes]
1264+ Logical volume size: 3288334336 [bytes]
1265+ Cipher: aes
1266+ Cipher mode: xts-plain64
1267+ PBKDF2 iterations: 97962
1268+ PBKDF2 salt: 173a4ec7447662ec79ca7a47df6c2a01
1269+
1270+ To activate the device, use open --type fvault2 option:
1271+
1272+ $ cryptsetup open --type fvault2 /dev/sda2 test
1273+ Enter passphrase for /dev/sda2: ...
1274+
1275+ And check the status of the active device:
1276+
1277+ $ cryptsetup status test
1278+ /dev/mapper/test is active.
1279+ type: FVAULT2
1280+ cipher: aes-xts-plain64
1281+ keysize: 256 bits
1282+ key location: dm-crypt
1283+ device: /dev/sda2
1284+ sector size: 512
1285+ offset: 131072 sectors
1286+ size: 6422528 sectors
1287+ mode: read/write
1288+
1289+ Now, if the kernel contains hfsplus filesystem driver, you can mount
1290+ decrypted content:
1291+
1292+ $ mount /dev/mapper/test /mnt/test
1293+
1294+ For more info about implementation, please refer to the master thesis
1295+ by Pavel Tobias, which was the source for this extension.
1296+ https://is.muni.cz/th/p0aok/?lang=en
1297+
1298+* libcryptsetup: no longer use global memory locking through mlockall()
1299+
1300+ For many years, libcryptsetup locked all memory (including dependent
1301+ library address space) to prevent swapping sensitive content outside
1302+ of RAM.
1303+
1304+ This strategy no longer works as the locking of basic libraries exceeds
1305+ the memory locking limit if running as a non-root user.
1306+
1307+ Libcryptsetup now locks only memory ranges containing sensitive
1308+ material (keys) through crypt_safe_alloc() calls.
1309+
1310+ This change solves many reported mysterious problems of unexpected
1311+ failures. If the initial lock was still under the limit and succeeded,
1312+ some following memory allocation could fail later as it exceeded
1313+ the locking limit. If the initial locking fails, memory locking
1314+ was quietly ignored completely.
1315+
1316+ The whole crypt_memory_lock() API call is deprecated; it no longer
1317+ calls memlockall().
1318+
1319+* libcryptsetup: process priority is increased only for key derivation
1320+ (PBKDF) calls.
1321+
1322+ Increasing priority was tight to memory locking and works only if
1323+ running under superuser.
1324+ Only PBKDF calls and benchmarking now increase the process priority.
1325+
1326+* Add new LUKS keyslot context handling functions and API.
1327+
1328+ In practice, the luksAddKey action does two operations.
1329+ It unlocks the existing device volume key and stores the unlocked
1330+ volume key in a new keyslot.
1331+ Previously the options were limited to key files and passphrases.
1332+
1333+ Newly available methods (keyslot contexts) are passphrase, keyfile,
1334+ key (binary representation), and LUKS2 token.
1335+
1336+ To unlock a keyslot user may:
1337+ - provide existing passphrase via interactive prompt (default method)
1338+ - use --key-file option to provide a file with a valid passphrase
1339+ - provide volume key directly via --volume-key-file
1340+ - unlock keyslot via all available LUKS2 tokens by --token-only
1341+ - unlock keyslot via specific token with --token-id
1342+ - unlock keyslot via specific token type by --token-type
1343+
1344+ To provide the passphrase for a new keyslot, a user may:
1345+ - provide existing passphrase via interactive prompt (default method)
1346+ - use --new-keyfile to read the passphrase from the file
1347+ - use --new-token-id to select LUKS2 token to get passphrase
1348+ for new keyslot. The new keyslot is assigned to the selected token
1349+ id if the operation is successful.
1350+
1351+* The volume key may now be extracted using a passphrase, keyfile, or
1352+ token. For LUKS devices, it also returns the volume key after
1353+ a successful crypt_format call.
1354+
1355+* Fix --disable-luks2-reencryption configuration option.
1356+
1357+* cryptsetup: Print a better error message and warning if the format
1358+ produces an image without space available for data.
1359+
1360+ Activation now fails early with a more descriptive message.
1361+
1362+* Print error if anti-forensic LUKS2 hash setting is not available.
1363+ If the specified hash was not available, activation quietly failed.
1364+
1365+* Fix internal crypt segment compare routine if the user
1366+ specified cipher in kernel format (capi: prefix).
1367+
1368+* cryptsetup: Add token unassign action.
1369+
1370+ This action allows removing token binding on specific keyslot.
1371+
1372+* veritysetup: add support for --use-tasklets option.
1373+
1374+ This option sets try_verify_in_tasklet kernel dm-verity option
1375+ (available since Linux kernel 6.0) to allow some performance
1376+ improvement on specific systems.
1377+
1378+* Provide pkgconfig Require.private settings.
1379+
1380+ While we do not completely provide static build on udev systems,
1381+ it helps produce statically linked binaries in certain situations.
1382+
1383+* Always update automake library files if autogen.sh is run.
1384+
1385+ For several releases, we distributed older automake scripts by mistake.
1386+
1387+* reencryption: Fix user defined moved segment size in LUKS2 decryption.
1388+
1389+ The --hotzone-size argument was ignored in cases where the actual data
1390+ size was less than the original LUKS2 data offset.
1391+
1392+* Delegate FIPS mode detection to configured crypto backend.
1393+ System FIPS mode check no longer depends on /etc/system-fips file.
1394+
1395+* tests: externally provided systemd plugin is now optionally compiled
1396+ from systemd git and tested with cryptsetup
1397+
1398+* tests: initial integration to OSS-fuzz project with basic crypt_load()
1399+ test for LUKS2 and JSON mutated fuzzing.
1400+
1401+ For more info, see README in tests/fuzz directory.
1402+
1403+* Update documentation, including FAQ and man pages.
1404+
1405+Libcryptsetup API extensions
1406+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1407+The libcryptsetup API is backward compatible with existing symbols.
1408+
1409+New symbols:
1410+ crypt_keyslot_context_init_by_passphrase
1411+ crypt_keyslot_context_init_by_keyfile
1412+ crypt_keyslot_context_init_by_token
1413+ crypt_keyslot_context_init_by_volume_key
1414+ crypt_keyslot_context_get_error
1415+ crypt_keyslot_context_set_pin
1416+ crypt_keyslot_context_get_type
1417+ crypt_keyslot_context_free
1418+ crypt_keyslot_add_by_keyslot_context
1419+ crypt_volume_key_get_by_keyslot_context
1420+
1421+New defines:
1422+ CRYPT_FVAULT2 "FVAULT2" (FileVault2 compatible mode)
1423+
1424+Keyslot context types:
1425+ CRYPT_KC_TYPE_PASSPHRASE
1426+ CRYPT_KC_TYPE_KEYFILE
1427+ CRYPT_KC_TYPE_TOKEN
1428+ CRYPT_KC_TYPE_KEY
1429+
1430+ CRYPT_ACTIVATE_TASKLETS (dm-verity: use tasklets activation flag)
1431+
1432+WARNING!
1433+~~~~~~~~
1434+The next version of cryptsetup will change the encryption mode and key
1435+derivation option for the PLAIN format.
1436+
1437+This change will cause backward incompatibility.
1438+For this reason, the user will have to specify the exact parameters
1439+for cipher, key size, and key derivation parameters for plain format.
1440+
1441+The default encryption mode will be AES-XTS with 512bit key (AES-256).
1442+The CBC mode is no longer considered the best default, as it allows easy
1443+bit-flipped ciphertext modification attacks and performance problems.
1444+
1445+For the passphrase hashing in plain mode, the encryption key is directly
1446+derived through iterative hashing from a user-provided passphrase
1447+(except a keyfile that is not hashed).
1448+
1449+The default hash is RIPEMD160, which is no longer the best default
1450+option. The exact change will be yet discussed but should include
1451+the possibility of using a password-based key derivation function
1452+instead of iterative hashing.
1453diff --git a/docs/v2.6.1-ReleaseNotes b/docs/v2.6.1-ReleaseNotes
1454new file mode 100644
1455index 0000000..82012b9
1456--- /dev/null
1457+++ b/docs/v2.6.1-ReleaseNotes
1458@@ -0,0 +1,50 @@
1459+Cryptsetup 2.6.1 Release Notes
1460+==============================
1461+Stable bug-fix release with minor extensions.
1462+
1463+All users of cryptsetup 2.6.0 should upgrade to this version.
1464+
1465+Changes since version 2.6.0
1466+~~~~~~~~~~~~~~~~~~~~~~~~~~~
1467+
1468+* bitlk: Fixes for BitLocker-compatible on-disk metadata parser
1469+ (found by new cryptsetup OSS-Fuzz fuzzers).
1470+ - Fix a possible memory leak if the metadata contains more than
1471+ one description field.
1472+ - Harden parsing of metadata entries for key and description entries.
1473+ - Fix broken metadata parsing that can cause a crash or out of memory.
1474+
1475+* Fix possible iteration overflow in OpenSSL2 PBKDF2 crypto backend.
1476+ OpenSSL2 uses a signed integer for PBKDF2 iteration count.
1477+ As cryptsetup uses an unsigned value, this can lead to overflow and
1478+ a decrease in the actual iteration count.
1479+ This situation can happen only if the user specifies
1480+ --pbkdf-force-iterations option.
1481+ OpenSSL3 (and other supported crypto backends) are not affected.
1482+
1483+* Fix compilation for new ISO C standards (gcc with -std=c11 and higher).
1484+
1485+* fvault2: Fix compilation with very old uuid.h.
1486+
1487+* verity: Fix possible hash offset setting overflow.
1488+
1489+* bitlk: Fix use of startup BEK key on big-endian platforms.
1490+
1491+* Fix compilation with latest musl library.
1492+ Recent musl no longer implements lseek64() in some configurations.
1493+ Use lseek() as 64-bit offset is mandatory for cryptsetup.
1494+
1495+* Do not initiate encryption (reencryption command) when the header and
1496+ data devices are the same.
1497+ If data device reduction is not requsted, this leads to data corruption
1498+ since LUKS metadata was written over the data device.
1499+
1500+* Fix possible memory leak if crypt_load() fails.
1501+
1502+* Always use passphrases with a minimal 8 chars length for benchmarking.
1503+ Some enterprise distributions decided to set an unconditional check
1504+ for PBKDF2 password length when running in FIPS mode.
1505+ This questionable change led to unexpected failures during LUKS format
1506+ and keyslot operations, where short passwords were used for
1507+ benchmarking PBKDF2 speed.
1508+ PBKDF2 benchmark calculations should not be affected by this change.
1509diff --git a/lib/Makemodule.am b/lib/Makemodule.am
1510index 2ebbae1..2e60a90 100644
1511--- a/lib/Makemodule.am
1512+++ b/lib/Makemodule.am
1513@@ -53,8 +53,6 @@ libcryptsetup_la_SOURCES = \
1514 lib/utils_loop.h \
1515 lib/utils_devpath.c \
1516 lib/utils_wipe.c \
1517- lib/utils_fips.c \
1518- lib/utils_fips.h \
1519 lib/utils_device.c \
1520 lib/utils_keyring.c \
1521 lib/utils_keyring.h \
1522@@ -75,6 +73,8 @@ libcryptsetup_la_SOURCES = \
1523 lib/loopaes/loopaes.c \
1524 lib/tcrypt/tcrypt.h \
1525 lib/tcrypt/tcrypt.c \
1526+ lib/keyslot_context.h \
1527+ lib/keyslot_context.c \
1528 lib/luks1/af.h \
1529 lib/luks1/af.c \
1530 lib/luks1/keyencryption.c \
1531@@ -106,4 +106,6 @@ libcryptsetup_la_SOURCES = \
1532 lib/utils_blkid.c \
1533 lib/utils_blkid.h \
1534 lib/bitlk/bitlk.h \
1535- lib/bitlk/bitlk.c
1536+ lib/bitlk/bitlk.c \
1537+ lib/fvault2/fvault2.h \
1538+ lib/fvault2/fvault2.c
1539diff --git a/lib/bitlk/bitlk.c b/lib/bitlk/bitlk.c
1540index 3548d10..de7bcea 100644
1541--- a/lib/bitlk/bitlk.c
1542+++ b/lib/bitlk/bitlk.c
1543@@ -1,9 +1,9 @@
1544 /*
1545 * BITLK (BitLocker-compatible) volume handling
1546 *
1547- * Copyright (C) 2019-2022 Red Hat, Inc. All rights reserved.
1548- * Copyright (C) 2019-2022 Milan Broz
1549- * Copyright (C) 2019-2022 Vojtech Trefny
1550+ * Copyright (C) 2019-2023 Red Hat, Inc. All rights reserved.
1551+ * Copyright (C) 2019-2023 Milan Broz
1552+ * Copyright (C) 2019-2023 Vojtech Trefny
1553 *
1554 * This file is free software; you can redistribute it and/or
1555 * modify it under the terms of the GNU Lesser General Public
1556@@ -255,13 +255,16 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
1557 (*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
1558 (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY;
1559
1560- while (end - start > 2) {
1561+ while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
1562 /* size of this entry */
1563 memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
1564 key_entry_size = le16_to_cpu(key_entry_size);
1565 if (key_entry_size == 0)
1566 break;
1567
1568+ if (key_entry_size > (end - start))
1569+ return -EINVAL;
1570+
1571 /* type and value of this entry */
1572 memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
1573 memcpy(&key_entry_value,
1574@@ -280,20 +283,24 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
1575 }
1576
1577 /* stretch key with salt, skip 4 B (encryption method of the stretch key) */
1578- if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY)
1579+ if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY) {
1580+ if ((end - start) < (BITLK_ENTRY_HEADER_LEN + BITLK_SALT_SIZE + 4))
1581+ return -EINVAL;
1582 memcpy((*vmk)->salt,
1583 data + start + BITLK_ENTRY_HEADER_LEN + 4,
1584- sizeof((*vmk)->salt));
1585+ BITLK_SALT_SIZE);
1586 /* AES-CCM encrypted key */
1587- else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
1588+ } else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
1589+ if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE))
1590+ return -EINVAL;
1591 /* nonce */
1592 memcpy((*vmk)->nonce,
1593 data + start + BITLK_ENTRY_HEADER_LEN,
1594- sizeof((*vmk)->nonce));
1595+ BITLK_NONCE_SIZE);
1596 /* MAC tag */
1597 memcpy((*vmk)->mac_tag,
1598 data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
1599- sizeof((*vmk)->mac_tag));
1600+ BITLK_VMK_MAC_TAG_SIZE);
1601 /* AES-CCM encrypted key */
1602 key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
1603 key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
1604@@ -318,6 +325,8 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
1605 } else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
1606 ;
1607 } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
1608+ if (key_entry_size < BITLK_ENTRY_HEADER_LEN)
1609+ return -EINVAL;
1610 string = malloc((key_entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
1611 if (!string)
1612 return -ENOMEM;
1613@@ -405,6 +414,7 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
1614 struct bitlk_fve_metadata fve = {};
1615 struct bitlk_entry_vmk entry_vmk = {};
1616 uint8_t *fve_entries = NULL;
1617+ size_t fve_entries_size = 0;
1618 uint32_t fve_metadata_size = 0;
1619 int fve_offset = 0;
1620 char guid_buf[UUID_STR_LEN] = {0};
1621@@ -413,7 +423,6 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
1622 int i = 0;
1623 int r = 0;
1624 int start = 0;
1625- int end = 0;
1626 size_t key_size = 0;
1627 const char *key = NULL;
1628 char *description = NULL;
1629@@ -514,7 +523,6 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
1630
1631 params->volume_size = le64_to_cpu(fve.volume_size);
1632 params->metadata_version = le16_to_cpu(fve.fve_version);
1633- fve_metadata_size = le32_to_cpu(fve.metadata_size);
1634
1635 switch (le16_to_cpu(fve.encryption)) {
1636 /* AES-CBC with Elephant difuser */
1637@@ -569,40 +577,56 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
1638
1639 params->creation_time = filetime_to_unixtime(le64_to_cpu(fve.creation_time));
1640
1641+ fve_metadata_size = le32_to_cpu(fve.metadata_size);
1642+ if (fve_metadata_size < (BITLK_FVE_METADATA_HEADER_LEN + sizeof(entry_size) + sizeof(entry_type)) ||
1643+ fve_metadata_size > BITLK_FVE_METADATA_SIZE) {
1644+ r = -EINVAL;
1645+ goto out;
1646+ }
1647+ fve_entries_size = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
1648+
1649 /* read and parse all FVE metadata entries */
1650- fve_entries = malloc(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN);
1651+ fve_entries = malloc(fve_entries_size);
1652 if (!fve_entries) {
1653 r = -ENOMEM;
1654 goto out;
1655 }
1656- memset(fve_entries, 0, (fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN));
1657+ memset(fve_entries, 0, fve_entries_size);
1658
1659- log_dbg(cd, "Reading BITLK FVE metadata entries of size %" PRIu32 " on device %s, offset %" PRIu64 ".",
1660- fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN, device_path(device),
1661- params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
1662+ log_dbg(cd, "Reading BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".",
1663+ fve_entries_size, device_path(device), params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
1664
1665 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
1666- device_alignment(device), fve_entries, fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN,
1667- params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN)) {
1668+ device_alignment(device), fve_entries, fve_entries_size,
1669+ params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)fve_entries_size) {
1670 log_err(cd, _("Failed to read BITLK metadata entries from %s."), device_path(device));
1671 r = -EINVAL;
1672 goto out;
1673 }
1674
1675- end = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
1676- while (end - start > 2) {
1677+ while ((fve_entries_size - start) >= (sizeof(entry_size) + sizeof(entry_type))) {
1678+
1679 /* size of this entry */
1680 memcpy(&entry_size, fve_entries + start, sizeof(entry_size));
1681 entry_size = le16_to_cpu(entry_size);
1682 if (entry_size == 0)
1683 break;
1684
1685+ if (entry_size > (fve_entries_size - start)) {
1686+ r = -EINVAL;
1687+ goto out;
1688+ }
1689+
1690 /* type of this entry */
1691 memcpy(&entry_type, fve_entries + start + sizeof(entry_size), sizeof(entry_type));
1692 entry_type = le16_to_cpu(entry_type);
1693
1694 /* VMK */
1695 if (entry_type == BITLK_ENTRY_TYPE_VMK) {
1696+ if (entry_size < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_vmk))) {
1697+ r = -EINVAL;
1698+ goto out;
1699+ }
1700 /* skip first four variables in the entry (entry size, type, value and version) */
1701 memcpy(&entry_vmk,
1702 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
1703@@ -639,7 +663,11 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
1704 vmk_p = vmk;
1705 vmk = vmk->next;
1706 /* FVEK */
1707- } else if (entry_type == BITLK_ENTRY_TYPE_FVEK) {
1708+ } else if (entry_type == BITLK_ENTRY_TYPE_FVEK && !params->fvek) {
1709+ if (entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE)) {
1710+ r = -EINVAL;
1711+ goto out;
1712+ }
1713 params->fvek = malloc(sizeof(struct bitlk_fvek));
1714 if (!params->fvek) {
1715 r = -ENOMEM;
1716@@ -647,11 +675,11 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
1717 }
1718 memcpy(params->fvek->nonce,
1719 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
1720- sizeof(params->fvek->nonce));
1721+ BITLK_NONCE_SIZE);
1722 /* MAC tag */
1723 memcpy(params->fvek->mac_tag,
1724 fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
1725- sizeof(params->fvek->mac_tag));
1726+ BITLK_VMK_MAC_TAG_SIZE);
1727 /* AES-CCM encrypted key */
1728 key_size = entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
1729 key = (const char *) fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
1730@@ -663,19 +691,29 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
1731 /* volume header info (location and size) */
1732 } else if (entry_type == BITLK_ENTRY_TYPE_VOLUME_HEADER) {
1733 struct bitlk_entry_header_block entry_header;
1734+ if ((fve_entries_size - start) < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_header))) {
1735+ r = -EINVAL;
1736+ goto out;
1737+ }
1738 memcpy(&entry_header,
1739 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
1740 sizeof(entry_header));
1741 params->volume_header_offset = le64_to_cpu(entry_header.offset);
1742 params->volume_header_size = le64_to_cpu(entry_header.size);
1743 /* volume description (utf-16 string) */
1744- } else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION) {
1745- description = malloc((entry_size - BITLK_ENTRY_HEADER_LEN - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
1746- if (!description)
1747- return -ENOMEM;
1748+ } else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION && !params->description) {
1749+ if (entry_size < BITLK_ENTRY_HEADER_LEN) {
1750+ r = -EINVAL;
1751+ goto out;
1752+ }
1753+ description = malloc((entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
1754+ if (!description) {
1755+ r = -ENOMEM;
1756+ goto out;
1757+ }
1758 r = crypt_utf16_to_utf8(&description, CONST_CAST(char16_t *)(fve_entries + start + BITLK_ENTRY_HEADER_LEN),
1759 entry_size - BITLK_ENTRY_HEADER_LEN);
1760- if (r < 0 || !description) {
1761+ if (r < 0) {
1762 free(description);
1763 BITLK_bitlk_vmk_free(vmk);
1764 log_err(cd, _("Failed to convert BITLK volume description"));
1765@@ -773,13 +811,13 @@ static int get_recovery_key(struct crypt_device *cd,
1766 - each part is a number dividable by 11
1767 */
1768 if (passwordLen != BITLK_RECOVERY_KEY_LEN) {
1769- if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
1770- /* looks like a recovery key with an extra newline, possibly from a key file */
1771- passwordLen--;
1772- log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
1773- } else
1774- return 0;
1775- }
1776+ if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
1777+ /* looks like a recovery key with an extra newline, possibly from a key file */
1778+ passwordLen--;
1779+ log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
1780+ } else
1781+ return 0;
1782+ }
1783
1784 for (i = BITLK_RECOVERY_PART_LEN; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1) {
1785 if (password[i] != '-')
1786@@ -822,13 +860,16 @@ static int parse_external_key_entry(struct crypt_device *cd,
1787 struct bitlk_guid guid;
1788 char guid_buf[UUID_STR_LEN] = {0};
1789
1790- while (end - start > 2) {
1791+ while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
1792 /* size of this entry */
1793 memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
1794 key_entry_size = le16_to_cpu(key_entry_size);
1795 if (key_entry_size == 0)
1796 break;
1797
1798+ if (key_entry_size > (end - start))
1799+ return -EINVAL;
1800+
1801 /* type and value of this entry */
1802 memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
1803 memcpy(&key_entry_value,
1804@@ -843,6 +884,8 @@ static int parse_external_key_entry(struct crypt_device *cd,
1805 }
1806
1807 if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
1808+ if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + 4))
1809+ return -EINVAL;
1810 key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
1811 key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
1812 *vk = crypt_alloc_volume_key(key_size, key);
1813@@ -854,6 +897,8 @@ static int parse_external_key_entry(struct crypt_device *cd,
1814 ;
1815 /* GUID of the BitLocker device we are trying to open with this key */
1816 else if (key_entry_value == BITLK_ENTRY_VALUE_GUID) {
1817+ if ((end - start) < (ssize_t)(BITLK_ENTRY_HEADER_LEN + sizeof(struct bitlk_guid)))
1818+ return -EINVAL;
1819 memcpy(&guid, data + start + BITLK_ENTRY_HEADER_LEN, sizeof(struct bitlk_guid));
1820 guid_to_string(&guid, guid_buf);
1821 if (strcmp(guid_buf, params->guid) != 0) {
1822@@ -887,7 +932,7 @@ static int get_startup_key(struct crypt_device *cd,
1823 uint16_t key_entry_type = 0;
1824 uint16_t key_entry_value = 0;
1825
1826- if (passwordLen < BITLK_BEK_FILE_HEADER_LEN)
1827+ if (passwordLen < (BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value)))
1828 return -EPERM;
1829
1830 memcpy(&bek_header, password, BITLK_BEK_FILE_HEADER_LEN);
1831@@ -899,13 +944,14 @@ static int get_startup_key(struct crypt_device *cd,
1832 else
1833 return -EPERM;
1834
1835- if (bek_header.metadata_version != 1) {
1836- log_err(cd, _("Unsupported BEK metadata version %" PRIu32), bek_header.metadata_version);
1837+ if (le32_to_cpu(bek_header.metadata_version) != 1) {
1838+ log_err(cd, _("Unsupported BEK metadata version %" PRIu32), le32_to_cpu(bek_header.metadata_version));
1839 return -ENOTSUP;
1840 }
1841
1842- if (bek_header.metadata_size != passwordLen) {
1843- log_err(cd, _("Unexpected BEK metadata size %" PRIu32 " does not match BEK file length"), bek_header.metadata_size);
1844+ if (le32_to_cpu(bek_header.metadata_size) != passwordLen) {
1845+ log_err(cd, _("Unexpected BEK metadata size %" PRIu32 " does not match BEK file length"),
1846+ le32_to_cpu(bek_header.metadata_size));
1847 return -EINVAL;
1848 }
1849
1850diff --git a/lib/bitlk/bitlk.h b/lib/bitlk/bitlk.h
1851index 5b54271..54d3dc7 100644
1852--- a/lib/bitlk/bitlk.h
1853+++ b/lib/bitlk/bitlk.h
1854@@ -1,9 +1,9 @@
1855 /*
1856 * BITLK (BitLocker-compatible) header definition
1857 *
1858- * Copyright (C) 2019-2022 Red Hat, Inc. All rights reserved.
1859- * Copyright (C) 2019-2022 Milan Broz
1860- * Copyright (C) 2019-2022 Vojtech Trefny
1861+ * Copyright (C) 2019-2023 Red Hat, Inc. All rights reserved.
1862+ * Copyright (C) 2019-2023 Milan Broz
1863+ * Copyright (C) 2019-2023 Vojtech Trefny
1864 *
1865 * This file is free software; you can redistribute it and/or
1866 * modify it under the terms of the GNU Lesser General Public
1867diff --git a/lib/crypt_plain.c b/lib/crypt_plain.c
1868index fc4873b..c839b09 100644
1869--- a/lib/crypt_plain.c
1870+++ b/lib/crypt_plain.c
1871@@ -2,8 +2,8 @@
1872 * cryptsetup plain device helper functions
1873 *
1874 * Copyright (C) 2004 Jana Saout <jana@saout.de>
1875- * Copyright (C) 2010-2022 Red Hat, Inc. All rights reserved.
1876- * Copyright (C) 2010-2022 Milan Broz
1877+ * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
1878+ * Copyright (C) 2010-2023 Milan Broz
1879 *
1880 * This program is free software; you can redistribute it and/or
1881 * modify it under the terms of the GNU General Public License
1882diff --git a/lib/crypto_backend/argon2_generic.c b/lib/crypto_backend/argon2_generic.c
1883index 663dd71..0ce67da 100644
1884--- a/lib/crypto_backend/argon2_generic.c
1885+++ b/lib/crypto_backend/argon2_generic.c
1886@@ -1,8 +1,8 @@
1887 /*
1888 * Argon2 PBKDF2 library wrapper
1889 *
1890- * Copyright (C) 2016-2022 Red Hat, Inc. All rights reserved.
1891- * Copyright (C) 2016-2022 Milan Broz
1892+ * Copyright (C) 2016-2023 Red Hat, Inc. All rights reserved.
1893+ * Copyright (C) 2016-2023 Milan Broz
1894 *
1895 * This file is free software; you can redistribute it and/or
1896 * modify it under the terms of the GNU Lesser General Public
1897diff --git a/lib/crypto_backend/base64.c b/lib/crypto_backend/base64.c
1898index af5e927..42f70cb 100644
1899--- a/lib/crypto_backend/base64.c
1900+++ b/lib/crypto_backend/base64.c
1901@@ -4,7 +4,7 @@
1902 * Copyright (C) 2010 Lennart Poettering
1903 *
1904 * cryptsetup related changes
1905- * Copyright (C) 2021-2022 Milan Broz
1906+ * Copyright (C) 2021-2023 Milan Broz
1907 *
1908 * This file is free software; you can redistribute it and/or
1909 * modify it under the terms of the GNU Lesser General Public
1910@@ -24,7 +24,6 @@
1911 #include <errno.h>
1912 #include <stdlib.h>
1913 #include <limits.h>
1914-#include <assert.h>
1915
1916 #include "crypto_backend.h"
1917
1918diff --git a/lib/crypto_backend/cipher_check.c b/lib/crypto_backend/cipher_check.c
1919index 9a972f5..98ec1a5 100644
1920--- a/lib/crypto_backend/cipher_check.c
1921+++ b/lib/crypto_backend/cipher_check.c
1922@@ -1,8 +1,8 @@
1923 /*
1924 * Cipher performance check
1925 *
1926- * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved.
1927- * Copyright (C) 2018-2022 Milan Broz
1928+ * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
1929+ * Copyright (C) 2018-2023 Milan Broz
1930 *
1931 * This file is free software; you can redistribute it and/or
1932 * modify it under the terms of the GNU Lesser General Public
1933diff --git a/lib/crypto_backend/cipher_generic.c b/lib/crypto_backend/cipher_generic.c
1934index 0623a78..b3a4407 100644
1935--- a/lib/crypto_backend/cipher_generic.c
1936+++ b/lib/crypto_backend/cipher_generic.c
1937@@ -1,8 +1,8 @@
1938 /*
1939 * Linux kernel cipher generic utilities
1940 *
1941- * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved.
1942- * Copyright (C) 2018-2022 Milan Broz
1943+ * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
1944+ * Copyright (C) 2018-2023 Milan Broz
1945 *
1946 * This file is free software; you can redistribute it and/or
1947 * modify it under the terms of the GNU Lesser General Public
1948diff --git a/lib/crypto_backend/crc32.c b/lib/crypto_backend/crc32.c
1949index 9d43623..9009b02 100644
1950--- a/lib/crypto_backend/crc32.c
1951+++ b/lib/crypto_backend/crc32.c
1952@@ -97,12 +97,71 @@ static const uint32_t crc32_tab[] = {
1953 0x2d02ef8dL
1954 };
1955
1956+static const uint32_t crc32c_tab[] = {
1957+ 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL,
1958+ 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL,
1959+ 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L,
1960+ 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
1961+ 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L,
1962+ 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL,
1963+ 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L,
1964+ 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
1965+ 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
1966+ 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L,
1967+ 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L,
1968+ 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
1969+ 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL,
1970+ 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L,
1971+ 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L,
1972+ 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
1973+ 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL,
1974+ 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
1975+ 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L,
1976+ 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
1977+ 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL,
1978+ 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L,
1979+ 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL,
1980+ 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
1981+ 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL,
1982+ 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL,
1983+ 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
1984+ 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
1985+ 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L,
1986+ 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL,
1987+ 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL,
1988+ 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
1989+ 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L,
1990+ 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL,
1991+ 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L,
1992+ 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
1993+ 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L,
1994+ 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL,
1995+ 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L,
1996+ 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
1997+ 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L,
1998+ 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L,
1999+ 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L,
2000+ 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
2001+ 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
2002+ 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L,
2003+ 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L,
2004+ 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
2005+ 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL,
2006+ 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L,
2007+ 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L,
2008+ 0xAD7D5351L
2009+};
2010+
2011 /*
2012 * This a generic crc32() function, it takes seed as an argument,
2013 * and does __not__ xor at the end. Then individual users can do
2014 * whatever they need.
2015 */
2016-uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
2017+static uint32_t compute_crc32(
2018+ const uint32_t *crc32_tab,
2019+ uint32_t seed,
2020+ const unsigned char *buf,
2021+ size_t len)
2022 {
2023 uint32_t crc = seed;
2024 const unsigned char *p = buf;
2025@@ -112,3 +171,13 @@ uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
2026
2027 return crc;
2028 }
2029+
2030+uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
2031+{
2032+ return compute_crc32(crc32_tab, seed, buf, len);
2033+}
2034+
2035+uint32_t crypt_crc32c(uint32_t seed, const unsigned char *buf, size_t len)
2036+{
2037+ return compute_crc32(crc32c_tab, seed, buf, len);
2038+}
2039diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h
2040index 9bfa65a..88562e9 100644
2041--- a/lib/crypto_backend/crypto_backend.h
2042+++ b/lib/crypto_backend/crypto_backend.h
2043@@ -1,8 +1,8 @@
2044 /*
2045 * crypto backend implementation
2046 *
2047- * Copyright (C) 2010-2022 Red Hat, Inc. All rights reserved.
2048- * Copyright (C) 2010-2022 Milan Broz
2049+ * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
2050+ * Copyright (C) 2010-2023 Milan Broz
2051 *
2052 * This file is free software; you can redistribute it and/or
2053 * modify it under the terms of the GNU Lesser General Public
2054@@ -21,6 +21,7 @@
2055 #ifndef _CRYPTO_BACKEND_H
2056 #define _CRYPTO_BACKEND_H
2057
2058+#include <assert.h>
2059 #include <stdint.h>
2060 #include <stdbool.h>
2061 #include <stddef.h>
2062@@ -40,7 +41,8 @@ struct crypt_storage;
2063 int crypt_backend_init(bool fips);
2064 void crypt_backend_destroy(void);
2065
2066-#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
2067+#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
2068+#define CRYPT_BACKEND_PBKDF2_INT (1 << 1) /* Iteration in PBKDF2 is signed int and can overflow */
2069
2070 uint32_t crypt_backend_flags(void);
2071 const char *crypt_backend_version(void);
2072@@ -88,6 +90,7 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
2073
2074 /* CRC32 */
2075 uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
2076+uint32_t crypt_crc32c(uint32_t seed, const unsigned char *buf, size_t len);
2077
2078 /* Base64 */
2079 int crypt_base64_encode(char **out, size_t *out_length, const char *in, size_t in_length);
2080@@ -152,4 +155,7 @@ static inline void crypt_backend_memzero(void *s, size_t n)
2081 /* Memcmp helper (memcmp in constant time) */
2082 int crypt_backend_memeq(const void *m1, const void *m2, size_t n);
2083
2084+/* crypto backend running in FIPS mode */
2085+bool crypt_fips_mode(void);
2086+
2087 #endif /* _CRYPTO_BACKEND_H */
2088diff --git a/lib/crypto_backend/crypto_backend_internal.h b/lib/crypto_backend/crypto_backend_internal.h
2089index ce40d3c..9b1cc69 100644
2090--- a/lib/crypto_backend/crypto_backend_internal.h
2091+++ b/lib/crypto_backend/crypto_backend_internal.h
2092@@ -1,8 +1,8 @@
2093 /*
2094 * crypto backend implementation
2095 *
2096- * Copyright (C) 2010-2022 Red Hat, Inc. All rights reserved.
2097- * Copyright (C) 2010-2022 Milan Broz
2098+ * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
2099+ * Copyright (C) 2010-2023 Milan Broz
2100 *
2101 * This file is free software; you can redistribute it and/or
2102 * modify it under the terms of the GNU Lesser General Public
2103diff --git a/lib/crypto_backend/crypto_cipher_kernel.c b/lib/crypto_backend/crypto_cipher_kernel.c
2104index e11c158..3460717 100644
2105--- a/lib/crypto_backend/crypto_cipher_kernel.c
2106+++ b/lib/crypto_backend/crypto_cipher_kernel.c
2107@@ -1,8 +1,8 @@
2108 /*
2109 * Linux kernel userspace API crypto backend implementation (skcipher)
2110 *
2111- * Copyright (C) 2012-2022 Red Hat, Inc. All rights reserved.
2112- * Copyright (C) 2012-2022 Milan Broz
2113+ * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
2114+ * Copyright (C) 2012-2023 Milan Broz
2115 *
2116 * This file is free software; you can redistribute it and/or
2117 * modify it under the terms of the GNU Lesser General Public
2118diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c
2119index 8d9767d..e974aa8 100644
2120--- a/lib/crypto_backend/crypto_gcrypt.c
2121+++ b/lib/crypto_backend/crypto_gcrypt.c
2122@@ -1,8 +1,8 @@
2123 /*
2124 * GCRYPT crypto backend implementation
2125 *
2126- * Copyright (C) 2010-2022 Red Hat, Inc. All rights reserved.
2127- * Copyright (C) 2010-2022 Milan Broz
2128+ * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
2129+ * Copyright (C) 2010-2023 Milan Broz
2130 *
2131 * This file is free software; you can redistribute it and/or
2132 * modify it under the terms of the GNU Lesser General Public
2133@@ -22,7 +22,6 @@
2134 #include <string.h>
2135 #include <stdio.h>
2136 #include <errno.h>
2137-#include <assert.h>
2138 #include <gcrypt.h>
2139 #include "crypto_backend_internal.h"
2140
2141@@ -555,3 +554,20 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
2142 {
2143 return crypt_internal_memeq(m1, m2, n);
2144 }
2145+
2146+#if !ENABLE_FIPS
2147+bool crypt_fips_mode(void) { return false; }
2148+#else
2149+bool crypt_fips_mode(void)
2150+{
2151+ static bool fips_mode = false, fips_checked = false;
2152+
2153+ if (fips_checked)
2154+ return fips_mode;
2155+
2156+ fips_mode = gcry_fips_mode_active();
2157+ fips_checked = true;
2158+
2159+ return fips_mode;
2160+}
2161+#endif /* ENABLE FIPS */
2162diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c
2163index 98f7477..8493c0a 100644
2164--- a/lib/crypto_backend/crypto_kernel.c
2165+++ b/lib/crypto_backend/crypto_kernel.c
2166@@ -1,8 +1,8 @@
2167 /*
2168 * Linux kernel userspace API crypto backend implementation
2169 *
2170- * Copyright (C) 2010-2022 Red Hat, Inc. All rights reserved.
2171- * Copyright (C) 2010-2022 Milan Broz
2172+ * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
2173+ * Copyright (C) 2010-2023 Milan Broz
2174 *
2175 * This file is free software; you can redistribute it and/or
2176 * modify it under the terms of the GNU Lesser General Public
2177@@ -421,3 +421,8 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
2178 {
2179 return crypt_internal_memeq(m1, m2, n);
2180 }
2181+
2182+bool crypt_fips_mode(void)
2183+{
2184+ return false;
2185+}
2186diff --git a/lib/crypto_backend/crypto_nettle.c b/lib/crypto_backend/crypto_nettle.c
2187index f74b15b..086e4fc 100644
2188--- a/lib/crypto_backend/crypto_nettle.c
2189+++ b/lib/crypto_backend/crypto_nettle.c
2190@@ -1,8 +1,8 @@
2191 /*
2192 * Nettle crypto backend implementation
2193 *
2194- * Copyright (C) 2011-2022 Red Hat, Inc. All rights reserved.
2195- * Copyright (C) 2011-2022 Milan Broz
2196+ * Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
2197+ * Copyright (C) 2011-2023 Milan Broz
2198 *
2199 * This file is free software; you can redistribute it and/or
2200 * modify it under the terms of the GNU Lesser General Public
2201@@ -453,3 +453,8 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
2202 /* The logic is inverse to memcmp... */
2203 return !memeql_sec(m1, m2, n);
2204 }
2205+
2206+bool crypt_fips_mode(void)
2207+{
2208+ return false;
2209+}
2210diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c
2211index ffeba38..c154812 100644
2212--- a/lib/crypto_backend/crypto_nss.c
2213+++ b/lib/crypto_backend/crypto_nss.c
2214@@ -1,8 +1,8 @@
2215 /*
2216 * NSS crypto backend implementation
2217 *
2218- * Copyright (C) 2010-2022 Red Hat, Inc. All rights reserved.
2219- * Copyright (C) 2010-2022 Milan Broz
2220+ * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
2221+ * Copyright (C) 2010-2023 Milan Broz
2222 *
2223 * This file is free software; you can redistribute it and/or
2224 * modify it under the terms of the GNU Lesser General Public
2225@@ -400,3 +400,8 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
2226 {
2227 return NSS_SecureMemcmp(m1, m2, n);
2228 }
2229+
2230+bool crypt_fips_mode(void)
2231+{
2232+ return false;
2233+}
2234diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c
2235index 006c20f..607ec38 100644
2236--- a/lib/crypto_backend/crypto_openssl.c
2237+++ b/lib/crypto_backend/crypto_openssl.c
2238@@ -1,8 +1,8 @@
2239 /*
2240 * OPENSSL crypto backend implementation
2241 *
2242- * Copyright (C) 2010-2022 Red Hat, Inc. All rights reserved.
2243- * Copyright (C) 2010-2022 Milan Broz
2244+ * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
2245+ * Copyright (C) 2010-2023 Milan Broz
2246 *
2247 * This file is free software; you can redistribute it and/or
2248 * modify it under the terms of the GNU Lesser General Public
2249@@ -30,6 +30,7 @@
2250
2251 #include <string.h>
2252 #include <errno.h>
2253+#include <limits.h>
2254 #include <openssl/crypto.h>
2255 #include <openssl/evp.h>
2256 #include <openssl/hmac.h>
2257@@ -231,7 +232,11 @@ void crypt_backend_destroy(void)
2258
2259 uint32_t crypt_backend_flags(void)
2260 {
2261+#if OPENSSL_VERSION_MAJOR >= 3
2262 return 0;
2263+#else
2264+ return CRYPT_BACKEND_PBKDF2_INT;
2265+#endif
2266 }
2267
2268 const char *crypt_backend_version(void)
2269@@ -574,6 +579,10 @@ static int openssl_pbkdf2(const char *password, size_t password_length,
2270 if (!hash_id)
2271 return -EINVAL;
2272
2273+ /* OpenSSL2 has iteration as signed int, avoid overflow */
2274+ if (iterations > INT_MAX)
2275+ return -EINVAL;
2276+
2277 r = PKCS5_PBKDF2_HMAC(password, (int)password_length, (const unsigned char *)salt,
2278 (int)salt_length, iterations, hash_id, (int)key_length, (unsigned char*) key);
2279 #endif
2280@@ -812,3 +821,29 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
2281 {
2282 return CRYPTO_memcmp(m1, m2, n);
2283 }
2284+
2285+#if !ENABLE_FIPS
2286+bool crypt_fips_mode(void) { return false; }
2287+#else
2288+static bool openssl_fips_mode(void)
2289+{
2290+#if OPENSSL_VERSION_MAJOR >= 3
2291+ return EVP_default_properties_is_fips_enabled(NULL);
2292+#else
2293+ return FIPS_mode();
2294+#endif
2295+}
2296+
2297+bool crypt_fips_mode(void)
2298+{
2299+ static bool fips_mode = false, fips_checked = false;
2300+
2301+ if (fips_checked)
2302+ return fips_mode;
2303+
2304+ fips_mode = openssl_fips_mode();
2305+ fips_checked = true;
2306+
2307+ return fips_mode;
2308+}
2309+#endif /* ENABLE FIPS */
2310diff --git a/lib/crypto_backend/crypto_storage.c b/lib/crypto_backend/crypto_storage.c
2311index 4e9aec5..13479dd 100644
2312--- a/lib/crypto_backend/crypto_storage.c
2313+++ b/lib/crypto_backend/crypto_storage.c
2314@@ -2,7 +2,7 @@
2315 * Generic wrapper for storage encryption modes and Initial Vectors
2316 * (reimplementation of some functions from Linux dm-crypt kernel)
2317 *
2318- * Copyright (C) 2014-2022 Milan Broz
2319+ * Copyright (C) 2014-2023 Milan Broz
2320 *
2321 * This file is free software; you can redistribute it and/or
2322 * modify it under the terms of the GNU Lesser General Public
2323diff --git a/lib/crypto_backend/pbkdf2_generic.c b/lib/crypto_backend/pbkdf2_generic.c
2324index a0afbdf..9e87e19 100644
2325--- a/lib/crypto_backend/pbkdf2_generic.c
2326+++ b/lib/crypto_backend/pbkdf2_generic.c
2327@@ -4,8 +4,8 @@
2328 * Copyright (C) 2004 Free Software Foundation
2329 *
2330 * cryptsetup related changes
2331- * Copyright (C) 2012-2022 Red Hat, Inc. All rights reserved.
2332- * Copyright (C) 2012-2022 Milan Broz
2333+ * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
2334+ * Copyright (C) 2012-2023 Milan Broz
2335 *
2336 * This file is free software; you can redistribute it and/or
2337 * modify it under the terms of the GNU Lesser General Public
2338diff --git a/lib/crypto_backend/pbkdf_check.c b/lib/crypto_backend/pbkdf_check.c
2339index 428ca2d..53a2da9 100644
2340--- a/lib/crypto_backend/pbkdf_check.c
2341+++ b/lib/crypto_backend/pbkdf_check.c
2342@@ -1,7 +1,7 @@
2343 /*
2344 * PBKDF performance check
2345- * Copyright (C) 2012-2022 Red Hat, Inc. All rights reserved.
2346- * Copyright (C) 2012-2022 Milan Broz
2347+ * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
2348+ * Copyright (C) 2012-2023 Milan Broz
2349 * Copyright (C) 2016-2020 Ondrej Mosnacek
2350 *
2351 * This file is free software; you can redistribute it and/or
2352diff --git a/lib/crypto_backend/utf8.c b/lib/crypto_backend/utf8.c
2353index cba5033..24e0d8d 100644
2354--- a/lib/crypto_backend/utf8.c
2355+++ b/lib/crypto_backend/utf8.c
2356@@ -4,7 +4,7 @@
2357 * Copyright (C) 2010 Lennart Poettering
2358 *
2359 * cryptsetup related changes
2360- * Copyright (C) 2021-2022 Vojtech Trefny
2361+ * Copyright (C) 2021-2023 Vojtech Trefny
2362
2363 * Parts of the original systemd implementation are based on the GLIB utf8
2364 * validation functions.
2365@@ -28,7 +28,6 @@
2366 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2367 */
2368
2369-#include <assert.h>
2370 #include <errno.h>
2371 #include <endian.h>
2372
2373diff --git a/lib/fvault2/fvault2.c b/lib/fvault2/fvault2.c
2374new file mode 100644
2375index 0000000..0b0c9ce
2376--- /dev/null
2377+++ b/lib/fvault2/fvault2.c
2378@@ -0,0 +1,1057 @@
2379+/*
2380+ * FVAULT2 (FileVault2-compatible) volume handling
2381+ *
2382+ * Copyright (C) 2021-2022 Pavel Tobias
2383+ *
2384+ * This file is free software; you can redistribute it and/or
2385+ * modify it under the terms of the GNU Lesser General Public
2386+ * License as published by the Free Software Foundation; either
2387+ * version 2.1 of the License, or (at your option) any later version.
2388+ *
2389+ * This file is distributed in the hope that it will be useful,
2390+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2391+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2392+ * Lesser General Public License for more details.
2393+ *
2394+ * You should have received a copy of the GNU Lesser General Public
2395+ * License along with this file; if not, write to the Free Software
2396+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2397+ */
2398+
2399+#include <errno.h>
2400+#include <regex.h>
2401+#include <stdio.h>
2402+#include <uuid/uuid.h>
2403+
2404+#include "internal.h"
2405+#include "fvault2.h"
2406+
2407+/* Core Storage signature/magic; "CS" big-endian */
2408+#define FVAULT2_CORE_STORAGE_MAGIC 0x4353
2409+
2410+/* size of the physical volume header in bytes */
2411+#define FVAULT2_VOL_HEADER_SIZE 512
2412+
2413+/* size of a single metadata block in bytes */
2414+#define FVAULT2_MD_BLOCK_SIZE 8192
2415+
2416+/* maximal offset to read metadata block */
2417+#define FVAULT2_MAX_OFF 1024*1024*1024
2418+
2419+/* encrypted metadata parsing progress flags (see _read_encrypted_metadata) */
2420+#define FVAULT2_ENC_MD_PARSED_0x0019 0b001
2421+#define FVAULT2_ENC_MD_PARSED_0x001A 0b010
2422+#define FVAULT2_ENC_MD_PARSED_0x0305 0b100
2423+#define FVAULT2_ENC_MD_PARSED_NONE 0b000
2424+#define FVAULT2_ENC_MD_PARSED_ALL 0b111
2425+
2426+/* sizes of decoded PassphraseWrappedKEKStruct and KEKWrappedVolumeKeyStruct */
2427+#define FVAULT2_PWK_SIZE 284
2428+#define FVAULT2_KWVK_SIZE 256
2429+
2430+/* size of an AES-128 key */
2431+#define FVAULT2_AES_KEY_SIZE 16
2432+
2433+/* size of the volume key and the encrypted metadata decryption key */
2434+#define FVAULT2_XTS_KEY_SIZE (FVAULT2_AES_KEY_SIZE * 2)
2435+
2436+/* size of an XTS tweak value */
2437+#define FVAULT2_XTS_TWEAK_SIZE 16
2438+
2439+/* size of a binary representation of a UUID */
2440+#define FVAULT2_UUID_BIN_SIZE 16
2441+
2442+struct crc32_checksum {
2443+ uint32_t value;
2444+ uint32_t seed;
2445+} __attribute__((packed));
2446+
2447+struct volume_header {
2448+ struct crc32_checksum checksum;
2449+ uint16_t version;
2450+ uint16_t block_type;
2451+ uint8_t unknown1[52];
2452+ uint64_t ph_vol_size;
2453+ uint8_t unknown2[16];
2454+ uint16_t magic;
2455+ uint32_t checksum_algo;
2456+ uint8_t unknown3[2];
2457+ uint32_t block_size;
2458+ uint32_t metadata_size;
2459+ uint64_t disklbl_blkoff;
2460+ uint64_t other_md_blkoffs[3];
2461+ uint8_t unknown4[32];
2462+ uint32_t key_data_size;
2463+ uint32_t cipher;
2464+ uint8_t key_data[FVAULT2_AES_KEY_SIZE];
2465+ uint8_t unknown5[112];
2466+ uint8_t ph_vol_uuid[FVAULT2_UUID_BIN_SIZE];
2467+ uint8_t unknown6[192];
2468+} __attribute__((packed));
2469+
2470+struct volume_groups_descriptor {
2471+ uint8_t unknown1[8];
2472+ uint64_t enc_md_blocks_n;
2473+ uint8_t unknown2[16];
2474+ uint64_t enc_md_blkoff;
2475+} __attribute__((packed));
2476+
2477+struct metadata_block_header {
2478+ struct crc32_checksum checksum;
2479+ uint16_t version;
2480+ uint16_t block_type;
2481+ uint8_t unknown1[20];
2482+ uint64_t block_num;
2483+ uint8_t unknown2[8];
2484+ uint32_t block_size;
2485+ uint8_t unknown3[12];
2486+} __attribute__((packed));
2487+
2488+struct metadata_block_0x0011 {
2489+ struct metadata_block_header header;
2490+ uint32_t md_size;
2491+ uint8_t unknown1[4];
2492+ struct crc32_checksum checksum;
2493+ uint8_t unknown2[140];
2494+ uint32_t vol_gr_des_off;
2495+} __attribute__((packed));
2496+
2497+struct metadata_block_0x0019 {
2498+ struct metadata_block_header header;
2499+ uint8_t unknown1[40];
2500+ uint32_t xml_comp_size;
2501+ uint32_t xml_uncomp_size;
2502+ uint32_t xml_off;
2503+ uint32_t xml_size;
2504+} __attribute__((packed));
2505+
2506+struct metadata_block_0x001a {
2507+ struct metadata_block_header header;
2508+ uint8_t unknown1[64];
2509+ uint32_t xml_off;
2510+ uint32_t xml_size;
2511+} __attribute__((packed));
2512+
2513+struct metadata_block_0x0305 {
2514+ struct metadata_block_header header;
2515+ uint32_t entries_n;
2516+ uint8_t unknown1[36];
2517+ uint32_t log_vol_blkoff;
2518+} __attribute__((packed));
2519+
2520+struct passphrase_wrapped_kek {
2521+ uint32_t pbkdf2_salt_type;
2522+ uint32_t pbkdf2_salt_size;
2523+ uint8_t pbkdf2_salt[FVAULT2_PBKDF2_SALT_SIZE];
2524+ uint32_t wrapped_kek_type;
2525+ uint32_t wrapped_kek_size;
2526+ uint8_t wrapped_kek[FVAULT2_WRAPPED_KEY_SIZE];
2527+ uint8_t unknown1[112];
2528+ uint32_t pbkdf2_iters;
2529+} __attribute__((packed));
2530+
2531+struct kek_wrapped_volume_key {
2532+ uint32_t wrapped_vk_type;
2533+ uint32_t wrapped_vk_size;
2534+ uint8_t wrapped_vk[FVAULT2_WRAPPED_KEY_SIZE];
2535+} __attribute__((packed));
2536+
2537+/**
2538+ * Test whether all bytes of a chunk of memory are equal to a constant value.
2539+ * @param[in] value the value all bytes should be equal to
2540+ * @param[in] data the tested chunk of memory
2541+ * @param[in] data_size byte-size of the chunk of memory
2542+ */
2543+static bool _filled_with(
2544+ uint8_t value,
2545+ const void *data,
2546+ size_t data_size)
2547+{
2548+ const uint8_t *data_bytes = data;
2549+ size_t i;
2550+
2551+ for (i = 0; i < data_size; i++)
2552+ if (data_bytes[i] != value)
2553+ return false;
2554+
2555+ return true;
2556+}
2557+
2558+/**
2559+ * Assert the validity of the CRC checksum of a chunk of memory.
2560+ * @param[in] data a chunk of memory starting with a crc32_checksum struct
2561+ * @param[in] data_size the size of the chunk of memory in bytes
2562+ */
2563+static int _check_crc(
2564+ const void *data,
2565+ size_t data_size)
2566+{
2567+ const size_t crc_size = sizeof(struct crc32_checksum);
2568+ uint32_t seed;
2569+ uint32_t value;
2570+
2571+ assert(data_size >= crc_size);
2572+
2573+ value = le32_to_cpu(((const struct crc32_checksum *)data)->value);
2574+ seed = le32_to_cpu(((const struct crc32_checksum *)data)->seed);
2575+ if (seed != 0xffffffff)
2576+ return -EINVAL;
2577+
2578+ if (crypt_crc32c(seed, (const uint8_t *)data + crc_size,
2579+ data_size - crc_size) != value)
2580+ return -EINVAL;
2581+
2582+ return 0;
2583+}
2584+
2585+/**
2586+ * Unwrap an AES-wrapped key.
2587+ * @param[in] kek the KEK with which the key has been wrapped
2588+ * @param[in] kek_size the size of the KEK in bytes
2589+ * @param[in] key_wrapped the wrapped key
2590+ * @param[in] key_wrapped_size the size of the wrapped key in bytes
2591+ * @param[out] key_buf key an output buffer for the unwrapped key
2592+ * @param[in] key_buf_size the size of the output buffer in bytes
2593+ */
2594+static int _unwrap_key(
2595+ const void *kek,
2596+ size_t kek_size,
2597+ const void *key_wrapped,
2598+ size_t key_wrapped_size,
2599+ void *key_buf,
2600+ size_t key_buf_size)
2601+{
2602+ /* Algorithm and notation taken from NIST Special Publication 800-38F:
2603+ https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
2604+
2605+ This implementation supports only 128-bit KEKs and wrapped keys. */
2606+
2607+ int r = 0;
2608+ struct crypt_cipher *cipher = NULL;
2609+ void *cipher_in = NULL;
2610+ void *cipher_out = NULL;
2611+ uint64_t a;
2612+ uint64_t r2;
2613+ uint64_t r3;
2614+ uint64_t t;
2615+ uint64_t r2_prev;
2616+
2617+ assert(kek_size == 16 && key_wrapped_size == 24 && key_buf_size == 16);
2618+
2619+ r = crypt_cipher_init(&cipher, "aes", "ecb", kek, kek_size);
2620+ if (r < 0)
2621+ goto out;
2622+
2623+ cipher_in = malloc(16);
2624+ if (cipher_in == NULL) {
2625+ r = -ENOMEM;
2626+ goto out;
2627+ }
2628+
2629+ cipher_out = malloc(16);
2630+ if (cipher_out == NULL) {
2631+ r = -ENOMEM;
2632+ goto out;
2633+ }
2634+
2635+ /* CHAPTER 6.1, ALGORITHM 2: W^-1(C) */
2636+
2637+ /* initialize variables */
2638+ a = ((const uint64_t *)key_wrapped)[0]; /* A = C_1 (see step 1c) */
2639+ r2 = ((const uint64_t *)key_wrapped)[1]; /* R_1 = C_2 (see step 1d) */
2640+ r3 = ((const uint64_t *)key_wrapped)[2]; /* R_2 = C_3 (see step 1d) */
2641+
2642+ /* calculate intermediate values for each t = s, ..., 1 (see step 2),
2643+ where s = 6 * (n - 1) (see step 1a) */
2644+ for (t = 6 * (3 - 1); t > 0; t--) {
2645+ /* store current R2 for later assignment (see step 2c) */
2646+ r2_prev = r2;
2647+
2648+ /* prepare input for CIPH^{-1}_K (see steps 2a, 2b) */
2649+ ((uint64_t *)cipher_in)[0] = a ^ cpu_to_be64(t);
2650+ ((uint64_t *)cipher_in)[1] = r3;
2651+
2652+ /* A||R2 = CIPH^{-1}_K(...) (see steps 2a, 2b) */
2653+ r = crypt_cipher_decrypt(cipher, cipher_in, cipher_out, 16, NULL, 0);
2654+ if (r < 0)
2655+ goto out;
2656+ a = ((uint64_t *)cipher_out)[0];
2657+ r2 = ((uint64_t *)cipher_out)[1];
2658+
2659+ /* assign previous R2 (see step 2c) */
2660+ r3 = r2_prev;
2661+ }
2662+
2663+ /* note that A||R_1||R_2 holds the result S (see step 3) */
2664+
2665+ /* CHAPTER 6.2, ALGORITHM 4: KW-AD(C) */
2666+
2667+ /* check whether MSB_{64}(S) (= A) matches ICV1 (see step 3) */
2668+ if (a != 0xA6A6A6A6A6A6A6A6) {
2669+ r = -EPERM;
2670+ goto out;
2671+ }
2672+
2673+ /* return LSB_{128}(S) (= R_1||R_2) (see step 4) */
2674+ ((uint64_t *)key_buf)[0] = r2;
2675+ ((uint64_t *)key_buf)[1] = r3;
2676+out:
2677+ free(cipher_in);
2678+ free(cipher_out);
2679+ if (cipher != NULL)
2680+ crypt_cipher_destroy(cipher);
2681+ return r;
2682+}
2683+
2684+/**
2685+ * Search XML plist data for a property and return its value.
2686+ * @param[in] xml a 0-terminated string containing the XML plist data
2687+ * @param[in] prop_key a 0-terminated string with the seeked property's key
2688+ * @param[in] prop_type a 0-terminated string with the seeked property's type
2689+ * @param[out] value a 0-terminated string with the found property's value
2690+ */
2691+static int _search_xml(
2692+ const char *xml,
2693+ const char *prop_key,
2694+ const char *prop_type,
2695+ char **value)
2696+{
2697+ int r = 0;
2698+ char *pattern = NULL;
2699+ bool regex_ready = false;
2700+ regex_t regex;
2701+ regmatch_t match[2];
2702+ const char *value_start;
2703+ size_t value_len;
2704+
2705+ if (asprintf(&pattern, "<key>%s</key><%s[^>]*>([^<]+)</%s>",
2706+ prop_key, prop_type, prop_type) < 0) {
2707+ r = -ENOMEM;
2708+ goto out;
2709+ }
2710+
2711+ if (regcomp(&regex, pattern, REG_EXTENDED) != 0) {
2712+ r = -EINVAL;
2713+ goto out;
2714+ }
2715+
2716+ regex_ready = true;
2717+
2718+ if (regexec(&regex, xml, 2, match, 0) != 0) {
2719+ r = -EINVAL;
2720+ goto out;
2721+ }
2722+
2723+ value_start = xml + match[1].rm_so;
2724+ value_len = match[1].rm_eo - match[1].rm_so;
2725+
2726+ *value = calloc(value_len + 1, 1);
2727+ if (*value == NULL) {
2728+ r = -ENOMEM;
2729+ goto out;
2730+ }
2731+
2732+ memcpy(*value, value_start, value_len);
2733+out:
2734+ free(pattern);
2735+ if (regex_ready)
2736+ regfree(&regex);
2737+ return r;
2738+}
2739+
2740+/**
2741+ * Extract relevant info from a metadata block of type 0x0019.
2742+ * @param[in] md_block the pre-read and decrypted metadata block
2743+ * @param[out] pbkdf2_iters number of PBKDF2 iterations
2744+ * @param[out] pbkdf2_salt PBKDF2 salt (intermt. key derivation from passphrase)
2745+ * @param[out] wrapped_kek KEK AES-wrapped with passphrase-derived key
2746+ * @param[out] wrapped_vk volume key AES-wrapped with KEK
2747+ */
2748+static int _parse_metadata_block_0x0019(
2749+ const struct metadata_block_0x0019 *md_block,
2750+ uint32_t *pbkdf2_iters,
2751+ uint8_t *pbkdf2_salt,
2752+ uint8_t *wrapped_kek,
2753+ uint8_t *wrapped_vk)
2754+{
2755+ int r = 0;
2756+ char *xml = NULL;
2757+ char *pwk_base64 = NULL;
2758+ char *kwvk_base64 = NULL;
2759+ struct passphrase_wrapped_kek *pwk = NULL;
2760+ struct kek_wrapped_volume_key *kwvk = NULL;
2761+ size_t decoded_size;
2762+ uint32_t xml_off = le32_to_cpu(md_block->xml_off);
2763+ uint32_t xml_size = le32_to_cpu(md_block->xml_size);
2764+
2765+ if (xml_off + xml_size > FVAULT2_MD_BLOCK_SIZE)
2766+ return -EINVAL;
2767+
2768+ xml = strndup((const char *)md_block + xml_off, xml_size);
2769+ if (xml == NULL)
2770+ return -ENOMEM;
2771+
2772+ r = _search_xml(xml, "PassphraseWrappedKEKStruct", "data", &pwk_base64);
2773+ if (r < 0)
2774+ goto out;
2775+ r = crypt_base64_decode((char **)&pwk, &decoded_size, pwk_base64, strlen(pwk_base64));
2776+ if (r < 0)
2777+ goto out;
2778+ if (decoded_size != FVAULT2_PWK_SIZE) {
2779+ r = -EINVAL;
2780+ goto out;
2781+ }
2782+
2783+ r = _search_xml(xml, "KEKWrappedVolumeKeyStruct", "data", &kwvk_base64);
2784+ if (r < 0)
2785+ goto out;
2786+ r = crypt_base64_decode((char **)&kwvk, &decoded_size, kwvk_base64, strlen(kwvk_base64));
2787+ if (r < 0)
2788+ goto out;
2789+ if (decoded_size != FVAULT2_KWVK_SIZE) {
2790+ r = -EINVAL;
2791+ goto out;
2792+ }
2793+
2794+ *pbkdf2_iters = le32_to_cpu(pwk->pbkdf2_iters);
2795+ memcpy(pbkdf2_salt, pwk->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE);
2796+ memcpy(wrapped_kek, pwk->wrapped_kek, FVAULT2_WRAPPED_KEY_SIZE);
2797+ memcpy(wrapped_vk, kwvk->wrapped_vk, FVAULT2_WRAPPED_KEY_SIZE);
2798+out:
2799+ free(xml);
2800+ free(pwk_base64);
2801+ free(kwvk_base64);
2802+ free(pwk);
2803+ free(kwvk);
2804+ return r;
2805+}
2806+
2807+/**
2808+ * Validate a UUID string and reformat it to match system defaults.
2809+ * @param[in] uuid_in the original UUID string
2810+ * @param[out] uuid_out the reformatted UUID string
2811+ */
2812+static int _reformat_uuid(
2813+ const char *uuid_in,
2814+ char *uuid_out)
2815+{
2816+ uint8_t uuid_bin[FVAULT2_UUID_LEN];
2817+ int r;
2818+
2819+ r = uuid_parse(uuid_in, uuid_bin);
2820+ if (r < 0)
2821+ return -EINVAL;
2822+
2823+ uuid_unparse(uuid_bin, uuid_out);
2824+ return 0;
2825+}
2826+
2827+/**
2828+ * Extract relevant info from a metadata block of type 0x001A.
2829+ * @param[in] md_block the pre-read and decrypted metadata block
2830+ * @param[out] log_vol_size encrypted logical volume size in bytes
2831+ * @param[out] family_uuid logical volume family UUID
2832+ */
2833+static int _parse_metadata_block_0x001a(
2834+ const struct metadata_block_0x001a *md_block,
2835+ uint64_t *log_vol_size,
2836+ char *family_uuid)
2837+{
2838+ int r = 0;
2839+ char *xml = NULL;
2840+ char *log_vol_size_str = NULL;
2841+ char *family_uuid_str = NULL;
2842+ uint32_t xml_off = le32_to_cpu(md_block->xml_off);
2843+ uint32_t xml_size = le32_to_cpu(md_block->xml_size);
2844+
2845+ if (xml_off + xml_size > FVAULT2_MD_BLOCK_SIZE)
2846+ return -EINVAL;
2847+
2848+ xml = strndup((const char *)md_block + xml_off, xml_size);
2849+ if (xml == NULL)
2850+ return -ENOMEM;
2851+
2852+ r = _search_xml(xml, "com.apple.corestorage.lv.size", "integer", &log_vol_size_str);
2853+ if (r < 0)
2854+ goto out;
2855+ *log_vol_size = strtoull(log_vol_size_str, NULL, 16);
2856+ if (*log_vol_size == 0 || *log_vol_size == ULLONG_MAX) {
2857+ r = -EINVAL;
2858+ goto out;
2859+ }
2860+
2861+ r = _search_xml(xml, "com.apple.corestorage.lv.familyUUID", "string", &family_uuid_str);
2862+ if (r < 0)
2863+ goto out;
2864+ r = _reformat_uuid(family_uuid_str, family_uuid);
2865+ if (r < 0)
2866+ goto out;
2867+out:
2868+ free(xml);
2869+ free(log_vol_size_str);
2870+ free(family_uuid_str);
2871+ return r;
2872+}
2873+
2874+/**
2875+ * Extract relevant info from a metadata block of type 0x0305.
2876+ * @param[in] md_block the pre-read and decrypted metadata block
2877+ * @param[out] log_vol_blkoff block-offset of the encrypted logical volume
2878+ */
2879+static int _parse_metadata_block_0x0305(
2880+ const struct metadata_block_0x0305 *md_block,
2881+ uint32_t *log_vol_blkoff)
2882+{
2883+ *log_vol_blkoff = le32_to_cpu(md_block->log_vol_blkoff);
2884+ return 0;
2885+}
2886+
2887+/**
2888+ * Extract relevant info from the physical volume header.
2889+ * @param[in] devfd opened device file descriptor
2890+ * @param[in] cd crypt_device passed into FVAULT2_read_metadata
2891+ * @param[out] block_size used to compute byte-offsets from block-offsets
2892+ * @param[out] disklbl_blkoff block-offset of the disk label block
2893+ * @param[out] ph_vol_uuid physical volume UUID
2894+ * @param[out] enc_md_key AES-XTS key used to decrypt the encrypted metadata
2895+ */
2896+static int _read_volume_header(
2897+ int devfd,
2898+ struct crypt_device *cd,
2899+ uint64_t *block_size,
2900+ uint64_t *disklbl_blkoff,
2901+ char *ph_vol_uuid,
2902+ struct volume_key **enc_md_key)
2903+{
2904+ int r = 0;
2905+ struct device *dev = crypt_metadata_device(cd);
2906+ struct volume_header *vol_header = NULL;
2907+
2908+ assert(sizeof(*vol_header) == FVAULT2_VOL_HEADER_SIZE);
2909+
2910+ vol_header = malloc(FVAULT2_VOL_HEADER_SIZE);
2911+ if (vol_header == NULL) {
2912+ r = -ENOMEM;
2913+ goto out;
2914+ }
2915+
2916+ log_dbg(cd, "Reading FVAULT2 volume header of size %u bytes.", FVAULT2_VOL_HEADER_SIZE);
2917+ if (read_blockwise(devfd, device_block_size(cd, dev),
2918+ device_alignment(dev), vol_header,
2919+ FVAULT2_VOL_HEADER_SIZE) != FVAULT2_VOL_HEADER_SIZE) {
2920+ log_err(cd, _("Could not read %u bytes of volume header."), FVAULT2_VOL_HEADER_SIZE);
2921+ r = -EIO;
2922+ goto out;
2923+ }
2924+
2925+ r = _check_crc(vol_header, FVAULT2_VOL_HEADER_SIZE);
2926+ if (r < 0) {
2927+ log_dbg(cd, "CRC mismatch.");
2928+ goto out;
2929+ }
2930+
2931+ if (le16_to_cpu(vol_header->version) != 1) {
2932+ log_err(cd, _("Unsupported FVAULT2 version %" PRIu16 "."),
2933+ le16_to_cpu(vol_header->version));
2934+ r = -EINVAL;
2935+ goto out;
2936+ }
2937+
2938+ if (be16_to_cpu(vol_header->magic) != FVAULT2_CORE_STORAGE_MAGIC) {
2939+ log_dbg(cd, "Invalid Core Storage magic bytes.");
2940+ r = -EINVAL;
2941+ goto out;
2942+ }
2943+
2944+ if (le32_to_cpu(vol_header->key_data_size) != FVAULT2_AES_KEY_SIZE) {
2945+ log_dbg(cd, "Unsupported AES key size: %" PRIu32 " bytes.",
2946+ le32_to_cpu(vol_header->key_data_size));
2947+ r = -EINVAL;
2948+ goto out;
2949+ }
2950+
2951+ *enc_md_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
2952+ if (*enc_md_key == NULL) {
2953+ r = -ENOMEM;
2954+ goto out;
2955+ }
2956+
2957+ *block_size = le32_to_cpu(vol_header->block_size);
2958+ *disklbl_blkoff = le64_to_cpu(vol_header->disklbl_blkoff);
2959+ uuid_unparse(vol_header->ph_vol_uuid, ph_vol_uuid);
2960+ memcpy((*enc_md_key)->key, vol_header->key_data, FVAULT2_AES_KEY_SIZE);
2961+ memcpy((*enc_md_key)->key + FVAULT2_AES_KEY_SIZE,
2962+ vol_header->ph_vol_uuid, FVAULT2_AES_KEY_SIZE);
2963+out:
2964+ free(vol_header);
2965+ return r;
2966+}
2967+
2968+/**
2969+ * Extract info from the disk label block and the volume groups descriptor.
2970+ * @param[in] devfd opened device file descriptor
2971+ * @param[in] cd crypt_device passed into FVAULT2_read_metadata
2972+ * @param[in] block_size used to compute byte-offsets from block-offsets
2973+ * @param[in] disklbl_blkoff block-offset of the disk label block
2974+ * @param[out] enc_md_blkoff block-offset of the encrypted metadata
2975+ * @param[out] enc_md_blocks_n total count of encrypted metadata blocks
2976+ */
2977+static int _read_disklabel(
2978+ int devfd,
2979+ struct crypt_device *cd,
2980+ uint64_t block_size,
2981+ uint64_t disklbl_blkoff,
2982+ uint64_t *enc_md_blkoff,
2983+ uint64_t *enc_md_blocks_n)
2984+{
2985+ int r = 0;
2986+ uint64_t off;
2987+ ssize_t size;
2988+ void *md_block = NULL;
2989+ struct metadata_block_0x0011 *md_block_11;
2990+ struct volume_groups_descriptor *vol_gr_des = NULL;
2991+ struct device *dev = crypt_metadata_device(cd);
2992+
2993+ md_block = malloc(FVAULT2_MD_BLOCK_SIZE);
2994+ if (md_block == NULL) {
2995+ r = -ENOMEM;
2996+ goto out;
2997+ }
2998+
2999+ if (uint64_mult_overflow(&off, disklbl_blkoff, block_size) ||
3000+ off > FVAULT2_MAX_OFF) {
3001+ log_dbg(cd, "Device offset overflow.");
3002+ r = -EINVAL;
3003+ goto out;
3004+ }
3005+ size = FVAULT2_MD_BLOCK_SIZE;
3006+ log_dbg(cd, "Reading FVAULT2 disk label header of size %zu bytes.", size);
3007+ if (read_lseek_blockwise(devfd, device_block_size(cd, dev),
3008+ device_alignment(dev), md_block, size, off) != size) {
3009+ r = -EIO;
3010+ goto out;
3011+ }
3012+
3013+ r = _check_crc(md_block, FVAULT2_MD_BLOCK_SIZE);
3014+ if (r < 0) {
3015+ log_dbg(cd, "CRC mismatch.");
3016+ goto out;
3017+ }
3018+
3019+ vol_gr_des = malloc(sizeof(*vol_gr_des));
3020+ if (vol_gr_des == NULL) {
3021+ r = -ENOMEM;
3022+ goto out;
3023+ }
3024+
3025+ md_block_11 = md_block;
3026+ off += le32_to_cpu(md_block_11->vol_gr_des_off);
3027+ if (off > FVAULT2_MAX_OFF) {
3028+ log_dbg(cd, "Device offset overflow.");
3029+ r = -EINVAL;
3030+ goto out;
3031+ }
3032+ size = sizeof(struct volume_groups_descriptor);
3033+ log_dbg(cd, "Reading FVAULT2 volume groups descriptor of size %zu bytes.", size);
3034+ if (read_lseek_blockwise(devfd, device_block_size(cd, dev),
3035+ device_alignment(dev), vol_gr_des, size, off) != size) {
3036+ r = -EIO;
3037+ goto out;
3038+ }
3039+
3040+ *enc_md_blkoff = le64_to_cpu(vol_gr_des->enc_md_blkoff);
3041+ *enc_md_blocks_n = le64_to_cpu(vol_gr_des->enc_md_blocks_n);
3042+out:
3043+ free(md_block);
3044+ free(vol_gr_des);
3045+ return r;
3046+}
3047+
3048+/**
3049+ * Extract info from relevant encrypted metadata blocks.
3050+ * @param[in] devfd opened device file descriptor
3051+ * @param[in] cd crypt_device passed into FVAULT2_read_metadata
3052+ * @param[in] block_size used to compute byte-offsets from block-offsets
3053+ * @param[in] start_blkoff block-offset of the start of the encrypted metadata
3054+ * @param[in] blocks_n total count of encrypted metadata blocks
3055+ * @param[in] key AES-XTS key for decryption
3056+ * @param[out] params decryption parameters struct to fill
3057+ */
3058+static int _read_encrypted_metadata(
3059+ int devfd,
3060+ struct crypt_device *cd,
3061+ uint64_t block_size,
3062+ uint64_t start_blkoff,
3063+ uint64_t blocks_n,
3064+ const struct volume_key *key,
3065+ struct fvault2_params *params)
3066+{
3067+ int r = 0;
3068+ int status = FVAULT2_ENC_MD_PARSED_NONE;
3069+ struct device *dev = crypt_metadata_device(cd);
3070+ struct crypt_cipher *cipher = NULL;
3071+ void *tweak;
3072+ void *md_block_enc = NULL;
3073+ void *md_block = NULL;
3074+ struct metadata_block_header *md_block_header;
3075+ uint32_t log_vol_blkoff;
3076+ uint64_t i, start_off;
3077+ off_t off;
3078+ unsigned int block_type;
3079+
3080+ tweak = calloc(FVAULT2_XTS_TWEAK_SIZE, 1);
3081+ if (tweak == NULL) {
3082+ r = -ENOMEM;
3083+ goto out;
3084+ }
3085+
3086+ md_block_enc = malloc(FVAULT2_MD_BLOCK_SIZE);
3087+ if (md_block_enc == NULL) {
3088+ r = -ENOMEM;
3089+ goto out;
3090+ }
3091+
3092+ md_block = malloc(FVAULT2_MD_BLOCK_SIZE);
3093+ if (md_block == NULL) {
3094+ r = -ENOMEM;
3095+ goto out;
3096+ }
3097+
3098+ r = crypt_cipher_init(&cipher, "aes", "xts", key->key, FVAULT2_XTS_KEY_SIZE);
3099+ if (r < 0)
3100+ goto out;
3101+
3102+ if (uint64_mult_overflow(&start_off, start_blkoff, block_size) ||
3103+ start_off > FVAULT2_MAX_OFF) {
3104+ log_dbg(cd, "Device offset overflow.");
3105+ r = -EINVAL;
3106+ goto out;
3107+ }
3108+
3109+ log_dbg(cd, "Reading FVAULT2 encrypted metadata blocks.");
3110+ for (i = 0; i < blocks_n; i++) {
3111+ off = start_off + i * FVAULT2_MD_BLOCK_SIZE;
3112+ if (off > FVAULT2_MAX_OFF) {
3113+ log_dbg(cd, "Device offset overflow.");
3114+ r = -EINVAL;
3115+ goto out;
3116+ }
3117+ if (read_lseek_blockwise(devfd, device_block_size(cd, dev),
3118+ device_alignment(dev), md_block_enc,
3119+ FVAULT2_MD_BLOCK_SIZE, off)
3120+ != FVAULT2_MD_BLOCK_SIZE) {
3121+ r = -EIO;
3122+ goto out;
3123+ }
3124+
3125+ if (_filled_with(0, md_block_enc, FVAULT2_MD_BLOCK_SIZE))
3126+ break;
3127+
3128+ *(uint64_t *)tweak = cpu_to_le64(i);
3129+ r = crypt_cipher_decrypt(cipher, md_block_enc, md_block,
3130+ FVAULT2_MD_BLOCK_SIZE, tweak, FVAULT2_XTS_TWEAK_SIZE);
3131+ if (r < 0)
3132+ goto out;
3133+
3134+ r = _check_crc(md_block, FVAULT2_MD_BLOCK_SIZE);
3135+ if (r < 0) {
3136+ log_dbg(cd, "CRC mismatch.");
3137+ goto out;
3138+ }
3139+
3140+ md_block_header = md_block;
3141+ block_type = le16_to_cpu(md_block_header->block_type);
3142+ switch (block_type) {
3143+ case 0x0019:
3144+ log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x0019.", i);
3145+ r = _parse_metadata_block_0x0019(md_block,
3146+ &params->pbkdf2_iters,
3147+ (uint8_t *)params->pbkdf2_salt,
3148+ (uint8_t *)params->wrapped_kek,
3149+ (uint8_t *)params->wrapped_vk);
3150+ if (r < 0)
3151+ goto out;
3152+ status |= FVAULT2_ENC_MD_PARSED_0x0019;
3153+ break;
3154+
3155+ case 0x001A:
3156+ log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x001A.", i);
3157+ r = _parse_metadata_block_0x001a(md_block,
3158+ &params->log_vol_size,
3159+ params->family_uuid);
3160+ if (r < 0)
3161+ goto out;
3162+ status |= FVAULT2_ENC_MD_PARSED_0x001A;
3163+ break;
3164+
3165+ case 0x0305:
3166+ log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x0305.", i);
3167+ r = _parse_metadata_block_0x0305(md_block,
3168+ &log_vol_blkoff);
3169+ if (r < 0)
3170+ goto out;
3171+ if (uint64_mult_overflow(&params->log_vol_off,
3172+ log_vol_blkoff, block_size)) {
3173+ log_dbg(cd, "Device offset overflow.");
3174+ r = -EINVAL;
3175+ goto out;
3176+ }
3177+ status |= FVAULT2_ENC_MD_PARSED_0x0305;
3178+ break;
3179+ }
3180+ }
3181+
3182+ if (status != FVAULT2_ENC_MD_PARSED_ALL) {
3183+ log_dbg(cd, "Necessary FVAULT2 metadata blocks not found.");
3184+ r = -EINVAL;
3185+ goto out;
3186+ }
3187+out:
3188+ free(tweak);
3189+ free(md_block_enc);
3190+ free(md_block);
3191+ if (cipher != NULL)
3192+ crypt_cipher_destroy(cipher);
3193+ return r;
3194+}
3195+
3196+/**
3197+ * Activate device.
3198+ * @param[in] cd crypt_device struct passed into FVAULT2_activate_by_*
3199+ * @param[in] name name of the mapped device
3200+ * @param[in] vol_key the pre-derived AES-XTS volume key
3201+ * @param[in] params logical volume decryption parameters
3202+ * @param[in] flags flags assigned to the crypt_dm_active_device struct
3203+ */
3204+static int _activate(
3205+ struct crypt_device *cd,
3206+ const char *name,
3207+ struct volume_key *vol_key,
3208+ const struct fvault2_params *params,
3209+ uint32_t flags)
3210+{
3211+ int r = 0;
3212+ char *cipher = NULL;
3213+ struct crypt_dm_active_device dm_dev = {
3214+ .flags = flags,
3215+ .size = params->log_vol_size / SECTOR_SIZE
3216+ };
3217+
3218+ r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
3219+ crypt_get_data_offset(cd), &dm_dev.size, &dm_dev.flags);
3220+ if (r)
3221+ return r;
3222+
3223+ if (asprintf(&cipher, "%s-%s", params->cipher, params->cipher_mode) < 0)
3224+ return -ENOMEM;
3225+
3226+ r = dm_crypt_target_set(&dm_dev.segment, 0, dm_dev.size,
3227+ crypt_data_device(cd), vol_key, cipher,
3228+ crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
3229+ crypt_get_integrity(cd), crypt_get_integrity_tag_size(cd),
3230+ crypt_get_sector_size(cd));
3231+
3232+ if (!r)
3233+ r = dm_create_device(cd, name, CRYPT_FVAULT2, &dm_dev);
3234+
3235+ dm_targets_free(cd, &dm_dev);
3236+ free(cipher);
3237+ return r;
3238+}
3239+
3240+int FVAULT2_read_metadata(
3241+ struct crypt_device *cd,
3242+ struct fvault2_params *params)
3243+{
3244+ int r = 0;
3245+ int devfd;
3246+ uint64_t block_size;
3247+ uint64_t disklbl_blkoff;
3248+ uint64_t enc_md_blkoff;
3249+ uint64_t enc_md_blocks_n;
3250+ struct volume_key *enc_md_key = NULL;
3251+ struct device *device = crypt_metadata_device(cd);
3252+
3253+ devfd = device_open(cd, device, O_RDONLY);
3254+ if (devfd < 0) {
3255+ log_err(cd, _("Cannot open device %s."), device_path(device));
3256+ return -EIO;
3257+ }
3258+
3259+ r = _read_volume_header(devfd, cd, &block_size, &disklbl_blkoff,
3260+ params->ph_vol_uuid, &enc_md_key);
3261+ if (r < 0)
3262+ goto out;
3263+
3264+ r = _read_disklabel(devfd, cd, block_size, disklbl_blkoff,
3265+ &enc_md_blkoff, &enc_md_blocks_n);
3266+ if (r < 0)
3267+ goto out;
3268+
3269+ r = _read_encrypted_metadata(devfd, cd, block_size, enc_md_blkoff,
3270+ enc_md_blocks_n, enc_md_key, params);
3271+ if (r < 0)
3272+ goto out;
3273+
3274+ params->cipher = "aes";
3275+ params->cipher_mode = "xts-plain64";
3276+ params->key_size = FVAULT2_XTS_KEY_SIZE;
3277+out:
3278+ crypt_free_volume_key(enc_md_key);
3279+ return r;
3280+}
3281+
3282+int FVAULT2_get_volume_key(
3283+ struct crypt_device *cd,
3284+ const char *passphrase,
3285+ size_t passphrase_len,
3286+ const struct fvault2_params *params,
3287+ struct volume_key **vol_key)
3288+{
3289+ int r = 0;
3290+ uint8_t family_uuid_bin[FVAULT2_UUID_BIN_SIZE];
3291+ struct volume_key *passphrase_key = NULL;
3292+ struct volume_key *kek = NULL;
3293+ struct crypt_hash *hash = NULL;
3294+
3295+ *vol_key = NULL;
3296+
3297+ if (uuid_parse(params->family_uuid, family_uuid_bin) < 0) {
3298+ log_dbg(cd, "Could not parse logical volume family UUID: %s.",
3299+ params->family_uuid);
3300+ r = -EINVAL;
3301+ goto out;
3302+ }
3303+
3304+ passphrase_key = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
3305+ if (passphrase_key == NULL) {
3306+ r = -ENOMEM;
3307+ goto out;
3308+ }
3309+
3310+ r = crypt_pbkdf("pbkdf2", "sha256", passphrase, passphrase_len,
3311+ params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key->key,
3312+ FVAULT2_AES_KEY_SIZE, params->pbkdf2_iters, 0, 0);
3313+ if (r < 0)
3314+ goto out;
3315+
3316+ kek = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
3317+ if (kek == NULL) {
3318+ r = -ENOMEM;
3319+ goto out;
3320+ }
3321+
3322+ r = _unwrap_key(passphrase_key->key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek,
3323+ FVAULT2_WRAPPED_KEY_SIZE, kek->key, FVAULT2_AES_KEY_SIZE);
3324+ if (r < 0)
3325+ goto out;
3326+
3327+ *vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
3328+ if (*vol_key == NULL) {
3329+ r = -ENOMEM;
3330+ goto out;
3331+ }
3332+
3333+ r = _unwrap_key(kek->key, FVAULT2_AES_KEY_SIZE, params->wrapped_vk,
3334+ FVAULT2_WRAPPED_KEY_SIZE, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
3335+ if (r < 0)
3336+ goto out;
3337+
3338+ r = crypt_hash_init(&hash, "sha256");
3339+ if (r < 0)
3340+ goto out;
3341+ r = crypt_hash_write(hash, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
3342+ if (r < 0)
3343+ goto out;
3344+ r = crypt_hash_write(hash, (char *)family_uuid_bin,
3345+ FVAULT2_UUID_BIN_SIZE);
3346+ if (r < 0)
3347+ goto out;
3348+ r = crypt_hash_final(hash, (*vol_key)->key + FVAULT2_AES_KEY_SIZE,
3349+ FVAULT2_AES_KEY_SIZE);
3350+ if (r < 0)
3351+ goto out;
3352+out:
3353+ crypt_free_volume_key(passphrase_key);
3354+ crypt_free_volume_key(kek);
3355+ if (r < 0) {
3356+ crypt_free_volume_key(*vol_key);
3357+ *vol_key = NULL;
3358+ }
3359+ if (hash != NULL)
3360+ crypt_hash_destroy(hash);
3361+ return r;
3362+}
3363+
3364+int FVAULT2_dump(
3365+ struct crypt_device *cd,
3366+ struct device *device,
3367+ const struct fvault2_params *params)
3368+{
3369+ log_std(cd, "Header information for FVAULT2 device %s.\n", device_path(device));
3370+
3371+ log_std(cd, "Physical volume UUID: \t%s\n", params->ph_vol_uuid);
3372+ log_std(cd, "Family UUID: \t%s\n", params->family_uuid);
3373+
3374+ log_std(cd, "Logical volume offset:\t%" PRIu64 " [bytes]\n", params->log_vol_off);
3375+
3376+ log_std(cd, "Logical volume size: \t%" PRIu64 " [bytes]\n",
3377+ params->log_vol_size);
3378+
3379+ log_std(cd, "Cipher: \t%s\n", params->cipher);
3380+ log_std(cd, "Cipher mode: \t%s\n", params->cipher_mode);
3381+
3382+ log_std(cd, "PBKDF2 iterations: \t%" PRIu32 "\n", params->pbkdf2_iters);
3383+
3384+ log_std(cd, "PBKDF2 salt: \t");
3385+ crypt_log_hex(cd, params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, " ", 0, NULL);
3386+ log_std(cd, "\n");
3387+
3388+ return 0;
3389+}
3390+
3391+int FVAULT2_activate_by_passphrase(
3392+ struct crypt_device *cd,
3393+ const char *name,
3394+ const char *passphrase,
3395+ size_t passphrase_len,
3396+ const struct fvault2_params *params,
3397+ uint32_t flags)
3398+{
3399+ int r;
3400+ struct volume_key *vol_key = NULL;
3401+
3402+ r = FVAULT2_get_volume_key(cd, passphrase, passphrase_len, params, &vol_key);
3403+ if (r < 0)
3404+ return r;
3405+
3406+ if (name)
3407+ r = _activate(cd, name, vol_key, params, flags);
3408+
3409+ crypt_free_volume_key(vol_key);
3410+ return r;
3411+}
3412+
3413+int FVAULT2_activate_by_volume_key(
3414+ struct crypt_device *cd,
3415+ const char *name,
3416+ const char *key,
3417+ size_t key_size,
3418+ const struct fvault2_params *params,
3419+ uint32_t flags)
3420+{
3421+ int r = 0;
3422+ struct volume_key *vol_key = NULL;
3423+
3424+ if (key_size != FVAULT2_XTS_KEY_SIZE)
3425+ return -EINVAL;
3426+
3427+ vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, key);
3428+ if (vol_key == NULL)
3429+ return -ENOMEM;
3430+
3431+ r = _activate(cd, name, vol_key, params, flags);
3432+
3433+ crypt_free_volume_key(vol_key);
3434+ return r;
3435+}
3436diff --git a/lib/fvault2/fvault2.h b/lib/fvault2/fvault2.h
3437new file mode 100644
3438index 0000000..ce50ee3
3439--- /dev/null
3440+++ b/lib/fvault2/fvault2.h
3441@@ -0,0 +1,80 @@
3442+/*
3443+ * FVAULT2 (FileVault2-compatible) volume handling
3444+ *
3445+ * Copyright (C) 2021-2022 Pavel Tobias
3446+ *
3447+ * This file is free software; you can redistribute it and/or
3448+ * modify it under the terms of the GNU Lesser General Public
3449+ * License as published by the Free Software Foundation; either
3450+ * version 2.1 of the License, or (at your option) any later version.
3451+ *
3452+ * This file is distributed in the hope that it will be useful,
3453+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3454+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3455+ * Lesser General Public License for more details.
3456+ *
3457+ * You should have received a copy of the GNU Lesser General Public
3458+ * License along with this file; if not, write to the Free Software
3459+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3460+ */
3461+
3462+#ifndef _CRYPTSETUP_FVAULT2_H
3463+#define _CRYPTSETUP_FVAULT2_H
3464+
3465+#include <stddef.h>
3466+#include <stdint.h>
3467+
3468+#define FVAULT2_WRAPPED_KEY_SIZE 24
3469+#define FVAULT2_PBKDF2_SALT_SIZE 16
3470+#define FVAULT2_UUID_LEN 37
3471+
3472+struct crypt_device;
3473+struct volume_key;
3474+
3475+struct fvault2_params {
3476+ const char *cipher;
3477+ const char *cipher_mode;
3478+ uint16_t key_size;
3479+ uint32_t pbkdf2_iters;
3480+ char pbkdf2_salt[FVAULT2_PBKDF2_SALT_SIZE];
3481+ char wrapped_kek[FVAULT2_WRAPPED_KEY_SIZE];
3482+ char wrapped_vk[FVAULT2_WRAPPED_KEY_SIZE];
3483+ char family_uuid[FVAULT2_UUID_LEN];
3484+ char ph_vol_uuid[FVAULT2_UUID_LEN];
3485+ uint64_t log_vol_off;
3486+ uint64_t log_vol_size;
3487+};
3488+
3489+int FVAULT2_read_metadata(
3490+ struct crypt_device *cd,
3491+ struct fvault2_params *params);
3492+
3493+int FVAULT2_get_volume_key(
3494+ struct crypt_device *cd,
3495+ const char *passphrase,
3496+ size_t passphrase_len,
3497+ const struct fvault2_params *params,
3498+ struct volume_key **vol_key);
3499+
3500+int FVAULT2_dump(
3501+ struct crypt_device *cd,
3502+ struct device *device,
3503+ const struct fvault2_params *params);
3504+
3505+int FVAULT2_activate_by_passphrase(
3506+ struct crypt_device *cd,
3507+ const char *name,
3508+ const char *passphrase,
3509+ size_t passphrase_len,
3510+ const struct fvault2_params *params,
3511+ uint32_t flags);
3512+
3513+int FVAULT2_activate_by_volume_key(
3514+ struct crypt_device *cd,
3515+ const char *name,
3516+ const char *key,
3517+ size_t key_size,
3518+ const struct fvault2_params *params,
3519+ uint32_t flags);
3520+
3521+#endif
3522diff --git a/lib/integrity/integrity.c b/lib/integrity/integrity.c
3523index 83ee89d..aeadc82 100644
3524--- a/lib/integrity/integrity.c
3525+++ b/lib/integrity/integrity.c
3526@@ -1,7 +1,7 @@
3527 /*
3528 * Integrity volume handling
3529 *
3530- * Copyright (C) 2016-2022 Milan Broz
3531+ * Copyright (C) 2016-2023 Milan Broz
3532 *
3533 * This file is free software; you can redistribute it and/or
3534 * modify it under the terms of the GNU Lesser General Public
3535diff --git a/lib/integrity/integrity.h b/lib/integrity/integrity.h
3536index 5eee821..2883ef8 100644
3537--- a/lib/integrity/integrity.h
3538+++ b/lib/integrity/integrity.h
3539@@ -1,7 +1,7 @@
3540 /*
3541 * Integrity header definition
3542 *
3543- * Copyright (C) 2016-2022 Milan Broz
3544+ * Copyright (C) 2016-2023 Milan Broz
3545 *
3546 * This file is free software; you can redistribute it and/or
3547 * modify it under the terms of the GNU Lesser General Public
3548diff --git a/lib/internal.h b/lib/internal.h
3549index 7c94a38..b5cb4e3 100644
3550--- a/lib/internal.h
3551+++ b/lib/internal.h
3552@@ -3,8 +3,8 @@
3553 *
3554 * Copyright (C) 2004 Jana Saout <jana@saout.de>
3555 * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
3556- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
3557- * Copyright (C) 2009-2022 Milan Broz
3558+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
3559+ * Copyright (C) 2009-2023 Milan Broz
3560 *
3561 * This program is free software; you can redistribute it and/or
3562 * modify it under the terms of the GNU General Public License
3563@@ -31,6 +31,7 @@
3564 #include <unistd.h>
3565 #include <inttypes.h>
3566 #include <fcntl.h>
3567+#include <assert.h>
3568
3569 #include "nls.h"
3570 #include "bitops.h"
3571@@ -38,7 +39,6 @@
3572 #include "utils_crypt.h"
3573 #include "utils_loop.h"
3574 #include "utils_dm.h"
3575-#include "utils_fips.h"
3576 #include "utils_keyring.h"
3577 #include "utils_io.h"
3578 #include "crypto_backend/crypto_backend.h"
3579@@ -178,8 +178,7 @@ int init_crypto(struct crypt_device *ctx);
3580
3581 int crypt_get_debug_level(void);
3582
3583-int crypt_memlock_inc(struct crypt_device *ctx);
3584-int crypt_memlock_dec(struct crypt_device *ctx);
3585+void crypt_process_priority(struct crypt_device *cd, int *priority, bool raise);
3586
3587 int crypt_metadata_locking_enabled(void);
3588
3589diff --git a/lib/keyslot_context.c b/lib/keyslot_context.c
3590new file mode 100644
3591index 0000000..89bd433
3592--- /dev/null
3593+++ b/lib/keyslot_context.c
3594@@ -0,0 +1,488 @@
3595+/*
3596+ * LUKS - Linux Unified Key Setup, keyslot unlock helpers
3597+ *
3598+ * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
3599+ * Copyright (C) 2022-2023 Ondrej Kozina
3600+ *
3601+ * This program is free software; you can redistribute it and/or
3602+ * modify it under the terms of the GNU General Public License
3603+ * as published by the Free Software Foundation; either version 2
3604+ * of the License, or (at your option) any later version.
3605+ *
3606+ * This program is distributed in the hope that it will be useful,
3607+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3608+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3609+ * GNU General Public License for more details.
3610+ *
3611+ * You should have received a copy of the GNU General Public License
3612+ * along with this program; if not, write to the Free Software
3613+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3614+ */
3615+
3616+#include <errno.h>
3617+
3618+#include "luks1/luks.h"
3619+#include "luks2/luks2.h"
3620+#include "keyslot_context.h"
3621+
3622+static int get_luks2_key_by_passphrase(struct crypt_device *cd,
3623+ struct crypt_keyslot_context *kc,
3624+ int keyslot,
3625+ int segment,
3626+ struct volume_key **r_vk)
3627+{
3628+ int r;
3629+
3630+ assert(cd);
3631+ assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
3632+ assert(r_vk);
3633+
3634+ r = LUKS2_keyslot_open(cd, keyslot, segment, kc->u.p.passphrase, kc->u.p.passphrase_size, r_vk);
3635+ if (r < 0)
3636+ kc->error = r;
3637+
3638+ return r;
3639+}
3640+
3641+static int get_luks1_volume_key_by_passphrase(struct crypt_device *cd,
3642+ struct crypt_keyslot_context *kc,
3643+ int keyslot,
3644+ struct volume_key **r_vk)
3645+{
3646+ int r;
3647+
3648+ assert(cd);
3649+ assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
3650+ assert(r_vk);
3651+
3652+ r = LUKS_open_key_with_hdr(keyslot, kc->u.p.passphrase, kc->u.p.passphrase_size,
3653+ crypt_get_hdr(cd, CRYPT_LUKS1), r_vk, cd);
3654+ if (r < 0)
3655+ kc->error = r;
3656+
3657+ return r;
3658+}
3659+
3660+static int get_luks2_volume_key_by_passphrase(struct crypt_device *cd,
3661+ struct crypt_keyslot_context *kc,
3662+ int keyslot,
3663+ struct volume_key **r_vk)
3664+{
3665+ return get_luks2_key_by_passphrase(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk);
3666+}
3667+
3668+static int get_passphrase_by_passphrase(struct crypt_device *cd,
3669+ struct crypt_keyslot_context *kc,
3670+ const char **r_passphrase,
3671+ size_t *r_passphrase_size)
3672+{
3673+ assert(cd);
3674+ assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
3675+ assert(r_passphrase);
3676+ assert(r_passphrase_size);
3677+
3678+ *r_passphrase = kc->u.p.passphrase;
3679+ *r_passphrase_size = kc->u.p.passphrase_size;
3680+
3681+ return 0;
3682+}
3683+
3684+static int get_passphrase_by_keyfile(struct crypt_device *cd,
3685+ struct crypt_keyslot_context *kc,
3686+ const char **r_passphrase,
3687+ size_t *r_passphrase_size)
3688+{
3689+ int r;
3690+
3691+ assert(cd);
3692+ assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
3693+ assert(r_passphrase);
3694+ assert(r_passphrase_size);
3695+
3696+ if (!kc->i_passphrase) {
3697+ r = crypt_keyfile_device_read(cd, kc->u.kf.keyfile,
3698+ &kc->i_passphrase, &kc->i_passphrase_size,
3699+ kc->u.kf.keyfile_offset, kc->u.kf.keyfile_size, 0);
3700+ if (r < 0) {
3701+ kc->error = r;
3702+ return r;
3703+ }
3704+ }
3705+
3706+ *r_passphrase = kc->i_passphrase;
3707+ *r_passphrase_size = kc->i_passphrase_size;
3708+
3709+ return 0;
3710+}
3711+
3712+static int get_luks2_key_by_keyfile(struct crypt_device *cd,
3713+ struct crypt_keyslot_context *kc,
3714+ int keyslot,
3715+ int segment,
3716+ struct volume_key **r_vk)
3717+{
3718+ int r;
3719+ const char *passphrase;
3720+ size_t passphrase_size;
3721+
3722+ assert(cd);
3723+ assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
3724+ assert(r_vk);
3725+
3726+ r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
3727+ if (r)
3728+ return r;
3729+
3730+ r = LUKS2_keyslot_open(cd, keyslot, segment, passphrase, passphrase_size, r_vk);
3731+ if (r < 0)
3732+ kc->error = r;
3733+
3734+ return r;
3735+}
3736+
3737+static int get_luks2_volume_key_by_keyfile(struct crypt_device *cd,
3738+ struct crypt_keyslot_context *kc,
3739+ int keyslot,
3740+ struct volume_key **r_vk)
3741+{
3742+ return get_luks2_key_by_keyfile(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk);
3743+}
3744+
3745+static int get_luks1_volume_key_by_keyfile(struct crypt_device *cd,
3746+ struct crypt_keyslot_context *kc,
3747+ int keyslot,
3748+ struct volume_key **r_vk)
3749+{
3750+ int r;
3751+ const char *passphrase;
3752+ size_t passphrase_size;
3753+
3754+ assert(cd);
3755+ assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
3756+ assert(r_vk);
3757+
3758+ r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
3759+ if (r)
3760+ return r;
3761+
3762+ r = LUKS_open_key_with_hdr(keyslot, passphrase, passphrase_size,
3763+ crypt_get_hdr(cd, CRYPT_LUKS1), r_vk, cd);
3764+ if (r < 0)
3765+ kc->error = r;
3766+
3767+ return r;
3768+}
3769+
3770+static int get_key_by_key(struct crypt_device *cd,
3771+ struct crypt_keyslot_context *kc,
3772+ int keyslot __attribute__((unused)),
3773+ int segment __attribute__((unused)),
3774+ struct volume_key **r_vk)
3775+{
3776+ assert(kc && kc->type == CRYPT_KC_TYPE_KEY);
3777+ assert(r_vk);
3778+
3779+ if (!kc->u.k.volume_key) {
3780+ kc->error = -ENOENT;
3781+ return kc->error;
3782+ }
3783+
3784+ *r_vk = crypt_alloc_volume_key(kc->u.k.volume_key_size, kc->u.k.volume_key);
3785+ if (!*r_vk) {
3786+ kc->error = -ENOMEM;
3787+ return kc->error;
3788+ }
3789+
3790+ return 0;
3791+}
3792+
3793+static int get_volume_key_by_key(struct crypt_device *cd,
3794+ struct crypt_keyslot_context *kc,
3795+ int keyslot __attribute__((unused)),
3796+ struct volume_key **r_vk)
3797+{
3798+ return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
3799+}
3800+
3801+static int get_luks2_key_by_token(struct crypt_device *cd,
3802+ struct crypt_keyslot_context *kc,
3803+ int keyslot __attribute__((unused)),
3804+ int segment,
3805+ struct volume_key **r_vk)
3806+{
3807+ int r;
3808+
3809+ assert(cd);
3810+ assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN);
3811+ assert(r_vk);
3812+
3813+ r = LUKS2_token_unlock_key(cd, crypt_get_hdr(cd, CRYPT_LUKS2), kc->u.t.id, kc->u.t.type,
3814+ kc->u.t.pin, kc->u.t.pin_size, segment, kc->u.t.usrptr, r_vk);
3815+ if (r < 0)
3816+ kc->error = r;
3817+
3818+ return r;
3819+}
3820+
3821+static int get_luks2_volume_key_by_token(struct crypt_device *cd,
3822+ struct crypt_keyslot_context *kc,
3823+ int keyslot __attribute__((unused)),
3824+ struct volume_key **r_vk)
3825+{
3826+ return get_luks2_key_by_token(cd, kc, -2 /* unused */, CRYPT_DEFAULT_SEGMENT, r_vk);
3827+}
3828+
3829+static int get_passphrase_by_token(struct crypt_device *cd,
3830+ struct crypt_keyslot_context *kc,
3831+ const char **r_passphrase,
3832+ size_t *r_passphrase_size)
3833+{
3834+ int r;
3835+
3836+ assert(cd);
3837+ assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN);
3838+ assert(r_passphrase);
3839+ assert(r_passphrase_size);
3840+
3841+ if (!kc->i_passphrase) {
3842+ r = LUKS2_token_unlock_passphrase(cd, crypt_get_hdr(cd, CRYPT_LUKS2), kc->u.t.id,
3843+ kc->u.t.type, kc->u.t.pin, kc->u.t.pin_size,
3844+ kc->u.t.usrptr, &kc->i_passphrase, &kc->i_passphrase_size);
3845+ if (r < 0) {
3846+ kc->error = r;
3847+ return r;
3848+ }
3849+ kc->u.t.id = r;
3850+ }
3851+
3852+ *r_passphrase = kc->i_passphrase;
3853+ *r_passphrase_size = kc->i_passphrase_size;
3854+
3855+ return kc->u.t.id;
3856+}
3857+
3858+static void unlock_method_init_internal(struct crypt_keyslot_context *kc)
3859+{
3860+ assert(kc);
3861+
3862+ kc->error = 0;
3863+ kc->i_passphrase = NULL;
3864+ kc->i_passphrase_size = 0;
3865+}
3866+
3867+void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
3868+ const char *volume_key,
3869+ size_t volume_key_size)
3870+{
3871+ assert(kc);
3872+
3873+ kc->type = CRYPT_KC_TYPE_KEY;
3874+ kc->u.k.volume_key = volume_key;
3875+ kc->u.k.volume_key_size = volume_key_size;
3876+ kc->get_luks2_key = get_key_by_key;
3877+ kc->get_luks2_volume_key = get_volume_key_by_key;
3878+ kc->get_luks1_volume_key = get_volume_key_by_key;
3879+ kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */
3880+ unlock_method_init_internal(kc);
3881+}
3882+
3883+void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
3884+ const char *passphrase,
3885+ size_t passphrase_size)
3886+{
3887+ assert(kc);
3888+
3889+ kc->type = CRYPT_KC_TYPE_PASSPHRASE;
3890+ kc->u.p.passphrase = passphrase;
3891+ kc->u.p.passphrase_size = passphrase_size;
3892+ kc->get_luks2_key = get_luks2_key_by_passphrase;
3893+ kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase;
3894+ kc->get_luks1_volume_key = get_luks1_volume_key_by_passphrase;
3895+ kc->get_passphrase = get_passphrase_by_passphrase;
3896+ unlock_method_init_internal(kc);
3897+}
3898+
3899+void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
3900+ const char *keyfile,
3901+ size_t keyfile_size,
3902+ uint64_t keyfile_offset)
3903+{
3904+ assert(kc);
3905+
3906+ kc->type = CRYPT_KC_TYPE_KEYFILE;
3907+ kc->u.kf.keyfile = keyfile;
3908+ kc->u.kf.keyfile_size = keyfile_size;
3909+ kc->u.kf.keyfile_offset = keyfile_offset;
3910+ kc->get_luks2_key = get_luks2_key_by_keyfile;
3911+ kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile;
3912+ kc->get_luks1_volume_key = get_luks1_volume_key_by_keyfile;
3913+ kc->get_passphrase = get_passphrase_by_keyfile;
3914+ unlock_method_init_internal(kc);
3915+}
3916+
3917+void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
3918+ int token,
3919+ const char *type,
3920+ const char *pin,
3921+ size_t pin_size,
3922+ void *usrptr)
3923+{
3924+ assert(kc);
3925+
3926+ kc->type = CRYPT_KC_TYPE_TOKEN;
3927+ kc->u.t.id = token;
3928+ kc->u.t.type = type;
3929+ kc->u.t.pin = pin;
3930+ kc->u.t.pin_size = pin_size;
3931+ kc->u.t.usrptr = usrptr;
3932+ kc->get_luks2_key = get_luks2_key_by_token;
3933+ kc->get_luks2_volume_key = get_luks2_volume_key_by_token;
3934+ kc->get_luks1_volume_key = NULL; /* LUKS1 is not supported */
3935+ kc->get_passphrase = get_passphrase_by_token;
3936+ unlock_method_init_internal(kc);
3937+}
3938+
3939+void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc)
3940+{
3941+ if (!kc)
3942+ return;
3943+
3944+ crypt_safe_free(kc->i_passphrase);
3945+ kc->i_passphrase = NULL;
3946+ kc->i_passphrase_size = 0;
3947+}
3948+
3949+void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
3950+{
3951+ crypt_keyslot_context_destroy_internal(kc);
3952+ free(kc);
3953+}
3954+
3955+int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd,
3956+ const char *passphrase,
3957+ size_t passphrase_size,
3958+ struct crypt_keyslot_context **kc)
3959+{
3960+ struct crypt_keyslot_context *tmp;
3961+
3962+ if (!kc || !passphrase)
3963+ return -EINVAL;
3964+
3965+ tmp = malloc(sizeof(*tmp));
3966+ if (!tmp)
3967+ return -ENOMEM;
3968+
3969+ crypt_keyslot_unlock_by_passphrase_init_internal(tmp, passphrase, passphrase_size);
3970+
3971+ *kc = tmp;
3972+
3973+ return 0;
3974+}
3975+
3976+int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd,
3977+ const char *keyfile,
3978+ size_t keyfile_size,
3979+ uint64_t keyfile_offset,
3980+ struct crypt_keyslot_context **kc)
3981+{
3982+ struct crypt_keyslot_context *tmp;
3983+
3984+ if (!kc || !keyfile)
3985+ return -EINVAL;
3986+
3987+ tmp = malloc(sizeof(*tmp));
3988+ if (!tmp)
3989+ return -ENOMEM;
3990+
3991+ crypt_keyslot_unlock_by_keyfile_init_internal(tmp, keyfile, keyfile_size, keyfile_offset);
3992+
3993+ *kc = tmp;
3994+
3995+ return 0;
3996+}
3997+
3998+int crypt_keyslot_context_init_by_token(struct crypt_device *cd,
3999+ int token,
4000+ const char *type,
4001+ const char *pin, size_t pin_size,
4002+ void *usrptr,
4003+ struct crypt_keyslot_context **kc)
4004+{
4005+ struct crypt_keyslot_context *tmp;
4006+
4007+ if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN))
4008+ return -EINVAL;
4009+
4010+ tmp = malloc(sizeof(*tmp));
4011+ if (!tmp)
4012+ return -ENOMEM;
4013+
4014+ crypt_keyslot_unlock_by_token_init_internal(tmp, token, type, pin, pin_size, usrptr);
4015+
4016+ *kc = tmp;
4017+
4018+ return 0;
4019+}
4020+
4021+int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd,
4022+ const char *volume_key,
4023+ size_t volume_key_size,
4024+ struct crypt_keyslot_context **kc)
4025+{
4026+ struct crypt_keyslot_context *tmp;
4027+
4028+ if (!kc)
4029+ return -EINVAL;
4030+
4031+ tmp = malloc(sizeof(*tmp));
4032+ if (!tmp)
4033+ return -ENOMEM;
4034+
4035+ crypt_keyslot_unlock_by_key_init_internal(tmp, volume_key, volume_key_size);
4036+
4037+ *kc = tmp;
4038+
4039+ return 0;
4040+}
4041+
4042+int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc)
4043+{
4044+ return kc ? kc->error : -EINVAL;
4045+}
4046+
4047+int crypt_keyslot_context_set_pin(struct crypt_device *cd,
4048+ const char *pin, size_t pin_size,
4049+ struct crypt_keyslot_context *kc)
4050+{
4051+ if (!kc || kc->type != CRYPT_KC_TYPE_TOKEN)
4052+ return -EINVAL;
4053+
4054+ kc->u.t.pin = pin;
4055+ kc->u.t.pin_size = pin_size;
4056+ kc->error = 0;
4057+
4058+ return 0;
4059+}
4060+
4061+int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc)
4062+{
4063+ return kc ? kc->type : -EINVAL;
4064+}
4065+
4066+const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc)
4067+{
4068+ assert(kc);
4069+
4070+ switch (kc->type) {
4071+ case CRYPT_KC_TYPE_PASSPHRASE:
4072+ return "passphrase";
4073+ case CRYPT_KC_TYPE_KEYFILE:
4074+ return "keyfile";
4075+ case CRYPT_KC_TYPE_TOKEN:
4076+ return "token";
4077+ case CRYPT_KC_TYPE_KEY:
4078+ return "key";
4079+ default:
4080+ return "<unknown>";
4081+ }
4082+}
4083diff --git a/lib/keyslot_context.h b/lib/keyslot_context.h
4084new file mode 100644
4085index 0000000..7ca7428
4086--- /dev/null
4087+++ b/lib/keyslot_context.h
4088@@ -0,0 +1,111 @@
4089+/*
4090+ * LUKS - Linux Unified Key Setup, keyslot unlock helpers
4091+ *
4092+ * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
4093+ * Copyright (C) 2022-2023 Ondrej Kozina
4094+ *
4095+ * This program is free software; you can redistribute it and/or
4096+ * modify it under the terms of the GNU General Public License
4097+ * as published by the Free Software Foundation; either version 2
4098+ * of the License, or (at your option) any later version.
4099+ *
4100+ * This program is distributed in the hope that it will be useful,
4101+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4102+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4103+ * GNU General Public License for more details.
4104+ *
4105+ * You should have received a copy of the GNU General Public License
4106+ * along with this program; if not, write to the Free Software
4107+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
4108+ */
4109+
4110+#ifndef KEYSLOT_CONTEXT_H
4111+#define KEYSLOT_CONTEXT_H
4112+
4113+#include <stdbool.h>
4114+#include <stdint.h>
4115+
4116+#include "internal.h"
4117+
4118+typedef int (*keyslot_context_get_key) (
4119+ struct crypt_device *cd,
4120+ struct crypt_keyslot_context *kc,
4121+ int keyslot,
4122+ int segment,
4123+ struct volume_key **r_vk);
4124+
4125+typedef int (*keyslot_context_get_volume_key) (
4126+ struct crypt_device *cd,
4127+ struct crypt_keyslot_context *kc,
4128+ int keyslot,
4129+ struct volume_key **r_vk);
4130+
4131+typedef int (*keyslot_context_get_passphrase) (
4132+ struct crypt_device *cd,
4133+ struct crypt_keyslot_context *kc,
4134+ const char **r_passphrase,
4135+ size_t *r_passphrase_size);
4136+
4137+/* crypt_keyslot_context */
4138+struct crypt_keyslot_context {
4139+ int type;
4140+
4141+ union {
4142+ struct {
4143+ const char *passphrase;
4144+ size_t passphrase_size;
4145+ } p;
4146+ struct {
4147+ const char *keyfile;
4148+ uint64_t keyfile_offset;
4149+ size_t keyfile_size;
4150+ } kf;
4151+ struct {
4152+ int id;
4153+ const char *type;
4154+ const char *pin;
4155+ size_t pin_size;
4156+ void *usrptr;
4157+ } t;
4158+ struct {
4159+ const char *volume_key;
4160+ size_t volume_key_size;
4161+ } k;
4162+ } u;
4163+
4164+ int error;
4165+
4166+ char *i_passphrase;
4167+ size_t i_passphrase_size;
4168+
4169+ keyslot_context_get_key get_luks2_key;
4170+ keyslot_context_get_volume_key get_luks1_volume_key;
4171+ keyslot_context_get_volume_key get_luks2_volume_key;
4172+ keyslot_context_get_passphrase get_passphrase;
4173+};
4174+
4175+void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *method);
4176+
4177+void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
4178+ const char *volume_key,
4179+ size_t volume_key_size);
4180+
4181+void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
4182+ const char *passphrase,
4183+ size_t passphrase_size);
4184+
4185+void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
4186+ const char *keyfile,
4187+ size_t keyfile_size,
4188+ uint64_t keyfile_offset);
4189+
4190+void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
4191+ int token,
4192+ const char *type,
4193+ const char *pin,
4194+ size_t pin_size,
4195+ void *usrptr);
4196+
4197+const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc);
4198+
4199+#endif /* KEYSLOT_CONTEXT_H */
4200diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h
4201index edb3078..e899829 100644
4202--- a/lib/libcryptsetup.h
4203+++ b/lib/libcryptsetup.h
4204@@ -3,8 +3,8 @@
4205 *
4206 * Copyright (C) 2004 Jana Saout <jana@saout.de>
4207 * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
4208- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4209- * Copyright (C) 2009-2022 Milan Broz
4210+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4211+ * Copyright (C) 2009-2023 Milan Broz
4212 *
4213 * This program is free software; you can redistribute it and/or
4214 * modify it under the terms of the GNU General Public License
4215@@ -46,6 +46,7 @@ extern "C" {
4216 */
4217
4218 struct crypt_device; /* crypt device handle */
4219+struct crypt_keyslot_context;
4220
4221 /**
4222 * Initialize crypt device handle and check if the provided device exists.
4223@@ -344,6 +345,7 @@ void crypt_set_iteration_time(struct crypt_device *cd, uint64_t iteration_time_m
4224
4225 /**
4226 * Helper to lock/unlock memory to avoid swap sensitive data to disk.
4227+ * \b Deprecated, only for backward compatibility. Memory with keys are locked automatically.
4228 *
4229 * @param cd crypt device handle, can be @e NULL
4230 * @param lock 0 to unlock otherwise lock memory
4231@@ -353,7 +355,7 @@ void crypt_set_iteration_time(struct crypt_device *cd, uint64_t iteration_time_m
4232 * @note Only root can do this.
4233 * @note It locks/unlocks all process memory, not only crypt context.
4234 */
4235-int crypt_memory_lock(struct crypt_device *cd, int lock);
4236+int crypt_memory_lock(struct crypt_device *cd, int lock) __attribute__((deprecated));
4237
4238 /**
4239 * Set global lock protection for on-disk metadata (file-based locking).
4240@@ -427,6 +429,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
4241 #define CRYPT_INTEGRITY "INTEGRITY"
4242 /** BITLK (BitLocker-compatible mode) */
4243 #define CRYPT_BITLK "BITLK"
4244+/** FVAULT2 (FileVault2-compatible mode) */
4245+#define CRYPT_FVAULT2 "FVAULT2"
4246
4247 /** LUKS any version */
4248 #define CRYPT_LUKS NULL
4249@@ -1107,6 +1111,187 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
4250 uint32_t flags);
4251
4252 /**
4253+ * @defgroup crypt-keyslot-context Crypt keyslot context
4254+ * @addtogroup crypt-keyslot-context
4255+ * @{
4256+ */
4257+
4258+/**
4259+ * Release crypt keyslot context and used memory.
4260+ *
4261+ * @param kc crypt keyslot context
4262+ */
4263+void crypt_keyslot_context_free(struct crypt_keyslot_context *kc);
4264+
4265+/**
4266+ * Initialize keyslot context via passphrase.
4267+ *
4268+ * @param cd crypt device handle initialized to LUKS device context
4269+ * @param passphrase passphrase for a keyslot
4270+ * @param passphrase_size size of passphrase
4271+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_PASSPHRASE
4272+ *
4273+ * @return zero on success or negative errno otherwise.
4274+ */
4275+int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd,
4276+ const char *passphrase,
4277+ size_t passphrase_size,
4278+ struct crypt_keyslot_context **kc);
4279+
4280+/**
4281+ * Initialize keyslot context via key file path.
4282+ *
4283+ * @param cd crypt device handle initialized to LUKS device context
4284+ *
4285+ * @param keyfile key file with passphrase for a keyslot
4286+ * @param keyfile_size number of bytes to read from keyfile, @e 0 is unlimited
4287+ * @param keyfile_offset number of bytes to skip at start of keyfile
4288+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEYFILE
4289+ *
4290+ * @return zero on success or negative errno otherwise.
4291+ */
4292+int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd,
4293+ const char *keyfile,
4294+ size_t keyfile_size,
4295+ uint64_t keyfile_offset,
4296+ struct crypt_keyslot_context **kc);
4297+
4298+/**
4299+ * Initialize keyslot context via LUKS2 token.
4300+ *
4301+ * @param cd crypt device handle initialized to LUKS2 device context
4302+ *
4303+ * @param token token providing passphrase for a keyslot or CRYPT_ANY_TOKEN
4304+ * @param type restrict type of token, if @e NULL all types are allowed
4305+ * @param pin passphrase (or PIN) to unlock token (may be binary data)
4306+ * @param pin_size size of @e pin
4307+ * @param usrptr provided identification in callback
4308+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_TOKEN
4309+ *
4310+ * @return zero on success or negative errno otherwise.
4311+ */
4312+int crypt_keyslot_context_init_by_token(struct crypt_device *cd,
4313+ int token,
4314+ const char *type,
4315+ const char *pin, size_t pin_size,
4316+ void *usrptr,
4317+ struct crypt_keyslot_context **kc);
4318+
4319+/**
4320+ * Initialize keyslot context via key.
4321+ *
4322+ * @param cd crypt device handle initialized to LUKS device context
4323+ *
4324+ * @param volume_key provided volume key or @e NULL if used after crypt_format
4325+ * or with CRYPT_VOLUME_KEY_NO_SEGMENT flag
4326+ * @param volume_key_size size of volume_key
4327+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEY
4328+ *
4329+ * @return zero on success or negative errno otherwise.
4330+ */
4331+int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd,
4332+ const char *volume_key,
4333+ size_t volume_key_size,
4334+ struct crypt_keyslot_context **kc);
4335+
4336+/**
4337+ * Get error code per keyslot context from last failed call.
4338+ *
4339+ * @note If @link crypt_keyslot_add_by_keyslot_context @endlink passed with
4340+ * no negative return code. The return value of this function is undefined.
4341+ *
4342+ * @param kc keyslot context involved in failed @link crypt_keyslot_add_by_keyslot_context @endlink
4343+ *
4344+ * @return Negative errno if keyslot context caused a failure, zero otherwise.
4345+ */
4346+int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc);
4347+
4348+/**
4349+ * Set new pin to token based keyslot context.
4350+ *
4351+ * @note Use when @link crypt_keyslot_add_by_keyslot_context @endlink failed
4352+ * and token keyslot context returned -ENOANO error code via
4353+ * @link crypt_keyslot_context_get_error @endlink.
4354+ *
4355+ * @param cd crypt device handle initialized to LUKS2 device context
4356+ * @param pin passphrase (or PIN) to unlock token (may be binary data)
4357+ * @param pin_size size of @e pin
4358+ * @param kc LUKS2 keyslot context (only @link CRYPT_KC_TYPE_TOKEN @endlink is allowed)
4359+ *
4360+ * @return zero on success or negative errno otherwise
4361+ */
4362+int crypt_keyslot_context_set_pin(struct crypt_device *cd,
4363+ const char *pin, size_t pin_size,
4364+ struct crypt_keyslot_context *kc);
4365+
4366+/**
4367+ * @defgroup crypt-keyslot-context-types Crypt keyslot context
4368+ * @addtogroup crypt-keyslot-context-types
4369+ * @{
4370+ */
4371+/** keyslot context initialized by passphrase (@link crypt_keyslot_context_init_by_passphrase @endlink) */
4372+#define CRYPT_KC_TYPE_PASSPHRASE INT16_C(1)
4373+/** keyslot context initialized by keyfile (@link crypt_keyslot_context_init_by_keyfile @endlink) */
4374+#define CRYPT_KC_TYPE_KEYFILE INT16_C(2)
4375+/** keyslot context initialized by token (@link crypt_keyslot_context_init_by_token @endlink) */
4376+#define CRYPT_KC_TYPE_TOKEN INT16_C(3)
4377+/** keyslot context initialized by volume key or unbound key (@link crypt_keyslot_context_init_by_volume_key @endlink) */
4378+#define CRYPT_KC_TYPE_KEY INT16_C(4)
4379+/** @} */
4380+
4381+/**
4382+ * Get type identifier for crypt keyslot context.
4383+ *
4384+ * @param kc keyslot context
4385+ *
4386+ * @return crypt keyslot context type id (see @link crypt-keyslot-context-types @endlink) or negative errno otherwise.
4387+ */
4388+int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc);
4389+/** @} */
4390+
4391+/**
4392+ * Add key slot by volume key provided by keyslot context (kc). New
4393+ * keyslot will be protected by passphrase provided by new keyslot context (new_kc).
4394+ * See @link crypt-keyslot-context @endlink for context initialization routines.
4395+ *
4396+ * @pre @e cd contains initialized and formatted LUKS device context.
4397+ *
4398+ * @param cd crypt device handle
4399+ * @param keyslot_existing existing keyslot or CRYPT_ANY_SLOT to get volume key from.
4400+ * @param kc keyslot context providing volume key.
4401+ * @param keyslot_new new keyslot or CRYPT_ANY_SLOT (first free number is used).
4402+ * @param new_kc keyslot context providing passphrase for new keyslot.
4403+ * @param flags key flags to set
4404+ *
4405+ * @return allocated key slot number or negative errno otherwise.
4406+ *
4407+ * @note new_kc can not be @e CRYPT_KC_TYPE_KEY type keyslot context.
4408+ *
4409+ * @note For kc parameter with type @e CRYPT_KC_TYPE_KEY the keyslot_existing
4410+ * parameter is ignored.
4411+ *
4412+ * @note in case there is no active LUKS keyslot to get existing volume key from, one of following must apply:
4413+ * @li @e cd must be device handle used in crypt_format() by current process (it holds reference to generated volume key)
4414+ * @li kc must be of @e CRYPT_KC_TYPE_KEY type with valid volume key.
4415+ *
4416+ * @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
4417+ * the new volume_key will be generated and stored in new keyslot. The keyslot will become unbound (unusable to
4418+ * dm-crypt device activation).
4419+ *
4420+ * @warning CRYPT_VOLUME_KEY_SET flag force updates volume key. It is @b not @b reencryption!
4421+ * By doing so you will most probably destroy your ciphertext data device. It's supposed
4422+ * to be used only in wrapped keys scheme for key refresh process where real (inner) volume
4423+ * key stays untouched. It may be involed on active @e keyslot which makes the (previously
4424+ * unbound) keyslot new regular keyslot.
4425+ */
4426+int crypt_keyslot_add_by_keyslot_context(struct crypt_device *cd,
4427+ int keyslot_existing,
4428+ struct crypt_keyslot_context *kc,
4429+ int keyslot_new,
4430+ struct crypt_keyslot_context *new_kc,
4431+ uint32_t flags);
4432+
4433+/**
4434 * Destroy (and disable) key slot.
4435 *
4436 * @pre @e cd contains initialized and formatted LUKS device context
4437@@ -1182,6 +1367,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
4438 #define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (UINT32_C(1) << 25)
4439 /** dm-integrity: reset automatic recalculation */
4440 #define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
4441+/** dm-verity: try to use tasklets */
4442+#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
4443
4444 /**
4445 * Active device runtime attributes
4446@@ -1471,6 +1658,9 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
4447 * @note For TCRYPT cipher chain is the volume key concatenated
4448 * for all ciphers in chain.
4449 * @note For VERITY the volume key means root hash used for activation.
4450+ * @note For LUKS devices, if passphrase is @e NULL and volume key is cached in
4451+ * device context it returns the volume key generated in preceding
4452+ * @link crypt_format @endlink call.
4453 */
4454 int crypt_volume_key_get(struct crypt_device *cd,
4455 int keyslot,
4456@@ -1480,6 +1670,41 @@ int crypt_volume_key_get(struct crypt_device *cd,
4457 size_t passphrase_size);
4458
4459 /**
4460+ * Get volume key from crypt device by keyslot context.
4461+ *
4462+ * @param cd crypt device handle
4463+ * @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
4464+ * @param volume_key buffer for volume key
4465+ * @param volume_key_size on input, size of buffer @e volume_key,
4466+ * on output size of @e volume_key
4467+ * @param kc keyslot context used to unlock volume key
4468+ *
4469+ * @return unlocked key slot number or negative errno otherwise.
4470+ *
4471+ * @note See @link crypt-keyslot-context-types @endlink for info on keyslot
4472+ * context initialization.
4473+ * @note For TCRYPT cipher chain is the volume key concatenated
4474+ * for all ciphers in chain (kc may be NULL).
4475+ * @note For VERITY the volume key means root hash used for activation
4476+ * (kc may be NULL).
4477+ * @note For LUKS devices, if kc is @e NULL and volume key is cached in
4478+ * device context it returns the volume key generated in preceding
4479+ * @link crypt_format @endlink call.
4480+ * @note @link CRYPT_KC_TYPE_TOKEN @endlink keyslot context is usable only with LUKS2 devices.
4481+ * @note @link CRYPT_KC_TYPE_KEY @endlink keyslot context can not be used.
4482+ * @note To get LUKS2 unbound key, keyslot parameter must not be @e CRYPT_ANY_SLOT.
4483+ * @note EPERM errno means provided keyslot context could not unlock any (or selected)
4484+ * keyslot.
4485+ * @note ENOENT errno means no LUKS keyslot is available to retrieve volume key from
4486+ * and there's no cached volume key in device handle.
4487+ */
4488+int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd,
4489+ int keyslot,
4490+ char *volume_key,
4491+ size_t *volume_key_size,
4492+ struct crypt_keyslot_context *kc);
4493+
4494+/**
4495 * Verify that provided volume key is valid for crypt device.
4496 *
4497 * @param cd crypt device handle
4498diff --git a/lib/libcryptsetup.pc.in b/lib/libcryptsetup.pc.in
4499index f3d3fb1..7836293 100644
4500--- a/lib/libcryptsetup.pc.in
4501+++ b/lib/libcryptsetup.pc.in
4502@@ -8,3 +8,4 @@ Description: cryptsetup library
4503 Version: @LIBCRYPTSETUP_VERSION@
4504 Cflags: -I${includedir}
4505 Libs: -L${libdir} -lcryptsetup
4506+Requires.private: @PKGMODULES@
4507diff --git a/lib/libcryptsetup.sym b/lib/libcryptsetup.sym
4508index b845967..d0f0d98 100644
4509--- a/lib/libcryptsetup.sym
4510+++ b/lib/libcryptsetup.sym
4511@@ -151,3 +151,17 @@ CRYPTSETUP_2.5 {
4512 crypt_get_subsystem;
4513 crypt_resume_by_token_pin;
4514 } CRYPTSETUP_2.4;
4515+
4516+CRYPTSETUP_2.6 {
4517+ global:
4518+ crypt_keyslot_context_free;
4519+ crypt_keyslot_context_init_by_passphrase;
4520+ crypt_keyslot_context_init_by_keyfile;
4521+ crypt_keyslot_context_init_by_token;
4522+ crypt_keyslot_context_init_by_volume_key;
4523+ crypt_keyslot_context_get_error;
4524+ crypt_keyslot_context_set_pin;
4525+ crypt_keyslot_context_get_type;
4526+ crypt_keyslot_add_by_keyslot_context;
4527+ crypt_volume_key_get_by_keyslot_context;
4528+} CRYPTSETUP_2.5;
4529diff --git a/lib/libcryptsetup_macros.h b/lib/libcryptsetup_macros.h
4530index d98adfe..55187ab 100644
4531--- a/lib/libcryptsetup_macros.h
4532+++ b/lib/libcryptsetup_macros.h
4533@@ -1,8 +1,8 @@
4534 /*
4535 * Definitions of common constant and generic macros of libcryptsetup
4536 *
4537- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4538- * Copyright (C) 2009-2022 Milan Broz
4539+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4540+ * Copyright (C) 2009-2023 Milan Broz
4541 *
4542 * This program is free software; you can redistribute it and/or
4543 * modify it under the terms of the GNU General Public License
4544diff --git a/lib/libcryptsetup_symver.h b/lib/libcryptsetup_symver.h
4545index aa27f88..a5aa8f9 100644
4546--- a/lib/libcryptsetup_symver.h
4547+++ b/lib/libcryptsetup_symver.h
4548@@ -1,7 +1,7 @@
4549 /*
4550 * Helpers for defining versioned symbols
4551 *
4552- * Copyright (C) 2021-2022 Red Hat, Inc. All rights reserved.
4553+ * Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved.
4554 *
4555 * This program is free software; you can redistribute it and/or
4556 * modify it under the terms of the GNU General Public License
4557@@ -72,9 +72,9 @@
4558 __attribute__((__symver__(#_public_sym _ver_str #_maj "." #_min)))
4559 #endif
4560
4561-#if !defined(_CRYPT_SYMVER) && defined(__GNUC__)
4562+#if !defined(_CRYPT_SYMVER) && (defined(__GNUC__) || defined(__clang__))
4563 # define _CRYPT_SYMVER(_local_sym, _public_sym, _ver_str, _maj, _min) \
4564- asm(".symver " #_local_sym "," #_public_sym _ver_str #_maj "." #_min);
4565+ __asm__(".symver " #_local_sym "," #_public_sym _ver_str #_maj "." #_min);
4566 #endif
4567
4568 #define _CRYPT_FUNC(_public_sym, _prefix_str, _maj, _min, _ret, ...) \
4569diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c
4570index a8d8c2a..9c5fc0c 100644
4571--- a/lib/libdevmapper.c
4572+++ b/lib/libdevmapper.c
4573@@ -3,8 +3,8 @@
4574 *
4575 * Copyright (C) 2004 Jana Saout <jana@saout.de>
4576 * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
4577- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4578- * Copyright (C) 2009-2022 Milan Broz
4579+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4580+ * Copyright (C) 2009-2023 Milan Broz
4581 *
4582 * This program is free software; you can redistribute it and/or
4583 * modify it under the terms of the GNU General Public License
4584@@ -31,7 +31,6 @@
4585 #ifdef HAVE_SYS_SYSMACROS_H
4586 # include <sys/sysmacros.h> /* for major, minor */
4587 #endif
4588-#include <assert.h>
4589 #include "internal.h"
4590
4591 #define DM_CRYPT_TARGET "crypt"
4592@@ -205,6 +204,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
4593 if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
4594 _dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
4595
4596+ if (_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch))
4597+ _dm_flags |= DM_VERITY_TASKLETS_SUPPORTED;
4598+
4599 _dm_verity_checked = true;
4600 }
4601
4602@@ -473,27 +475,22 @@ static size_t int_log10(uint64_t x)
4603 return r;
4604 }
4605
4606-#define CLEN 64 /* 2*MAX_CIPHER_LEN */
4607-#define CLENS "63" /* for sscanf length + '\0' */
4608-#define CAPIL 144 /* should be enough to fit whole capi string */
4609-#define CAPIS "143" /* for sscanf of crypto API string + 16 + \0 */
4610-
4611-static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
4612+static int cipher_dm2c(const char *org_c, const char *org_i, unsigned tag_size,
4613 char *c_dm, int c_dm_size,
4614 char *i_dm, int i_dm_size)
4615 {
4616 int c_size = 0, i_size = 0, i;
4617- char cipher[CLEN], mode[CLEN], iv[CLEN+1], tmp[CLEN];
4618- char capi[CAPIL];
4619+ char cipher[MAX_CAPI_ONE_LEN], mode[MAX_CAPI_ONE_LEN], iv[MAX_CAPI_ONE_LEN+1],
4620+ tmp[MAX_CAPI_ONE_LEN], capi[MAX_CAPI_LEN];
4621
4622 if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
4623 return -EINVAL;
4624
4625- i = sscanf(org_c, "%" CLENS "[^-]-%" CLENS "s", cipher, tmp);
4626+ i = sscanf(org_c, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", cipher, tmp);
4627 if (i != 2)
4628 return -EINVAL;
4629
4630- i = sscanf(tmp, "%" CLENS "[^-]-%" CLENS "s", mode, iv);
4631+ i = sscanf(tmp, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", mode, iv);
4632 if (i == 1) {
4633 memset(iv, 0, sizeof(iv));
4634 strncpy(iv, mode, sizeof(iv)-1);
4635@@ -540,75 +537,6 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
4636 return 0;
4637 }
4638
4639-static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
4640-{
4641- char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN];
4642- char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1];
4643- size_t len;
4644- int i;
4645-
4646- if (!c_dm)
4647- return -EINVAL;
4648-
4649- /* legacy mode */
4650- if (strncmp(c_dm, "capi:", 4)) {
4651- if (!(*org_c = strdup(c_dm)))
4652- return -ENOMEM;
4653- *org_i = NULL;
4654- return 0;
4655- }
4656-
4657- /* modes with capi: prefix */
4658- i = sscanf(c_dm, "capi:%" CAPIS "[^-]-%" CLENS "s", tmp, iv);
4659- if (i != 2)
4660- return -EINVAL;
4661-
4662- len = strlen(tmp);
4663- if (len < 2)
4664- return -EINVAL;
4665-
4666- if (tmp[len-1] == ')')
4667- tmp[len-1] = '\0';
4668-
4669- if (sscanf(tmp, "rfc4309(%" CAPIS "s", capi) == 1) {
4670- if (!(*org_i = strdup("aead")))
4671- return -ENOMEM;
4672- } else if (sscanf(tmp, "rfc7539(%" CAPIS "[^,],%" CLENS "s", capi, auth) == 2) {
4673- if (!(*org_i = strdup(auth)))
4674- return -ENOMEM;
4675- } else if (sscanf(tmp, "authenc(%" CLENS "[^,],%" CAPIS "s", auth, capi) == 2) {
4676- if (!(*org_i = strdup(auth)))
4677- return -ENOMEM;
4678- } else {
4679- if (i_dm) {
4680- if (!(*org_i = strdup(i_dm)))
4681- return -ENOMEM;
4682- } else
4683- *org_i = NULL;
4684- memset(capi, 0, sizeof(capi));
4685- strncpy(capi, tmp, sizeof(capi)-1);
4686- }
4687-
4688- i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher);
4689- if (i == 2)
4690- i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
4691- else
4692- i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
4693- if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) {
4694- free(*org_i);
4695- *org_i = NULL;
4696- return -EINVAL;
4697- }
4698-
4699- if (!(*org_c = strdup(dmcrypt_tmp))) {
4700- free(*org_i);
4701- *org_i = NULL;
4702- return -ENOMEM;
4703- }
4704-
4705- return 0;
4706-}
4707-
4708 static char *_uf(char *buf, size_t buf_size, const char *s, unsigned u)
4709 {
4710 size_t r = snprintf(buf, buf_size, " %s:%u", s, u);
4711@@ -626,7 +554,7 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
4712 if (!tgt)
4713 return NULL;
4714
4715- r = cipher_c2dm(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size,
4716+ r = cipher_dm2c(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size,
4717 cipher_dm, sizeof(cipher_dm), integrity_dm, sizeof(integrity_dm));
4718 if (r < 0)
4719 return NULL;
4720@@ -734,6 +662,8 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
4721 num_options++;
4722 if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
4723 num_options++;
4724+ if (flags & CRYPT_ACTIVATE_TASKLETS)
4725+ num_options++;
4726
4727 max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256;
4728 fec_features = crypt_safe_alloc(max_fec_size);
4729@@ -764,13 +694,14 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
4730 } else
4731 *verity_verify_args = '\0';
4732
4733- if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 */
4734- r = snprintf(features, sizeof(features), " %d%s%s%s%s%s", num_options,
4735+ if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 + 22 */
4736+ r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s", num_options,
4737 (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
4738 (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
4739 (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
4740 (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
4741- (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
4742+ (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "",
4743+ (flags & CRYPT_ACTIVATE_TASKLETS) ? " try_verify_in_tasklet" : "");
4744 if (r < 0 || (size_t)r >= sizeof(features))
4745 goto out;
4746 } else
4747@@ -1705,6 +1636,12 @@ int dm_create_device(struct crypt_device *cd, const char *name,
4748 r = -EINVAL;
4749 }
4750
4751+ if (dmd->flags & CRYPT_ACTIVATE_TASKLETS &&
4752+ !(dmt_flags & DM_VERITY_TASKLETS_SUPPORTED)) {
4753+ log_err(cd, _("Requested dm-verity tasklets option is not supported."));
4754+ r = -EINVAL;
4755+ }
4756+
4757 if (dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
4758 !(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED)) {
4759 log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
4760@@ -2054,9 +1991,7 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
4761
4762 /* cipher */
4763 if (get_flags & DM_ACTIVE_CRYPT_CIPHER) {
4764- r = cipher_dm2c(CONST_CAST(char**)&cipher,
4765- CONST_CAST(char**)&integrity,
4766- rcipher, rintegrity);
4767+ r = crypt_capi_to_cipher(&cipher, &integrity, rcipher, rintegrity);
4768 if (r < 0)
4769 goto err;
4770 }
4771@@ -2289,6 +2224,8 @@ static int _dm_target_query_verity(struct crypt_device *cd,
4772 *act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
4773 else if (!strcasecmp(arg, "check_at_most_once"))
4774 *act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
4775+ else if (!strcasecmp(arg, "try_verify_in_tasklet"))
4776+ *act_flags |= CRYPT_ACTIVATE_TASKLETS;
4777 else if (!strcasecmp(arg, "use_fec_from_device")) {
4778 str = strsep(&params, " ");
4779 str2 = crypt_lookup_dev(str);
4780@@ -2842,7 +2779,8 @@ int dm_query_device(struct crypt_device *cd, const char *name,
4781 return r;
4782 }
4783
4784-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)
4785+static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps,
4786+ char **names, size_t names_offset, size_t names_length)
4787 {
4788 #if HAVE_DECL_DM_DEVICE_GET_NAME
4789 struct crypt_dm_active_device dmd;
4790@@ -2888,7 +2826,8 @@ static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_
4791 #endif
4792 }
4793
4794-int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
4795+int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix,
4796+ char **names, size_t names_length)
4797 {
4798 struct dm_task *dmt;
4799 struct dm_info dmi;
4800diff --git a/lib/loopaes/loopaes.c b/lib/loopaes/loopaes.c
4801index f639670..224d3d0 100644
4802--- a/lib/loopaes/loopaes.c
4803+++ b/lib/loopaes/loopaes.c
4804@@ -1,8 +1,8 @@
4805 /*
4806 * loop-AES compatible volume handling
4807 *
4808- * Copyright (C) 2011-2022 Red Hat, Inc. All rights reserved.
4809- * Copyright (C) 2011-2022 Milan Broz
4810+ * Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
4811+ * Copyright (C) 2011-2023 Milan Broz
4812 *
4813 * This file is free software; you can redistribute it and/or
4814 * modify it under the terms of the GNU Lesser General Public
4815diff --git a/lib/loopaes/loopaes.h b/lib/loopaes/loopaes.h
4816index c777483..a921694 100644
4817--- a/lib/loopaes/loopaes.h
4818+++ b/lib/loopaes/loopaes.h
4819@@ -1,8 +1,8 @@
4820 /*
4821 * loop-AES compatible volume handling
4822 *
4823- * Copyright (C) 2011-2022 Red Hat, Inc. All rights reserved.
4824- * Copyright (C) 2011-2022 Milan Broz
4825+ * Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
4826+ * Copyright (C) 2011-2023 Milan Broz
4827 *
4828 * This file is free software; you can redistribute it and/or
4829 * modify it under the terms of the GNU Lesser General Public
4830diff --git a/lib/luks1/af.c b/lib/luks1/af.c
4831index 12ff78a..76afeac 100644
4832--- a/lib/luks1/af.c
4833+++ b/lib/luks1/af.c
4834@@ -2,7 +2,7 @@
4835 * AFsplitter - Anti forensic information splitter
4836 *
4837 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
4838- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4839+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4840 *
4841 * AFsplitter diffuses information over a large stripe of data,
4842 * therefore supporting secure data destruction.
4843diff --git a/lib/luks1/af.h b/lib/luks1/af.h
4844index 2db78eb..8a2bceb 100644
4845--- a/lib/luks1/af.h
4846+++ b/lib/luks1/af.h
4847@@ -2,7 +2,7 @@
4848 * AFsplitter - Anti forensic information splitter
4849 *
4850 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
4851- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4852+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4853 *
4854 * AFsplitter diffuses information over a large stripe of data,
4855 * therefore supporting secure data destruction.
4856diff --git a/lib/luks1/keyencryption.c b/lib/luks1/keyencryption.c
4857index fbbfc8a..c1c8201 100644
4858--- a/lib/luks1/keyencryption.c
4859+++ b/lib/luks1/keyencryption.c
4860@@ -2,8 +2,8 @@
4861 * LUKS - Linux Unified Key Setup
4862 *
4863 * Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
4864- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4865- * Copyright (C) 2012-2022 Milan Broz
4866+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4867+ * Copyright (C) 2012-2023 Milan Broz
4868 *
4869 * This program is free software; you can redistribute it and/or
4870 * modify it under the terms of the GNU General Public License
4871diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c
4872index f81aaef..fe49a00 100644
4873--- a/lib/luks1/keymanage.c
4874+++ b/lib/luks1/keymanage.c
4875@@ -2,8 +2,8 @@
4876 * LUKS - Linux Unified Key Setup
4877 *
4878 * Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
4879- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4880- * Copyright (C) 2013-2022 Milan Broz
4881+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4882+ * Copyright (C) 2013-2023 Milan Broz
4883 *
4884 * This program is free software; you can redistribute it and/or
4885 * modify it under the terms of the GNU General Public License
4886@@ -28,8 +28,8 @@
4887 #include <stdlib.h>
4888 #include <string.h>
4889 #include <ctype.h>
4890-#include <assert.h>
4891 #include <uuid/uuid.h>
4892+#include <limits.h>
4893
4894 #include "luks.h"
4895 #include "af.h"
4896@@ -232,11 +232,12 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
4897 hdr_size = LUKS_device_sectors(&hdr) << SECTOR_SHIFT;
4898 buffer_size = size_round_up(hdr_size, crypt_getpagesize());
4899
4900- buffer = crypt_safe_alloc(buffer_size);
4901+ buffer = malloc(buffer_size);
4902 if (!buffer || hdr_size < LUKS_ALIGN_KEYSLOTS || hdr_size > buffer_size) {
4903 r = -ENOMEM;
4904 goto out;
4905 }
4906+ memset(buffer, 0, buffer_size);
4907
4908 log_dbg(ctx, "Storing backup of header (%zu bytes) and keyslot area (%zu bytes).",
4909 sizeof(hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);
4910@@ -280,7 +281,8 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
4911 r = 0;
4912 out:
4913 crypt_safe_memzero(&hdr, sizeof(hdr));
4914- crypt_safe_free(buffer);
4915+ crypt_safe_memzero(buffer, buffer_size);
4916+ free(buffer);
4917 return r;
4918 }
4919
4920@@ -308,7 +310,7 @@ int LUKS_hdr_restore(
4921 goto out;
4922 }
4923
4924- buffer = crypt_safe_alloc(buffer_size);
4925+ buffer = malloc(buffer_size);
4926 if (!buffer) {
4927 r = -ENOMEM;
4928 goto out;
4929@@ -379,7 +381,8 @@ int LUKS_hdr_restore(
4930 r = LUKS_read_phdr(hdr, 1, 0, ctx);
4931 out:
4932 device_sync(ctx, device);
4933- crypt_safe_free(buffer);
4934+ crypt_safe_memzero(buffer, buffer_size);
4935+ free(buffer);
4936 return r;
4937 }
4938
4939@@ -922,8 +925,12 @@ int LUKS_set_key(unsigned int keyIndex,
4940 hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
4941 derived_key->key, hdr->keyBytes,
4942 hdr->keyblock[keyIndex].passwordIterations, 0, 0);
4943- if (r < 0)
4944+ if (r < 0) {
4945+ if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) &&
4946+ hdr->keyblock[keyIndex].passwordIterations > INT_MAX)
4947+ log_err(ctx, _("PBKDF2 iteration value overflow."));
4948 goto out;
4949+ }
4950
4951 /*
4952 * AF splitting, the volume key stored in vk->key is split to AfKey
4953@@ -1227,6 +1234,10 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
4954 uint64_t offset, length;
4955 size_t wipe_block;
4956
4957+ r = LUKS_check_device_size(ctx, hdr, 1);
4958+ if (r)
4959+ return r;
4960+
4961 /* Wipe complete header, keyslots and padding areas with zeroes. */
4962 offset = 0;
4963 length = (uint64_t)hdr->payloadOffset * SECTOR_SIZE;
4964diff --git a/lib/luks1/luks.h b/lib/luks1/luks.h
4965index a5a1b7b..9c3f386 100644
4966--- a/lib/luks1/luks.h
4967+++ b/lib/luks1/luks.h
4968@@ -2,7 +2,7 @@
4969 * LUKS - Linux Unified Key Setup
4970 *
4971 * Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
4972- * Copyright (C) 2009-2022 Red Hat, Inc. All rights reserved.
4973+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
4974 *
4975 * This program is free software; you can redistribute it and/or
4976 * modify it under the terms of the GNU General Public License
4977diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h
4978index 3e61993..dfccf02 100644
4979--- a/lib/luks2/luks2.h
4980+++ b/lib/luks2/luks2.h
4981@@ -1,8 +1,8 @@
4982 /*
4983 * LUKS - Linux Unified Key Setup v2
4984 *
4985- * Copyright (C) 2015-2022 Red Hat, Inc. All rights reserved.
4986- * Copyright (C) 2015-2022 Milan Broz
4987+ * Copyright (C) 2015-2023 Red Hat, Inc. All rights reserved.
4988+ * Copyright (C) 2015-2023 Milan Broz
4989 *
4990 * This program is free software; you can redistribute it and/or
4991 * modify it under the terms of the GNU General Public License
4992@@ -121,6 +121,7 @@ struct luks2_hdr {
4993 uint8_t salt2[LUKS2_SALT_L];
4994 char uuid[LUKS2_UUID_L];
4995 void *jobj;
4996+ void *jobj_rollback;
4997 };
4998
4999 struct luks2_keyslot_params {
5000@@ -167,6 +168,7 @@ int LUKS2_hdr_version_unlocked(struct crypt_device *cd,
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches