From 63a3b1968305d7cd67ffa13c5681c7880b642eb4 Mon Sep 17 00:00:00 2001 From: "deepin-community-bot[bot]" <156989552+deepin-community-bot[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 06:19:26 +0000 Subject: [PATCH] feat: update cryptsetup to 2:2.8.2-1 --- .codeql-config.yml | 31 + .gitignore | 3 +- .gitlab-ci.yml | 12 +- .gitlab/ci/alpinelinux.yml | 18 +- .gitlab/ci/annocheck.yml | 9 +- .gitlab/ci/build_srpm | 32 + .gitlab/ci/centos.yml | 60 +- .gitlab/ci/cibuild-setup-ubuntu.sh | 29 +- .gitlab/ci/cifuzz.yml | 55 +- .gitlab/ci/clang-Wall | 3 +- .gitlab/ci/compilation-clang.gitlab-ci.yml | 65 +- .gitlab/ci/compilation-gcc.gitlab-ci.yml | 66 +- .gitlab/ci/compilation-spellcheck.yml | 20 + .gitlab/ci/compilation-various-disables.yml | 32 +- .gitlab/ci/csmock.yml | 29 +- .../ci/{ubuntu-32bit.yml => debian-i686.yml} | 10 +- .gitlab/ci/debian.yml | 152 +- .gitlab/ci/fedora-opal.yml | 145 + .gitlab/ci/fedora.yml | 29 +- .gitlab/ci/gcc-Wall | 5 +- .gitlab/ci/gitlab-shared-docker.yml | 48 +- .gitlab/ci/rhel.yml | 106 - .gitlab/ci/run_csmock | 22 + .gitlab/ci/spellcheck | 31 + .gitlab/issue_templates/Bug.md | 3 + .lgtm.yml | 11 - CONTRIBUTING.md | 5 +- FAQ.md | 19 +- Makefile.am | 6 +- README.licensing | 20 + README.md | 28 +- configure.ac | 75 +- debian/.gitattributes | 1 - debian/README.Debian | 2 +- debian/README.gnupg | 2 +- debian/README.initramfs | 21 +- debian/changelog | 122 +- debian/control | 4 +- debian/copyright | 81 +- debian/functions | 8 +- debian/initramfs/hooks/cryptroot | 19 +- debian/initramfs/po/Makefile | 38 - debian/initramfs/po/cryptroot.pot | 42 - debian/initramfs/po/zh_CN.po | 43 - debian/initramfs/scripts/local-top/cryptroot | 68 +- debian/libcryptsetup12.symbols | 12 + ...-compat-test-from-Makefile.localtest.patch | 49 + debian/patches/series | 1 + debian/po/ca.po | 54 + debian/po/tr.po | 57 + debian/rules | 3 - debian/scripts/decrypt_gnupg | 2 +- .../suspend/cryptsetup-suspend-wrapper | 20 +- debian/tests/control | 26 +- debian/tests/cryptdisks | 4 + debian/tests/cryptroot-lvm.d/mock | 9 +- debian/tests/cryptroot-md.d/setup | 4 +- debian/tests/cryptroot-nested.d/config | 7 + debian/tests/cryptroot-nested.d/setup | 2 +- debian/tests/cryptroot-sysvinit.d/config | 9 +- debian/tests/cryptroot-sysvinit.d/mock | 3 +- debian/tests/utils/cryptroot-common | 13 + debian/tests/utils/init | 7 + debian/tests/utils/initramfs-hook.common | 28 +- debian/tests/utils/mock.pm | 26 +- debian/watch | 13 +- docs/examples/crypt_log_usage.c | 2 +- docs/examples/crypt_luks_usage.c | 2 +- docs/licenses/COPYING.Apache-2.0 | 202 + docs/licenses/COPYING.CC-BY-SA-4.0 | 428 ++ ...or-later-WITH-cryptsetup-OpenSSL-exception | 354 ++ ...or-later-WITH-cryptsetup-OpenSSL-exception | 0 docs/on-disk-format-luks2.pdf | Bin 373190 -> 373682 bytes docs/v2.8.0-ReleaseNotes | 328 ++ docs/v2.8.1-ReleaseNotes | 40 + docs/v2.8.2-ReleaseNotes | 58 + lib/bitlk/bitlk.c | 402 +- lib/bitlk/bitlk.h | 27 +- lib/bitops.h | 6 +- lib/crypt_plain.c | 6 +- lib/crypto_backend/Makemodule.am | 6 +- lib/crypto_backend/argon2/blake2/blake2b.c | 2 +- lib/crypto_backend/argon2/core.c | 11 +- lib/crypto_backend/argon2/encoding.c | 2 +- lib/crypto_backend/argon2_generic.c | 4 +- lib/crypto_backend/base64.c | 4 +- lib/crypto_backend/cipher_check.c | 49 +- lib/crypto_backend/cipher_generic.c | 4 +- lib/crypto_backend/crypto_backend.h | 28 +- lib/crypto_backend/crypto_backend_internal.h | 17 +- lib/crypto_backend/crypto_cipher_kernel.c | 57 +- lib/crypto_backend/crypto_gcrypt.c | 18 +- lib/crypto_backend/crypto_kernel.c | 4 +- lib/crypto_backend/crypto_mbedtls.c | 535 ++ lib/crypto_backend/crypto_nettle.c | 6 +- lib/crypto_backend/crypto_nss.c | 8 +- lib/crypto_backend/crypto_openssl.c | 13 +- lib/crypto_backend/crypto_storage.c | 42 +- lib/crypto_backend/memutils.c | 61 + lib/crypto_backend/meson.build | 1 + lib/crypto_backend/pbkdf2_generic.c | 4 +- lib/crypto_backend/pbkdf_check.c | 9 +- lib/crypto_backend/utf8.c | 19 +- lib/fvault2/fvault2.c | 103 +- lib/fvault2/fvault2.h | 15 +- lib/integrity/integrity.c | 128 +- lib/integrity/integrity.h | 16 +- lib/internal.h | 56 +- lib/keyslot_context.c | 661 ++- lib/keyslot_context.h | 68 +- lib/libcryptsetup.h | 393 +- lib/libcryptsetup.sym | 15 + lib/libcryptsetup_macros.h | 12 +- lib/libcryptsetup_symver.h | 2 +- lib/libdevmapper.c | 635 ++- lib/loopaes/loopaes.c | 32 +- lib/loopaes/loopaes.h | 4 +- lib/luks1/af.c | 2 +- lib/luks1/af.h | 2 +- lib/luks1/keyencryption.c | 21 +- lib/luks1/keymanage.c | 116 +- lib/luks1/luks.h | 2 +- lib/luks2/hw_opal/hw_opal.c | 198 +- lib/luks2/hw_opal/hw_opal.h | 3 +- lib/luks2/luks2.h | 73 +- lib/luks2/luks2_digest.c | 37 +- lib/luks2/luks2_digest_pbkdf2.c | 4 +- lib/luks2/luks2_disk_metadata.c | 98 +- lib/luks2/luks2_internal.h | 47 +- lib/luks2/luks2_json_format.c | 9 +- lib/luks2/luks2_json_metadata.c | 164 +- lib/luks2/luks2_keyslot.c | 301 +- lib/luks2/luks2_keyslot_luks2.c | 95 +- lib/luks2/luks2_keyslot_reenc.c | 4 +- lib/luks2/luks2_luks1_convert.c | 82 +- lib/luks2/luks2_reencrypt.c | 444 +- lib/luks2/luks2_reencrypt_digest.c | 61 +- lib/luks2/luks2_segment.c | 14 +- lib/luks2/luks2_token.c | 89 +- lib/luks2/luks2_token_keyring.c | 4 +- lib/nls.h | 4 +- lib/random.c | 2 +- lib/setup.c | 1679 +++---- lib/tcrypt/tcrypt.c | 333 +- lib/tcrypt/tcrypt.h | 4 +- lib/utils.c | 4 +- lib/utils_benchmark.c | 4 +- lib/utils_blkid.c | 14 +- lib/utils_blkid.h | 2 +- lib/utils_crypt.c | 33 +- lib/utils_crypt.h | 6 +- lib/utils_device.c | 92 +- lib/utils_device_locking.c | 6 +- lib/utils_device_locking.h | 4 +- lib/utils_devpath.c | 41 +- lib/utils_dm.h | 134 +- lib/utils_io.c | 6 +- lib/utils_io.h | 4 +- lib/utils_keyring.c | 133 +- lib/utils_keyring.h | 10 +- lib/utils_loop.c | 6 +- lib/utils_loop.h | 4 +- lib/utils_pbkdf.c | 25 +- lib/utils_safe_memory.c | 42 +- lib/utils_storage_wrappers.c | 19 +- lib/utils_storage_wrappers.h | 2 +- lib/utils_wipe.c | 13 +- lib/verity/rs.h | 2 +- lib/verity/rs_decode_char.c | 2 +- lib/verity/rs_encode_char.c | 2 +- lib/verity/verity.c | 30 +- lib/verity/verity.h | 2 +- lib/verity/verity_fec.c | 2 +- lib/verity/verity_hash.c | 7 +- lib/volumekey.c | 188 +- man/common_footer.adoc | 10 +- man/common_options.adoc | 1239 ++--- man/cryptsetup-benchmark.8.adoc | 24 +- man/cryptsetup-bitlkDump.8.adoc | 15 +- man/cryptsetup-close.8.adoc | 8 +- man/cryptsetup-config.8.adoc | 11 +- man/cryptsetup-convert.8.adoc | 23 +- man/cryptsetup-erase.8.adoc | 18 +- man/cryptsetup-fvault2Dump.8.adoc | 15 +- man/cryptsetup-isLuks.8.adoc | 4 +- man/cryptsetup-luksAddKey.8.adoc | 46 +- man/cryptsetup-luksChangeKey.8.adoc | 44 +- man/cryptsetup-luksConvertKey.8.adoc | 31 +- man/cryptsetup-luksDump.8.adoc | 43 +- man/cryptsetup-luksFormat.8.adoc | 59 +- man/cryptsetup-luksHeaderBackup.8.adoc | 19 +- man/cryptsetup-luksHeaderRestore.8.adoc | 17 +- man/cryptsetup-luksKillSlot.8.adoc | 37 +- man/cryptsetup-luksRemoveKey.8.adoc | 21 +- man/cryptsetup-luksResume.8.adoc | 13 +- man/cryptsetup-luksSuspend.8.adoc | 17 +- man/cryptsetup-luksUUID.8.adoc | 5 +- man/cryptsetup-open.8.adoc | 161 +- man/cryptsetup-reencrypt.8.adoc | 89 +- man/cryptsetup-refresh.8.adoc | 30 +- man/cryptsetup-repair.8.adoc | 43 +- man/cryptsetup-resize.8.adoc | 30 +- man/cryptsetup-ssh.8.adoc | 42 +- man/cryptsetup-tcryptDump.8.adoc | 24 +- man/cryptsetup-token.8.adoc | 42 +- man/cryptsetup.8.adoc | 677 +-- man/integritysetup.8.adoc | 276 +- man/meson.build | 1 + man/veritysetup.8.adoc | 281 +- meson.build | 53 +- meson_options.txt | 4 +- misc/dict_search/crypt_dict.c | 2 +- misc/fedora/cryptsetup.spec | 8 +- misc/keyslot_checker/chk_luks_keyslots.c | 4 +- po/LINGUAS | 1 + po/POTFILES.in | 2 + po/cryptsetup.pot | 1866 ++++--- po/cs.po | 1915 +++---- po/de.po | 2001 ++++---- po/es.po | 1908 +++---- po/fr.po | 1991 ++++---- po/ja.po | 1963 ++++---- po/ka.po | 2347 +++++---- po/pl.po | 1983 ++++---- po/ro.po | 1990 ++++---- po/ru.po | 2111 ++++---- po/sk.po | 4388 +++++++++++++++++ po/sr.po | 2388 +++++---- po/sv.po | 2981 +++++------ po/uk.po | 1989 ++++---- po/zh_CN.po | 3080 ++++++------ src/Makemodule.am | 2 + src/cryptsetup.c | 828 ++-- src/cryptsetup.h | 12 +- src/cryptsetup_arg_list.h | 26 +- src/cryptsetup_args.h | 12 +- src/integritysetup.c | 108 +- src/integritysetup_arg_list.h | 12 +- src/integritysetup_args.h | 5 +- src/meson.build | 8 + src/utils_arg_macros.h | 4 +- src/utils_arg_names.h | 12 +- src/utils_args.c | 4 +- src/utils_blockdev.c | 13 +- src/utils_key_description.c | 159 + src/utils_keyslot_check.c | 199 + src/utils_luks.c | 204 +- src/utils_luks.h | 44 +- src/utils_password.c | 14 +- src/utils_progress.c | 4 +- src/utils_reencrypt.c | 1302 ++++- src/utils_reencrypt_luks1.c | 4 +- src/utils_tools.c | 36 +- src/veritysetup.c | 33 +- src/veritysetup_arg_list.h | 6 +- src/veritysetup_args.h | 5 +- tests/00modules-test | 2 +- tests/Makefile.am | 10 +- tests/align-test | 11 +- tests/align-test2 | 9 +- tests/all-symbols-test.c | 4 +- tests/api-test-2.c | 581 ++- tests/api-test.c | 103 +- tests/api_test.h | 70 +- tests/bitlk-compat-test | 85 +- tests/bitlk-images.tar.xz | Bin 293068 -> 355720 bytes tests/blockwise-compat-test | 7 +- tests/compat-args-test | 20 +- tests/compat-test | 85 +- tests/compat-test-opal | 84 +- tests/compat-test2 | 135 +- tests/crypto-check.c | 109 + tests/crypto-vectors.c | 66 +- tests/device-test | 37 +- tests/differ.c | 2 +- tests/discards-test | 9 +- tests/fuzz/LUKS2.proto | 4 +- tests/fuzz/LUKS2_plain_JSON.proto | 4 +- tests/fuzz/crypt2_load_fuzz.cc | 4 +- tests/fuzz/crypt2_load_proto_fuzz.cc | 4 +- .../fuzz/crypt2_load_proto_plain_json_fuzz.cc | 4 +- tests/fuzz/oss-fuzz-build.sh | 68 +- tests/fuzz/plain_json_proto_to_luks2.cc | 4 +- .../plain_json_proto_to_luks2_converter.cc | 4 +- .../plain_json_proto_to_luks2_converter.h | 4 +- tests/fuzz/proto_to_luks2.cc | 4 +- tests/fuzz/proto_to_luks2_converter.cc | 4 +- tests/fuzz/proto_to_luks2_converter.h | 4 +- tests/fvault2-compat-test | 25 +- tests/generate-symbols-list | 4 +- ...-luks2-area-in-json-hdr-space-json0.img.sh | 4 +- ...nerate-luks2-argon2-leftover-params.img.sh | 4 +- .../generate-luks2-correct-full-json0.img.sh | 4 +- ...s2-corrupted-hdr0-with-correct-chks.img.sh | 4 +- ...s2-corrupted-hdr1-with-correct-chks.img.sh | 4 +- ...te-luks2-invalid-checksum-both-hdrs.img.sh | 4 +- ...enerate-luks2-invalid-checksum-hdr0.img.sh | 4 +- ...enerate-luks2-invalid-checksum-hdr1.img.sh | 4 +- ...generate-luks2-invalid-json-size-c0.img.sh | 4 +- ...generate-luks2-invalid-json-size-c1.img.sh | 4 +- ...generate-luks2-invalid-json-size-c2.img.sh | 4 +- ...rate-luks2-invalid-keyslots-size-c0.img.sh | 4 +- ...rate-luks2-invalid-keyslots-size-c1.img.sh | 4 +- ...rate-luks2-invalid-keyslots-size-c2.img.sh | 4 +- ...ate-luks2-invalid-object-type-json0.img.sh | 4 +- ...te-luks2-invalid-opening-char-json0.img.sh | 4 +- .../generate-luks2-invalid-tokens.img.sh | 4 +- .../generate-luks2-invalid-top-objects.img.sh | 4 +- .../generate-luks2-keyslot-invalid-af.img.sh | 4 +- ...ate-luks2-keyslot-invalid-area-size.img.sh | 4 +- ...generate-luks2-keyslot-invalid-area.img.sh | 4 +- ...erate-luks2-keyslot-invalid-objects.img.sh | 4 +- ...nerate-luks2-keyslot-missing-digest.img.sh | 4 +- ...rate-luks2-keyslot-too-many-digests.img.sh | 4 +- ...-luks2-metadata-size-128k-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-128k.img.sh | 4 +- ...e-luks2-metadata-size-16k-secondary.img.sh | 4 +- ...te-luks2-metadata-size-1m-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-1m.img.sh | 4 +- ...-luks2-metadata-size-256k-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-256k.img.sh | 4 +- ...te-luks2-metadata-size-2m-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-2m.img.sh | 4 +- ...e-luks2-metadata-size-32k-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-32k.img.sh | 4 +- ...te-luks2-metadata-size-4m-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-4m.img.sh | 4 +- ...-luks2-metadata-size-512k-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-512k.img.sh | 4 +- ...luks2-metadata-size-64k-inv-area-c0.img.sh | 4 +- ...luks2-metadata-size-64k-inv-area-c1.img.sh | 4 +- ...adata-size-64k-inv-keyslots-size-c0.img.sh | 4 +- ...e-luks2-metadata-size-64k-secondary.img.sh | 4 +- .../generate-luks2-metadata-size-64k.img.sh | 4 +- ...ks2-metadata-size-invalid-secondary.img.sh | 4 +- ...enerate-luks2-metadata-size-invalid.img.sh | 4 +- ...issing-keyslot-referenced-in-digest.img.sh | 4 +- ...missing-keyslot-referenced-in-token.img.sh | 4 +- ...issing-segment-referenced-in-digest.img.sh | 4 +- ...s2-missing-trailing-null-byte-json0.img.sh | 4 +- ...e-luks2-non-compact-json-4k-token-0.img.sh | 58 + ...rate-luks2-non-compact-json-token-0.img.sh | 52 + ...te-luks2-non-null-byte-beyond-json0.img.sh | 4 +- ...e-luks2-non-null-bytes-beyond-json0.img.sh | 4 +- ...te-luks2-overlapping-areas-c0-json0.img.sh | 4 +- ...te-luks2-overlapping-areas-c1-json0.img.sh | 4 +- ...te-luks2-overlapping-areas-c2-json0.img.sh | 4 +- ...rate-luks2-pbkdf2-leftover-params-0.img.sh | 4 +- ...rate-luks2-pbkdf2-leftover-params-1.img.sh | 4 +- ...uks2-segment-crypt-empty-encryption.img.sh | 4 +- ...s2-segment-crypt-missing-encryption.img.sh | 4 +- ...uks2-segment-crypt-missing-ivoffset.img.sh | 4 +- ...s2-segment-crypt-missing-sectorsize.img.sh | 4 +- ...uks2-segment-crypt-wrong-encryption.img.sh | 4 +- ...-luks2-segment-crypt-wrong-ivoffset.img.sh | 4 +- ...s2-segment-crypt-wrong-sectorsize-0.img.sh | 4 +- ...s2-segment-crypt-wrong-sectorsize-1.img.sh | 4 +- ...s2-segment-crypt-wrong-sectorsize-2.img.sh | 4 +- ...nerate-luks2-segment-missing-offset.img.sh | 4 +- ...generate-luks2-segment-missing-size.img.sh | 4 +- ...generate-luks2-segment-missing-type.img.sh | 4 +- .../generate-luks2-segment-two.img.sh | 4 +- ...generate-luks2-segment-unknown-type.img.sh | 4 +- ...te-luks2-segment-wrong-backup-key-0.img.sh | 4 +- ...te-luks2-segment-wrong-backup-key-1.img.sh | 4 +- ...e-luks2-segment-wrong-flags-element.img.sh | 4 +- .../generate-luks2-segment-wrong-flags.img.sh | 4 +- ...generate-luks2-segment-wrong-offset.img.sh | 4 +- ...generate-luks2-segment-wrong-size-0.img.sh | 4 +- ...generate-luks2-segment-wrong-size-1.img.sh | 4 +- ...generate-luks2-segment-wrong-size-2.img.sh | 4 +- .../generate-luks2-segment-wrong-type.img.sh | 4 +- ...erate-luks2-uint64-max-segment-size.img.sh | 4 +- ...-luks2-uint64-overflow-segment-size.img.sh | 4 +- ...te-luks2-uint64-signed-segment-size.img.sh | 4 +- tests/generators/lib.sh | 62 +- tests/integrity-compat-test | 159 +- tests/keyring-compat-test | 21 +- tests/keyring-test | 12 +- tests/keyring-trusted-test | 187 + tests/loopaes-test | 29 +- tests/luks1-compat-test | 38 +- tests/luks2-integrity-test | 129 +- tests/luks2-reencryption-mangle-test | 49 +- tests/luks2-reencryption-test | 517 +- tests/luks2-validation-test | 38 +- tests/meson.build | 21 + tests/mode-test | 24 +- tests/password-hash-test | 9 +- tests/reencryption-compat-test | 57 +- tests/run-all-symbols | 4 +- tests/ssh-test-plugin | 25 +- tests/systemd-test-plugin | 31 +- tests/tcrypt-compat-test | 107 +- tests/tcrypt-images.tar.xz | Bin 325760 -> 351900 bytes tests/test_utils.c | 25 +- tests/unit-utils-crypt.c | 4 +- tests/unit-utils-io.c | 2 +- tests/unit-wipe-test | 21 +- tests/unit-wipe.c | 2 +- tests/verity-compat-test | 94 +- tokens/ssh/cryptsetup-ssh.c | 4 +- tokens/ssh/libcryptsetup-token-ssh.c | 4 +- tokens/ssh/meson.build | 4 + tokens/ssh/ssh-utils.c | 4 +- tokens/ssh/ssh-utils.h | 4 +- 406 files changed, 35465 insertions(+), 21289 deletions(-) create mode 100644 .codeql-config.yml create mode 100755 .gitlab/ci/build_srpm create mode 100644 .gitlab/ci/compilation-spellcheck.yml rename .gitlab/ci/{ubuntu-32bit.yml => debian-i686.yml} (81%) create mode 100644 .gitlab/ci/fedora-opal.yml delete mode 100644 .gitlab/ci/rhel.yml create mode 100755 .gitlab/ci/run_csmock create mode 100755 .gitlab/ci/spellcheck delete mode 100644 .lgtm.yml create mode 100644 README.licensing delete mode 100644 debian/.gitattributes delete mode 100644 debian/initramfs/po/Makefile delete mode 100644 debian/initramfs/po/cryptroot.pot delete mode 100644 debian/initramfs/po/zh_CN.po create mode 100644 debian/patches/Exclude-reencryption-compat-test-from-Makefile.localtest.patch create mode 100644 debian/patches/series create mode 100644 debian/po/ca.po create mode 100644 debian/po/tr.po create mode 100644 docs/licenses/COPYING.Apache-2.0 create mode 100644 docs/licenses/COPYING.CC-BY-SA-4.0 create mode 100644 docs/licenses/COPYING.GPL-2.0-or-later-WITH-cryptsetup-OpenSSL-exception rename COPYING.LGPL => docs/licenses/COPYING.LGPL-2.1-or-later-WITH-cryptsetup-OpenSSL-exception (100%) create mode 100644 docs/v2.8.0-ReleaseNotes create mode 100644 docs/v2.8.1-ReleaseNotes create mode 100644 docs/v2.8.2-ReleaseNotes create mode 100644 lib/crypto_backend/crypto_mbedtls.c create mode 100644 lib/crypto_backend/memutils.c create mode 100644 po/sk.po create mode 100644 src/utils_key_description.c create mode 100644 src/utils_keyslot_check.c create mode 100644 tests/crypto-check.c create mode 100755 tests/generators/generate-luks2-non-compact-json-4k-token-0.img.sh create mode 100755 tests/generators/generate-luks2-non-compact-json-token-0.img.sh create mode 100755 tests/keyring-trusted-test diff --git a/.codeql-config.yml b/.codeql-config.yml new file mode 100644 index 0000000..1311657 --- /dev/null +++ b/.codeql-config.yml @@ -0,0 +1,31 @@ +name: "Cryptsetup CodeQL config" + +query-filters: +- exclude: + id: cpp/fixme-comment +- exclude: + id: cpp/empty-block +- exclude: + id: cpp/poorly-documented-function +- exclude: + id: cpp/loop-variable-changed +- exclude: + id: cpp/empty-if +- exclude: + id: cpp/long-switch +- exclude: + id: cpp/complex-condition +- exclude: + id: cpp/commented-out-code + +# These produce many false positives +- exclude: + id: cpp/uninitialized-local +- exclude: + id: cpp/path-injection +- exclude: + id: cpp/missing-check-scanf + +# CodeQL should understand coverity [toctou] comments +- exclude: + id: cpp/toctou-race-condition diff --git a/.gitignore b/.gitignore index 3b59b1b..537c3a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ po/*gmo *~ -#Makefile +Makefile Makefile.in Makefile.in.in *.lo @@ -17,6 +17,7 @@ ABOUT-NLS aclocal.m4 autom4te.cache/ compile +compile_commands.json config.guess config.h config.h.in diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3153145..c5c3f26 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,23 +1,23 @@ stages: - test + - test-opal -.dump_kernel_log: +.fail_if_coredump_generated: after_script: - - sudo dmesg > /mnt/artifacts/dmesg.log - - sudo journalctl > /mnt/artifacts/journalctl.log - '[ "$(ls -A /var/coredumps)" ] && exit 1 || true' include: - local: .gitlab/ci/debian.yml - local: .gitlab/ci/fedora.yml - - local: .gitlab/ci/rhel.yml + - local: .gitlab/ci/fedora-opal.yml - local: .gitlab/ci/centos.yml - - local: .gitlab/ci/annocheck.yml +# - local: .gitlab/ci/annocheck.yml - local: .gitlab/ci/csmock.yml - local: .gitlab/ci/gitlab-shared-docker.yml - local: .gitlab/ci/compilation-various-disables.yml - local: .gitlab/ci/compilation-gcc.gitlab-ci.yml - local: .gitlab/ci/compilation-clang.gitlab-ci.yml + - local: .gitlab/ci/compilation-spellcheck.yml - local: .gitlab/ci/alpinelinux.yml - - local: .gitlab/ci/ubuntu-32bit.yml + - local: .gitlab/ci/debian-i686.yml - local: .gitlab/ci/cifuzz.yml diff --git a/.gitlab/ci/alpinelinux.yml b/.gitlab/ci/alpinelinux.yml index 81bd6cb..5c9f587 100644 --- a/.gitlab/ci/alpinelinux.yml +++ b/.gitlab/ci/alpinelinux.yml @@ -1,14 +1,16 @@ .alpinelinux-dependencies: - after_script: - - sudo dmesg > /mnt/artifacts/dmesg.log - - sudo cp /var/log/messages /mnt/artifacts/ - - '[ "$(ls -A /var/coredumps)" ] && exit 1 || true' + variables: + DISTRO: cryptsetup-alpine-edge + extends: + - .fail_if_coredump_generated before_script: - > sudo apk add - lvm2-dev openssl1.1-compat-dev popt-dev util-linux-dev json-c-dev - argon2-dev device-mapper which sharutils gettext gettext-dev automake + lvm2-dev openssl-dev popt-dev util-linux-dev json-c-dev + argon2-dev device-mapper which sharutils gettext-dev argp-standalone automake autoconf libtool build-base keyutils tar jq expect git asciidoctor + # Be sure we have updated basic tools and system + - sudo apk upgrade gcc binutils build-base musl - ./autogen.sh - ./configure --prefix=/usr --libdir=/lib --sbindir=/sbin --disable-static --enable-libargon2 --with-crypto_backend=openssl --disable-external-tokens --disable-ssh-token --enable-asciidoc @@ -17,7 +19,7 @@ test-main-commit-job-alpinelinux: - .alpinelinux-dependencies tags: - libvirt - - alpinelinux + - cryptsetup-alpine-edge stage: test interruptible: true variables: @@ -38,7 +40,7 @@ test-mergerq-job-alpinelinux: - .alpinelinux-dependencies tags: - libvirt - - alpinelinux + - cryptsetup-alpine-edge stage: test interruptible: true variables: diff --git a/.gitlab/ci/annocheck.yml b/.gitlab/ci/annocheck.yml index 5b3a715..8d12dfb 100644 --- a/.gitlab/ci/annocheck.yml +++ b/.gitlab/ci/annocheck.yml @@ -1,19 +1,18 @@ test-main-commit-job-annocheck: extends: - - .dump_kernel_log + - .fail_if_coredump_generated tags: - libvirt - - rhel9-annocheck + - cryptsetup-rhel-9 stage: test interruptible: true allow_failure: true variables: + DISTRO: cryptsetup-rhel-9 RUN_SSH_PLUGIN_TEST: "1" rules: - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" when: never - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ script: - - /opt/build-rpm-script.sh > /dev/null 2>&1 - - annocheck /var/lib/mock/rhel-9.0.0-candidate-x86_64/result/*.rpm --profile=el9 - - annocheck /var/lib/mock/rhel-9.0.0-candidate-x86_64/result/*.rpm --profile=el8 + - sudo /opt/run-annocheck.sh diff --git a/.gitlab/ci/build_srpm b/.gitlab/ci/build_srpm new file mode 100755 index 0000000..240276c --- /dev/null +++ b/.gitlab/ci/build_srpm @@ -0,0 +1,32 @@ +#!/bin/bash + +set -e + +SAVED_PWD=$(pwd) +GIT_DIR="$SAVED_PWD/upstream_git" +SPEC="$GIT_DIR/misc/fedora/cryptsetup.spec" + +rm -fr $GIT_DIR + +git clone -q --depth 1 https://gitlab.com/cryptsetup/cryptsetup.git $GIT_DIR +cd $GIT_DIR + +GIT_COMMIT=$(git rev-parse --short=8 HEAD) +[ -z "$GIT_COMMIT" ] && exit 1 + +sed -i "s/^AC_INIT.*/AC_INIT([cryptsetup],[$GIT_COMMIT])/" $GIT_DIR/configure.ac +sed -i "s/^Version:.*/Version: $GIT_COMMIT/" $SPEC +sed -i "s/%{version_no_tilde}/$GIT_COMMIT/" $SPEC +sed -i "2i %global source_date_epoch_from_changelog 0" $SPEC +sed -i "3i %define _unpackaged_files_terminate_build 0" $SPEC + +./autogen.sh +./configure +make -j dist + +rpmbuild --define "_sourcedir $GIT_DIR" --define "_srcrpmdir $SAVED_PWD" -bs $SPEC + +cd $SAVED_PWD +rm -fr $GIT_DIR + +exit 0 diff --git a/.gitlab/ci/centos.yml b/.gitlab/ci/centos.yml index 6f5559c..310aa15 100644 --- a/.gitlab/ci/centos.yml +++ b/.gitlab/ci/centos.yml @@ -1,14 +1,16 @@ .centos-openssl-backend: extends: - - .dump_kernel_log + - .fail_if_coredump_generated before_script: + - sudo dnf clean all - > sudo dnf -y -q install autoconf automake device-mapper-devel gcc gettext-devel json-c-devel libblkid-devel libpwquality-devel libselinux-devel libssh-devel libtool libuuid-devel make popt-devel libsepol-devel nc openssh-clients passwd pkgconfig sharutils sshpass tar uuid-devel vim-common device-mapper - expect gettext git jq keyutils openssl-devel openssl gem + expect gettext git jq keyutils openssl-devel openssl gem swtpm swtpm-tools + tpm2-tools - sudo gem install asciidoctor - sudo -E git clean -xdf - ./autogen.sh @@ -21,11 +23,13 @@ test-main-commit-centos-stream9: - .centos-openssl-backend tags: - libvirt - - centos-stream9 + - cryptsetup-centos-stream-9 stage: test interruptible: true variables: + DISTRO: cryptsetup-centos-stream-9 RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" rules: - if: $RUN_SYSTEMD_PLUGIN_TEST != null when: never @@ -42,11 +46,59 @@ test-mergerq-centos-stream9: - .centos-openssl-backend tags: - libvirt - - centos-stream9 + - cryptsetup-centos-stream-9 stage: test interruptible: true variables: + DISTRO: cryptsetup-centos-stream-9 RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $RUN_SYSTEMD_PLUGIN_TEST != null + when: never + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + script: + - make -j + - make -j -C tests check-programs + - sudo -E make check + +test-main-commit-centos-stream10: + extends: + - .centos-openssl-backend + tags: + - libvirt + - cryptsetup-centos-stream-10 + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-centos-stream-10 + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $RUN_SYSTEMD_PLUGIN_TEST != null + when: never + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + script: + - make -j + - make -j -C tests check-programs + - sudo -E make check + +test-mergerq-centos-stream10: + extends: + - .centos-openssl-backend + tags: + - libvirt + - cryptsetup-centos-stream-10 + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-centos-stream-10 + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" rules: - if: $RUN_SYSTEMD_PLUGIN_TEST != null when: never diff --git a/.gitlab/ci/cibuild-setup-ubuntu.sh b/.gitlab/ci/cibuild-setup-ubuntu.sh index 07b0990..12649d4 100755 --- a/.gitlab/ci/cibuild-setup-ubuntu.sh +++ b/.gitlab/ci/cibuild-setup-ubuntu.sh @@ -5,17 +5,20 @@ set -ex PACKAGES=( git make autoconf automake autopoint pkg-config libtool libtool-bin gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev - libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev - sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass - asciidoctor + libjson-c-dev libssh-dev libblkid-dev tar libargon2-dev libpwquality-dev + sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client + sshpass asciidoctor ) COMPILER="${COMPILER:?}" COMPILER_VERSION="${COMPILER_VERSION:?}" -grep -E '^deb' /etc/apt/sources.list > /etc/apt/sources.list~ -sed -Ei 's/^deb /deb-src /' /etc/apt/sources.list~ -cat /etc/apt/sources.list~ >> /etc/apt/sources.list +sed -i 's/^Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/ubuntu.sources + +# use this on older Ubuntu +# grep -E '^deb' /etc/apt/sources.list > /etc/apt/sources.list~ +# sed -Ei 's/^deb /deb-src /' /etc/apt/sources.list~ +# cat /etc/apt/sources.list~ >> /etc/apt/sources.list apt-get -y update --fix-missing DEBIAN_FRONTEND=noninteractive apt-get -yq install software-properties-common wget lsb-release @@ -28,7 +31,7 @@ if [[ $COMPILER == "gcc" ]]; then PACKAGES+=(gcc-$COMPILER_VERSION) elif [[ $COMPILER == "clang" ]]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - - add-apt-repository "deb http://apt.llvm.org/${RELEASE}/ llvm-toolchain-${RELEASE}-${COMPILER_VERSION} main" + add-apt-repository -n "deb http://apt.llvm.org/${RELEASE}/ llvm-toolchain-${RELEASE}-${COMPILER_VERSION} main" # scan-build PACKAGES+=(clang-tools-$COMPILER_VERSION clang-$COMPILER_VERSION lldb-$COMPILER_VERSION lld-$COMPILER_VERSION clangd-$COMPILER_VERSION) @@ -37,14 +40,8 @@ else exit 1 fi -apt-get -y update --fix-missing +#apt-get -y update --fix-missing +(r=3;while ! apt-get -y update --fix-missing ; do ((--r))||exit;sleep 5;echo "Retrying";done) + DEBIAN_FRONTEND=noninteractive apt-get -yq install "${PACKAGES[@]}" apt-get -y build-dep cryptsetup - -echo "====================== VERSIONS ===================" -if [[ $COMPILER == "clang" ]]; then - echo "Using scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}" -fi - -${COMPILER}-$COMPILER_VERSION -v -echo "====================== END VERSIONS ===================" diff --git a/.gitlab/ci/cifuzz.yml b/.gitlab/ci/cifuzz.yml index 063b912..add288c 100644 --- a/.gitlab/ci/cifuzz.yml +++ b/.gitlab/ci/cifuzz.yml @@ -1,46 +1,25 @@ cifuzz: - variables: - OSS_FUZZ_PROJECT_NAME: cryptsetup - CFL_PLATFORM: gitlab - CIFUZZ_DEBUG: "True" - FUZZ_SECONDS: 300 # 5 minutes per fuzzer - ARCHITECTURE: "x86_64" - DRY_RUN: "False" - LOW_DISK_SPACE: "True" - BAD_BUILD_CHECK: "True" - LANGUAGE: "c" - DOCKER_HOST: "tcp://docker:2375" - DOCKER_IN_DOCKER: "true" - DOCKER_DRIVER: overlay2 - DOCKER_TLS_CERTDIR: "" - image: - name: gcr.io/oss-fuzz-base/cifuzz-base - entrypoint: [""] - services: - - docker:dind - + image: ubuntu:noble + tags: + - gitlab-org-docker stage: test - parallel: - matrix: - - SANITIZER: [address, undefined, memory] + interruptible: true rules: - # Default code change. - # - if: $CI_PIPELINE_SOURCE == "merge_request_event" - # variables: - # MODE: "code-change" - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" when: never - if: $BUILD_AND_RUN_FUZZERS != null before_script: - # Get gitlab's container id. - - export CFL_CONTAINER_ID=`cut -c9- < /proc/1/cpuset` + - apt-get -y update + - > + apt-get -y install -y -qq git clang make autoconf automake autopoint + pkgconf libtool libtool-bin gettext libssl-dev libdevmapper-dev + libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev + flex bison cmake ninja-build + parallel: + matrix: + # memory does not work for now + - SANITIZER: [address, undefined] script: - # Will build and run the fuzzers. - # We use a hack to override CI_JOB_ID, because otherwise a bad path is used - # in GitLab CI environment - - CI_JOB_ID="$CI_PROJECT_NAMESPACE/$CI_PROJECT_TITLE" python3 "/opt/oss-fuzz/infra/cifuzz/cifuzz_combined_entrypoint.py" - artifacts: - # Upload artifacts when a crash makes the job fail. - when: always - paths: - - artifacts/ + - cd tests/fuzz + - ./oss-fuzz-build.sh + - ls -l out diff --git a/.gitlab/ci/clang-Wall b/.gitlab/ci/clang-Wall index d09e154..52c2dad 100755 --- a/.gitlab/ci/clang-Wall +++ b/.gitlab/ci/clang-Wall @@ -25,10 +25,9 @@ EXTRA="\ -Wswitch \ -Wmissing-format-attribute \ -Winit-self \ - -Wdeclaration-after-statement \ -Wold-style-definition \ -Wno-missing-field-initializers \ - -Wno-unused-parameter \ + -Wunused-parameter \ -Wno-long-long" exec $CLANG $PEDANTIC $CONVERSION \ diff --git a/.gitlab/ci/compilation-clang.gitlab-ci.yml b/.gitlab/ci/compilation-clang.gitlab-ci.yml index 6f5cd42..734348b 100644 --- a/.gitlab/ci/compilation-clang.gitlab-ci.yml +++ b/.gitlab/ci/compilation-clang.gitlab-ci.yml @@ -3,25 +3,86 @@ test-clang-compilation: - .gitlab-shared-clang script: - export CFLAGS="-Wall -Werror" + - ./autogen.sh + - $CC --version - ./configure - make -j - make -j check-programs -test-clang-Wall-script: +test-clang-Wall-script-ubuntu: extends: - .gitlab-shared-clang script: - export CFLAGS="-g -O0" - export CC="$CI_PROJECT_DIR/.gitlab/ci/clang-Wall" + - ./autogen.sh + - $CC --version - ./configure - make -j CFLAGS="-g -O0 -Werror" - make -j CFLAGS="-g -O0 -Werror" check-programs -test-scan-build: +test-clang-Wall-script-alpine: + extends: + - .gitlab-shared-clang-alpine + allow_failure: true + script: + - export CFLAGS="-g -O0" + - export CC="$CI_PROJECT_DIR/.gitlab/ci/clang-Wall" + - ./autogen.sh + - $CC --version + - ./configure + - make -j CFLAGS="-g -O0 -Werror" + - make -j CFLAGS="-g -O0 -Werror" check-programs + +test-scan-build-ubuntu: extends: - .gitlab-shared-clang script: + - ./autogen.sh + - echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}" + - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0" + - make clean + - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j + - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs + +test-scan-build-alpine: + extends: + - .gitlab-shared-clang-alpine + allow_failure: true + script: + - ./autogen.sh + - echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}" - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0" - make clean - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs + +test-scan-build-backends: + extends: + - .gitlab-shared-clang + parallel: + matrix: + - BACKENDS: [ + "openssl", + "gcrypt", + "nss", + "kernel", + "nettle", + "mbedtls" + ] + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + changes: + - lib/crypto_backend/* + script: + - DEBIAN_FRONTEND=noninteractive apt-get -yq install libgcrypt20-dev libnss3-dev nettle-dev libmbedtls-dev + - ./autogen.sh + - echo "Configuring with crypto backend $BACKENDS" + - echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}" + - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0" --with-crypto_backend=$BACKENDS + - make clean + - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j + - scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs + - ./tests/vectors-test diff --git a/.gitlab/ci/compilation-gcc.gitlab-ci.yml b/.gitlab/ci/compilation-gcc.gitlab-ci.yml index 00fae36..482c817 100644 --- a/.gitlab/ci/compilation-gcc.gitlab-ci.yml +++ b/.gitlab/ci/compilation-gcc.gitlab-ci.yml @@ -3,25 +3,83 @@ test-gcc-compilation: - .gitlab-shared-gcc script: - export CFLAGS="-Wall -Werror" + - ./autogen.sh + - $CC --version - ./configure - make -j - make -j check-programs -test-gcc-Wall-script: +test-gcc-Wall-script-ubuntu: extends: - .gitlab-shared-gcc script: - export CFLAGS="-g -O0" - export CC="$CI_PROJECT_DIR/.gitlab/ci/gcc-Wall" + - ./autogen.sh + - $CC --version - ./configure - make -j CFLAGS="-g -O0 -Werror" - make -j CFLAGS="-g -O0 -Werror" check-programs -test-gcc-fanalyzer: +test-gcc-Wall-script-alpine: extends: - - .gitlab-shared-gcc + - .gitlab-shared-gcc-alpine + allow_failure: true script: - - export CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" + - export CFLAGS="-g -O0" + - export CC="$CI_PROJECT_DIR/.gitlab/ci/gcc-Wall" + - ./autogen.sh + - $CC --version - ./configure + - make -j CFLAGS="-g -O0 -Werror" + - make -j CFLAGS="-g -O0 -Werror" check-programs + +test-gcc-fanalyzer-ubuntu: + extends: + - .gitlab-shared-gcc + script: + - ./autogen.sh + - $CC --version + - ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" --host=x86_64 + - make -j + - make -j check-programs + +test-gcc-fanalyzer-alpine: + extends: + - .gitlab-shared-gcc-alpine + allow_failure: true + script: + - ./autogen.sh + - $CC --version + - ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events -Wno-analyzer-fd-leak" --host=x86_64 + - make -j + - make -j check-programs + +test-gcc-fanalyzer-backends: + extends: + - .gitlab-shared-gcc + parallel: + matrix: + - BACKENDS: [ + "openssl", + "gcrypt", + "nss", + "kernel", + "nettle", + "mbedtls" + ] + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + changes: + - lib/crypto_backend/* + script: + - DEBIAN_FRONTEND=noninteractive apt-get -yq install libgcrypt20-dev libnss3-dev nettle-dev libmbedtls-dev + - ./autogen.sh + - $CC --version + - echo "Configuring with crypto backend $BACKENDS" + - ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" --host=x86_64 --with-crypto_backend=$BACKENDS - make -j - make -j check-programs + - ./tests/vectors-test diff --git a/.gitlab/ci/compilation-spellcheck.yml b/.gitlab/ci/compilation-spellcheck.yml new file mode 100644 index 0000000..d53a197 --- /dev/null +++ b/.gitlab/ci/compilation-spellcheck.yml @@ -0,0 +1,20 @@ +test-run-spellcheck: + image: ubuntu:noble + tags: + - gitlab-org-docker + stage: test + interruptible: true + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + artifacts: + name: "spellcheck-$CI_COMMIT_REF_NAME" + paths: + - _spellcheck + before_script: + - apt-get -y update --fix-missing + - apt-get -y install git lintian codespell + script: + - echo "Running spellcheck" + - .gitlab/ci/spellcheck diff --git a/.gitlab/ci/compilation-various-disables.yml b/.gitlab/ci/compilation-various-disables.yml index 1414f9e..00ceae3 100644 --- a/.gitlab/ci/compilation-various-disables.yml +++ b/.gitlab/ci/compilation-various-disables.yml @@ -4,18 +4,30 @@ test-gcc-disable-compiles: parallel: matrix: - DISABLE_FLAGS: [ - "--disable-keyring", - "--disable-external-tokens --disable-ssh-token", - "--disable-luks2-reencryption", - "--disable-cryptsetup --disable-veritysetup --disable-integritysetup", - "--disable-kernel_crypto", - "--disable-selinux", - "--disable-udev", - "--disable-internal-argon2", - "--disable-blkid" + "keyring", + "external-tokens ssh-token", + "luks2-reencryption", + "cryptsetup veritysetup integritysetup", + "kernel_crypto", + "udev", + "internal-argon2", + "blkid", + "hw-opal" ] + artifacts: + name: "meson-build-logs-$CI_COMMIT_REF_NAME" + paths: + - meson_builddir/meson-logs script: + - DEBIAN_FRONTEND=noninteractive apt-get -yq install meson ninja-build - export CFLAGS="-Wall -Werror" - - ./configure $DISABLE_FLAGS + - ./autogen.sh + - echo "Configuring with --disable-$DISABLE_FLAGS" + - ./configure $(for i in $DISABLE_FLAGS; do echo "--disable-$i"; done) - make -j - make -j check-programs + - git checkout -f && git clean -xdf + - meson -v + - echo "Configuring with -D$DISABLE_FLAGS=false" + - meson setup meson_builddir $(for i in $DISABLE_FLAGS; do [ "$i" == "internal-argon2" ] && echo "-Dargon-implementation=internal" || echo "-D$i=false"; done) + - ninja -C meson_builddir diff --git a/.gitlab/ci/csmock.yml b/.gitlab/ci/csmock.yml index 72b53ed..ada2d0c 100644 --- a/.gitlab/ci/csmock.yml +++ b/.gitlab/ci/csmock.yml @@ -1,17 +1,36 @@ +.dnf-csmock: + variables: + DISTRO: cryptsetup-fedora-rawhide + DISK_SIZE: 20 + extends: + - .fail_if_coredump_generated + before_script: + - > + sudo dnf -y -q install + autoconf automake device-mapper-devel gcc gettext-devel json-c-devel + libblkid-devel libpwquality-devel libselinux-devel + libssh-devel libtool libuuid-devel make popt-devel + libsepol-devel.x86_64 pkgconfig tar uuid-devel git + openssl-devel asciidoctor meson ninja-build + rpm-build csmock + test-commit-job-csmock: extends: - - .dump_kernel_log + - .dnf-csmock tags: - libvirt - - rhel7-csmock + - cryptsetup-fedora-rawhide stage: test interruptible: true allow_failure: true - variables: - RUN_SSH_PLUGIN_TEST: "1" rules: - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" when: never - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ || $CI_PIPELINE_SOURCE == "merge_request_event" script: - - /opt/csmock-run-script.sh + - .gitlab/ci/build_srpm + - .gitlab/ci/run_csmock + artifacts: + when: always + paths: + - cryptsetup-csmock-results.tar.xz diff --git a/.gitlab/ci/ubuntu-32bit.yml b/.gitlab/ci/debian-i686.yml similarity index 81% rename from .gitlab/ci/ubuntu-32bit.yml rename to .gitlab/ci/debian-i686.yml index f51c059..09db9e0 100644 --- a/.gitlab/ci/ubuntu-32bit.yml +++ b/.gitlab/ci/debian-i686.yml @@ -1,12 +1,13 @@ -test-mergerq-job-ubuntu-32bit: +test-mergerq-job-debian-i686: extends: - .debian-prep tags: - libvirt - - ubuntu-bionic-32bit + - cryptsetup-debian-12i686 stage: test interruptible: true variables: + DISTRO: cryptsetup-debian-12i686 RUN_SSH_PLUGIN_TEST: "1" rules: - if: $RUN_SYSTEMD_PLUGIN_TEST != null @@ -19,15 +20,16 @@ test-mergerq-job-ubuntu-32bit: - make -j -C tests check-programs - sudo -E make check -test-main-commit-job-ubuntu-32bit: +test-main-commit-job-debian-i686: extends: - .debian-prep tags: - libvirt - - ubuntu-bionic-32bit + - cryptsetup-debian-12i686 stage: test interruptible: true variables: + DISTRO: cryptsetup-debian-12i686 RUN_SSH_PLUGIN_TEST: "1" rules: - if: $RUN_SYSTEMD_PLUGIN_TEST != null diff --git a/.gitlab/ci/debian.yml b/.gitlab/ci/debian.yml index fad9d97..0cb4480 100644 --- a/.gitlab/ci/debian.yml +++ b/.gitlab/ci/debian.yml @@ -1,17 +1,16 @@ .debian-prep: extends: - - .dump_kernel_log + - .fail_if_coredump_generated before_script: - - > - [ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] || - sudo apt-get -y install -y -qq swtpm meson ninja-build python3-jinja2 - gperf libcap-dev tpm2-tss-engine-dev libmount-dev swtpm-tools + - sudo apt-get -y update - > sudo apt-get -y install -y -qq git gcc make autoconf automake autopoint pkgconf libtool libtool-bin gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev - tar libargon2-0-dev libpwquality-dev sharutils dmsetup jq xxd expect - keyutils netcat passwd openssh-client sshpass asciidoctor + tar libargon2-dev libpwquality-dev sharutils dmsetup jq xxd expect + keyutils netcat-openbsd passwd openssh-client sshpass asciidoctor + swtpm meson ninja-build python3-jinja2 gperf libcap-dev libtss2-dev + libmount-dev swtpm-tools tpm2-tools - sudo apt-get -y build-dep cryptsetup - sudo -E git clean -xdf - ./autogen.sh @@ -22,11 +21,13 @@ test-mergerq-job-debian: - .debian-prep tags: - libvirt - - debian11 + - cryptsetup-debian-unstable stage: test interruptible: true variables: + DISTRO: cryptsetup-debian-unstable RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" rules: - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" when: never @@ -41,11 +42,55 @@ test-main-commit-job-debian: - .debian-prep tags: - libvirt - - debian11 + - cryptsetup-debian-unstable + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-debian-unstable + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + script: + - make -j + - make -j -C tests check-programs + - sudo -E make check + +test-mergerq-job-debian12: + extends: + - .debian-prep + tags: + - libvirt + - cryptsetup-debian-12 + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-debian-12 + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + script: + - make -j + - make -j -C tests check-programs + - sudo -E make check + +test-main-commit-job-debian12: + extends: + - .debian-prep + tags: + - libvirt + - cryptsetup-debian-12 stage: test interruptible: true variables: + DISTRO: cryptsetup-debian-12 RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" rules: - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" when: never @@ -54,3 +99,92 @@ test-main-commit-job-debian: - make -j - make -j -C tests check-programs - sudo -E make check + +# meson tests +test-mergerq-job-debian-meson: + extends: + - .debian-prep + tags: + - libvirt + - cryptsetup-debian-unstable + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-debian-unstable + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + script: + - sudo apt-get -y install -y -qq meson ninja-build + - meson setup build + - ninja -C build + - cd build && sudo -E meson test --verbose --print-errorlogs + +test-main-commit-job-debian-meson: + extends: + - .debian-prep + tags: + - libvirt + - cryptsetup-debian-unstable + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-debian-unstable + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + script: + - sudo apt-get -y install -y -qq meson ninja-build + - meson setup build + - ninja -C build + - cd build && sudo -E meson test --verbose --print-errorlogs + +test-mergerq-job-debian12-meson: + extends: + - .debian-prep + tags: + - libvirt + - cryptsetup-debian-12 + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-debian-12 + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + script: + - sudo apt-get -y install -y -qq meson ninja-build + - meson setup build + - ninja -C build + - cd build && sudo -E meson test --verbose --print-errorlogs + +test-main-commit-job-debian12-meson: + extends: + - .debian-prep + tags: + - libvirt + - cryptsetup-debian-12 + stage: test + interruptible: true + variables: + DISTRO: cryptsetup-debian-12 + RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + script: + - sudo apt-get -y install -y -qq meson ninja-build + - meson setup build + - ninja -C build + - cd build && sudo -E meson test --verbose --print-errorlogs diff --git a/.gitlab/ci/fedora-opal.yml b/.gitlab/ci/fedora-opal.yml new file mode 100644 index 0000000..d7072bf --- /dev/null +++ b/.gitlab/ci/fedora-opal.yml @@ -0,0 +1,145 @@ +.opal-template-fedora: + extends: + - .dnf-openssl-backend + tags: + - libvirt + - cryptsetup-fedora-rawhide + stage: test-opal + interruptible: false + variables: + OPAL2_DEV: "/dev/nvme0n1" + OPAL2_PSID_FILE: "/home/gitlab-runner/psid.txt" + VOLATILE: 1 + script: + - sudo dnf install -y -q nvme-cli + - sudo nvme list + - make -j + - make -j -C tests check-programs + - sudo -E make check TESTS="00modules-test compat-test-opal" + +# Samsung SSD 980 500GB (on tiber machine) +test-commit-rawhide-samsung980: + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + extends: + - .opal-template-fedora + tags: + - tiber + resource_group: samsung980-on-tiber + interruptible: false + variables: + PCI_PASSTHROUGH_VENDOR_ID: "144d" + PCI_PASSTHROUGH_DEVICE_ID: "a809" + +test-mergerq-rawhide-samsung980: + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + extends: + - .opal-template-fedora + tags: + - tiber + resource_group: samsung980-on-tiber + interruptible: false + variables: + PCI_PASSTHROUGH_VENDOR_ID: "144d" + PCI_PASSTHROUGH_DEVICE_ID: "a809" + +# WD PC SN740 SDDQNQD-512G-1014 (on tiber machine) +# Disabled on 2025-03-20, seems broken +#test-commit-rawhide-sn740: +# rules: +# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" +# when: never +# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ +# extends: +# - .opal-template-fedora +# tags: +# - tiber +# resource_group: sn740-on-tiber +# interruptible: false +# variables: +# PCI_PASSTHROUGH_VENDOR_ID: "15b7" +# PCI_PASSTHROUGH_DEVICE_ID: "5017" +# +#test-mergerq-rawhide-sn740: +# rules: +# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" +# when: never +# - if: $CI_PIPELINE_SOURCE == "merge_request_event" +# extends: +# - .opal-template-fedora +# tags: +# - tiber +# resource_group: sn740-on-tiber +# interruptible: false +# variables: +# PCI_PASSTHROUGH_VENDOR_ID: "15b7" +# PCI_PASSTHROUGH_DEVICE_ID: "5017" + +# Samsung SSD 980 PRO 1TB (on trantor machine) +test-commit-rawhide-samsung980pro: + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + extends: + - .opal-template-fedora + tags: + - trantor + resource_group: samsung980pro-on-trantor + interruptible: false + variables: + PCI_PASSTHROUGH_VENDOR_ID: "144d" + PCI_PASSTHROUGH_DEVICE_ID: "a80a" + +test-mergerq-rawhide-samsung980pro: + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + extends: + - .opal-template-fedora + tags: + - trantor + resource_group: samsung980pro-on-trantor + interruptible: false + variables: + PCI_PASSTHROUGH_VENDOR_ID: "144d" + PCI_PASSTHROUGH_DEVICE_ID: "a80a" + +# # UMIS RPETJ256MGE2MDQ (on tiber machine) +# test-commit-rawhide-umis: +# rules: +# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" +# when: never +# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ +# extends: +# - .opal-template-fedora +# tags: +# - tiber +# resource_group: umis-on-tiber +# stage: test +# interruptible: false +# variables: +# PCI_PASSTHROUGH_VENDOR_ID: "1cc4" +# PCI_PASSTHROUGH_DEVICE_ID: "6302" +# +# test-mergerq-rawhide-umis: +# rules: +# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" +# when: never +# - if: $CI_PIPELINE_SOURCE == "merge_request_event" +# extends: +# - .opal-template-fedora +# tags: +# - tiber +# resource_group: umis-on-tiber +# stage: test +# interruptible: false +# variables: +# PCI_PASSTHROUGH_VENDOR_ID: "1cc4" +# PCI_PASSTHROUGH_DEVICE_ID: "6302" diff --git a/.gitlab/ci/fedora.yml b/.gitlab/ci/fedora.yml index 7fd9c7e..cbd1e13 100644 --- a/.gitlab/ci/fedora.yml +++ b/.gitlab/ci/fedora.yml @@ -1,20 +1,19 @@ .dnf-openssl-backend: - extends: - - .dump_kernel_log - before_script: - - > - [ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] || - sudo dnf -y -q install - swtpm meson ninja-build python3-jinja2 gperf libcap-devel tpm2-tss-devel - libmount-devel swtpm-tools - - > - sudo dnf -y -q install + variables: + DISTRO: cryptsetup-fedora-rawhide + PKGS: >- autoconf automake device-mapper-devel gcc gettext-devel json-c-devel libargon2-devel libblkid-devel libpwquality-devel libselinux-devel libssh-devel libtool libuuid-devel make popt-devel libsepol-devel.x86_64 netcat openssh-clients passwd pkgconfig sharutils sshpass tar uuid-devel vim-common device-mapper expect gettext git jq - keyutils openssl-devel openssl asciidoctor + keyutils openssl-devel openssl asciidoctor swtpm meson ninja-build + python3-jinja2 gperf libcap-devel tpm2-tss-devel libmount-devel swtpm-tools + extends: + - .fail_if_coredump_generated + before_script: + - sudo dnf clean all + - (r=3;while ! sudo dnf -y -q install $PKGS ; do ((--r))||exit;sleep 5;echo "Retrying";done) - sudo -E git clean -xdf - ./autogen.sh - ./configure --enable-fips --enable-pwquality --enable-libargon2 --with-crypto_backend=openssl --enable-asciidoc @@ -24,12 +23,14 @@ test-main-commit-job-rawhide: - .dnf-openssl-backend tags: - libvirt - - fedora-rawhide + - cryptsetup-fedora-rawhide stage: test interruptible: true allow_failure: true variables: RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + RUN_SYSTEMD_PLUGIN_TEST: "1" rules: - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" when: never @@ -44,12 +45,14 @@ test-mergerq-job-rawhide: - .dnf-openssl-backend tags: - libvirt - - fedora-rawhide + - cryptsetup-fedora-rawhide stage: test interruptible: true allow_failure: true variables: RUN_SSH_PLUGIN_TEST: "1" + RUN_KEYRING_TRUSTED_TEST: "1" + RUN_SYSTEMD_PLUGIN_TEST: "1" rules: - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" when: never diff --git a/.gitlab/ci/gcc-Wall b/.gitlab/ci/gcc-Wall index 6669504..bc78705 100755 --- a/.gitlab/ci/gcc-Wall +++ b/.gitlab/ci/gcc-Wall @@ -31,12 +31,13 @@ EXTRA="-Wextra \ -Wunsafe-loop-optimizations \ -Wold-style-definition \ -Wno-missing-field-initializers \ - -Wno-unused-parameter \ + -Wunused-parameter \ -Wno-long-long \ -Wmaybe-uninitialized \ -Wvla \ -Wformat-overflow \ - -Wformat-truncation" + -Wformat-truncation \ + -Wstringop-overread" exec $GCC $PEDANTIC $CONVERSION \ -Wall $Wuninitialized \ diff --git a/.gitlab/ci/gitlab-shared-docker.yml b/.gitlab/ci/gitlab-shared-docker.yml index 1edacc8..59659e8 100644 --- a/.gitlab/ci/gitlab-shared-docker.yml +++ b/.gitlab/ci/gitlab-shared-docker.yml @@ -1,5 +1,6 @@ -.gitlab-shared-docker: - image: ubuntu:focal +# Ubuntu +.gitlab-shared-docker-ubuntu: + image: ubuntu:noble tags: - gitlab-org-docker stage: test @@ -12,20 +13,49 @@ - .gitlab/ci/cibuild-setup-ubuntu.sh - export CC="${COMPILER}${COMPILER_VERSION:+-$COMPILER_VERSION}" - export CXX="${COMPILER}++${COMPILER_VERSION:+-$COMPILER_VERSION}" - - ./autogen.sh + +# Alpine +.gitlab-shared-docker-alpine: + image: alpine:latest + tags: + - gitlab-org-docker + stage: test + interruptible: true + rules: + - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ + before_script: + - apk add bash build-base clang clang-analyzer argp-standalone lvm2-dev openssl-dev popt-dev util-linux-dev json-c-dev device-mapper gettext-dev libssh-dev automake autoconf libtool tar asciidoctor + - export CC="${COMPILER}${COMPILER_VERSION:+-$COMPILER_VERSION}" + - export CXX="${COMPILER}++${COMPILER_VERSION:+-$COMPILER_VERSION}" .gitlab-shared-gcc: extends: - - .gitlab-shared-docker + - .gitlab-shared-docker-ubuntu variables: COMPILER: "gcc" - COMPILER_VERSION: "11" - RUN_SSH_PLUGIN_TEST: "1" + COMPILER_VERSION: "14" + CC: "gcc-14" .gitlab-shared-clang: extends: - - .gitlab-shared-docker + - .gitlab-shared-docker-ubuntu + variables: + COMPILER: "clang" + COMPILER_VERSION: "20" + CC: "clang-20" + +.gitlab-shared-gcc-alpine: + extends: + - .gitlab-shared-docker-alpine + variables: + COMPILER: "gcc" + CC: "gcc" + +.gitlab-shared-clang-alpine: + extends: + - .gitlab-shared-docker-alpine variables: COMPILER: "clang" - COMPILER_VERSION: "13" - RUN_SSH_PLUGIN_TEST: "1" + CC: "clang" diff --git a/.gitlab/ci/rhel.yml b/.gitlab/ci/rhel.yml deleted file mode 100644 index f71533c..0000000 --- a/.gitlab/ci/rhel.yml +++ /dev/null @@ -1,106 +0,0 @@ -.rhel-openssl-backend: - extends: - - .dump_kernel_log - before_script: - - > - sudo yum -y -q install - autoconf automake device-mapper-devel gcc gettext-devel json-c-devel - libblkid-devel libpwquality-devel libselinux-devel libssh-devel libtool - libuuid-devel make popt-devel libsepol-devel nc openssh-clients passwd - pkgconfig sharutils sshpass tar uuid-devel vim-common device-mapper - expect gettext git jq keyutils openssl-devel openssl gem > /dev/null 2>&1 - - sudo gem install asciidoctor - - sudo -E git clean -xdf - - ./autogen.sh - - ./configure --enable-fips --enable-pwquality --with-crypto_backend=openssl --enable-asciidoc - -# non-FIPS jobs - -test-main-commit-rhel8: - extends: - - .rhel-openssl-backend - tags: - - libvirt - - rhel8 - stage: test - interruptible: true - variables: - RUN_SSH_PLUGIN_TEST: "1" - rules: - - if: $RUN_SYSTEMD_PLUGIN_TEST != null - when: never - - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" - when: never - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ - script: - - make -j - - make -j -C tests check-programs - - sudo -E make check - -test-main-commit-rhel9: - extends: - - .rhel-openssl-backend - tags: - - libvirt - - rhel9 - stage: test - interruptible: true - variables: - RUN_SSH_PLUGIN_TEST: "1" - rules: - - if: $RUN_SYSTEMD_PLUGIN_TEST != null - when: never - - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" - when: never - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ - script: - - make -j - - make -j -C tests check-programs - - sudo -E make check - -# FIPS jobs - -test-main-commit-rhel8-fips: - extends: - - .rhel-openssl-backend - tags: - - libvirt - - rhel8-fips - stage: test - interruptible: true - variables: - RUN_SSH_PLUGIN_TEST: "1" - rules: - - if: $RUN_SYSTEMD_PLUGIN_TEST != null - when: never - - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" - when: never - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ - script: - - fips-mode-setup --check || exit 1 - - make -j - - make -j -C tests check-programs - - sudo -E make check - -test-main-commit-rhel9-fips: - extends: - - .rhel-openssl-backend - tags: - - libvirt - - rhel9-fips - stage: test - interruptible: true - allow_failure: true - variables: - RUN_SSH_PLUGIN_TEST: "1" - rules: - - if: $RUN_SYSTEMD_PLUGIN_TEST != null - when: never - - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup" - when: never - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ - script: - - fips-mode-setup --check || exit 1 - - make -j - - make -j -C tests check-programs - - sudo -E make check diff --git a/.gitlab/ci/run_csmock b/.gitlab/ci/run_csmock new file mode 100755 index 0000000..707e0ff --- /dev/null +++ b/.gitlab/ci/run_csmock @@ -0,0 +1,22 @@ +#!/bin/bash + +CSMOCK="sudo /usr/bin/csmock" +CSMOCK_TOOLS="gcc,clang,cppcheck,shellcheck" +CSMOCK_TXZ="cryptsetup-csmock-results.tar.xz" +CSMOCK_ERR="cryptsetup-csmock-results/scan-results.err" + +$CSMOCK cryptsetup-*.src.rpm \ + --keep-going --force \ + --cswrap-timeout 300 \ + --skip-patches \ + --tools $CSMOCK_TOOLS \ + --output $CSMOCK_TXZ \ + --gcc-analyze \ + --cppcheck-add-flag=--check-level=exhaustive \ + || { echo "csmock command failed"; exit 2; } + +tar xJf $CSMOCK_TXZ $CSMOCK_ERR --strip-components 1 \ + && test -s $CSMOCK_ERR \ + && { echo "csmock discovered important errors"; echo 3; } + +exit 0 diff --git a/.gitlab/ci/spellcheck b/.gitlab/ci/spellcheck new file mode 100755 index 0000000..6a92f62 --- /dev/null +++ b/.gitlab/ci/spellcheck @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e +DIR="_spellcheck" + +[ ! -d $DIR ] && mkdir $DIR + +echo "[SPELLINTIAN]" +git ls-tree -rz --name-only HEAD | grep -Evz -e '\.(pdf|xz)$' -e ^po/ | \ + xargs -r0 spellintian | \ + grep -v "(duplicate word)" | \ + grep -v "docs/" | tee $DIR/spell1.txt + +echo "[CODESPELL]" +git ls-tree -rz --name-only HEAD | grep -Evz -e '\.(pdf|xz)$' -e ^po/ | \ + xargs -r0 codespell | \ + grep -v "EXPCT" | \ + grep -v "params, prams" | \ + grep -v "pad, padded" | \ + grep -v "CIPHER, CHIP" | \ + grep -v "gost" | \ + grep -v "userA" | \ + grep -v "re-use" | \ + grep -v "fo ==" | \ + grep -v "docs/" | tee $DIR/spell2.txt + + +[ -s $DIR/spell1.txt ] && exit 1 +[ -s $DIR/spell2.txt ] && exit 2 + +exit 0 diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md index f8837aa..88ad54b 100644 --- a/.gitlab/issue_templates/Bug.md +++ b/.gitlab/issue_templates/Bug.md @@ -9,7 +9,10 @@ ### Debug log + + ``` Output with --debug option: ``` + diff --git a/.lgtm.yml b/.lgtm.yml deleted file mode 100644 index 64d9cc8..0000000 --- a/.lgtm.yml +++ /dev/null @@ -1,11 +0,0 @@ -queries: - - exclude: cpp/fixme-comment - - exclude: cpp/empty-block -# symver attribute detection cannot be used, disable it for lgtm -extraction: - cpp: - configure: - command: - - "./autogen.sh" - - "./configure --enable-external-tokens --enable-ssh-token" - - "echo \"#undef HAVE_ATTRIBUTE_SYMVER\" >> config.h" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01bea7c..e929b6e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,7 +119,7 @@ libtool --mode=execute gdb --args ./cryptsetup --debug $@ This will ensure that a properly compiled libcryptsetup file is used. ### Coding style -Cryptsetup uses [Linux kernel coding style](https://www.kernel.org/doc/html/latest/process/coding-style.html) for libcryptsetup and tools (where applicable) with some additional notes: +Cryptsetup uses [Linux kernel coding style](https://cdn.kernel.org/doc/html/latest/process/coding-style.html) for libcryptsetup and tools (where applicable) with some additional notes: - Use tabulators for indentation; the line should not exceed 100 characters with an 8-character tabulator. Otherwise, use a tab of any length. :-). - The minimal C standard required is C99. - The ``goto`` use is allowed only for error path (``goto out`` for common code path, ``goto err`` for specific error code path). @@ -127,7 +127,8 @@ Cryptsetup uses [Linux kernel coding style](https://www.kernel.org/doc/html/late - Use an elaborative description in the patch header. - No need to use sign-off-by lines. - Use name prefixes (``crypt_``, ``LUKS2_`` and similar). -- Avoid extensive preprocessor use (specifically ``#ifdef`` sections). +- Avoid extensive preprocessor use (specifically conditional ``#if`` or ``#ifdef`` sections). +- To check detected configuration options stored in config.h, always use ``#if SOMETHING`` (do NOT use ``#ifdef``). - Use output only through ``log_err, log_std, log_verbose, log_dbg`` macros. The ``log_dbg`` is always in English; the others should be wrapped in the ``_()`` macro for translation. - Use ``assert()`` but only for simple invariants and variables (avoid calling functions). diff --git a/FAQ.md b/FAQ.md index 4441ff5..21e806f 100644 --- a/FAQ.md +++ b/FAQ.md @@ -38,7 +38,7 @@ LUKS1 and LUKS2. The LUKS1 on-disk format specification is at - https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf + https://cdn.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf The LUKS2 on-disk format specification is at https://gitlab.com/cryptsetup/LUKS2-docs @@ -705,9 +705,12 @@ this. The only legitimate reason I can think of is if you want to have two LUKS devices with the same volume key. Even then, I think it would be preferable to just use key-slots with the same passphrase, or to use - plain dm-crypt instead. If you really have a good reason, please tell - me. If I am convinced, I will add how to do this here. + plain dm-crypt instead. + Use the --volume-key-file option, like this: +``` + cryptsetup luksFormat --volume-key-file keyfile /dev/loop0 +``` * **2.12 What are the security requirements for a key read from file?** @@ -1923,10 +1926,6 @@ Hence, LUKS has no kill option because it would do much more harm than good. - Still, if you have a good use-case (i.e. non-abstract real-world - situation) where a Nuke-Option would actually be beneficial, please let - me know. - * **5.22 Does cryptsetup open network connections to websites, etc. ?** @@ -2680,8 +2679,7 @@ can be converted to the raw volume key for example via: Note that at the time this FAQ item was written, 1.5.4 was the latest 1.5.x version and it has the flaw, i.e. works with the old Whirlpool - version. Possibly later 1.5.x versions will work as well. If not, - please let me know. + version. Possibly later 1.5.x versions will work as well. The only two ways to access older LUKS containers created with Whirlpool are to either decrypt with an old gcrypt version that has the flaw or to @@ -2797,8 +2795,7 @@ can be converted to the raw volume key for example via: 03) Creating your own initrd The two examples below should give you most of what is needed. This is - tested with LUKS1 and should work with LUKS2 as well. If not, please - let me know. + tested with LUKS1 and should work with LUKS2 as well. Here is a really minimal example. It does nothing but set up some things and then drop to an interactive shell. It is perfect to try out diff --git a/Makefile.am b/Makefile.am index 1be9ed7..688cb77 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -EXTRA_DIST = README.md SECURITY.md COPYING.LGPL CONTRIBUTING.md FAQ.md docs misc autogen.sh +EXTRA_DIST = README.md SECURITY.md README.licensing CONTRIBUTING.md FAQ.md docs misc autogen.sh EXTRA_DIST += meson_options.txt \ meson.build \ lib/crypto_backend/argon2/meson.build \ @@ -9,6 +9,7 @@ EXTRA_DIST += meson_options.txt \ scripts/meson.build \ src/meson.build \ tests/meson.build \ + tests/fuzz/meson.build \ tokens/meson.build \ tokens/ssh/meson.build @@ -24,8 +25,7 @@ AM_CPPFLAGS = \ -DLIBDIR=\""$(libdir)"\" \ -DPREFIX=\""$(prefix)"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ - -DVERSION=\""$(VERSION)"\" \ - -DEXTERNAL_LUKS2_TOKENS_PATH=\"${EXTERNAL_LUKS2_TOKENS_PATH}\" + -DVERSION=\""$(VERSION)"\" AM_CFLAGS = -Wall AM_CXXFLAGS = -Wall AM_LDFLAGS = diff --git a/README.licensing b/README.licensing new file mode 100644 index 0000000..c20b52a --- /dev/null +++ b/README.licensing @@ -0,0 +1,20 @@ +The cryptsetup project does not use the same license for all of the code and documentation. + +There is code and documentation under: + + * GPL-2.0-or-later - GNU General Public License version 2, or any later version + + * LGPL-2.1-or-later WITH cryptsetup-OpenSSL-exception + * LGPL-2.1-or-later - GNU Lesser General Public License 2.1 or any later version, + (with cryptsetup-OpenSSL-exception where applicable) + + * Apache-2.0 - Apache License 2.0 + + * CC-BY-SA-4.0 - Creative Commons Attribution Share Alike 4.0 International + + * Public Domain + +Please, check the source code for more details. + +The ./COPYING file (GPL-2.0-or-later) is the default license for code without +an explicitly defined license. diff --git a/README.md b/README.md index 7fc88a3..7b57c17 100644 --- a/README.md +++ b/README.md @@ -30,28 +30,22 @@ which enables users to transport or migrate data seamlessly. * The latest version of the [LUKS2 format specification](https://gitlab.com/cryptsetup/LUKS2-docs). * The latest version of the - [LUKS1 format specification](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf). + [LUKS1 format specification](https://cdn.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf). * [Project home page](https://gitlab.com/cryptsetup/cryptsetup/). * [Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions) Download -------- Release notes and tarballs are available at -[kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/). +[kernel.org](https://cdn.kernel.org/pub/linux/utils/cryptsetup/). -**The latest stable cryptsetup release version is 2.7.5** - * [cryptsetup-2.7.5.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/cryptsetup-2.7.5.tar.xz) - * Signature [cryptsetup-2.7.5.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/cryptsetup-2.7.5.tar.sign) +**The latest stable cryptsetup release version is 2.8.2** + * [cryptsetup-2.8.2.tar.xz](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.2.tar.xz) + * Signature [cryptsetup-2.8.2.tar.sign](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.2.tar.sign) _(You need to decompress file first to check signature.)_ - * [Cryptsetup 2.7.5 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/v2.7.5-ReleaseNotes). + * [Cryptsetup 2.8.2 Release Notes](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/v2.8.2-ReleaseNotes). -Previous versions - * [Version 2.6.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.xz) - - [Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.sign) - - [Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/v2.5.0-ReleaseNotes). - * [Version 1.7.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.xz) - - [Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.sign) - - [Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.5-ReleaseNotes). +[Previous versions](https://cdn.kernel.org/pub/linux/utils/cryptsetup) Source and API documentation ---------------------------- @@ -76,8 +70,7 @@ Below are the packages needed to build for certain Linux distributions: **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 +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 rubygem-asciidoctor Optionally: libargon2-devel libpwquality-devel ``` @@ -88,14 +81,13 @@ sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openss **For Debian and Ubuntu**: ``` -git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev -libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev tar +git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev tar asciidoctor Optionally: libargon2-0-dev libpwquality-dev ``` To run the internal testsuite (make check) you also need to install ``` -sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass +sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client sshpass ``` Note that the list may change as Linux distributions evolve. diff --git a/configure.ac b/configure.ac index e2e73db..4ceece7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,9 @@ AC_PREREQ([2.67]) -AC_INIT([cryptsetup],[2.7.5]) +AC_INIT([cryptsetup],[2.8.2]) dnl library version from ..[-] LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-) -LIBCRYPTSETUP_VERSION_INFO=22:0:10 +LIBCRYPTSETUP_VERSION_INFO=23:0:11 AM_SILENT_RULES([yes]) AC_CONFIG_SRCDIR(src/cryptsetup.c) @@ -399,6 +399,23 @@ AC_DEFUN([CONFIGURE_NETTLE], [ NO_FIPS([]) ]) +AC_DEFUN([CONFIGURE_MBEDTLS], [ + AC_CHECK_HEADERS(mbedtls/version.h,, + [AC_MSG_ERROR([You need mbedTLS cryptographic library.])]) + + saved_LIBS=$LIBS + AC_CHECK_LIB(mbedcrypto, mbedtls_md_init,, + [AC_MSG_ERROR([You need mbedTLS cryptographic library.])]) + AC_CHECK_FUNCS(mbedtls_pkcs5_pbkdf2_hmac_ext) + CRYPTO_LIBS=$LIBS + LIBS=$saved_LIBS + + CRYPTO_STATIC_LIBS=$CRYPTO_LIBS + use_internal_pbkdf2=0 + use_internal_argon2=1 + NO_FIPS([]) +]) + dnl ========================================================================== saved_LIBS=$LIBS @@ -481,7 +498,7 @@ fi dnl Crypto backend configuration. AC_ARG_WITH([crypto_backend], - AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [openssl]]), + AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle/mbedtls) [openssl]]), [], [with_crypto_backend=openssl]) dnl Kernel crypto API backend needed for benchmark and tcrypt @@ -501,6 +518,7 @@ case $with_crypto_backend in nss) CONFIGURE_NSS([]) ;; kernel) CONFIGURE_KERNEL([]) ;; nettle) CONFIGURE_NETTLE([]) ;; + mbedtls) CONFIGURE_MBEDTLS([]) ;; *) AC_MSG_ERROR([Unknown crypto backend.]) ;; esac AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test "$with_crypto_backend" = "gcrypt") @@ -508,6 +526,7 @@ AM_CONDITIONAL(CRYPTO_BACKEND_OPENSSL, test "$with_crypto_backend" = "openssl") AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test "$with_crypto_backend" = "nss") AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test "$with_crypto_backend" = "kernel") AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test "$with_crypto_backend" = "nettle") +AM_CONDITIONAL(CRYPTO_BACKEND_MBEDTLS, test "$with_crypto_backend" = "mbedtls") AM_CONDITIONAL(CRYPTO_INTERNAL_PBKDF2, test $use_internal_pbkdf2 = 1) AC_DEFINE_UNQUOTED(USE_INTERNAL_PBKDF2, [$use_internal_pbkdf2], [Use internal PBKDF2]) @@ -661,8 +680,36 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]) CFLAGS=$saved_CFLAGS +dnl Force compiler to use zero_call_used_regs("used") to check for the function attribute support. +dnl Otherwise the compiler may falsely advertise it with __has_attribute operator, even though +dnl it does not implement it on some archs. +AC_MSG_CHECKING([for zero_call_used_regs(user)]) +saved_CFLAGS=$CFLAGS +CFLAGS="-O0 -Werror" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + void _test_function(void); + __attribute__((zero_call_used_regs("used"))) void _test_function(void) { + volatile int *i; volatile int j = 0; if (j) *i = 0; + } +]], +[[ _test_function() ]] +)],[ + AC_DEFINE([HAVE_ATTRIBUTE_ZEROCALLUSEDREGS], 1, [Define to 1 to use __attribute__((zero_call_used_regs("used")))]) + AC_MSG_RESULT([yes]) +], [ + AC_MSG_RESULT([no]) +]) +CFLAGS=$saved_CFLAGS + AC_MSG_CHECKING([for systemd tmpfiles config directory]) -PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no]) +if test "x$prefix" != "xNONE"; then + saved_PKG_CONFIG=$PKG_CONFIG + PKG_CONFIG="$PKG_CONFIG --define-variable=prefix='${prefix}'" + PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no]) + PKG_CONFIG=$saved_PKG_CONFIG +else + PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no]) +fi AC_MSG_RESULT([$systemd_tmpfilesdir]) AC_SUBST([DEVMAPPER_LIBS]) @@ -776,8 +823,9 @@ CS_NUM_WITH([verity-hash-block], [hash block size for verity mode], [4096]) CS_NUM_WITH([verity-salt-size], [salt size for verity mode], [32]) CS_NUM_WITH([verity-fec-roots], [parity bytes for verity FEC], [2]) -CS_STR_WITH([tmpfilesdir], [override default path to directory with systemd temporary files], []) -test -z "$with_tmpfilesdir" && with_tmpfilesdir=$systemd_tmpfilesdir +AC_ARG_WITH([tmpfilesdir], + AS_HELP_STRING([--with-tmpfilesdir=DIR], [override default path to directory with systemd temporary files]), + [], [with_tmpfilesdir=$systemd_tmpfilesdir]) test "x$with_tmpfilesdir" = "xno" || { CS_ABSPATH([${with_tmpfilesdir}],[with-tmpfilesdir]) DEFAULT_TMPFILESDIR=$with_tmpfilesdir @@ -796,7 +844,9 @@ test -z "$with_luks2_lock_dir_perms" && with_luks2_lock_dir_perms=0700 DEFAULT_LUKS2_LOCK_DIR_PERMS=$with_luks2_lock_dir_perms AC_SUBST(DEFAULT_LUKS2_LOCK_DIR_PERMS) -CS_STR_WITH([luks2-external-tokens-path], [path to directory with LUKSv2 external token handlers (plugins)], [LIBDIR/cryptsetup]) +AC_ARG_WITH([luks2-external-tokens-path], + AS_HELP_STRING([--with-luks2-external-tokens-path=DIR], [path to directory with LUKSv2 external token handlers (plugins)]), + [], [with_luks2_external_tokens_path=""]) if test -n "$with_luks2_external_tokens_path"; then CS_ABSPATH([${with_luks2_external_tokens_path}],[with-luks2-external-tokens-path]) EXTERNAL_LUKS2_TOKENS_PATH=$with_luks2_external_tokens_path @@ -804,6 +854,17 @@ else EXTERNAL_LUKS2_TOKENS_PATH="\${libdir}/cryptsetup" fi AC_SUBST(EXTERNAL_LUKS2_TOKENS_PATH) +dnl We need to define expanded EXTERNAL_LUKS2_TOKENS_PATH, but some other code can depend on prefix=NONE. +dnl Pretend you do not see this hack :-) +saved_prefix=$prefix +saved_exec_prefix=$exec_prefix +test "x$prefix" = "xNONE" && prefix="$ac_default_prefix" +test "x$exec_prefix" = "xNONE" && exec_prefix="$prefix" +expanded_EXTERNAL_LUKS2_TOKENS_PATH=$(eval echo "$EXTERNAL_LUKS2_TOKENS_PATH") +expanded_EXTERNAL_LUKS2_TOKENS_PATH=$(eval echo "$expanded_EXTERNAL_LUKS2_TOKENS_PATH") +AC_DEFINE_UNQUOTED([EXTERNAL_LUKS2_TOKENS_PATH], ["$expanded_EXTERNAL_LUKS2_TOKENS_PATH"], [path to directory with LUKSv2 external token handlers (plugins)]) +prefix=$saved_prefix +exec_prefix=$saved_exec_prefix dnl Override default LUKS format version (for cryptsetup or cryptsetup-reencrypt format actions only). AC_ARG_WITH([default_luks_format], diff --git a/debian/.gitattributes b/debian/.gitattributes deleted file mode 100644 index 592f8c4..0000000 --- a/debian/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -/changelog merge=dpkg-mergechangelogs diff --git a/debian/README.Debian b/debian/README.Debian index 99633bf..d8e28bc 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -277,7 +277,7 @@ manage the keyslots for both original and backup device independently. 10. Changing the boot order of cryptdisks init scripts ------------------------------------------------------ +------------------------------------------------------ In order to support non-standard setups, it might be necessary to change the order of init scripts in the boot process. Cryptsetup already installs two diff --git a/debian/README.gnupg b/debian/README.gnupg index 837d151..5aa26d8 100644 --- a/debian/README.gnupg +++ b/debian/README.gnupg @@ -10,7 +10,7 @@ The following example assumes that you store the encrypted keyfile in First, you'll have to create the encrypted keyfile: dd if=/dev/random bs=1 count=256 | gpg --no-options --no-random-seed-file \ - --no-default-keyring --keyring /dev/null --secret-keyring /dev/null \ + --no-default-keyring --keyring /dev/null \ --trustdb-name /dev/null --symmetric --output /etc/keys/cryptkey.gpg Next the LUKS device needs to be formated with the key. For that, the diff --git a/debian/README.initramfs b/debian/README.initramfs index d85ae9c..1afbc90 100644 --- a/debian/README.initramfs +++ b/debian/README.initramfs @@ -247,13 +247,13 @@ this limitation: [#671037]: https://bugs.debian.org/671037 -12. Storing keyfiles directly in the initrd -------------------------------------------- +12. Storing keyfiles directly in the initramfs +---------------------------------------------- Normally devices using a keyfile are ignored (with a loud warning), and -the key file itself is not included in the initrd, because the initramfs +the key file itself is not included in the initramfs, because the initramfs image typically lives on an unencrypted `/boot` partition. However in -some cases it is desirable to include the key file in the initrd; for +some cases it is desirable to include the key file in the initramfs; for instance recent versions of GRUB support booting from encrypted block devices, allowing an encrypted `/boot` partition. @@ -262,7 +262,7 @@ of the environment variable KEYFILE_PATTERN (interpreted as a shell pattern) will be included in the initramfs image. For instance if `/etc/crypttab` lists two key files `/etc/keys/{root,swap}.key`, you can add the following to `/etc/cryptsetup-initramfs/conf-hook` to add them to -the initrd. +the initramfs. KEYFILE_PATTERN="/etc/keys/*.key" @@ -273,6 +273,17 @@ following to `/etc/initramfs-tools/initramfs.conf`. UMASK=0077 +13. The stages in the initramfs at which dm-crypt devices are mapped +-------------------------------------------------------------------- + +The devices necessary for the root filesystem, /usr, any resume swap device and +any device with the `initramfs`-option in `crypttab` are first tried to be +mapped (that is: "opened" or "decrypted") in `initramfs-tools`'s `local-top`- +phase. +Any which couldn't be mapped there are retried in the `local-block`-phase. + +This may be subject to change. + -- David Härdeman -- Jonas Meurer Thu, 01 Nov 2012 13:44:31 +0100 diff --git a/debian/changelog b/debian/changelog index f9a68ae..f7d3489 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,20 +1,108 @@ -cryptsetup (2:2.7.5-1deepin2.3) unstable; urgency=medium - - * add Chinese localization to cryptroot - - -- Liang Bo Thu, 26 Apr 2025 16:40:22 +0800 - -cryptsetup (2:2.7.5-1deepin2.2) unstable; urgency=medium - - * skip ERROR on usr-overlay device when updating initramfs - - -- Liang Bo Mon, 28 Apr 2024 16:00:51 +0800 - -cryptsetup (2:2.7.5-1deepin2.1) unstable; urgency=medium - - * revert to 2:2.7.5-1 - - -- Liang Bo Tue, 01 Apr 2024 14:52:13 +0800 +cryptsetup (2:2.8.2-1) unstable; urgency=medium + + * New upstream bugfix release. + * d/t/cryptdisks: Add calls to `udevadm settle`. + * d/control: Remove `Rules-Requires-Root: no`. + * d/watch: Port to Version 5. + + -- Guilhem Moulin Thu, 18 Dec 2025 22:04:25 +0100 + +cryptsetup (2:2.8.1-2) unstable; urgency=medium + + * Exclude `reencryption-compat-test` from Makefile.localtest. + (Closes: #1122539) + + -- Guilhem Moulin Thu, 11 Dec 2025 23:29:35 +0100 + +cryptsetup (2:2.8.1-1) unstable; urgency=medium + + * New upstream release. + * DEP-8: Don't skip TPM trusted upstream tests. This adds `Depends: + swtpm, swtpm-tools, tpm2-tools` to the upstream testsuite autopkgtest. + * DEP-8: Don't skip upstream's systemd plugin tests. This adds `Depends: + systemd-cryptsetup` to the upstream testsuite autopkgtest. + + -- Guilhem Moulin Tue, 19 Aug 2025 13:38:37 +0200 + +cryptsetup (2:2.8.0-3) unstable; urgency=medium + + [ Nuri KÜÇÜKLER ] + * Add Turkish debconf templates translation. + + [ Luca Boccassi ] + * DEP-8: Remove 80-systemd-osc-context.sh bash profile drop-in from + cryptroot-* test images in order to fix compatibility with systemd v258. + (Closes: #1110818) + + -- Guilhem Moulin Wed, 13 Aug 2025 13:38:32 +0200 + +cryptsetup (2:2.8.0-2) unstable; urgency=medium + + * Upload to unstable. + + -- Guilhem Moulin Sat, 09 Aug 2025 22:21:31 +0200 + +cryptsetup (2:2.8.0-1) experimental; urgency=medium + + * New upstream release. + + -- Guilhem Moulin Tue, 24 Jun 2025 11:40:36 +0200 + +cryptsetup (2:2.8.0~rc1-1) experimental; urgency=low + + * New upstream release candidate. + * Drop d/patches/* applied upstream. + + -- Guilhem Moulin Mon, 16 Jun 2025 15:44:19 +0200 + +cryptsetup (2:2.8.0~rc0-1) experimental; urgency=low + + * New upstream release candidate 2.8.0, with support for inline mode (use HW + sectors with additional hardware metadata space). + * DEP-8: Add Depends: e2fsprogs. + * d/libcryptsetup12.symbols: Add new symbols. + * Adjust d/copyright. + * DEP-8: Build libcrypto_backend.la and crypto-check before running the + upstream test suite. + + -- Guilhem Moulin Thu, 12 Jun 2025 19:00:45 +0200 + +cryptsetup (2:2.7.5-2) unstable; urgency=medium + + [ Christoph Anton Mitterer ] + * d/README.Debian: Minor improvements. + * d/README.Debian: Document when during the initramfs devices are mapped. + * d/README.Debian: Change initrd to initramfs. + + [ Stephen Gildea ] + * initramfs hook: Improve the "Source mismatch" error message when + /etc/crypttab gives a source device that does not match the current + source. + + [ Guilhem Moulin ] + * DEP-8: No longer mark cryptroot-* as flaky and only run them on amd64, see + https://bugs.debian.org/1073052#50. + * Fix d/t/initramfs-hook and d/t/initramfs-hook-legacy with initramfs-tools + ≥0.146. (Closes: #1099818) + * cryptsetup-suspend-wrapper, DEP-8: Don't hardcode unmkinitramfs destdir. + * d/t/cryptroot-*: Pass --bitmap=internal to mdadm(8). + * decrypt_gnupg: Drop obsolete option --secret-keyring. (Closes: #1099760) + * initramfs hook: Add vmx_crypto module. (Closes: #1087271) + * d/copyright: Replace FSF's old postal address with an URL. + * Update Standards-Version to 4.7.2 (no changes necessary). + * Boot script: Fix prereq() logic between directories. (Closes: #1081552) + + [ Carles Pina i Estany ] + * Added po-debconf Catalan translation. (Closes: #1101115) + + [ Vladimir Petko ] + * Fix cryptroot-* autopkgtests on Ubuntu. (Closes: #1031198) + + [ Nicolas Melot ] + * initramfs: Process crypttab entries with the 'initramfs' option first and + preserve their order. (Closes: #1055024) + + -- Guilhem Moulin Sun, 04 May 2025 21:55:13 +0200 cryptsetup (2:2.7.5-1) unstable; urgency=medium diff --git a/debian/control b/debian/control index 69372a4..16663f2 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,6 @@ Priority: optional Maintainer: Debian Cryptsetup Team Uploaders: Jonas Meurer , Guilhem Moulin -Rules-Requires-Root: no Build-Depends: asciidoctor , autoconf, automake (>= 1:1.12), @@ -24,13 +23,14 @@ Build-Depends: asciidoctor , libssh-dev, libssl-dev (>> 3.2~), libtool, + openssl-provider-legacy , pkgconf, po-debconf, procps , uuid-dev, xsltproc , xxd -Standards-Version: 4.7.0 +Standards-Version: 4.7.2 Homepage: https://gitlab.com/cryptsetup/cryptsetup Vcs-Browser: https://salsa.debian.org/cryptsetup-team/cryptsetup Vcs-Git: https://salsa.debian.org/cryptsetup-team/cryptsetup.git -b debian/latest diff --git a/debian/copyright b/debian/copyright index 2334d87..963374a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -6,8 +6,8 @@ Upstream-Name: cryptsetup Files: * Copyright: © 2004 Christophe Saout © 2004-2008 Clemens Fruhwirth - © 2008-2023 Red Hat, Inc. - © 2008-2023 Milan Broz + © 2008-2025 Red Hat, Inc. + © 2008-2025 Milan Broz License: GPL-2+ with OpenSSL exception Files: debian/* @@ -15,7 +15,7 @@ Copyright: © 2004-2005 Wesley W. Terpstra © 2005-2006 Michael Gebetsroither © 2006-2008 David Härdeman © 2005-2015 Jonas Meurer - © 2016-2023 Guilhem Moulin + © 2016-2025 Guilhem Moulin License: GPL-2+ Files: debian/scripts/suspend/cryptsetup-suspend.c @@ -57,37 +57,37 @@ Copyright: © 2005-2015 Jonas Meurer License: GPL-2+ Files: debian/tests/* -Copyright: © 2021-2022 Guilhem Moulin +Copyright: © 2021-2025 Guilhem Moulin License: GPL-3+ -Files: docs/examples/* tests/all-symbols-test.c -Copyright: © 2011-2023 Red Hat, Inc. +Files: docs/examples/* tests/all-symbols-test.c tests/crypto-check.c +Copyright: © 2011-2025 Red Hat, Inc. License: LGPL-2.1+ Files: lib/bitlk/* -Copyright: © 2019-2023 Red Hat, Inc. - © 2019-2023 Milan Broz - © 2019-2023 Vojtech Trefny +Copyright: © 2019-2025 Red Hat, Inc. + © 2019-2025 Milan Broz + © 2019-2025 Vojtech Trefny License: LGPL-2.1+ Files: tokens/ssh/* -Copyright: © 2016-2023 Milan Broz - © 2020-2023 Vojtech Trefny +Copyright: © 2016-2025 Milan Broz + © 2020-2025 Vojtech Trefny License: LGPL-2.1+ Files: tokens/ssh/cryptsetup-ssh.c -Copyright: © 2016-2023 Milan Broz - © 2021-2023 Vojtech Trefny +Copyright: © 2016-2025 Milan Broz + © 2021-2025 Vojtech Trefny License: GPL-2+ -Files: lib/crypto_backend/* lib/integrity/* lib/loopaes/* lib/tcrypt/* lib/verity/* -Copyright: © 2009-2023 Red Hat, Inc. - © 2010-2023 Milan Broz +Files: lib/crypto_backend/* lib/integrity/* lib/loopaes/* lib/luks2/hw_opal/* lib/tcrypt/* lib/utils_storage_wrappers.* lib/verity/* +Copyright: © 2009-2025 Red Hat, Inc. + © 2010-2025 Milan Broz License: LGPL-2.1+ Files: lib/crypto_backend/base64.c Copyright: © 2010 Lennart Poettering - © 2021-2023 Milan Broz + © 2021-2025 Milan Broz License: LGPL-2.1+ Files: lib/crypto_backend/utf8.c @@ -98,8 +98,8 @@ Copyright: © 2010 Lennart Poettering License: GPL-2+ Files: lib/crypto_backend/crypto_openssl.c -Copyright: © 2009-2023 Red Hat, Inc. - © 2010-2023 Milan Broz +Copyright: © 2009-2025 Red Hat, Inc. + © 2010-2025 Milan Broz License: LGPL-2.1+ with OpenSSL exception Files: lib/fvault2/fvault2.c lib/fvault2/fvault2.h @@ -107,8 +107,8 @@ Copyright: © 2021-2022 Pavel Tobias License: LGPL-2.1+ with OpenSSL exception Files: lib/keyslot_context.c lib/keyslot_context.h -Copyright: © 2022-2023 Red Hat, Inc. - © 2022-2023 Ondrej Kozina +Copyright: © 2022-2025 Red Hat, Inc. + © 2022-2025 Ondrej Kozina License: GPL-2+ Files: lib/crypto_backend/argon2/* @@ -122,6 +122,14 @@ Files: lib/crypto_backend/argon2/encoding.c Copyright: © 2015 Thomas Pornin License: CC0 or Apache-2.0 +Files: tests/fuzz/FuzzerInterface.h +Copyright: © LLVM Project +License: Apache-2.0 + +Files: tests/fuzz/json_proto_converter.cc tests/fuzz/json_proto_converter.h +Copyright: © 2020 Google, Inc. +License: Apache-2.0 + Files: lib/crypto_backend/crc32.c Copyright: © 1986 Gary S. Brown License: public-domain @@ -139,7 +147,7 @@ License: public-domain what you wish. Files: misc/luks-header-from-active -Copyright: © 2011-2024 Milan Broz +Copyright: © 2011-2025 Milan Broz License: LGPL-2.1+ Files: FAQ.md @@ -158,10 +166,8 @@ License: GPL-2+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. + You should have received a copy of the GNU General Public License along + with this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'. @@ -177,10 +183,8 @@ License: GPL-2+ with OpenSSL exception MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. + You should have received a copy of the GNU General Public License along + with this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'. @@ -208,9 +212,8 @@ License: GPL-3+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License along + with this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 3 can be found in `/usr/share/common-licenses/GPL-3`. @@ -226,10 +229,8 @@ License: LGPL-2.1+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. . - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . . On Debian systems, the complete text of the GNU Lesser General Public License version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'. @@ -245,10 +246,8 @@ License: LGPL-2.1+ with OpenSSL exception MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. . - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . . On Debian systems, the complete text of the GNU Lesser General Public License version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'. diff --git a/debian/functions b/debian/functions index 3845b9a..63ecf5d 100644 --- a/debian/functions +++ b/debian/functions @@ -162,7 +162,6 @@ crypttab_validate_option() { submit-from-crypt-cpus) OPTION="submit_from_crypt_cpus";; no-read-workqueue) OPTION="no_read_workqueue";; no-write-workqueue) OPTION="no_write_workqueue";; - tpm2-device) OPTION="tpm2_device";; esac case "$o" in @@ -248,7 +247,6 @@ crypttab_validate_option() { submit-from-crypt-cpus) ;; no-read-workqueue) ;; no-write-workqueue) ;; - tpm2-device) ;; x-initrd.attach) unset -v OPTION ;; # ignored, cf. #1072058 *) @@ -597,11 +595,9 @@ _resolve_device() { MAJ="$maj" MIN="$min" return 0 + else + cryptsetup_message "ERROR: Couldn't resolve device $spec" fi - case $spec in - overlay|usr-overlay) ;; - *) cryptsetup_message "ERROR: Couldn't resolve device $spec";; - esac return 1 } diff --git a/debian/initramfs/hooks/cryptroot b/debian/initramfs/hooks/cryptroot index a667354..ca759bd 100644 --- a/debian/initramfs/hooks/cryptroot +++ b/debian/initramfs/hooks/cryptroot @@ -51,10 +51,11 @@ crypttab_find_and_print_entry() { # crypttab_parse_options(). # Return 0 on success, 1 on error. crypttab_print_entry() { - local DEV MAJ MIN uuid keyfile + local DEV MAJ MIN name_uses uuid keyfile if _resolve_device "$CRYPTTAB_SOURCE"; then - if [ "$(dmsetup info -c --noheadings -o devnos_used -- "$CRYPTTAB_NAME" 2>/dev/null)" != "$MAJ:$MIN" ]; then - cryptsetup_message "ERROR: $CRYPTTAB_NAME: Source mismatch" + name_uses="$(dmsetup info -c --noheadings -o devnos_used -- "$CRYPTTAB_NAME" 2>/dev/null)" || name_uses="N/A" + if [ "$name_uses" != "$MAJ:$MIN" ]; then + cryptsetup_message "ERROR: Source mismatch: $CRYPTTAB_NAME uses $name_uses, but $CRYPTTAB_SOURCE is $MAJ:$MIN" elif [ "${_CRYPTTAB_SOURCE#[A-Za-z]*=}" = "$_CRYPTTAB_SOURCE" ] && \ [ "${CRYPTTAB_SOURCE#/dev/disk/by-}" = "$CRYPTTAB_SOURCE" ] && \ [ "${CRYPTTAB_SOURCE#/dev/mapper/}" = "$CRYPTTAB_SOURCE" ] && \ @@ -177,6 +178,9 @@ generate_initrd_crypttab() { true >"$DESTDIR/cryptroot/targets" { + # add crypttab entries with the 'initramfs' option set + crypttab_foreach_entry crypttab_print_initramfs_entry + if devnos="$(get_mnt_devno /)"; then usage=rootfs foreach_cryptdev crypttab_find_and_print_entry $devnos else @@ -190,9 +194,6 @@ generate_initrd_crypttab() { if devnos="$(get_mnt_devno /usr)"; then usage="" foreach_cryptdev crypttab_find_and_print_entry $devnos fi - - # add crypttab entries with the 'initramfs' option set - crypttab_foreach_entry crypttab_print_initramfs_entry } 3>"$DESTDIR/cryptroot/crypttab" rm -f "$DESTDIR/cryptroot/targets" } @@ -351,10 +352,6 @@ copy_exec /sbin/dmsetup [ "$ASKPASS" = n ] || copy_exec /lib/cryptsetup/askpass -copy_exec /bin/gettext -mkdir -p $DESTDIR/usr/share/locale/zh_CN/LC_MESSAGES/ -cp /usr/share/locale/zh_CN/LC_MESSAGES/cryptroot.mo $DESTDIR/usr/share/locale/zh_CN/LC_MESSAGES/ - # We need sed. Either via busybox or as standalone binary. if [ "$BUSYBOX" = n ] || [ -z "$BUSYBOXDIR" ]; then copy_exec /bin/sed @@ -380,7 +377,7 @@ if [ "$MODULES" = most ]; then else if [ "$MODULES" != "dep" ]; then # with large initramfs, we always add a basic subset of modules - add_crypto_modules aes cbc chainiv cryptomgr krng sha256 xts + add_crypto_modules aes cbc chainiv cryptomgr krng sha256 xts vmx_crypto fi add_crypto_modules $(printf '%s' "${CRYPTO_MODULES-}" | tr ' ' '\n' | sort -u) fi diff --git a/debian/initramfs/po/Makefile b/debian/initramfs/po/Makefile deleted file mode 100644 index c5fce87..0000000 --- a/debian/initramfs/po/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -XGETTEXT = xgettext -MSGFMT = msgfmt -MSGMERGE = msgmerge - -LOCALEDIR = /usr/share/locale - -.SUFFIXES: .po .mo .pot - -%.mo: %.po - $(MSGFMT) -o $@ $< - -PO = $(wildcard *.po) -LANG = $(basename $(PO)) -MO = $(addsuffix .mo,$(LANG)) -SOURCES = ../scripts/local-top/cryptroot - -all: update $(MO) -update: cryptroot.pot - -@for po in $(PO); do \ - echo -n "Updating $$po"; \ - $(MSGMERGE) -U $$po cryptroot.pot; \ - done; - -cryptroot.pot: $(SOURCES) - $(XGETTEXT) -c -L Shell --keyword=get_loc_str \ - -o $@ $(SOURCES) - -install: all - for i in $(MO) ; do \ - t=$(DESTDIR)/$(LOCALEDIR)/`basename $$i .mo`/LC_MESSAGES ;\ - install -d $$t ;\ - install -m 644 $$i $$t/cryptroot.mo ;\ - done - -clean: - $(RM) $(MO) *~ - -.PHONY: update diff --git a/debian/initramfs/po/cryptroot.pot b/debian/initramfs/po/cryptroot.pot deleted file mode 100644 index ae5338e..0000000 --- a/debian/initramfs/po/cryptroot.pot +++ /dev/null @@ -1,42 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-01-03 14:13+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../scripts/local-top/cryptroot:186 -msgid "Failed to unlock automatically, please check TPM or input recovery key." -msgstr "" - -#: ../scripts/local-top/cryptroot:188 -msgid "Wrong password! You have %s input chances more." -msgstr "" - -#: ../scripts/local-top/cryptroot:191 -msgid "Wrong recovery key! You have %s input chances more" -msgstr "" - -#: ../scripts/local-top/cryptroot:194 -msgid "Wrong password! You have %s input chances more" -msgstr "" - -#: ../scripts/local-top/cryptroot:225 -msgid "Unlocking successfully!" -msgstr "" - -#: ../scripts/local-top/cryptroot:230 -msgid "Please reboot!" -msgstr "" diff --git a/debian/initramfs/po/zh_CN.po b/debian/initramfs/po/zh_CN.po deleted file mode 100644 index dcd2357..0000000 --- a/debian/initramfs/po/zh_CN.po +++ /dev/null @@ -1,43 +0,0 @@ -# Chinese translations for PACKAGE package -# PACKAGE 软件包的简体中文翻译. -# Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# , 2024. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-01-03 14:13+0800\n" -"PO-Revision-Date: 2024-01-03 14:19+0800\n" -"Last-Translator: liangbo@uniontech.com\n" -"Language-Team: Chinese (simplified)\n" -"Language: zh_CN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2.1\n" - -#: ../scripts/local-top/cryptroot:186 -msgid "Failed to unlock automatically, please check TPM or input recovery key." -msgstr "自动解密失败,请检查TPM硬件或输入恢复密钥解密." - -#: ../scripts/local-top/cryptroot:188 -msgid "Wrong password! You have %s input chances more." -msgstr "密码错误,您还可以输入%s次." - -#: ../scripts/local-top/cryptroot:191 -msgid "Wrong recovery key! You have %s input chances more" -msgstr "恢复密钥错误,您还可以输入%s次" - -#: ../scripts/local-top/cryptroot:194 -msgid "Wrong password! You have %s input chances more" -msgstr "密码错误,您还可以输入%s次" - -#: ../scripts/local-top/cryptroot:225 -msgid "Unlocking successfully!" -msgstr "解锁成功!" - -#: ../scripts/local-top/cryptroot:230 -msgid "Please reboot!" -msgstr "多次输入错误,请重启系统后再尝试" diff --git a/debian/initramfs/scripts/local-top/cryptroot b/debian/initramfs/scripts/local-top/cryptroot index c8318b1..cf32118 100644 --- a/debian/initramfs/scripts/local-top/cryptroot +++ b/debian/initramfs/scripts/local-top/cryptroot @@ -5,16 +5,17 @@ PREREQ="cryptroot-prepare" # # Standard initramfs preamble # -prereqs() -{ - # Make sure that cryptroot is run last in local-top - local req - for req in "${0%/*}"/*; do - script="${req##*/}" - if [ "$script" != "${0##*/}" ]; then - printf '%s\n' "$script" - fi - done +prereqs() { + # Make sure that cryptroot is run last in local-top + local req script="${0##*/}" dir + dir="$DESTDIR/scripts/${CRYPTROOT_STAGE-local-top}" + for req in "$dir"/*; do + test -x "$req" || continue + req="${req##*/}" + if [ "$req" != "$script" ]; then + printf '%s\n' "$req" + fi + done } case $1 in @@ -29,19 +30,6 @@ esac [ -f /lib/cryptsetup/functions ] || return 0 . /lib/cryptsetup/functions -if [ -f /etc/default/locale ]; then - . /etc/default/locale -fi -if [ -z $LANG ]; then - if [ -n "$locales" ]; then - LANG=$locales - LANGUAGE=${locales%.*} - fi -fi -export LANG -export LANGUAGE - -alias get_loc_str='gettext "cryptroot"' # wait_for_source() # Wait for encrypted $CRYPTTAB_SOURCE . Set $CRYPTTAB_SOURCE @@ -161,7 +149,7 @@ setup_mapping() { fi fi - local count=0 maxtries="${CRYPTTAB_OPTION_tries:-10}" recovery_tries=5 fstype vg rv + local count=0 maxtries="${CRYPTTAB_OPTION_tries:-3}" fstype vg rv while [ $maxtries -le 0 ] || [ $count -lt $maxtries ]; do if [ -z "${CRYPTTAB_OPTION_keyscript+x}" ] && [ "$CRYPTTAB_KEY" != "none" ]; then # unlock via keyfile @@ -174,29 +162,8 @@ setup_mapping() { count=$(( $count + 1 )) if [ $rv -ne 0 ]; then - left_count=$(( $maxtries - $count)) - if [ -f "/tmp/crypt_mode" ]; then - if [ $left_count -ge $recovery_tries ]; then - left_count=$(($left_count - $recovery_tries)) - crypt_mode=$(cat /tmp/crypt_mode) - if [ "$crypt_mode" = "tpm" ]; then - count=5 - # make askpass accept recovery key - echo "$CRYPTTAB_NAME 6" > /tmp/crypt-tries.cache - pattern=$(get_loc_str "Failed to unlock automatically, please check TPM or input recovery key.") - else - pattern=$(get_loc_str "Wrong password! You have %s input chances more.") - fi - else - pattern=$(get_loc_str "Wrong recovery key! You have %s input chances more") - fi - else - pattern=$(get_loc_str "Wrong password! You have %s input chances more") - fi - wrong_pass_tip=$(printf $pattern $left_count) - plymouth message --text="$wrong_pass_tip" - sleep 2 - plymouth message --text="" + cryptsetup_message "ERROR: $CRYPTTAB_NAME: cryptsetup failed, bad password or options?" + sleep 1 continue elif ! dev="$(dm_blkdevname "$CRYPTTAB_NAME")"; then cryptsetup_message "ERROR: $CRYPTTAB_NAME: unknown error setting up device mapping" @@ -214,15 +181,12 @@ setup_mapping() { fi fi - plymouth message --text="$(get_loc_str "Unlocking successfully!")" + cryptsetup_message "$CRYPTTAB_NAME: set up successfully" wait_for_udev 10 return 0 done - plymouth message --text="$(get_loc_str "Please reboot!")" - while true; do - sleep 100 - done + cryptsetup_message "ERROR: $CRYPTTAB_NAME: maximum number of tries exceeded" exit 1 } diff --git a/debian/libcryptsetup12.symbols b/debian/libcryptsetup12.symbols index 5b30b7f..76548c9 100644 --- a/debian/libcryptsetup12.symbols +++ b/debian/libcryptsetup12.symbols @@ -5,6 +5,7 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER# CRYPTSETUP_2.5@CRYPTSETUP_2.5 2:2.5 CRYPTSETUP_2.6@CRYPTSETUP_2.6 2:2.6 CRYPTSETUP_2.7@CRYPTSETUP_2.7 2:2.7 + CRYPTSETUP_2.8@CRYPTSETUP_2.8 2:2.8 crypt_activate_by_keyfile@CRYPTSETUP_2.0 2:1.4 crypt_activate_by_keyfile_offset@CRYPTSETUP_2.0 2:1.4.3 crypt_activate_by_keyring@CRYPTSETUP_2.0 2:2.0 @@ -25,6 +26,7 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER# crypt_dump_json@CRYPTSETUP_2.4 2:2.4 crypt_format@CRYPTSETUP_2.0 2:1.4 crypt_format@CRYPTSETUP_2.4 2:2.4 + crypt_format_inline@CRYPTSETUP_2.8 2:2.8 crypt_format_luks2_opal@CRYPTSETUP_2.7 2:2.7 crypt_free@CRYPTSETUP_2.0 2:1.4 crypt_get_active_device@CRYPTSETUP_2.0 2:1.4 @@ -43,6 +45,7 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER# crypt_get_label@CRYPTSETUP_2.5 2:2.5 crypt_get_metadata_device_name@CRYPTSETUP_2.0 2:2.1 crypt_get_metadata_size@CRYPTSETUP_2.0 2:2.1 + crypt_get_old_volume_key_size@CRYPTSETUP_2.8 2:2.8 crypt_get_pbkdf_default@CRYPTSETUP_2.0 2:2.0.3 crypt_get_pbkdf_type@CRYPTSETUP_2.0 2:2.0 crypt_get_pbkdf_type_params@CRYPTSETUP_2.0 2:2.1 @@ -74,12 +77,19 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER# crypt_keyslot_context_get_error@CRYPTSETUP_2.6 2:2.6 crypt_keyslot_context_get_type@CRYPTSETUP_2.6 2:2.6 crypt_keyslot_context_init_by_keyfile@CRYPTSETUP_2.6 2:2.6 + crypt_keyslot_context_init_by_keyfile@CRYPTSETUP_2.8 2:2.8 crypt_keyslot_context_init_by_keyring@CRYPTSETUP_2.7 2:2.7 + crypt_keyslot_context_init_by_keyring@CRYPTSETUP_2.8 2:2.8 crypt_keyslot_context_init_by_passphrase@CRYPTSETUP_2.6 2:2.6 + crypt_keyslot_context_init_by_passphrase@CRYPTSETUP_2.8 2:2.8 crypt_keyslot_context_init_by_signed_key@CRYPTSETUP_2.7 2:2.7 + crypt_keyslot_context_init_by_signed_key@CRYPTSETUP_2.8 2:2.8 crypt_keyslot_context_init_by_token@CRYPTSETUP_2.6 2:2.6 + crypt_keyslot_context_init_by_token@CRYPTSETUP_2.8 2:2.8 crypt_keyslot_context_init_by_vk_in_keyring@CRYPTSETUP_2.7 2:2.7 + crypt_keyslot_context_init_by_vk_in_keyring@CRYPTSETUP_2.8 2:2.8 crypt_keyslot_context_init_by_volume_key@CRYPTSETUP_2.6 2:2.6 + crypt_keyslot_context_init_by_volume_key@CRYPTSETUP_2.8 2:2.8 crypt_keyslot_context_set_pin@CRYPTSETUP_2.6 2:2.6 crypt_keyslot_destroy@CRYPTSETUP_2.0 2:1.4 crypt_keyslot_get_encryption@CRYPTSETUP_2.0 2:2.1 @@ -99,6 +109,7 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER# crypt_persistent_flags_set@CRYPTSETUP_2.0 2:2.0 crypt_reencrypt@CRYPTSETUP_2.0 2:2.2 crypt_reencrypt_init_by_keyring@CRYPTSETUP_2.0 2:2.2 + crypt_reencrypt_init_by_keyslot_context@CRYPTSETUP_2.8 2:2.8 crypt_reencrypt_init_by_passphrase@CRYPTSETUP_2.0 2:2.2 crypt_reencrypt_run@CRYPTSETUP_2.4 2:2.4 crypt_reencrypt_status@CRYPTSETUP_2.0 2:2.2 @@ -113,6 +124,7 @@ libcryptsetup.so.12 libcryptsetup12 #MINVER# crypt_resume_by_volume_key@CRYPTSETUP_2.0 2:2.3 crypt_safe_alloc@CRYPTSETUP_2.0 2:2.3 crypt_safe_free@CRYPTSETUP_2.0 2:2.3 + crypt_safe_memcpy@CRYPTSETUP_2.8 2:2.8 crypt_safe_memzero@CRYPTSETUP_2.0 2:2.3 crypt_safe_realloc@CRYPTSETUP_2.0 2:2.3 crypt_set_compatibility@CRYPTSETUP_2.0 2:2.3 diff --git a/debian/patches/Exclude-reencryption-compat-test-from-Makefile.localtest.patch b/debian/patches/Exclude-reencryption-compat-test-from-Makefile.localtest.patch new file mode 100644 index 0000000..cab0e91 --- /dev/null +++ b/debian/patches/Exclude-reencryption-compat-test-from-Makefile.localtest.patch @@ -0,0 +1,49 @@ +From: Guilhem Moulin +Date: Thu, 11 Dec 2025 23:23:36 +0100 +Subject: Exclude `reencryption-compat-test` from Makefile.localtest + +On Debian unstable (linux 6.17.11+deb14-amd64, udev 259~rc3-1) the test +appears to fail with + + $ sudo make -f Makefile.localtest -j tests CRYPTSETUP_PATH=/sbin TESTSUITE_NOSKIP=y + […] + [reencryption-compat-test] + [1] Reencryption + [2] Reencryption with data shift + [3] Reencryption with keyfile + [4] Encryption of not yet encrypted device + [5] Reencryption using specific keyslot + [6] Reencryption using all active keyslots + [7] Reencryption of block devices with different block size + [512 sector]Cannot use scsi_debug module (in use or compiled-in), test skipped. + make: *** [Makefile.localtest:56: tests] Error 1 + +or (linux 6.17.9+deb14-amd64, udev 259~rc2-1) + + […] + [reencryption-compat-test] + [1] Reencryption + [2] Reencryption with data shift + [3] Reencryption with keyfile + [4] Encryption of not yet encrypted device + [5] Reencryption using specific keyslot + losetup: reenc-data: failed to set up loop device: Device or resource busy + +Bug-Debian: https://bugs.debian.org/1122539 +--- + tests/Makefile.localtest | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/Makefile.localtest b/tests/Makefile.localtest +index 89ce2c3..22d0d7e 100644 +--- a/tests/Makefile.localtest ++++ b/tests/Makefile.localtest +@@ -7,7 +7,7 @@ CPPFLAGS=-I../lib/ -I../lib/luks1 -DHAVE_DECL_DM_TASK_RETRY_REMOVE -DKERNEL_KEYR + -DHAVE_SYS_SYSMACROS_H -DNO_CRYPTSETUP_PATH + CFLAGS=-O2 -g -Wall -D_GNU_SOURCE + LDLIBS=-lcryptsetup -ldevmapper +-TESTS=$(wildcard *-test *-test2) api-test api-test-2 all-symbols-test unit-utils-crypt-test ++TESTS=$(filter-out reencryption-compat-test,$(wildcard *-test *-test2)) api-test api-test-2 all-symbols-test unit-utils-crypt-test + TESTS_UTILS=differ unit-utils-io unit-wipe + + ifneq ($(RUN_SSH_PLUGIN_TEST),) diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..0d4147c --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +Exclude-reencryption-compat-test-from-Makefile.localtest.patch diff --git a/debian/po/ca.po b/debian/po/ca.po new file mode 100644 index 0000000..161e458 --- /dev/null +++ b/debian/po/ca.po @@ -0,0 +1,54 @@ +# Catalan translation of cryptsetup's debconf messages +# Copyright © 2024 Free Software Foundation, Inc. +# This file is distributed under the same license as the cryptsetup package. +# poc senderi , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: cryptsetup\n" +"Report-Msgid-Bugs-To: cryptsetup@packages.debian.org\n" +"POT-Creation-Date: 2018-06-18 01:42+0200\n" +"PO-Revision-Date: 2024-12-07 16:56+0100\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: poc senderi \n" +"Language-Team: Catalan \n" +"X-Generator: Poedit 2.4.2\n" + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "Continue with cryptsetup removal?" +msgstr "Voleu continuar amb l'eliminació del «cryptsetup»?" + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "This system has unlocked dm-crypt devices: ${cryptmap}" +msgstr "Aquest sistema té dispositius «dm-crypt» desbloquejats: ${cryptmap}" + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "" +"If these devices are managed with cryptsetup, you might be unable to lock the " +"devices after the package removal, though other tools can be used for " +"managing dm-crypt devices. Any system shutdown or reboot will lock the " +"devices." +msgstr "" +"Si aquests dispositius es gestionen amb el «cryptsetup», és possible que no " +"pugueu bloquejar els dispositius després de l'eliminació del paquet, tot i " +"que es poden utilitzar altres eines per a gestionar dispositius «dm-crypt». " +"Qualsevol apagada o reinici del sistema bloquejarà els dispositius." + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "" +"Do not choose this option if you want to lock the dm-crypt devices before " +"package removal." +msgstr "" +"No trieu aquesta opció si voleu bloquejar els dispositius «dm-crypt» abans de " +"l'eliminació del paquet." diff --git a/debian/po/tr.po b/debian/po/tr.po new file mode 100644 index 0000000..0d2fa98 --- /dev/null +++ b/debian/po/tr.po @@ -0,0 +1,57 @@ +# Turkish debconf translation of cryptsetup package. +# Copyright (C) 2025 Debian Turkish L10n Team +# This file is distributed under the same license as the cryptsetup package. +# Translator: +# Nuri KÜÇÜKLER , 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: cryptsetup\n" +"Report-Msgid-Bugs-To: cryptsetup@packages.debian.org\n" +"POT-Creation-Date: 2018-06-18 01:42+0200\n" +"PO-Revision-Date: 2025-07-09 17:25+0300\n" +"Last-Translator: Nuri KÜÇÜKLER \n" +"Language-Team: Debian L10n Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 3.2.2\n" + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "Continue with cryptsetup removal?" +msgstr "cryptsetup paketinin kaldırılmasına devam edilsin mi?" + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "This system has unlocked dm-crypt devices: ${cryptmap}" +msgstr "Bu sistemde kilidi açılmış dm-crypt aygıtları var: ${cryptmap}" + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "" +"If these devices are managed with cryptsetup, you might be unable to lock " +"the devices after the package removal, though other tools can be used for " +"managing dm-crypt devices. Any system shutdown or reboot will lock the " +"devices." +msgstr "" +"Bu aygıtlar cryptsetup ile yönetiliyorsa, paket kaldırıldıktan sonra " +"bunları yeniden kilitleyemeyebilirsiniz. Ancak dm-crypt aygıtlarını " +"yönetmek için başka araçlar da mevcuttur. Sistem kapatılır ya da yeniden " +"başlatılırsa, aygıtlar kilitlenecektir." + +#. Type: boolean +#. Description +#: ../cryptsetup.templates:1001 +msgid "" +"Do not choose this option if you want to lock the dm-crypt devices before " +"package removal." +msgstr "" +"Paket kaldırılmadan önce dm-crypt aygıtlarını kilitlemek için bu seçeneği " +"tercih etmeyin." diff --git a/debian/rules b/debian/rules index 7727646..6c32fa1 100755 --- a/debian/rules +++ b/debian/rules @@ -51,7 +51,6 @@ endif # generate gettext po files (for luksformat) $(MAKE) -C debian/scripts/po all luksformat.pot - $(MAKE) -C debian/initramfs/po all cryptroot.pot execute_before_dh_auto_test: # tests/fake_token_path.so is built without global $(CFLAGS) @@ -60,7 +59,6 @@ execute_before_dh_auto_test: execute_after_dh_auto_install: # install gettext po files (for luksformat) $(MAKE) -C debian/scripts/po DESTDIR=$(CURDIR)/debian/cryptsetup-bin install - $(MAKE) -C debian/initramfs/po DESTDIR=$(CURDIR)/debian/cryptsetup-initramfs install execute_after_dh_install: # install apport files when building on Ubuntu @@ -76,7 +74,6 @@ override_dh_installinit: execute_after_dh_auto_clean: $(MAKE) -C debian/scripts/po update clean - $(MAKE) -C debian/initramfs/po update clean if [ -f $(CURDIR)/debian/cryptsetup-initramfs.preinst.in ]; then \ mv -fT $(CURDIR)/debian/cryptsetup-initramfs.preinst.in $(CURDIR)/debian/cryptsetup-initramfs.preinst; \ fi diff --git a/debian/scripts/decrypt_gnupg b/debian/scripts/decrypt_gnupg index 18ab575..5b0a1d9 100644 --- a/debian/scripts/decrypt_gnupg +++ b/debian/scripts/decrypt_gnupg @@ -5,7 +5,7 @@ decrypt_gpg () { if ! /lib/cryptsetup/askpass "Enter passphrase for key $1: " | \ /usr/bin/gpg -q --batch --no-options \ --no-random-seed-file --no-default-keyring \ - --keyring /dev/null --secret-keyring /dev/null \ + --keyring /dev/null \ --trustdb-name /dev/null --passphrase-fd 0 --decrypt -- "$1"; then return 1 fi diff --git a/debian/scripts/suspend/cryptsetup-suspend-wrapper b/debian/scripts/suspend/cryptsetup-suspend-wrapper index 953196c..0c60ebc 100644 --- a/debian/scripts/suspend/cryptsetup-suspend-wrapper +++ b/debian/scripts/suspend/cryptsetup-suspend-wrapper @@ -102,14 +102,18 @@ mount_initramfs() { new="y" fi - # unmkinitramfs(8) extracts microcode into folders "early*" and the actual initramfs into "main" - if [ -f "$INITRAMFS_MNT/sbin/cryptsetup" ]; then - INITRAMFS_DIR="$INITRAMFS_MNT" - elif [ -f "$INITRAMFS_MNT/main/sbin/cryptsetup" ]; then - INITRAMFS_DIR="$INITRAMFS_MNT/main" - else - log_error "Directory $INITRAMFS_MNT has unpected content" >&2 - exit 1 + INITRAMFS_DIR="$INITRAMFS_MNT" + if [ ! -f "$INITRAMFS_DIR/sbin/cryptsetup" ]; then + # unmkinitramfs(8) extracts microcode and actual initramfs into different folders + for p in "$INITRAMFS_MNT"/*/sbin/cryptsetup; do + if [ -f "$p" ] && [ -d "${p%"/sbin/cryptsetup"}/usr" ]; then + INITRAMFS_DIR="${p%"/sbin/cryptsetup"}" + fi + done + if [ ! -f "$INITRAMFS_DIR/sbin/cryptsetup" ]; then + log_error "Directory $INITRAMFS_MNT has unpected content" >&2 + exit 1 + fi fi if [ "$new" = "y" ]; then diff --git a/debian/tests/control b/debian/tests/control index 9fedc5f..0168594 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -1,12 +1,20 @@ # Run the installed binaries and libraries through the full upstream test suite. Features: test-name=upstream-testsuite -Test-Command: make -C ./tests -f Makefile.localtest -j tests CRYPTSETUP_PATH=/sbin TESTSUITE_NOSKIP=y +Test-Command: + dh_update_autotools_config && + dh_autoreconf && + make -f debian/rules override_dh_auto_configure DEB_BUILD_OPTIONS="nocheck nodoc" DEB_BUILD_PROFILES="noudeb" && + make libcrypto_backend.la && + cd ./tests && + gcc -I ../lib -c ./crypto-check.c && + gcc -o ./crypto-check ./crypto-check.o ../.libs/libcrypto_backend.a -lcrypto && + make -f Makefile.localtest -j tests CRYPTSETUP_PATH=/sbin TESTSUITE_NOSKIP=y + RUN_KEYRING_TRUSTED_TEST=y + RUN_SYSTEMD_PLUGIN_TEST=y Depends: cryptsetup-bin, # to compile tests/*.c - gcc, libcryptsetup-dev, - libdevmapper-dev, -# + @builddeps@, # for hexdump(1) bsdextrautils, # for dmsetup(8) @@ -25,6 +33,12 @@ Depends: cryptsetup-bin, procps, # for uuencode(1) sharutils, +# for swtpm(8) and swtpm_ioctl(8) + swtpm, + swtpm-tools, + tpm2-tools, +# for systemd-cryptenroll(1) + systemd-cryptsetup, # for xxd(1) xxd # @@ -66,6 +80,7 @@ Tests: cryptroot-lvm, cryptroot-legacy # cryptsetup is not listed since we only install it in the VM. Depends: cryptsetup-bin, dosfstools [arm64 armhf], + e2fsprogs, fdisk, genext2fs, initramfs-tools-core, @@ -83,6 +98,7 @@ Architecture: amd64 Tests: cryptroot-md Depends: cryptsetup-bin, dosfstools [arm64 armhf], + e2fsprogs, fdisk, genext2fs, initramfs-tools-core, @@ -100,6 +116,7 @@ Tests: cryptroot-nested Depends: btrfs-progs, cryptsetup-bin, dosfstools [arm64 armhf], + e2fsprogs, fdisk, genext2fs, initramfs-tools-core, @@ -116,6 +133,7 @@ Architecture: amd64 Tests: cryptroot-sysvinit Depends: cryptsetup-bin, dosfstools [arm64 armhf], + e2fsprogs, fdisk, genext2fs, initramfs-tools-core, diff --git a/debian/tests/cryptdisks b/debian/tests/cryptdisks index b8c6bcc..4276536 100755 --- a/debian/tests/cryptdisks +++ b/debian/tests/cryptdisks @@ -197,9 +197,11 @@ EOF # having an existing file system before the offset has no effect (cf. #994056) dmsetup create hidden --table "0 $offset linear $CRYPT_DEV 0" +udevadm settle mke2fs -t ext2 -m0 -Fq /dev/mapper/hidden u="$(blkid -p -s UUID -o value /dev/mapper/hidden)" dd if=/dev/mapper/hidden of="$TMPDIR/hidden.img" bs=512 +udevadm settle dmsetup remove hidden u2="$(blkid -p -s UUID -o value -- "$CRYPT_DEV")" test "$u" = "$u2" @@ -593,8 +595,10 @@ cat >/etc/crypttab <<-EOF EOF dmsetup create hidden --table "0 4096 linear $CRYPT_DEV $offset" +udevadm settle mke2fs -t ext2 -m0 -Fq /dev/mapper/hidden u="$(blkid -p -s UUID -o value /dev/mapper/hidden)" +udevadm settle dmsetup remove hidden u2="$(blkid -p -O$((offset*512)) -s UUID -o value -- "$CRYPT_DEV")" test "$u" = "$u2" diff --git a/debian/tests/cryptroot-lvm.d/mock b/debian/tests/cryptroot-lvm.d/mock index f57e42f..f777763 100755 --- a/debian/tests/cryptroot-lvm.d/mock +++ b/debian/tests/cryptroot-lvm.d/mock @@ -36,8 +36,13 @@ else { expect($SERIAL => qr/(?:^|\s)?PM: suspend exit\r\n/m); unlock_disk("topsecret"); - # consume PS1 to make sure we're at a shell prompt - expect($CONSOLE => qr/\A $PS1 \z/aamsx); + # suspend() leaves clutter in the console due to the retries + # that prevents test from succeeding. + consume($CONSOLE); + + # ensure that shell is available + shell(q{echo ready}, rv => 0); + my $out = shell(q{dmsetup info -c --noheadings -omangled_name,suspended --separator ' '}); die if grep !/[:[:blank:]]Active$/i, split(/\r?\n/, $out); diff --git a/debian/tests/cryptroot-md.d/setup b/debian/tests/cryptroot-md.d/setup index a8f49ed..ad633c8 100644 --- a/debian/tests/cryptroot-md.d/setup +++ b/debian/tests/cryptroot-md.d/setup @@ -55,9 +55,9 @@ for d in vda3 vda4 vdb3 vdb4; do udevadm settle done -mdadm --create /dev/md0 --metadata=default --level=1 --raid-devices=2 /dev/vda2 /dev/vdb2 +mdadm --create /dev/md0 --metadata=default --level=1 --raid-devices=2 --bitmap=internal /dev/vda2 /dev/vdb2 mdadm --create /dev/md1 --metadata=default --level=0 --raid-devices=2 /dev/mapper/vda3_crypt /dev/mapper/vdb3_crypt -mdadm --create /dev/md2 --metadata=default --level=1 --raid-devices=2 /dev/mapper/vda4_crypt /dev/mapper/vdb4_crypt +mdadm --create /dev/md2 --metadata=default --level=1 --raid-devices=2 --bitmap=internal /dev/mapper/vda4_crypt /dev/mapper/vdb4_crypt udevadm settle lvm pvcreate /dev/md2 diff --git a/debian/tests/cryptroot-nested.d/config b/debian/tests/cryptroot-nested.d/config index 995200c..fcfba32 100644 --- a/debian/tests/cryptroot-nested.d/config +++ b/debian/tests/cryptroot-nested.d/config @@ -1,6 +1,13 @@ PKGS_EXTRA+=( btrfs-progs lvm2 mdadm ) PKGS_EXTRA+=( cryptsetup-initramfs ) +# "$DISTRIBUTOR_ID" is defined in ../utils/cryptroot-common +# Workaround for LP1831747 https://bugs.launchpad.net/ubuntu/+source/initramfs-tools/+bug/1831747 +# Add implicit dependency of cryptsetup-initramfs +if [ "$DISTRIBUTOR_ID" = "ubuntu" ]; then + PKGS_EXTRA+=( e2fsprogs ) +fi + # /dev/mapper/testvg-lv1_crypt and /dev/vdc are both 1G and used in RAID1 mode DRIVE_SIZES=( "1G" "264M" "1G" "512M" ) diff --git a/debian/tests/cryptroot-nested.d/setup b/debian/tests/cryptroot-nested.d/setup index b08da17..1b3aa7d 100644 --- a/debian/tests/cryptroot-nested.d/setup +++ b/debian/tests/cryptroot-nested.d/setup @@ -60,7 +60,7 @@ cryptsetup luksOpen --key-file=/keyfile --allow-discards \ -- "/dev/testvg/lv1" "testvg-lv1_crypt" udevadm settle -mdadm --create /dev/md0 --metadata=default --level=1 --raid-devices=2 \ +mdadm --create /dev/md0 --metadata=default --level=1 --raid-devices=2 --bitmap=internal \ /dev/mapper/testvg-lv1_crypt /dev/vdc udevadm settle diff --git a/debian/tests/cryptroot-sysvinit.d/config b/debian/tests/cryptroot-sysvinit.d/config index f6b7392..1d41c24 100644 --- a/debian/tests/cryptroot-sysvinit.d/config +++ b/debian/tests/cryptroot-sysvinit.d/config @@ -1,5 +1,10 @@ PKGS_EXTRA+=( e2fsprogs ) # for fsck.ext4 PKGS_EXTRA+=( cryptsetup-initramfs cryptsetup ) -PKG_INIT="sysvinit-core" - +# "$DISTRIBUTOR_ID" is defined in ../utils/cryptroot-common +case "$DISTRIBUTOR_ID" in + debian) PKG_INIT="sysvinit-core";; + ubuntu) PKG_INIT="systemd-sysv";; + *) echo "ERROR: Unknown distributor ID '$DISTRIBUTOR_ID', can't determine default init package" >&2; + exit 1;; +esac # vim: set filetype=bash : diff --git a/debian/tests/cryptroot-sysvinit.d/mock b/debian/tests/cryptroot-sysvinit.d/mock index b729022..ff9b05b 100755 --- a/debian/tests/cryptroot-sysvinit.d/mock +++ b/debian/tests/cryptroot-sysvinit.d/mock @@ -22,7 +22,8 @@ die unless $out =~ m#\Avda5\s.*\r?\n^`-vda5_crypt\s+crypt\s+/\s*\r?\n\z#m; # make sure only vda5 is processed at initramfs stage # XXX unmkinitramfs doesn't work on /initrd.img with COMPRESS=zstd, cf. #1015954 shell(q{unmkinitramfs /boot/initrd.img-`uname -r` /tmp/initramfs}); -shell(q{grep -E '^vd\S+_crypt\s' /tmp/out}); +shell(q{find /tmp/initramfs -path "*/cryptroot/crypttab" -type f -print0 >/tmp/paths}); +shell(q{xargs -r0a/tmp/paths grep -Eh '^vd\S+_crypt\s' >/tmp/out}); shell(q{grep -E '^vda5_crypt\s' 0); shell(q{grep -Ev '^vda5_crypt\s' 1); diff --git a/debian/tests/utils/cryptroot-common b/debian/tests/utils/cryptroot-common index 6617670..4146a84 100755 --- a/debian/tests/utils/cryptroot-common +++ b/debian/tests/utils/cryptroot-common @@ -81,6 +81,7 @@ load_os_release() { } case "${DISTRIBUTOR_ID:="$(load_os_release && printf "%s" "${ID,,[A-Z]}")"}" in debian) APT_REPO_ORIGIN="Debian"; APT_REPO_URI="http://deb.debian.org/debian";; + ubuntu) APT_REPO_ORIGIN="Ubuntu"; APT_REPO_URI="http://archive.ubuntu.com/ubuntu";; # suitable values for derivative can be added here *) echo "ERROR: Unknown distributor ID '$DISTRIBUTOR_ID', can't extract APT origin" >&2; exit 1;; @@ -164,6 +165,12 @@ case "$BOOT" in efi) PKG_BOOTLOADER="grub-efi";; *) echo "ERROR unknown boot method '$BOOT'" >&2; exit 1;; esac + +if [ "$DISTRIBUTOR_ID" = "ubuntu" ]; then + echo "Overriding kernel arch to generic" + KERNEL_ARCH="generic" +fi + PKG_KERNEL="linux-image-$KERNEL_ARCH" PKG_INIT="systemd-sysv" # default pid1 MERGED_USR="" # use default layout for the target version @@ -302,6 +309,12 @@ setup_apt() { esac >"$TEMPDIR/apt/sources.list" fi + # ubuntu CI populates sources.list.d with PPA source, append them to the list + if [ "$DISTRIBUTOR_ID" = "ubuntu" ] && [ -d /etc/apt/sources.list.d ]; then + echo "Append contents of /etc/apt/sources.list.d to $TEMPDIR/apt/sources.list" + find /etc/apt/sources.list.d -type f -name "*.list" -execdir cat {} + >> "$TEMPDIR/apt/sources.list" + fi + local apt_repo for apt_repo in "${EXTRA_REPOS[@]}"; do printf "%s\\n" "$apt_repo" >>"$TEMPDIR/apt/sources.list" diff --git a/debian/tests/utils/init b/debian/tests/utils/init index 331cd6f..94f3b41 100755 --- a/debian/tests/utils/init +++ b/debian/tests/utils/init @@ -245,6 +245,13 @@ if [ -f /init.postinst ]; then rm -f "$ROOT/init.postinst" fi +# These break 'expect' so remove it from the image under test +if [ -f "$ROOT/usr/lib/tmpfiles.d/20-systemd-osc-context.conf" ]; then + rm -f "$ROOT/etc/profile.d/80-systemd-osc-context.sh" + mkdir -p "$ROOT/etc/tmpfiles.d" + ln -s /dev/null "$ROOT/etc/tmpfiles.d/20-systemd-osc-context.conf" +fi + # allow service startup again mv "$ROOT/sbin/start-stop-daemon.REAL" "$ROOT/sbin/start-stop-daemon" rm "$ROOT/usr/sbin/policy-rc.d" diff --git a/debian/tests/utils/initramfs-hook.common b/debian/tests/utils/initramfs-hook.common index 863d08d..4332a13 100644 --- a/debian/tests/utils/initramfs-hook.common +++ b/debian/tests/utils/initramfs-hook.common @@ -41,22 +41,36 @@ cat >"$TMPDIR/initramfs-tools/initramfs.conf" <<-EOF EOF INITRD_IMG="$TMPDIR/initrd.img" -INITRD_DIR="$TMPDIR/initrd" +UNMKINITRAMFS_DESTDIR="$TMPDIR/initrd" +unset INITRD_DIR cleanup_initrd_dir() { local d - for d in dev proc sys; do - mountpoint -q "$INITRD_DIR/$d" && umount "$INITRD_DIR/$d" || true - done - rm -rf --one-file-system -- "$INITRD_DIR" + if [ -n "${INITRD_DIR+x}" ] && [ -d "$INITRD_DIR" ]; then + for d in dev proc sys; do + mountpoint -q "$INITRD_DIR/$d" && umount "$INITRD_DIR/$d" || true + done + rm -rf --one-file-system -- "$INITRD_DIR" + fi + rm -rf --one-file-system -- "$UNMKINITRAMFS_DESTDIR" + unset INITRD_DIR } trap cleanup_initrd_dir EXIT INT TERM mkinitramfs() { - local d + local d p command mkinitramfs -d "$TMPDIR/initramfs-tools" -o "$INITRD_IMG" # `mkinitramfs -k` would be better but we can't set $DESTDIR in advance cleanup_initrd_dir - command unmkinitramfs "$INITRD_IMG" "$INITRD_DIR" + command unmkinitramfs "$INITRD_IMG" "$UNMKINITRAMFS_DESTDIR" + if [ -f "$UNMKINITRAMFS_DESTDIR/sbin/cryptsetup" ]; then + INITRD_DIR="$UNMKINITRAMFS_DESTDIR" + else + for p in "$UNMKINITRAMFS_DESTDIR"/*/sbin/cryptsetup; do + if [ -f "$p" ] && [ -d "${p%"/sbin/cryptsetup"}/usr" ]; then + INITRD_DIR="${p%"/sbin/cryptsetup"}" + fi + done + fi for d in dev proc sys; do mkdir -p "$INITRD_DIR/$d" mount --bind "/$d" "$INITRD_DIR/$d" diff --git a/debian/tests/utils/mock.pm b/debian/tests/utils/mock.pm index 4db861d..36f44d2 100644 --- a/debian/tests/utils/mock.pm +++ b/debian/tests/utils/mock.pm @@ -98,6 +98,26 @@ sub expect(;$$) { #print STDERR "INFO done reading\n"; } +sub consume($) { + my $chan = shift; + my $buffer = defined $chan ? \$BUFFER{$chan} : undef; + if (! defined $buffer) { + return; + } + + while(unpack("b*", $RBITS) != 0) { + my $rout = $RBITS; + if (select($rout, undef, undef, 1) == -1) { + return; + } + read_data($rout); + if (length($$buffer) == 0) { + return; + } + $$buffer = ""; + } +} + sub write_data($$%) { my $chan = shift; my $data = shift; @@ -168,11 +188,13 @@ BEGIN { hibernate poweroff expect + consume /; } *expect = \&CryptrootTest::Utils::expect; *write_data = \&CryptrootTest::Utils::write_data; +*consume = \&CryptrootTest::Utils::consume; sub unlock_disk($) { my $passphrase = shift; @@ -231,7 +253,9 @@ sub shell($%) { sub suspend() { @QMP::EVENTS = (); # flush the event queue - write_data($CONSOLE => q{systemctl suspend}); + # there is a race condition that causes suspend to fail. + # retry until success. Note, this may leave clutter in the console + write_data($CONSOLE => q{until systemctl suspend; do sleep 1; done}); # while the command is asynchronous the system might suspend before # we have a chance to read the next $PS1 diff --git a/debian/watch b/debian/watch index dabcd8b..13d9675 100644 --- a/debian/watch +++ b/debian/watch @@ -1,6 +1,7 @@ -version=4 -options="mode=git,pgpmode=gittag, \ - uversionmangle=s/-(alpha|beta|rc)(\d*)$/~$1$2/, \ - compression=gzip" \ - https://gitlab.com/cryptsetup/cryptsetup.git \ - refs/tags/v?@ANY_VERSION@ +Version: 5 +Mode: git +Pgp-Mode: gittag +Uversion-Mangle: s/-(alpha|beta|rc)(\d*)$/~$1$2/ +Compression: gzip +Source: https://gitlab.com/cryptsetup/cryptsetup.git +Matching-Pattern: refs/tags/@ANY_VERSION@ diff --git a/docs/examples/crypt_log_usage.c b/docs/examples/crypt_log_usage.c index 05e3c97..de8d45c 100644 --- a/docs/examples/crypt_log_usage.c +++ b/docs/examples/crypt_log_usage.c @@ -2,7 +2,7 @@ /* * libcryptsetup API log example * - * Copyright (C) 2011-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/docs/examples/crypt_luks_usage.c b/docs/examples/crypt_luks_usage.c index 002b744..784d368 100644 --- a/docs/examples/crypt_luks_usage.c +++ b/docs/examples/crypt_luks_usage.c @@ -2,7 +2,7 @@ /* * libcryptsetup API - using LUKS device example * - * Copyright (C) 2011-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/docs/licenses/COPYING.Apache-2.0 b/docs/licenses/COPYING.Apache-2.0 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/docs/licenses/COPYING.Apache-2.0 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/docs/licenses/COPYING.CC-BY-SA-4.0 b/docs/licenses/COPYING.CC-BY-SA-4.0 new file mode 100644 index 0000000..2d58298 --- /dev/null +++ b/docs/licenses/COPYING.CC-BY-SA-4.0 @@ -0,0 +1,428 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + diff --git a/docs/licenses/COPYING.GPL-2.0-or-later-WITH-cryptsetup-OpenSSL-exception b/docs/licenses/COPYING.GPL-2.0-or-later-WITH-cryptsetup-OpenSSL-exception new file mode 100644 index 0000000..86289a1 --- /dev/null +++ b/docs/licenses/COPYING.GPL-2.0-or-later-WITH-cryptsetup-OpenSSL-exception @@ -0,0 +1,354 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + +----- +In addition, as a special exception, the copyright holders give +permission to link the code of portions of this program with the +OpenSSL library under certain conditions as described in each +individual source file, and distribute linked combinations +including the two. + +You must obey the GNU General Public License in all respects +for all of the code used other than OpenSSL. If you modify +file(s) with this exception, you may extend this exception to your +version of the file(s), but you are not obligated to do so. If you +do not wish to do so, delete this exception statement from your +version. If you delete this exception statement from all source +files in the program, then also delete it here. diff --git a/COPYING.LGPL b/docs/licenses/COPYING.LGPL-2.1-or-later-WITH-cryptsetup-OpenSSL-exception similarity index 100% rename from COPYING.LGPL rename to docs/licenses/COPYING.LGPL-2.1-or-later-WITH-cryptsetup-OpenSSL-exception diff --git a/docs/on-disk-format-luks2.pdf b/docs/on-disk-format-luks2.pdf index eb7eaa6256459a19ed5fcd4ceecf37f19eb73fa7..6a9df0198a233a176f670eb13e43289b79eaf35a 100644 GIT binary patch delta 44518 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 Kjg;~?u~ diff --git a/docs/v2.8.0-ReleaseNotes b/docs/v2.8.0-ReleaseNotes new file mode 100644 index 0000000..f08909e --- /dev/null +++ b/docs/v2.8.0-ReleaseNotes @@ -0,0 +1,328 @@ +Cryptsetup 2.8.0 Release Notes +============================== +Stable release with new features and bug fixes + +All users of cryptsetup 2.7 must upgrade to this version. + +Changes since version 2.7.5 +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Introduce support for inline mode (use HW sectors with additional hardware metadata space). + + Some enterprise NVMe drives allow formatting sector size with additional metadata space, + for example, sector size 4096 bytes + 64 bytes for metadata. + We hope common firmware will soon support such features in more recent models. + + If this metadata space is available (not internally used by a data integrity profile), + it removes the need to use the dm-integrity layer for sector metadata allocation. + This means that the performance bottleneck caused by the dm-integrity journal is eliminated. + + Note: such drive must be reformatted with an external nvme tool. + You can check for support (reported as LBA format) by running the command + "nvme id-ns -H " and then you can reformat to the selected profile + (with complete data loss) with "nvme format -l . + This way, you can also reformat NVMe drive to 4096-byte sectors,which is strongly recommended + for encryption performance. + + The required device mapper for inline mode was introduced in Linux kernel version 6.11. + + The inline mode can be used with the new --integrity-inline option. + + For integritysetup, the kernel dm-integrity layer is still used, but it directly maps metadata + to the hardware (eliminating the journal). + For cryptsetup, the dm-integrity layer is eliminated, and only the dm-crypt kernel driver is used. + The libcryptsetup exports a new crypt_format_inline API call. + + Examples (underlying device must provide inline HW metadata space): + + Use integritysetup format with inline mode with default CRC32 checksums: + + # integritysetup format --sector-size 4096 --integrity-inline [--no-wipe] + # integritysetup open test + # integritysetup status test + /dev/mapper/test is active. + type: INTEGRITY + tag size: 4 [bytes] + integrity: crc32c + device: + sector size: 4096 [bytes] + ... + inline mode + journal: not active + + Use LUKS2 with authenticated encryption (here with AEGIS AEAD cipher): + + # cryptsetup luksFormat --integrity-inline --integrity aead --sector-size 4096 \ + -c aegis128-random --key-size 128 [--integrity-no-wipe] + # cryptsetup open test + # cryptsetup luksDump + ... + Requirements: inline-hw-tags + + After format, the inline mode is used automatically, and no special options are needed. + Please check the manual pages for more details about used options. + + Note that the LUKS2 authenticated encryption is still an experimental feature. + The inline mode only improves performance by removing the dm-integrity layer. + +* Finalize use of keyslot context API. + + Keyslot context is a generic abstraction over keyslot manipulation. + It extends many exiting commands by additional functions like tokens in activation, resume, + reencryption and similar commands without introducing new specific API functions. + +* Make all keyslot context types fully self-contained. + + In the previous version, the caller is responsible for releasing of some allocated memory. + In this version, all memory is allocated internally. The existing keyslot context API function + provides backward compatibility through versioned symbols. + +* Add --key-description and --new-key-description cryptsetup options. + + These can be used for the specification of the keyring with passphrase retrieval in the open, + resize, luksResume, luksFormat, luksAddKey and luksDump. + +* Support more precise keyslot selection in reencryption initialization. + + Reencryption must update stored keys in keyslots, so it needs to unlock all keyslots first. + + When no specific keyslot is selected by the --key-slot option, all active keyslots are updated. + + Users may narrow down the selection of keyslots by specifying either --token-id, --token-type + or --token-only option. Only keyslots associated with the specific token (--token-id) or + a specific type (--token-type) or any token (--token-only) will be updated. + All other keyslots will be erased after reencryption is finished. + + During reencryption, there are two volume keys (old and new). + For very specific use cases, reencryption can also be initialized by providing + volume keys directly by --volume-key-file, --new-volume-key-file, --volume-key-keyring + or --new-volume-key-keyring options. These options allow reencryption of the device with + no active keyslots (these can be added later). + If the --force-no-keyslots option is specified, all active keyslots will be erased after + the reencryption operation is finished. + +* Allow reencryption to resume using token and volume keys. + + The reencryption can be resumed using tokens (similar to initialization described above). + For very specific use cases, reencryption can be resumed by providing volume keys. + +* Cryptsetup repair command now tries to check LUKS keyslot areas for corruption. + + A keyslot binary area contains an encrypted volume key diffused to a larger area by + the anti-forensic splitter. If this area is corrupted, the keyslot can no longer be unlocked, + even with the correct password. + + Active keyslot area should look like random data, so some specific corruption can be detected + by randomness analysis. + + Cryptsetup repair command now tries to analyze the area expecting a uniform distribution + of bytes in 4096-byte blocks. If a problem is detected, it tries to localize corruption + in a smaller block (using the expected bit count). + Both tests are based on the Chi-squared statistical test. + + This analysis can replace the external keyslot check program and usually is more sensitive. + However, it cannot detect all corruptions and can produce false positives. + + Please use it as a hint when your password is no longer accepted, and you suspect + header corruption. This is the example output of the analysis: + + # cryptsetup repair + Keyslot 2 binary data could be corrupted. + Suspected offset: 0x88000 + You can use hexdump -v -C -n 128 -s to inspect the data. + + The test does not modify the header. A keyslot corruption cannot be repaired. + You have to use a backup header. + +* Opal2 SED: PSID keyfile is now expected to be 32 alphanumeric characters. + + If the keyfile size is not explicitly set, it uses only first 32 bytes. + All Opal2 manufacturers seem to use PSID of this length. + +* Opal2: Avoid the Erase method and use Secure Erase for locking range. + + The Erase method is defined for Single-user mode (SUM) and works on SUM-enabled locking ranges. + As we do not use SUM yet, this always fails and falls back to Secure erase anyway. + +* Opal2: Fix some error description (in debug only). + + Some Opal error messages were incorrect. + Cryptsetup now use all codes according to TCG specifications. + +* Opal2: Do not allow deferred deactivation. + + The self-encrypting drive must be locked immediately; deferred deactivation is not supported. + +* Allow --reduce-device-size and --device-size combination for reencryption (encrypt) action. + + For some very specific cases, this can be used to encrypt only part of the device together + with allocation a new space for the LUKS header. + +* Fix the userspace storage backend to support kernel "capi:" cipher specification format. + + This avoids unnecessary fallback to the device-mapper instead of the userspace crypto library + in luksFormat. The "capi:" is Linux kernel cryptographic format. + For example, capi:xts(aes)-plain64 is equivalent of aes-xts-plain64. + +* Disallow conversion from LUKS2 to LUKS1 if kernel "capi:" cipher specification is used. + + LUKS1 never officially supported this cipher specification format. + Such devices cannot be converted to LUKS1 (while existing devices can still be activated). + +* Explicitly disallow kernel "capi:" cipher specification format for LUKS2 keyslot encryption. + + This specification is intended to be used for data encryption, not for keyslots. + +* Do not allow conversion of LUKS2 to LUKS1 if an unbound keyslot is present. + + LUKS1 does not support unbound keyslots. Such devices cannot be converted. + +* cryptsetup: Adjust the XTS key size for kernel "capi:" cipher specification. + + Double key size as there are two keys the same way as for dm-crypt format. + +* Remove keyslot warning about possible failure due to low memory. + + This check was intended to warn users about possible out-of-memory situations + but produced many false positives. + +* Do not limit Argon2 KDF memory cost on systems with more than 4GB of available memory. + + The memory cost is intended to be limited only in low-memory situations (like virtual machines + without swap), not on systems with plenty of RAM. + +* Properly report out of memory error for cryptographic backends implementing Argon2. + +* Avoid KDF2 memory cost overflow on 32-bit platforms. + +* Do not use page size as a fallback for device block size. + + This check produced wrong values if used on platforms with larger page sizes (64kB) + and specific underlying storage (like ZFS). + +* veritysetup: Check hash device size in advance. + + If hashes are stored in a file image, allocate the size in advance. + For a block device, check if hashes (Merkle tree) fits the device. + +* Print a better error message for unsupported LUKS2 AEAD device resize. + +* Optimize LUKS2 metadata writes. + + LUKS2 supports several JSON area length configurations. Do not write full metadata + (including padding), as it may generate noticeable overhead with LUKS2. + +* veritysetup: support --error-as-corruption option. + + The panic/restart_on_error options were introduced in Linux kernel 6.12 and process errors + (like media read error) the same way as data corruption. + Use this flag in combination with --panic-on-corruption or --restart-on-corruption. + +* Report all sizes in status and dump command output in the correct units. + + Since the support of --sector-size option, the meaning of "sectors" became ambiguous as it + usually means 512-byte sectors (device-mapper unit). Confusion occurs when the sector size + is 4096 bytes while units used for display are 512-byte sectors. + + All status commands in tools now display units explicitly to avoid confusion. + + For example: + # cryptsetup status test + ... + sector size: 4096 [bytes] + offset: 32768 [512-byte units] (134217728 [bytes]) + size: 7501443760 [512-byte units] (30725913640960 [bytes]) + + If you parse the output of status commands, please check your scripts to ensure they work + with the new output properly. + +* Add --integrity-key-size option to cryptsetup. + + This option can be used to set up non-standard integrity key size (e.g. for HMAC). + It adds a new (optional) JSON "key_size" attribute in the segment.integrity JSON object + (see updated LUKS2 specification). If not set, the code uses selected hash length size. + +* Support trusted & encrypted keyrings for plain devices. + +* Support plain format resize with a keyring key. + + If a plain dm-crypt device references the keyring, cryptsetup now allows resizing. + The user must ensure that the key in the keyring is unchanged since activation. + Otherwise, reloading the key can cause data corruption after an unexpected key change. + +* TCRYPT: Clear mapping of system-encrypted partitions. + + TrueCrypt/VeraCrypt supports full system encryption (only a partition table is not encrypted) + or system partition encryption (only a system partition is encrypted). + The metadata header then contains the offset and size of the encrypted area. + Cryptsetup needs to know the specific partition offset to calculate encryption parameters. + + To properly map a partition, the user must specify a real partition device so cryptsetup + can calculate this offset. As the partition can be an image in a file, cryptsetup now tries + to determine proper parameters and use device size stored in VeraCrypt metadata. + + Please see the manual page description (TCRYPT section) for a detailed description. + +* TCRYPT: Print all information from the decrypted metadata header in the tcryptDump command. + + Print also volume sizes (if present) and flags. + +* Always lock the volume key structure in memory. + + Some memory for safe allocation was not allocated from locked (unswappable) memory. + Older cryptsetup locked all memory. Selective locking was introduced in version 2.6.0. + +* Do not run direct-io read check on block devices. + + Block devices always support direct-io. + This check produced unnecessary error with locked Opal2 devices. + +* Fix a possible segfault in deferred deactivation. + + Thanks Clément Guérin for the report. + +* Exclude cipher allocation time from the cryptsetup benchmark. + +* Add Mbed-TLS optional crypto backend. + + Mbed-TLS is a tiny TLS implementation designed for embedded environments. + The backend can be enabled with the --with-crypto_backend=mbedtls configure option. + +* Fix the wrong preprocessor use of #ifdef for config.h processed by Meson. + + Cryptsetup supports Autoconf and, optionally, Meson configuration. + Part of the code wrongly used #ifdef instead of #if conditional sections. + This caused problems with Meson-generated config.h. + +* Reorganize license files. + + The license text files are now in docs/licenses. + The COPYING file in the root directory is the default license. + +Libcryptsetup API extensions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The libcryptsetup API is backward compatible with all existing symbols. + +Due to the self-contained memory allocation, these symbols have the new version + crypt_keyslot_context_init_by_passphrase; + crypt_keyslot_context_init_by_keyfile; + crypt_keyslot_context_init_by_token; + crypt_keyslot_context_init_by_volume_key; + crypt_keyslot_context_init_by_signed_key; + crypt_keyslot_context_init_by_keyring; + crypt_keyslot_context_init_by_vk_in_keyring; + +New symbols: + crypt_format_inline + crypt_get_old_volume_key_size + crypt_reencrypt_init_by_keyslot_context + crypt_safe_memcpy + +New defines: + CRYPT_ACTIVATE_HIGH_PRIORITY + CRYPT_ACTIVATE_ERROR_AS_CORRUPTION + CRYPT_ACTIVATE_INLINE_MODE + CRYPT_REENCRYPT_CREATE_NEW_DIGEST + +New requirement flag: + CRYPT_REQUIREMENT_INLINE_HW_TAGS diff --git a/docs/v2.8.1-ReleaseNotes b/docs/v2.8.1-ReleaseNotes new file mode 100644 index 0000000..92f2e96 --- /dev/null +++ b/docs/v2.8.1-ReleaseNotes @@ -0,0 +1,40 @@ +Cryptsetup 2.8.1 Release Notes +============================== +Stable bug-fix release with minor extensions. + +All users of cryptsetup 2.8.0 must upgrade to this version. + +Changes since version 2.8.0 +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Fix status and deactivation of TCRYPT (VeraCrypt compatible) devices that use chained ciphers. + +* Fix unlocking BITLK (BitLocker compatible) devices with multibyte UTF8 characters in the passphrase. + +* Do not allow activation of the LUKS2 device if the used keyslot is not encrypted (it uses a null cipher). + + Such a configuration cannot be created by cryptsetup, but can be crafted outside of it. + Null cipher is sometimes used to create an empty container for later reencryption. + Only an empty passphrase can activate such a container (the same as in LUKS1). + +* Do not silently decrease PBKDF parallel cost (threads) if set by an option. + The maximum parallel cost is limited to 4 threads. + +* Fixes to configuration and installation scripts. + + Meson and autoconf tools now properly support --prefix option for temporary directory installation. + Multiple fixes and cleanups to config.h for compatibility between Meson and autoconf. + Fix the luks2-external-tokens-path Meson option to work the same as in autoconf. + Fix Meson install for tool binaries, install fvault2Open man page and include test/fuzz/meson.build in release. + +* Major update to manual pages. + + Try to explain the PBKDF hardcoded limits. + Add a better explanation for automatic integrity tag recalculation. + Mention crypt/verity/integritytab. + Remove or reformulate some misleading warnings present only with old and no longer supported kernels. + Clarify that some commands do not wipe data and unify OPAL reset wording. + Clarify the --label option. + There are also many other grammar and stylistic fixes to unify the man-page style. + +* Fixes for false-positive and annoying (optional) warnings added in recent compilers. diff --git a/docs/v2.8.2-ReleaseNotes b/docs/v2.8.2-ReleaseNotes new file mode 100644 index 0000000..bc78cd8 --- /dev/null +++ b/docs/v2.8.2-ReleaseNotes @@ -0,0 +1,58 @@ +Cryptsetup 2.8.2 Release Notes +============================== +Stable bug-fix release with minor extensions. + +All users of cryptsetup 2.8.x must upgrade to this version. + +Changes since version 2.8.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Fix cryptsetup LUKS2 status for HW inline integrity device. + Cryptsetup status did not print the inline flag if the underlying device with + HW integrity tags was used. + +* Fix LUKS2 format with detached header and data device with HW integrity tags. + +* Fix PBKDF serialization flag during device activation. + The --serialize-memory-hard-pbkdf and CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF API flag + is now properly supported again. This option is an optional workaround for situations where + multiple devices are activated in parallel (e.g., systemd crypttab activation). + +* BITLK: Add support for opening devices with Clear Key in BitLocker compatible mode. + BitLocker devices that are not yet encrypted can contain a Clear Key that is not protected + by a password. Cryptsetup can now map such devices and allow the user to access data on them. + Note that while such a device is detected as BitLocker, it must be treated as an unencrypted + device. Cryptsetup still does not allow mapping of partially encrypted BitLocker devices + (those in the middle of the encryption process). + +* BITLK: Harden metadata check by properly validating BitLocker metadata. + BitLocker metadata store checksums and authentication tags to detect random or malicious + manipulation. BITLK code now properly validates these and uses a backup metadata block + if validation fails. Previously, only the first metadata block was used. + +* Fix documentation to explicitly mention units for various API functions and in help messages. + Note that due to compatibility reasons, cryptsetup arguments use key sizes in bits while + integritysetup uses bytes. + +* Fix handling of too-long labels and subsystem fields. + LUKS2 labels are stored in the binary header area, which has a limited size. + Cryptsetup no longer silently truncates too-long labels; it prints an error instead. + +* Optimize reencryption to not repeatedly test access to the device. + +* Allow to use PHMAC (protected HMAC) with integritysetup and cryptsetup. + PHMAC is used by S390 mainframes. Support was added in Linux kernel 6.17. Configuration requires + steps using s390-tools; once that's done, it can be handled as a common LUKS2 or integrity device. + +* Opal2 SED: Fix misleading error messages during the self-encrypting drives format. + Cryptsetup misinterpreted some error codes when the kernel interface was not available + or the system call failed. + +* Opal2 SED: Ensure the system tries to rescan the device after the PSID reset. + Udev should now receive change events, allowing rescan of partition table after PSID reset. + +* Fix typos in volume-key-file help and integritysetup man page. + +* Fix detection of supported compiler attributes on PPC64 architecture. + +* Fix const compilation warnings with new gcc and glibc headers. diff --git a/lib/bitlk/bitlk.c b/lib/bitlk/bitlk.c index 686b42c..5f1762a 100644 --- a/lib/bitlk/bitlk.c +++ b/lib/bitlk/bitlk.c @@ -2,9 +2,9 @@ /* * BITLK (BitLocker-compatible) volume handling * - * Copyright (C) 2019-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2019-2024 Milan Broz - * Copyright (C) 2019-2024 Vojtech Trefny + * Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2019-2025 Milan Broz + * Copyright (C) 2019-2025 Vojtech Trefny */ #include @@ -111,6 +111,7 @@ struct bitlk_superblock { struct bitlk_fve_metadata { /* FVE metadata block header */ uint8_t signature[8]; + /* size of this block (in 16-byte units) */ uint16_t fve_size; uint16_t fve_version; uint16_t curr_state; @@ -132,6 +133,32 @@ struct bitlk_fve_metadata { uint64_t creation_time; } __attribute__ ((packed)); +struct bitlk_validation_hash { + uint16_t size; + uint16_t role; + uint16_t type; + uint16_t flags; + /* likely a hash type code, anything other than 0x2005 isn't supported */ + uint16_t hash_type; + uint16_t unknown1; + /* SHA-256 */ + uint8_t hash[32]; +} __attribute__ ((packed)); + +struct bitlk_fve_metadata_validation { + /* FVE metadata validation block header */ + uint16_t validation_size; + uint16_t validation_version; + uint32_t fve_crc32; + /* this is a single nested structure's header defined here for simplicity */ + uint16_t nested_struct_size; + uint16_t nested_struct_role; + uint16_t nested_struct_type; + uint16_t nested_struct_flags; + /* datum containing a similar nested structure (encrypted using VMK) with hash (SHA256) */ + uint8_t nested_struct_data[BITLK_VALIDATION_VMK_DATA_SIZE]; +} __attribute__ ((packed)); + struct bitlk_entry_header_block { uint64_t offset; uint64_t size; @@ -237,10 +264,11 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in bool supported = false; int r = 0; - /* only passphrase or recovery passphrase vmks are supported (can be used to activate) */ + /* only passphrase, recovery passphrase, startup key and clearkey vmks are supported (can be used to activate) */ supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE || (*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE || - (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY; + (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY || + (*vmk)->protection == BITLK_PROTECTION_CLEAR_KEY; while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) { /* size of this entry */ @@ -297,17 +325,13 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in crypt_volume_key_add_next(&((*vmk)->vk), vk); /* clear key for a partially decrypted volume */ } else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) { - /* We currently don't want to support opening a partially decrypted - * device so we don't need to store this key. - * - * key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4); - * key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4; - * vk = crypt_alloc_volume_key(key_size, key); - * if (vk == NULL) - * return -ENOMEM; - * crypt_volume_key_add_next(&((*vmk)->vk), vk); - */ - log_dbg(cd, "Skipping clear key metadata entry."); + /* For clearkey protection, we need to store this key */ + key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4); + key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4; + vk = crypt_alloc_volume_key(key_size, key); + if (vk == NULL) + return -ENOMEM; + crypt_volume_key_add_next(&((*vmk)->vk), vk); /* unknown timestamps in recovery protected VMK */ } else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) { ; @@ -361,6 +385,54 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in return 0; } +static bool check_fve_metadata(struct bitlk_fve_metadata *fve) +{ + if (memcmp(fve->signature, BITLK_SIGNATURE, sizeof(fve->signature)) || le16_to_cpu(fve->fve_version) != 2 || + (fve->fve_size << 4) > BITLK_FVE_METADATA_SIZE) + return false; + + return true; +} + +static bool check_fve_metadata_validation(struct bitlk_fve_metadata_validation *validation) +{ + /* only check if there is room for CRC-32, the actual size must be larger */ + if (le16_to_cpu(validation->validation_size) < 8 || le16_to_cpu(validation->validation_version > 2)) + return false; + + return true; +} + +static bool parse_fve_metadata_validation(struct bitlk_metadata *params, struct bitlk_fve_metadata_validation *validation) +{ + /* extra checks for a nested structure (MAC) and BITLK FVE metadata */ + + if (le16_to_cpu(validation->validation_size) < sizeof(struct bitlk_fve_metadata_validation)) + return false; + + if (le16_to_cpu(validation->nested_struct_size != BITLK_VALIDATION_VMK_HEADER_SIZE + BITLK_VALIDATION_VMK_DATA_SIZE) || + le16_to_cpu(validation->nested_struct_role) != 0 || + le16_to_cpu(validation->nested_struct_type) != 5) + return false; + + /* nonce */ + memcpy(params->validation->nonce, + validation->nested_struct_data, + BITLK_NONCE_SIZE); + + /* MAC tag */ + memcpy(params->validation->mac_tag, + validation->nested_struct_data + BITLK_NONCE_SIZE, + BITLK_VMK_MAC_TAG_SIZE); + + /* AES-CCM encrypted datum with SHA256 hash */ + memcpy(params->validation->enc_datum, + validation->nested_struct_data + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE, + BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE); + + return true; +} + void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek) { if (!fvek) @@ -375,10 +447,8 @@ void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk) struct bitlk_vmk *vmk_next = NULL; while (vmk) { - if (vmk->guid) - free(vmk->guid); - if (vmk->name) - free(vmk->name); + free(vmk->guid); + free(vmk->name); crypt_free_volume_key(vmk->vk); vmk_next = vmk->next; free(vmk); @@ -392,8 +462,8 @@ void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata) return; free(metadata->guid); - if (metadata->description) - free(metadata->description); + free(metadata->description); + free(metadata->validation); BITLK_bitlk_vmk_free(metadata->vmks); BITLK_bitlk_fvek_free(metadata->fvek); } @@ -405,20 +475,25 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params) struct bitlk_signature sig = {}; struct bitlk_superblock sb = {}; struct bitlk_fve_metadata fve = {}; + struct bitlk_fve_metadata_validation validation = {}; struct bitlk_entry_vmk entry_vmk = {}; uint8_t *fve_entries = NULL; + uint8_t *fve_validated_block = NULL; size_t fve_entries_size = 0; uint32_t fve_metadata_size = 0; + uint32_t fve_size_real = 0; int fve_offset = 0; char guid_buf[UUID_STR_LEN] = {0}; uint16_t entry_size = 0; uint16_t entry_type = 0; int i = 0; int r = 0; + int valid_fve_metadata_idx = -1; int start = 0; size_t key_size = 0; const char *key = NULL; char *description = NULL; + struct crypt_hash *hash; struct bitlk_vmk *vmk = NULL; struct bitlk_vmk *vmk_p = params->vmks; @@ -493,15 +568,80 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params) for (i = 0; i < 3; i++) params->metadata_offset[i] = le64_to_cpu(sb.fve_offset[i]); - log_dbg(cd, "Reading BITLK FVE metadata of size %zu on device %s, offset %" PRIu64 ".", - sizeof(fve), device_path(device), params->metadata_offset[0]); + fve_validated_block = malloc(BITLK_FVE_METADATA_SIZE); + if (fve_validated_block == NULL) { + r = -ENOMEM; + goto out; + } - /* read FVE metadata from the first metadata area */ - if (read_lseek_blockwise(devfd, device_block_size(cd, device), - device_alignment(device), &fve, sizeof(fve), params->metadata_offset[0]) != sizeof(fve) || - memcmp(fve.signature, BITLK_SIGNATURE, sizeof(fve.signature)) || - le16_to_cpu(fve.fve_version) != 2) { - log_err(cd, _("Failed to read BITLK FVE metadata from %s."), device_path(device)); + for (i = 0; i < 3; i++) { + /* iterate over FVE metadata copies and pick the valid one */ + log_dbg(cd, "Reading BITLK FVE metadata copy #%d of size %zu on device %s, offset %" PRIu64 ".", + i, sizeof(fve), device_path(device), params->metadata_offset[i]); + + if (read_lseek_blockwise(devfd, device_block_size(cd, device), + device_alignment(device), &fve, sizeof(fve), params->metadata_offset[i]) != sizeof(fve) || + !check_fve_metadata(&fve) || + (fve_size_real = le16_to_cpu(fve.fve_size) << 4, read_lseek_blockwise(devfd, device_block_size(cd, device), + device_alignment(device), &validation, sizeof(validation), params->metadata_offset[i] + fve_size_real) != sizeof(validation)) || + !check_fve_metadata_validation(&validation) || + /* double-fetch is here, but we aren't validating MAC */ + read_lseek_blockwise(devfd, device_block_size(cd, device), device_alignment(device), fve_validated_block, fve_size_real, + params->metadata_offset[i]) != fve_size_real || + (crypt_crc32(~0, fve_validated_block, fve_size_real) ^ ~0) != le32_to_cpu(validation.fve_crc32)) { + /* found an invalid FVE metadata copy, log and skip */ + log_dbg(cd, _("Failed to read or validate BITLK FVE metadata copy #%d from %s."), i, device_path(device)); + } else { + /* found a valid FVE metadata copy, use it */ + valid_fve_metadata_idx = i; + break; + } + } + + if (valid_fve_metadata_idx < 0) { + /* all FVE metadata copies are invalid, fail */ + log_err(cd, _("Failed to read and validate BITLK FVE metadata from %s."), device_path(device)); + r = -EINVAL; + goto out; + } + + /* check that a valid FVE metadata block is in its expected location */ + if (params->metadata_offset[valid_fve_metadata_idx] != le64_to_cpu(fve.fve_offset[valid_fve_metadata_idx])) { + log_err(cd, _("Failed to validate the location of BITLK FVE metadata from %s."), device_path(device)); + r = -EINVAL; + goto out; + } + + /* update offsets from a valid FVE metadata copy */ + for (i = 0; i < 3; i++) + params->metadata_offset[i] = le64_to_cpu(fve.fve_offset[i]); + + /* check that the FVE metadata hasn't changed between reads, because we are preparing for the MAC check */ + if (memcmp(&fve, fve_validated_block, sizeof(fve)) != 0) { + log_err(cd, _("BITLK FVE metadata changed between reads from %s."), device_path(device)); + r = -EINVAL; + goto out; + } + + crypt_backend_memzero(¶ms->sha256_fve, 32); + if (crypt_hash_init(&hash, "sha256")) { + log_err(cd, _("Failed to hash BITLK FVE metadata read from %s."), device_path(device)); + r = -EINVAL; + goto out; + } + crypt_hash_write(hash, (const char *)fve_validated_block, fve_size_real); + crypt_hash_final(hash, (char *)¶ms->sha256_fve, 32); + crypt_hash_destroy(hash); + + /* do some extended checks against FVE metadata, but not including MAC verification */ + params->validation = malloc(sizeof(struct bitlk_validation)); + if (!params->validation) { + r = -ENOMEM; + goto out; + } + + if (!parse_fve_metadata_validation(params, &validation)) { + log_err(cd, _("Failed to parse BITLK FVE validation metadata from %s."), device_path(device)); r = -EINVAL; goto out; } @@ -586,17 +726,18 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params) } memset(fve_entries, 0, fve_entries_size); - log_dbg(cd, "Reading BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".", - fve_entries_size, device_path(device), params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN); + log_dbg(cd, "Getting BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".", + fve_entries_size, device_path(device), params->metadata_offset[valid_fve_metadata_idx] + BITLK_FVE_METADATA_HEADERS_LEN); - if (read_lseek_blockwise(devfd, device_block_size(cd, device), - device_alignment(device), fve_entries, fve_entries_size, - params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)fve_entries_size) { - log_err(cd, _("Failed to read BITLK metadata entries from %s."), device_path(device)); + if (BITLK_FVE_METADATA_HEADERS_LEN + fve_entries_size > fve_size_real) { + log_err(cd, _("Failed to check BITLK metadata entries previously read from %s."), device_path(device)); r = -EINVAL; goto out; } + /* fetch these entries from validated buffer to avoid double-fetch */ + memcpy(fve_entries, fve_validated_block + BITLK_FVE_METADATA_HEADERS_LEN, fve_entries_size); + while ((fve_entries_size - start) >= (sizeof(entry_size) + sizeof(entry_type))) { /* size of this entry */ @@ -717,10 +858,10 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params) start += entry_size; } - out: - if (fve_entries) - free(fve_entries); + free(fve_entries); + free(fve_validated_block); + return r; } @@ -742,7 +883,7 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta log_std(cd, "Description: \t%s\n", params->description); log_std(cd, "Cipher name: \t%s\n", params->cipher); log_std(cd, "Cipher mode: \t%s\n", params->cipher_mode); - log_std(cd, "Cipher key: \t%u bits\n", params->key_size); + log_std(cd, "Cipher key: \t%u [bits]\n", params->key_size); log_std(cd, "\n"); @@ -761,15 +902,15 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta vk_p = vmk_p->vk; while (vk_p) { - log_std(cd, "\tKey data size:\t%zu [bytes]\n", vk_p->keylength); - vk_p = vk_p->next; + log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(vk_p)); + vk_p = crypt_volume_key_next(vk_p); } vmk_p = vmk_p->next; next_id++; } log_std(cd, " %d: FVEK\n", next_id); - log_std(cd, "\tKey data size:\t%zu [bytes]\n", params->fvek->vk->keylength); + log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(params->fvek->vk)); log_std(cd, "\n"); @@ -987,9 +1128,13 @@ static int bitlk_kdf(const char *password, struct crypt_hash *hd = NULL; int len = 0; char16_t *utf16Password = NULL; + size_t utf16Len = 0; int i = 0; int r = 0; + if (!password) + return -EINVAL; + memcpy(kdf.salt, salt, 16); r = crypt_hash_init(&hd, BITLK_KDF_HASH); @@ -1012,7 +1157,8 @@ static int bitlk_kdf(const char *password, if (r < 0) goto out; - crypt_hash_write(hd, (char*)utf16Password, passwordLen * 2); + utf16Len = crypt_char16_strlen(utf16Password); + crypt_hash_write(hd, (char*)utf16Password, utf16Len * 2); r = crypt_hash_final(hd, kdf.initial_sha256, len); if (r < 0) goto out; @@ -1058,11 +1204,14 @@ static int decrypt_key(struct crypt_device *cd, int r; uint16_t key_size = 0; - outbuf = crypt_safe_alloc(enc_key->keylength); + outbuf = crypt_safe_alloc(crypt_volume_key_length(enc_key)); if (!outbuf) return -ENOMEM; - r = crypt_bitlk_decrypt_key(key->key, key->keylength, enc_key->key, outbuf, enc_key->keylength, + r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(key), + crypt_volume_key_length(key), + crypt_volume_key_get_key(enc_key), outbuf, + crypt_volume_key_length(enc_key), (const char*)iv, iv_size, (const char*)tag, tag_size); if (r < 0) { if (r == -ENOTSUP) @@ -1073,9 +1222,10 @@ static int decrypt_key(struct crypt_device *cd, /* key_data has it's size as part of the metadata */ memcpy(&key_size, outbuf, 2); key_size = le16_to_cpu(key_size); - if (enc_key->keylength != key_size) { + if (crypt_volume_key_length(enc_key) != key_size) { log_err(cd, _("Unexpected key data size.")); - log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", enc_key->keylength, key_size); + log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", + crypt_volume_key_length(enc_key), key_size); r = -EINVAL; goto out; @@ -1085,7 +1235,7 @@ static int decrypt_key(struct crypt_device *cd, crypt_get_volume_key_size(cd) == 32) { /* 128bit AES-CBC with Elephant -- key size is 256 bit (2 keys) but key data is 512 bits, data: 16B CBC key, 16B empty, 16B elephant key, 16B empty */ - memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN, + crypt_safe_memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN, outbuf + 2 * 16 + BITLK_OPEN_KEY_METADATA_LEN, 16); key_size = 32 + BITLK_OPEN_KEY_METADATA_LEN; } @@ -1099,6 +1249,41 @@ static int decrypt_key(struct crypt_device *cd, return r; } +static int get_clear_key(struct crypt_device *cd, const struct bitlk_vmk *vmk, struct volume_key **vmk_dec_key) +{ + struct volume_key *nested_key = vmk->vk; + + if (!nested_key) { + log_dbg(cd, "Clearkey VMK structure incomplete - missing nested key"); + return -ENOTSUP; + } + + struct volume_key *encrypted_vmk = crypt_volume_key_next(nested_key); + + if (!encrypted_vmk) { + log_dbg(cd, "Clearkey VMK structure incomplete - missing encrypted VMK"); + return -ENOTSUP; + } + + /** + * For clearkey protection, we need to decrypt the encrypted VMK using the nested key + * and return the decrypted VMK as vmk_dec_key + */ + struct volume_key *decrypted_vmk = NULL; + int r = decrypt_key(cd, &decrypted_vmk, encrypted_vmk, nested_key, + vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE, + vmk->nonce, BITLK_NONCE_SIZE, false); + + if (r == 0 && decrypted_vmk) { + log_dbg(cd, "Successfully decrypted VMK using nested key"); + *vmk_dec_key = decrypted_vmk; + return 0; + } else { + log_dbg(cd, "Failed to decrypt VMK using nested key (error: %d)", r); + return r; + } +} + int BITLK_get_volume_key(struct crypt_device *cd, const char *password, size_t passwordLen, @@ -1109,10 +1294,12 @@ int BITLK_get_volume_key(struct crypt_device *cd, struct volume_key *open_vmk_key = NULL; struct volume_key *vmk_dec_key = NULL; struct volume_key *recovery_key = NULL; + struct bitlk_validation_hash dec_hash = {}; const struct bitlk_vmk *next_vmk = NULL; next_vmk = params->vmks; while (next_vmk) { + bool is_decrypted = false; if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) { r = bitlk_kdf(password, passwordLen, false, next_vmk->salt, &vmk_dec_key); if (r) { @@ -1134,7 +1321,8 @@ int BITLK_get_volume_key(struct crypt_device *cd, continue; } log_dbg(cd, "Trying to use given password as a recovery key."); - r = bitlk_kdf(recovery_key->key, recovery_key->keylength, + r = bitlk_kdf(crypt_volume_key_get_key(recovery_key), + crypt_volume_key_length(recovery_key), true, next_vmk->salt, &vmk_dec_key); crypt_free_volume_key(recovery_key); if (r) @@ -1146,8 +1334,18 @@ int BITLK_get_volume_key(struct crypt_device *cd, continue; } log_dbg(cd, "Trying to use external key found in provided password."); + } else if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) { + r = get_clear_key(cd, next_vmk, &vmk_dec_key); + if (r) { + /* something wrong happened, but we still want to check other key slots */ + next_vmk = next_vmk->next; + continue; + } + is_decrypted = true; + open_vmk_key = vmk_dec_key; + log_dbg(cd, "Extracted VMK using clearkey."); } else { - /* only passphrase, recovery passphrase and startup key VMKs supported right now */ + /* only passphrase, recovery passphrase, startup key and clearkey VMKs supported right now */ log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection)); next_vmk = next_vmk->next; if (r == 0) @@ -1156,19 +1354,51 @@ int BITLK_get_volume_key(struct crypt_device *cd, continue; } - log_dbg(cd, "Trying to decrypt %s.", get_vmk_protection_string(next_vmk->protection)); - r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key, - next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE, - next_vmk->nonce, BITLK_NONCE_SIZE, false); + if (!is_decrypted) { + r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key, + next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE, + next_vmk->nonce, BITLK_NONCE_SIZE, false); + + crypt_free_volume_key(vmk_dec_key); + } if (r < 0) { log_dbg(cd, "Failed to decrypt VMK using provided passphrase."); - crypt_free_volume_key(vmk_dec_key); + if (r == -ENOTSUP) return r; next_vmk = next_vmk->next; continue; } - crypt_free_volume_key(vmk_dec_key); + + log_dbg(cd, "Trying to decrypt validation metadata using VMK."); + r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(open_vmk_key), + crypt_volume_key_length(open_vmk_key), + (const char*)params->validation->enc_datum, + (char *)&dec_hash, + BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE, + (const char*)params->validation->nonce, BITLK_NONCE_SIZE, + (const char*)params->validation->mac_tag, BITLK_VMK_MAC_TAG_SIZE); + if (r < 0) { + log_dbg(cd, "Failed to decrypt validation metadata using VMK."); + crypt_free_volume_key(open_vmk_key); + if (r == -ENOTSUP) + return r; + break; + } + + /* now, do the MAC validation */ + if (le16_to_cpu(dec_hash.role) != 0 ||le16_to_cpu(dec_hash.type) != 1 || + (le16_to_cpu(dec_hash.hash_type) != 0x2005)) { + log_dbg(cd, "Failed to parse decrypted validation metadata."); + crypt_free_volume_key(open_vmk_key); + return -ENOTSUP; + } + + if (memcmp(dec_hash.hash, params->sha256_fve, sizeof(dec_hash.hash)) != 0) { + log_dbg(cd, "Failed MAC validation of BITLK FVE metadata."); + crypt_free_volume_key(open_vmk_key); + return -EINVAL; + } r = decrypt_key(cd, open_fvek_key, params->fvek->vk, open_vmk_key, params->fvek->mac_tag, BITLK_VMK_MAC_TAG_SIZE, @@ -1197,8 +1427,6 @@ int BITLK_get_volume_key(struct crypt_device *cd, static int _activate_check(struct crypt_device *cd, const struct bitlk_metadata *params) { - const struct bitlk_vmk *next_vmk = NULL; - if (!params->state) { log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated.")); return -ENOTSUP; @@ -1209,15 +1437,6 @@ static int _activate_check(struct crypt_device *cd, return -ENOTSUP; } - next_vmk = params->vmks; - while (next_vmk) { - if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) { - log_err(cd, _("Activation of partially decrypted BITLK device is not supported.")); - return -ENOTSUP; - } - next_vmk = next_vmk->next; - } - return 0; } @@ -1241,7 +1460,7 @@ static int _activate(struct crypt_device *cd, uint64_t next_start = 0; uint64_t next_end = 0; uint64_t last_segment = 0; - uint32_t dmt_flags = 0; + uint64_t dmt_flags = 0; r = _activate_check(cd, params); if (r) @@ -1365,7 +1584,7 @@ static int _activate(struct crypt_device *cd, crypt_get_cipher_spec(cd), segments[i].iv_offset, segments[i].iv_offset, - NULL, 0, + NULL, 0, 0, params->sector_size); if (r) goto out; @@ -1401,54 +1620,17 @@ static int _activate(struct crypt_device *cd, return r; } -int BITLK_activate_by_passphrase(struct crypt_device *cd, - const char *name, - const char *password, - size_t passwordLen, - const struct bitlk_metadata *params, - uint32_t flags) -{ - int r = 0; - struct volume_key *open_fvek_key = NULL; - - r = _activate_check(cd, params); - if (r) - return r; - - r = BITLK_get_volume_key(cd, password, passwordLen, params, &open_fvek_key); - if (r < 0) - goto out; - - /* Password verify only */ - if (!name) - goto out; - - r = _activate(cd, name, open_fvek_key, params, flags); -out: - crypt_free_volume_key(open_fvek_key); - return r; -} - int BITLK_activate_by_volume_key(struct crypt_device *cd, const char *name, - const char *volume_key, - size_t volume_key_size, + struct volume_key *vk, const struct bitlk_metadata *params, uint32_t flags) { - int r = 0; - struct volume_key *open_fvek_key = NULL; + int r; r = _activate_check(cd, params); if (r) return r; - open_fvek_key = crypt_alloc_volume_key(volume_key_size, volume_key); - if (!open_fvek_key) - return -ENOMEM; - - r = _activate(cd, name, open_fvek_key, params, flags); - - crypt_free_volume_key(open_fvek_key); - return r; + return _activate(cd, name, vk, params, flags); } diff --git a/lib/bitlk/bitlk.h b/lib/bitlk/bitlk.h index f175683..dde32bf 100644 --- a/lib/bitlk/bitlk.h +++ b/lib/bitlk/bitlk.h @@ -2,9 +2,9 @@ /* * BITLK (BitLocker-compatible) header definition * - * Copyright (C) 2019-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2019-2024 Milan Broz - * Copyright (C) 2019-2024 Vojtech Trefny + * Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2019-2025 Milan Broz + * Copyright (C) 2019-2025 Vojtech Trefny */ #ifndef _CRYPTSETUP_BITLK_H @@ -21,6 +21,8 @@ struct volume_key; #define BITLK_NONCE_SIZE 12 #define BITLK_SALT_SIZE 16 #define BITLK_VMK_MAC_TAG_SIZE 16 +#define BITLK_VALIDATION_VMK_HEADER_SIZE 8 +#define BITLK_VALIDATION_VMK_DATA_SIZE 72 #define BITLK_STATE_NORMAL 0x0004 @@ -85,6 +87,13 @@ struct bitlk_fvek { struct volume_key *vk; }; +struct bitlk_validation { + uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE]; + uint8_t nonce[BITLK_NONCE_SIZE]; + /* technically, this is not "VMK", but some sources call it this way */ + uint8_t enc_datum[BITLK_VALIDATION_VMK_DATA_SIZE]; +}; + struct bitlk_metadata { uint16_t sector_size; uint64_t volume_size; @@ -101,8 +110,10 @@ struct bitlk_metadata { uint32_t metadata_version; uint64_t volume_header_offset; uint64_t volume_header_size; + const char *sha256_fve[32]; struct bitlk_vmk *vmks; struct bitlk_fvek *fvek; + struct bitlk_validation *validation; }; int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params); @@ -115,17 +126,9 @@ int BITLK_get_volume_key(struct crypt_device *cd, const struct bitlk_metadata *params, struct volume_key **open_fvek_key); -int BITLK_activate_by_passphrase(struct crypt_device *cd, - const char *name, - const char *password, - size_t passwordLen, - const struct bitlk_metadata *params, - uint32_t flags); - int BITLK_activate_by_volume_key(struct crypt_device *cd, const char *name, - const char *volume_key, - size_t volume_key_size, + struct volume_key *vk, const struct bitlk_metadata *params, uint32_t flags); diff --git a/lib/bitops.h b/lib/bitops.h index a991687..1ef9718 100644 --- a/lib/bitops.h +++ b/lib/bitops.h @@ -10,13 +10,13 @@ #include #include -#if defined(HAVE_BYTESWAP_H) +#if HAVE_BYTESWAP_H # include #endif -#if defined(HAVE_ENDIAN_H) +#if HAVE_ENDIAN_H # include -#elif defined(HAVE_SYS_ENDIAN_H) /* BSDs have them here */ +#elif HAVE_SYS_ENDIAN_H /* BSDs have them here */ # include #endif diff --git a/lib/crypt_plain.c b/lib/crypt_plain.c index 3886d29..21e008e 100644 --- a/lib/crypt_plain.c +++ b/lib/crypt_plain.c @@ -3,8 +3,8 @@ * cryptsetup plain device helper functions * * Copyright (C) 2004 Jana Saout - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2024 Milan Broz + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Milan Broz */ #include @@ -92,7 +92,7 @@ int crypt_plain_hash(struct crypt_device *cd, log_dbg(cd, "Too short plain passphrase."); return -EINVAL; } - memcpy(key, passphrase, hash_size); + crypt_safe_memcpy(key, passphrase, hash_size); r = 0; } else r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase); diff --git a/lib/crypto_backend/Makemodule.am b/lib/crypto_backend/Makemodule.am index 7507763..a983637 100644 --- a/lib/crypto_backend/Makemodule.am +++ b/lib/crypto_backend/Makemodule.am @@ -13,7 +13,8 @@ libcrypto_backend_la_SOURCES = \ lib/crypto_backend/utf8.c \ lib/crypto_backend/argon2_generic.c \ lib/crypto_backend/cipher_generic.c \ - lib/crypto_backend/cipher_check.c + lib/crypto_backend/cipher_check.c \ + lib/crypto_backend/memutils.c if CRYPTO_BACKEND_GCRYPT libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_gcrypt.c @@ -30,6 +31,9 @@ endif if CRYPTO_BACKEND_NETTLE libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_nettle.c endif +if CRYPTO_BACKEND_MBEDTLS +libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_mbedtls.c +endif if CRYPTO_INTERNAL_PBKDF2 libcrypto_backend_la_SOURCES += lib/crypto_backend/pbkdf2_generic.c diff --git a/lib/crypto_backend/argon2/blake2/blake2b.c b/lib/crypto_backend/argon2/blake2/blake2b.c index d8f69e8..66b2df6 100644 --- a/lib/crypto_backend/argon2/blake2/blake2b.c +++ b/lib/crypto_backend/argon2/blake2/blake2b.c @@ -360,7 +360,7 @@ int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) { TRY(blake2b_final(&blake_state, out, outlen)); } else { uint32_t toproduce; - uint8_t out_buffer[BLAKE2B_OUTBYTES]; + uint8_t out_buffer[BLAKE2B_OUTBYTES] = {0}; uint8_t in_buffer[BLAKE2B_OUTBYTES]; TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); diff --git a/lib/crypto_backend/argon2/core.c b/lib/crypto_backend/argon2/core.c index f128d84..1f74a44 100644 --- a/lib/crypto_backend/argon2/core.c +++ b/lib/crypto_backend/argon2/core.c @@ -128,7 +128,7 @@ void secure_wipe_memory(void *v, size_t n) { void secure_wipe_memory(void *v, size_t n) { memset_s(v, n, 0, n); } -#elif defined(HAVE_EXPLICIT_BZERO) +#elif HAVE_EXPLICIT_BZERO void secure_wipe_memory(void *v, size_t n) { explicit_bzero(v, n); } @@ -356,12 +356,9 @@ static int fill_memory_blocks_mt(argon2_instance_t *instance) { } fail: - if (thread != NULL) { - free(thread); - } - if (thr_data != NULL) { - free(thr_data); - } + free(thread); + free(thr_data); + return rc; } diff --git a/lib/crypto_backend/argon2/encoding.c b/lib/crypto_backend/argon2/encoding.c index a717263..4020977 100644 --- a/lib/crypto_backend/argon2/encoding.c +++ b/lib/crypto_backend/argon2/encoding.c @@ -83,7 +83,7 @@ static int b64_byte_to_char(unsigned x) { return (LT(x, 26) & (x + 'A')) | (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | - (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') | + (GE(x, 52) & LT(x, 62) & (x - (52 - '0'))) | (EQ(x, 62) & '+') | (EQ(x, 63) & '/'); } diff --git a/lib/crypto_backend/argon2_generic.c b/lib/crypto_backend/argon2_generic.c index e69799e..d50bb9b 100644 --- a/lib/crypto_backend/argon2_generic.c +++ b/lib/crypto_backend/argon2_generic.c @@ -2,8 +2,8 @@ /* * Argon2 PBKDF2 library wrapper * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Milan Broz + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Milan Broz */ #include diff --git a/lib/crypto_backend/base64.c b/lib/crypto_backend/base64.c index e196f6b..d9733a0 100644 --- a/lib/crypto_backend/base64.c +++ b/lib/crypto_backend/base64.c @@ -5,7 +5,7 @@ * Copyright (C) 2010 Lennart Poettering * * cryptsetup related changes - * Copyright (C) 2021-2024 Milan Broz + * Copyright (C) 2021-2025 Milan Broz */ #include @@ -19,7 +19,7 @@ /* https://tools.ietf.org/html/rfc4648#section-4 */ static char base64char(int x) { - static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + static const char table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; return table[x & 63]; diff --git a/lib/crypto_backend/cipher_check.c b/lib/crypto_backend/cipher_check.c index 524ffe3..d8c7a60 100644 --- a/lib/crypto_backend/cipher_check.c +++ b/lib/crypto_backend/cipher_check.c @@ -2,8 +2,8 @@ /* * Cipher performance check * - * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2018-2024 Milan Broz + * Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2025 Milan Broz */ #include @@ -42,43 +42,36 @@ static int time_ms(struct timespec *start, struct timespec *end, double *ms) return 0; } -static int cipher_perf_one(const char *name, const char *mode, char *buffer, size_t buffer_size, - const char *key, size_t key_size, const char *iv, size_t iv_size, int enc) +static int cipher_perf_one(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size, + const char *iv, size_t iv_size, int enc) { - struct crypt_cipher_kernel cipher; size_t done = 0, block = CIPHER_BLOCK_BYTES; int r; if (buffer_size < block) block = buffer_size; - r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size); - if (r < 0) - return r; - while (done < buffer_size) { if ((done + block) > buffer_size) block = buffer_size - done; if (enc) - r = crypt_cipher_encrypt_kernel(&cipher, &buffer[done], &buffer[done], + r = crypt_cipher_encrypt_kernel(cipher, &buffer[done], &buffer[done], block, iv, iv_size); else - r = crypt_cipher_decrypt_kernel(&cipher, &buffer[done], &buffer[done], + r = crypt_cipher_decrypt_kernel(cipher, &buffer[done], &buffer[done], block, iv, iv_size); if (r < 0) - break; + return r; done += block; } - crypt_cipher_destroy_kernel(&cipher); - - return r; + return 0; } -static int cipher_measure(const char *name, const char *mode, char *buffer, size_t buffer_size, - const char *key, size_t key_size, const char *iv, size_t iv_size, - int encrypt, double *ms) + +static int cipher_measure(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size, + const char *iv, size_t iv_size, int encrypt, double *ms) { struct timespec start, end; int r; @@ -90,7 +83,7 @@ static int cipher_measure(const char *name, const char *mode, char *buffer, size if (clock_gettime(CLOCK_MONOTONIC_RAW, &start) < 0) return -EINVAL; - r = cipher_perf_one(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, encrypt); + r = cipher_perf_one(cipher, buffer, buffer_size, iv, iv_size, encrypt); if (r < 0) return r; @@ -118,15 +111,20 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s const char *key, size_t key_size, const char *iv, size_t iv_size, double *encryption_mbs, double *decryption_mbs) { + struct crypt_cipher_kernel cipher; double ms_enc, ms_dec, ms; int r, repeat_enc, repeat_dec; + r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size); + if (r < 0) + return r; + ms_enc = 0.0; repeat_enc = 1; while (ms_enc < 1000.0) { - r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 1, &ms); + r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 1, &ms); if (r < 0) - return r; + goto out; ms_enc += ms; repeat_enc++; } @@ -134,9 +132,9 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s ms_dec = 0.0; repeat_dec = 1; while (ms_dec < 1000.0) { - r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 0, &ms); + r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 0, &ms); if (r < 0) - return r; + goto out; ms_dec += ms; repeat_dec++; } @@ -144,5 +142,8 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s *encryption_mbs = speed_mbs(buffer_size * repeat_enc, ms_enc); *decryption_mbs = speed_mbs(buffer_size * repeat_dec, ms_dec); - return 0; + r = 0; +out: + crypt_cipher_destroy_kernel(&cipher); + return r; } diff --git a/lib/crypto_backend/cipher_generic.c b/lib/crypto_backend/cipher_generic.c index 41774a2..be7e4a0 100644 --- a/lib/crypto_backend/cipher_generic.c +++ b/lib/crypto_backend/cipher_generic.c @@ -2,8 +2,8 @@ /* * Linux kernel cipher generic utilities * - * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2018-2024 Milan Broz + * Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2025 Milan Broz */ #include diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h index 6a5db9b..9c37cf1 100644 --- a/lib/crypto_backend/crypto_backend.h +++ b/lib/crypto_backend/crypto_backend.h @@ -2,8 +2,8 @@ /* * crypto backend implementation * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2024 Milan Broz + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Milan Broz */ #ifndef _CRYPTO_BACKEND_H @@ -14,13 +14,17 @@ #include #include #include -#ifdef HAVE_UCHAR_H +#if HAVE_UCHAR_H #include #else #define char32_t uint32_t #define char16_t uint16_t #endif +# ifdef __cplusplus +extern "C" { +# endif + struct crypt_hash; struct crypt_hmac; struct crypt_cipher; @@ -89,6 +93,7 @@ int crypt_base64_decode(char **out, size_t *out_length, const char *in, size_t i /* UTF8/16 */ int crypt_utf16_to_utf8(char **out, const char16_t *s, size_t length /* bytes! */); int crypt_utf8_to_utf16(char16_t **out, const char *s, size_t length); +size_t crypt_char16_strlen(const char16_t *s); /* Block ciphers */ int crypt_cipher_ivsize(const char *name, const char *mode); @@ -132,15 +137,10 @@ int crypt_bitlk_decrypt_key(const void *key, size_t key_length, const char *tag, size_t tag_length); /* Memzero helper (memset on stack can be optimized out) */ -static inline void crypt_backend_memzero(void *s, size_t n) -{ -#ifdef HAVE_EXPLICIT_BZERO - explicit_bzero(s, n); -#else - volatile uint8_t *p = (volatile uint8_t *)s; - while(n--) *p++ = 0; -#endif -} +void crypt_backend_memzero(void *s, size_t n); + +/* Memcpy helper to avoid spilling sensitive data through additional registers */ +void *crypt_backend_memcpy(void *dst, const void *src, size_t n); /* Memcmp helper (memcmp in constant time) */ int crypt_backend_memeq(const void *m1, const void *m2, size_t n); @@ -148,4 +148,8 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n); /* crypto backend running in FIPS mode */ bool crypt_fips_mode(void); +# ifdef __cplusplus +} +# endif + #endif /* _CRYPTO_BACKEND_H */ diff --git a/lib/crypto_backend/crypto_backend_internal.h b/lib/crypto_backend/crypto_backend_internal.h index 9f01968..5326094 100644 --- a/lib/crypto_backend/crypto_backend_internal.h +++ b/lib/crypto_backend/crypto_backend_internal.h @@ -2,8 +2,8 @@ /* * crypto backend implementation * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2024 Milan Broz + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Milan Broz */ #ifndef _CRYPTO_BACKEND_INTERNAL_H @@ -47,17 +47,6 @@ int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length, const char *tag, size_t tag_length); /* Internal implementation for constant time memory comparison */ -static inline int crypt_internal_memeq(const void *m1, const void *m2, size_t n) -{ - const unsigned char *_m1 = (const unsigned char *) m1; - const unsigned char *_m2 = (const unsigned char *) m2; - unsigned char result = 0; - size_t i; - - for (i = 0; i < n; i++) - result |= _m1[i] ^ _m2[i]; - - return result; -} +int crypt_internal_memeq(const void *m1, const void *m2, size_t n); #endif /* _CRYPTO_BACKEND_INTERNAL_H */ diff --git a/lib/crypto_backend/crypto_cipher_kernel.c b/lib/crypto_backend/crypto_cipher_kernel.c index 7019798..72918eb 100644 --- a/lib/crypto_backend/crypto_cipher_kernel.c +++ b/lib/crypto_backend/crypto_cipher_kernel.c @@ -2,8 +2,8 @@ /* * Linux kernel userspace API crypto backend implementation (skcipher) * - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2024 Milan Broz + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Milan Broz */ #include @@ -14,7 +14,7 @@ #include #include "crypto_backend_internal.h" -#ifdef ENABLE_AF_ALG +#if ENABLE_AF_ALG #include @@ -40,6 +40,8 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx, const void *key, size_t key_length, size_t tag_length, struct sockaddr_alg *sa) { + void *optval = NULL; + if (!ctx) return -EINVAL; @@ -60,7 +62,7 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx, return -EINVAL; } - if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, tag_length) < 0) { + if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, &optval, tag_length) < 0) { crypt_cipher_destroy_kernel(ctx); return -EINVAL; } @@ -97,6 +99,20 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name, return _crypt_cipher_init(ctx, key, key_length, 0, &sa); } +/* musl has broken CMSG_NXTHDR macro in system headers */ +static inline struct cmsghdr *_CMSG_NXTHDR(struct msghdr* mhdr, struct cmsghdr* cmsg) +{ +#if !defined(__GLIBC__) && defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcast-align" +#pragma clang diagnostic ignored "-Wsign-compare" + return CMSG_NXTHDR(mhdr, cmsg); +#pragma clang diagnostic pop +#else + return CMSG_NXTHDR(mhdr, cmsg); +#endif +} + /* The in/out should be aligned to page boundary */ /* coverity[ -taint_source : arg-3 ] */ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx, @@ -144,7 +160,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx, /* Set IV */ if (iv) { - header = CMSG_NXTHDR(&msg, header); + header = _CMSG_NXTHDR(&msg, header); if (!header) return -EINVAL; @@ -153,7 +169,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx, header->cmsg_len = iv_msg_size; alg_iv = (void*)CMSG_DATA(header); alg_iv->ivlen = iv_length; - memcpy(alg_iv->iv, iv, iv_length); + crypt_backend_memcpy(alg_iv->iv, iv, iv_length); } len = sendmsg(ctx->opfd, &msg, 0); @@ -200,8 +216,8 @@ int crypt_cipher_check_kernel(const char *name, const char *mode, const char *integrity, size_t key_length) { struct crypt_cipher_kernel c; - char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key; - const char *salg_type; + char mode_name[64], tmp_salg_name[180], *cipher_iv = NULL, *key; + const char *salg_type, *real_mode; bool aead; int r; struct sockaddr_alg sa = { @@ -209,6 +225,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode, }; aead = integrity && strcmp(integrity, "none"); + real_mode = NULL; /* Remove IV if present */ if (mode) { @@ -229,14 +246,22 @@ int crypt_cipher_check_kernel(const char *name, const char *mode, memset(tmp_salg_name, 0, sizeof(tmp_salg_name)); /* FIXME: this is duplicating a part of devmapper backend */ - if (aead && !strcmp(integrity, "poly1305")) - r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity); - else if (!real_mode) - r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name); - else if (aead && !strcmp(real_mode, "ccm")) - r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name); - else - r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name); + if (aead) { + /* In AEAD, mode parameter can be just IV like "random" */ + if (!strcmp(integrity, "poly1305")) + r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity); + else if (!real_mode) + r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name); + else if (!strcmp(real_mode, "ccm")) + r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name); + else + r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name); + } else { + if (!mode) + r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name); + else + r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode ?: mode_name, name); + } if (r < 0 || (size_t)r >= sizeof(tmp_salg_name)) return -EINVAL; diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c index d188e02..a50cb45 100644 --- a/lib/crypto_backend/crypto_gcrypt.c +++ b/lib/crypto_backend/crypto_gcrypt.c @@ -2,8 +2,8 @@ /* * GCRYPT crypto backend implementation * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2024 Milan Broz + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Milan Broz */ #include @@ -249,7 +249,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) if (!hash) return -EINVAL; - memcpy(buffer, hash, length); + crypt_backend_memcpy(buffer, hash, length); crypt_hash_restart(ctx); return 0; @@ -323,7 +323,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) if (!hash) return -EINVAL; - memcpy(buffer, hash, length); + crypt_backend_memcpy(buffer, hash, length); crypt_hmac_restart(ctx); return 0; @@ -451,6 +451,7 @@ static int gcrypt_argon2(const char *type, .dispatch_job = gcrypt_dispatch_job, .wait_all_jobs = gcrypt_wait_all_jobs }; + gpg_error_t err; if (!strcmp(type, "argon2i")) atype = GCRY_KDF_ARGON2I; @@ -464,12 +465,11 @@ static int gcrypt_argon2(const char *type, param[2] = memory; param[3] = parallel; - if (gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4, + err = gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4, password, password_length, salt, salt_length, - NULL, 0, NULL, 0)) { - free(threads.jobs_ctx); - return -EINVAL; - } + NULL, 0, NULL, 0); + if (err) + return ((err & GPG_ERR_CODE_MASK) == GPG_ERR_ENOMEM) ? -ENOMEM : -EINVAL; if (parallel == 1) { /* Do not use threads here */ diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c index 719dcb3..8b96e9e 100644 --- a/lib/crypto_backend/crypto_kernel.c +++ b/lib/crypto_backend/crypto_kernel.c @@ -2,8 +2,8 @@ /* * Linux kernel userspace API crypto backend implementation * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2024 Milan Broz + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Milan Broz */ #include diff --git a/lib/crypto_backend/crypto_mbedtls.c b/lib/crypto_backend/crypto_mbedtls.c new file mode 100644 index 0000000..09d7e16 --- /dev/null +++ b/lib/crypto_backend/crypto_mbedtls.c @@ -0,0 +1,535 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * Mbed TLS crypto backend implementation + * + * Copyright (C) 2024-2025 Yiyuan Zhong + */ + +#include "crypto_backend.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crypto_backend_internal.h" + +struct crypt_hash { + const mbedtls_md_info_t *info; + mbedtls_md_context_t md; +}; + +struct crypt_hmac { + const mbedtls_md_info_t *info; + mbedtls_md_context_t md; +}; + +struct crypt_cipher { + const mbedtls_cipher_info_t *info; + mbedtls_cipher_context_t enc; + mbedtls_cipher_context_t dec; + int ecb; +}; + +static bool g_initialized = false; +static char g_backend_version[32]; +static mbedtls_entropy_context g_entropy; +static mbedtls_ctr_drbg_context g_ctr_drbg; + +static const mbedtls_md_info_t *crypt_get_hash(const char *name) +{ + static const struct hash_alg { + const char *name; + mbedtls_md_type_t type; + } kHash[] = { + {"sha1", MBEDTLS_MD_SHA1 }, + {"sha224", MBEDTLS_MD_SHA224 }, + {"sha256", MBEDTLS_MD_SHA256 }, + {"sha384", MBEDTLS_MD_SHA384 }, + {"sha512", MBEDTLS_MD_SHA512 }, + {"ripemd160", MBEDTLS_MD_RIPEMD160}, + {NULL, 0, } + }; + + size_t i = 0; + + while (name && kHash[i].name) { + if (strcmp(kHash[i].name, name) == 0) + return mbedtls_md_info_from_type(kHash[i].type); + i++; + } + + return NULL; +} + +int crypt_backend_init(bool fips) +{ + int ret; + + if (g_initialized) + return 0; + + if (fips) + return -ENOTSUP; + + mbedtls_version_get_string_full(g_backend_version); + + mbedtls_entropy_init(&g_entropy); + mbedtls_ctr_drbg_init(&g_ctr_drbg); + + ret = mbedtls_ctr_drbg_seed( + &g_ctr_drbg, mbedtls_entropy_func, + &g_entropy, NULL, MBEDTLS_CTR_DRBG_ENTROPY_LEN); + + if (ret) + return -EINVAL; + + g_initialized = true; + return 0; +} + +void crypt_backend_destroy(void) +{ + if (!g_initialized) + return; + + mbedtls_ctr_drbg_free(&g_ctr_drbg); + mbedtls_entropy_free(&g_entropy); + g_initialized = false; +} + +uint32_t crypt_backend_flags(void) +{ + return 0; +} + +const char *crypt_backend_version(void) +{ + return g_backend_version; +} + +bool crypt_fips_mode(void) +{ + return false; +} + +int crypt_backend_memeq(const void *m1, const void *m2, size_t n) +{ + return mbedtls_ct_memcmp(m1, m2, n); +} + +/* HASH */ +int crypt_hash_size(const char *name) +{ + const mbedtls_md_info_t *info; + info = crypt_get_hash(name); + return info ? mbedtls_md_get_size(info) : -ENOENT; +} + +int crypt_hash_init(struct crypt_hash **ctx, const char *name) +{ + struct crypt_hash *h; + + h = malloc(sizeof(*h)); + if (!h) + return -ENOMEM; + + h->info = crypt_get_hash(name); + if (!h->info) { + free(h); + return -ENOENT; + } + + mbedtls_md_init(&h->md); + + if (mbedtls_md_setup(&h->md, h->info, 0)) { + mbedtls_md_free(&h->md); + free(h); + return -EINVAL; + } + + if (mbedtls_md_starts(&h->md)) { + mbedtls_md_free(&h->md); + free(h); + return -EINVAL; + } + + *ctx = h; + return 0; +} + +int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length) +{ + if (mbedtls_md_update(&ctx->md, (const unsigned char *)buffer, length)) + return -EINVAL; + + return 0; +} + +int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) +{ + unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; + + if (length > mbedtls_md_get_size(ctx->info)) + return -EINVAL; + + if (mbedtls_md_finish(&ctx->md, tmp)) + return -EINVAL; + + crypt_backend_memcpy(buffer, tmp, length); + crypt_backend_memzero(tmp, sizeof(tmp)); + + if (mbedtls_md_starts(&ctx->md)) + return -EINVAL; + + return 0; +} + +void crypt_hash_destroy(struct crypt_hash *ctx) +{ + mbedtls_md_free(&ctx->md); + crypt_backend_memzero(ctx, sizeof(*ctx)); + free(ctx); +} + +/* HMAC */ +int crypt_hmac_size(const char *name) +{ + return crypt_hash_size(name); +} + +int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, + const void *key, size_t key_length) +{ + struct crypt_hmac *h; + + h = malloc(sizeof(*h)); + if (!h) + return -ENOMEM; + + h->info = crypt_get_hash(name); + if (!h->info) { + free(h); + return -ENOENT; + } + + mbedtls_md_init(&h->md); + + if (mbedtls_md_setup(&h->md, h->info, 1)) { + mbedtls_md_free(&h->md); + free(h); + return -EINVAL; + } + + if (mbedtls_md_hmac_starts(&h->md, key, key_length)) { + mbedtls_md_free(&h->md); + free(h); + return -EINVAL; + } + + *ctx = h; + return 0; +} + +int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length) +{ + if (mbedtls_md_hmac_update(&ctx->md, (const unsigned char *)buffer, length)) + return -EINVAL; + + return 0; +} + +int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) +{ + unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; + + if (length > mbedtls_md_get_size(ctx->info)) + return -EINVAL; + + if (mbedtls_md_hmac_finish(&ctx->md, tmp)) + return -EINVAL; + + crypt_backend_memcpy(buffer, tmp, length); + crypt_backend_memzero(tmp, sizeof(tmp)); + + if (mbedtls_md_hmac_reset(&ctx->md)) + return -EINVAL; + + return 0; +} + +void crypt_hmac_destroy(struct crypt_hmac *ctx) +{ + mbedtls_md_free(&ctx->md); + crypt_backend_memzero(ctx, sizeof(*ctx)); + free(ctx); +} + +/* RNG */ +int crypt_backend_rng(char *buffer, size_t length, int quality, int fips) +{ + if (fips) + return -ENOTSUP; + + /* Allow skipping reseeding for non-cryptographic strong random numbers */ + if (quality == CRYPT_RND_NORMAL || quality == CRYPT_RND_SALT) + mbedtls_ctr_drbg_set_prediction_resistance(&g_ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF); + else + mbedtls_ctr_drbg_set_prediction_resistance(&g_ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON); + + if (mbedtls_ctr_drbg_random(&g_ctr_drbg, (unsigned char *)buffer, length)) + return -EINVAL; + + return 0; +} + +/* CIPHER */ +int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) +{ + static const struct { + const char *name; + mbedtls_cipher_id_t id; + } kCipher[] = { + { "aes", MBEDTLS_CIPHER_ID_AES }, + { "aria", MBEDTLS_CIPHER_ID_ARIA }, + { "camellia", MBEDTLS_CIPHER_ID_CAMELLIA }, + { NULL, 0 } + }; + + static const struct { + const char *name; + mbedtls_cipher_mode_t mode; + } kMode[] = { + { "ecb", MBEDTLS_MODE_ECB }, + { "cbc", MBEDTLS_MODE_CBC }, + { "cfb", MBEDTLS_MODE_CFB }, + { "ofb", MBEDTLS_MODE_OFB }, + { "ctr", MBEDTLS_MODE_CTR }, + { "xts", MBEDTLS_MODE_XTS }, + { NULL, 0 } + }; + + mbedtls_cipher_id_t cid = MBEDTLS_CIPHER_ID_NONE; + mbedtls_cipher_mode_t cmode = MBEDTLS_MODE_NONE; + struct crypt_cipher *h; + size_t i; + int bits; + + for (i = 0; kCipher[i].name; i++) { + if (strcmp(kCipher[i].name, name) == 0) { + cid = kCipher[i].id; + break; + } + } + + for (i = 0; kMode[i].name; i++) { + if (strcmp(kMode[i].name, mode) == 0) { + cmode = kMode[i].mode; + break; + } + } + + if (cid == MBEDTLS_CIPHER_ID_NONE || cmode == MBEDTLS_MODE_NONE) + return -ENOENT; + + h = malloc(sizeof(*h)); + if (!h) + return -ENOMEM; + + bits = key_length * 8; + h->info = mbedtls_cipher_info_from_values(cid, bits, cmode); + if (!h->info) { + free(h); + return -ENOENT; + } + + mbedtls_cipher_init(&h->enc); + mbedtls_cipher_init(&h->dec); + if (mbedtls_cipher_setup(&h->enc, h->info) || + mbedtls_cipher_setup(&h->dec, h->info) || + mbedtls_cipher_setkey(&h->enc, key, bits, MBEDTLS_ENCRYPT) || + mbedtls_cipher_setkey(&h->dec, key, bits, MBEDTLS_DECRYPT)) { + + mbedtls_cipher_free(&h->dec); + mbedtls_cipher_free(&h->enc); + free(h); + return -EINVAL; + } + + if (cmode == MBEDTLS_MODE_CBC) { + if (mbedtls_cipher_set_padding_mode(&h->enc, MBEDTLS_PADDING_NONE) || + mbedtls_cipher_set_padding_mode(&h->dec, MBEDTLS_PADDING_NONE)) { + + mbedtls_cipher_free(&h->dec); + mbedtls_cipher_free(&h->enc); + free(h); + return -EINVAL; + } + } + + h->ecb = cmode == MBEDTLS_MODE_ECB; + *ctx = h; + return 0; +} + +void crypt_cipher_destroy(struct crypt_cipher *ctx) +{ + mbedtls_cipher_free(&ctx->dec); + mbedtls_cipher_free(&ctx->enc); + free(ctx); +} + +static int crypt_cipher_crypt( + mbedtls_cipher_context_t *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length, + int ecb) +{ + const unsigned char *input; + unsigned char *output; + size_t outlen; + size_t block; + size_t len; + + if (ecb) /* ECB requires exactly block length input */ + block = mbedtls_cipher_get_block_size(ctx); + else + block = length; + + input = (const unsigned char *)in; + output = (unsigned char *)out; + + if (mbedtls_cipher_set_iv(ctx, (const unsigned char *)iv, iv_length)) + return -EINVAL; + + if (mbedtls_cipher_reset(ctx)) + return -EINVAL; + + while (length) { + len = length < block ? length : block; + if (mbedtls_cipher_update(ctx, input, len, output, &outlen)) + return -EINVAL; + + output += outlen; + length -= len; + input += len; + } + + if (mbedtls_cipher_finish(ctx, output, &outlen)) + return -EINVAL; + + return 0; +} + +int crypt_cipher_encrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_crypt(&ctx->enc, in, out, length, iv, iv_length, ctx->ecb); +} + +int crypt_cipher_decrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_crypt(&ctx->dec, in, out, length, iv, iv_length, ctx->ecb); +} + +bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused))) +{ + return false; +} + +int crypt_pbkdf(const char *kdf, const char *hash, + const char *password, size_t password_length, + const char *salt, size_t salt_length, + char *key, size_t key_length, + uint32_t iterations, uint32_t memory, uint32_t parallel) +{ + const mbedtls_md_info_t *info; +#if !HAVE_MBEDTLS_PKCS5_PBKDF2_HMAC_EXT + mbedtls_md_context_t md; +#endif + + if (!kdf) + return -EINVAL; + + if (strcmp(kdf, "pbkdf2") == 0) { + info = crypt_get_hash(hash); + if (!info) + return -EINVAL; + +#if HAVE_MBEDTLS_PKCS5_PBKDF2_HMAC_EXT + if (mbedtls_pkcs5_pbkdf2_hmac_ext(mbedtls_md_get_type(info), + (const unsigned char *)password, password_length, + (const unsigned char *)salt, salt_length, + iterations, key_length, (unsigned char *)key)) { + + return -EINVAL; + } +#else + mbedtls_md_init(&md); + if (mbedtls_md_setup(&md, info, 1)) + return -EINVAL; + + if (mbedtls_pkcs5_pbkdf2_hmac(&md, + (const unsigned char *)password, password_length, + (const unsigned char *)salt, salt_length, + iterations, key_length, (unsigned char *)key)) { + + mbedtls_md_free(&md); + return -EINVAL; + } + + mbedtls_md_free(&md); +#endif + return 0; + + } else if (strncmp(kdf, "argon2", 6) == 0) { + return argon2(kdf, password, password_length, salt, salt_length, + key, key_length, iterations, memory, parallel); + } + + return -EINVAL; +} + +int crypt_bitlk_decrypt_key(const void *key, size_t key_length, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length, + const char *tag, size_t tag_length) +{ + const unsigned char *tagptr; + const unsigned char *input; + const unsigned char *ivptr; + mbedtls_ccm_context ctx; + unsigned char *output; + + tagptr = (const unsigned char *)tag; + ivptr = (const unsigned char *)iv; + input = (const unsigned char *)in; + output = (unsigned char *)out; + mbedtls_ccm_init(&ctx); + + if (mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, key_length * 8)) { + mbedtls_ccm_free(&ctx); + return -EINVAL; + } + + if (mbedtls_ccm_auth_decrypt(&ctx, length, ivptr, iv_length, NULL, 0, + input, output, tagptr, tag_length)) { + + mbedtls_ccm_free(&ctx); + return -EINVAL; + } + + mbedtls_ccm_free(&ctx); + return 0; +} diff --git a/lib/crypto_backend/crypto_nettle.c b/lib/crypto_backend/crypto_nettle.c index 4c91271..3ce239a 100644 --- a/lib/crypto_backend/crypto_nettle.c +++ b/lib/crypto_backend/crypto_nettle.c @@ -2,8 +2,8 @@ /* * Nettle crypto backend implementation * - * Copyright (C) 2011-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2011-2024 Milan Broz + * Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2025 Milan Broz */ #include @@ -298,7 +298,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, return -ENOMEM; } - memcpy(h->key, key, key_length); + crypt_backend_memcpy(h->key, key, key_length); h->key_length = key_length; h->hash->init(&h->nettle_ctx); diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c index 19b2202..bbf6533 100644 --- a/lib/crypto_backend/crypto_nss.c +++ b/lib/crypto_backend/crypto_nss.c @@ -2,8 +2,8 @@ /* * NSS crypto backend implementation * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2024 Milan Broz + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Milan Broz */ #include @@ -164,7 +164,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess) return -EINVAL; - memcpy(buffer, tmp, length); + crypt_backend_memcpy(buffer, tmp, length); crypt_backend_memzero(tmp, sizeof(tmp)); if (tmp_len < length) @@ -264,7 +264,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess) return -EINVAL; - memcpy(buffer, tmp, length); + crypt_backend_memcpy(buffer, tmp, length); crypt_backend_memzero(tmp, sizeof(tmp)); if (tmp_len < length) diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c index 60e43ca..762cd71 100644 --- a/lib/crypto_backend/crypto_openssl.c +++ b/lib/crypto_backend/crypto_openssl.c @@ -2,8 +2,8 @@ /* * OPENSSL crypto backend implementation * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2024 Milan Broz + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Milan Broz */ #include @@ -19,6 +19,7 @@ #include #include #include +#include static OSSL_PROVIDER *ossl_legacy = NULL; static OSSL_PROVIDER *ossl_default = NULL; static OSSL_LIB_CTX *ossl_ctx = NULL; @@ -381,7 +382,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) if (EVP_DigestFinal_ex(ctx->md, tmp, &tmp_len) != 1) return -EINVAL; - memcpy(buffer, tmp, length); + crypt_backend_memcpy(buffer, tmp, length); crypt_backend_memzero(tmp, sizeof(tmp)); if (tmp_len < length) @@ -510,7 +511,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) HMAC_Final(ctx->md, tmp, &tmp_len); #endif - memcpy(buffer, tmp, length); + crypt_backend_memcpy(buffer, tmp, length); crypt_backend_memzero(tmp, sizeof(tmp)); if (tmp_len < length) @@ -638,6 +639,10 @@ static int openssl_argon2(const char *type, const char *password, size_t passwor EVP_KDF_CTX_free(ctx); EVP_KDF_free(argon2); + /* Memory allocation is common issue with memory-hard Argon2 */ + if (r == 0 && ERR_GET_REASON(ERR_get_error()) == ERR_R_MALLOC_FAILURE) + return -ENOMEM; + /* _derive() returns 0 or negative value on error, 1 on success */ return r == 1 ? 0 : -EINVAL; #else diff --git a/lib/crypto_backend/crypto_storage.c b/lib/crypto_backend/crypto_storage.c index 0eed502..edd4db7 100644 --- a/lib/crypto_backend/crypto_storage.c +++ b/lib/crypto_backend/crypto_storage.c @@ -3,16 +3,19 @@ * Generic wrapper for storage encryption modes and Initial Vectors * (reimplementation of some functions from Linux dm-crypt kernel) * - * Copyright (C) 2014-2024 Milan Broz + * Copyright (C) 2014-2025 Milan Broz */ +#include #include #include #include #include "bitops.h" #include "crypto_backend.h" -#define SECTOR_SHIFT 9 +#define SECTOR_SHIFT 9 +#define MAX_CAPI_LEN 64 +#define MAX_CAPI_LEN_STR "63" /* * Internal IV helper @@ -74,7 +77,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx, ctx->type = IV_PLAIN; } else if (!strncasecmp(iv_name, "essiv:", 6)) { struct crypt_hash *h = NULL; - char *hash_name = strchr(iv_name, ':'); + const char *hash_name = strchr(iv_name, ':'); int hash_size; char tmp[256]; @@ -212,36 +215,49 @@ int crypt_storage_init(struct crypt_storage **ctx, bool large_iv) { struct crypt_storage *s; - char mode_name[64]; + char cipher_name[MAX_CAPI_LEN], mode_name[MAX_CAPI_LEN], mode_tmp[MAX_CAPI_LEN]; char *cipher_iv = NULL; - int r = -EIO; + int r; if (sector_size < (1 << SECTOR_SHIFT) || sector_size > (1 << (SECTOR_SHIFT + 3)) || sector_size & (sector_size - 1)) return -EINVAL; - s = malloc(sizeof(*s)); - if (!s) - return -ENOMEM; - memset(s, 0, sizeof(*s)); + /* Convert from capi mode */ + if (!strncmp(cipher, "capi:", 5)) { + r = sscanf(cipher, "capi:%" MAX_CAPI_LEN_STR "[^(](%" MAX_CAPI_LEN_STR "[^)])", mode_tmp, cipher_name); + if (r != 2) + return -EINVAL; + r = snprintf(mode_name, sizeof(mode_name), "%s-%s", mode_tmp, cipher_mode); + if (r < 0 || (size_t)r >= sizeof(mode_name)) + return -EINVAL; + } else { + strncpy(cipher_name, cipher, sizeof(cipher_name)); + cipher_name[sizeof(cipher_name) - 1] = 0; + strncpy(mode_name, cipher_mode, sizeof(mode_name)); + mode_name[sizeof(mode_name) - 1] = 0; + } /* Remove IV if present */ - strncpy(mode_name, cipher_mode, sizeof(mode_name)); - mode_name[sizeof(mode_name) - 1] = 0; cipher_iv = strchr(mode_name, '-'); if (cipher_iv) { *cipher_iv = '\0'; cipher_iv++; } - r = crypt_cipher_init(&s->cipher, cipher, mode_name, key, key_length); + s = malloc(sizeof(*s)); + if (!s) + return -ENOMEM; + memset(s, 0, sizeof(*s)); + + r = crypt_cipher_init(&s->cipher, cipher_name, mode_name, key, key_length); if (r) { crypt_storage_destroy(s); return r; } - r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size); + r = crypt_sector_iv_init(&s->cipher_iv, cipher_name, mode_name, cipher_iv, key, key_length, sector_size); if (r) { crypt_storage_destroy(s); return r; diff --git a/lib/crypto_backend/memutils.c b/lib/crypto_backend/memutils.c new file mode 100644 index 0000000..a041b3e --- /dev/null +++ b/lib/crypto_backend/memutils.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * Safe memory utilities + * + * Copyright (C) 2024-2025 Milan Broz + */ + +#include "crypto_backend_internal.h" + +#define ATTR_NOINLINE __attribute__ ((noinline)) +#define ATTR_ZERO_REGS +#if HAVE_ATTRIBUTE_ZEROCALLUSEDREGS +# undef ATTR_ZERO_REGS +# define ATTR_ZERO_REGS __attribute__ ((zero_call_used_regs("used"))) +#endif + +/* Workaround for https://github.com/google/sanitizers/issues/1507 */ +#if defined __has_feature +# if __has_feature (memory_sanitizer) +# undef HAVE_EXPLICIT_BZERO +# endif +#endif + +/* Memzero helper (memset on stack can be optimized out) */ +ATTR_NOINLINE ATTR_ZERO_REGS +void crypt_backend_memzero(void *s, size_t n) +{ +#if HAVE_EXPLICIT_BZERO + explicit_bzero(s, n); +#else + volatile uint8_t *p = (volatile uint8_t *)s; + while(n--) *p++ = 0; +#endif +} + +/* Memcpy helper to avoid spilling sensitive data through additional registers */ +ATTR_NOINLINE ATTR_ZERO_REGS +void *crypt_backend_memcpy(void *dst, const void *src, size_t n) +{ + volatile uint8_t *d = (volatile uint8_t *)dst; + const volatile uint8_t *s = (const volatile uint8_t *)src; + + while(n--) *d++ = *s++; + + return dst; +} + +/* Internal implementation for constant time memory comparison */ +ATTR_NOINLINE ATTR_ZERO_REGS +int crypt_internal_memeq(const void *m1, const void *m2, size_t n) +{ + const unsigned char *_m1 = (const unsigned char *) m1; + const unsigned char *_m2 = (const unsigned char *) m2; + unsigned char result = 0; + size_t i; + + for (i = 0; i < n; i++) + result |= _m1[i] ^ _m2[i]; + + return result; +} diff --git a/lib/crypto_backend/meson.build b/lib/crypto_backend/meson.build index d6c31fd..43cf40e 100644 --- a/lib/crypto_backend/meson.build +++ b/lib/crypto_backend/meson.build @@ -11,6 +11,7 @@ libcrypto_backend_link_with = [] libcrypto_backend_sources = files( 'argon2_generic.c', 'base64.c', + 'memutils.c', 'cipher_check.c', 'cipher_generic.c', 'crc32.c', diff --git a/lib/crypto_backend/pbkdf2_generic.c b/lib/crypto_backend/pbkdf2_generic.c index cebaea4..e5e5a9c 100644 --- a/lib/crypto_backend/pbkdf2_generic.c +++ b/lib/crypto_backend/pbkdf2_generic.c @@ -5,8 +5,8 @@ * Copyright (C) 2004 Free Software Foundation * * cryptsetup related changes - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2024 Milan Broz + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Milan Broz */ #include diff --git a/lib/crypto_backend/pbkdf_check.c b/lib/crypto_backend/pbkdf_check.c index d5e1257..5eb21f3 100644 --- a/lib/crypto_backend/pbkdf_check.c +++ b/lib/crypto_backend/pbkdf_check.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: LGPL-2.1-or-later /* * PBKDF performance check - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2024 Milan Broz + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Milan Broz * Copyright (C) 2016-2020 Ondrej Mosnacek */ @@ -300,6 +300,7 @@ static int crypt_argon2_check(const char *kdf, const char *password, } while (ms < ms_atleast || ms > ms_atmost); out: if (key) { + /* Key can be derived from a real provided password */ crypt_backend_memzero(key, key_length); free(key); } @@ -381,6 +382,7 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash, } out: if (key) { + /* Key can be derived from a real provided password */ crypt_backend_memzero(key, key_length); free(key); } @@ -406,6 +408,9 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash, if (r < 0) return r; + if (parallel_threads > pbkdf_limits.max_parallel) + return -EINVAL; + min_memory = pbkdf_limits.min_bench_memory; if (min_memory > max_memory_kb) min_memory = max_memory_kb; diff --git a/lib/crypto_backend/utf8.c b/lib/crypto_backend/utf8.c index 07a45eb..c68d1b7 100644 --- a/lib/crypto_backend/utf8.c +++ b/lib/crypto_backend/utf8.c @@ -5,7 +5,7 @@ * Copyright (C) 2010 Lennart Poettering * * cryptsetup related changes - * Copyright (C) 2021-2024 Vojtech Trefny + * Copyright (C) 2021-2025 Vojtech Trefny * Parts of the original systemd implementation are based on the GLIB utf8 * validation functions. @@ -274,3 +274,20 @@ int crypt_utf8_to_utf16(char16_t **out, const char *s, size_t length) *p = 0; return 0; } + +/** + * crypt_char16_strlen() + * @s: string to get length of + * + * Returns: number of 16-bit words in the string + */ +size_t crypt_char16_strlen(const char16_t *s) { + size_t n = 0; + + assert(s); + + while (*s != 0) + n++, s++; + + return n; +} diff --git a/lib/fvault2/fvault2.c b/lib/fvault2/fvault2.c index f55f2c4..59f4570 100644 --- a/lib/fvault2/fvault2.c +++ b/lib/fvault2/fvault2.c @@ -513,6 +513,7 @@ static int _read_volume_header( int r = 0; struct device *dev = crypt_metadata_device(cd); struct volume_header *vol_header = NULL; + void *enc_key = NULL; assert(sizeof(*vol_header) == FVAULT2_VOL_HEADER_SIZE); @@ -557,8 +558,8 @@ static int _read_volume_header( goto out; } - *enc_md_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL); - if (*enc_md_key == NULL) { + enc_key = crypt_safe_alloc(FVAULT2_XTS_KEY_SIZE); + if (!enc_key) { r = -ENOMEM; goto out; } @@ -566,9 +567,15 @@ static int _read_volume_header( *block_size = le32_to_cpu(vol_header->block_size); *disklbl_blkoff = le64_to_cpu(vol_header->disklbl_blkoff); uuid_unparse(vol_header->ph_vol_uuid, ph_vol_uuid); - memcpy((*enc_md_key)->key, vol_header->key_data, FVAULT2_AES_KEY_SIZE); - memcpy((*enc_md_key)->key + FVAULT2_AES_KEY_SIZE, + crypt_safe_memcpy(enc_key, vol_header->key_data, FVAULT2_AES_KEY_SIZE); + crypt_safe_memcpy((char *)enc_key + FVAULT2_AES_KEY_SIZE, vol_header->ph_vol_uuid, FVAULT2_AES_KEY_SIZE); + + *enc_md_key = crypt_alloc_volume_key_by_safe_alloc(&enc_key); + if (*enc_md_key == NULL) { + crypt_safe_free(enc_key); + r = -ENOMEM; + } out: free(vol_header); return r; @@ -704,7 +711,7 @@ static int _read_encrypted_metadata( goto out; } - r = crypt_cipher_init(&cipher, "aes", "xts", key->key, FVAULT2_XTS_KEY_SIZE); + r = crypt_cipher_init(&cipher, "aes", "xts", crypt_volume_key_get_key(key), FVAULT2_XTS_KEY_SIZE); if (r < 0) goto out; @@ -835,8 +842,7 @@ static int _activate( r = dm_crypt_target_set(&dm_dev.segment, 0, dm_dev.size, crypt_data_device(cd), vol_key, cipher, crypt_get_iv_offset(cd), crypt_get_data_offset(cd), - crypt_get_integrity(cd), crypt_get_integrity_tag_size(cd), - crypt_get_sector_size(cd)); + NULL, 0, 0, crypt_get_sector_size(cd)); if (!r) r = dm_create_device(cd, name, CRYPT_FVAULT2, &dm_dev); @@ -893,15 +899,14 @@ int FVAULT2_get_volume_key( const char *passphrase, size_t passphrase_len, const struct fvault2_params *params, - struct volume_key **vol_key) + struct volume_key **r_vol_key) { int r = 0; uint8_t family_uuid_bin[FVAULT2_UUID_BIN_SIZE]; - struct volume_key *passphrase_key = NULL; - struct volume_key *kek = NULL; struct crypt_hash *hash = NULL; + void *passphrase_key = NULL, *kek = NULL, *vol_key= NULL; - *vol_key = NULL; + *r_vol_key = NULL; if (uuid_parse(params->family_uuid, family_uuid_bin) < 0) { log_dbg(cd, "Could not parse logical volume family UUID: %s.", @@ -910,61 +915,62 @@ int FVAULT2_get_volume_key( goto out; } - passphrase_key = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL); + passphrase_key = crypt_safe_alloc(FVAULT2_AES_KEY_SIZE); if (passphrase_key == NULL) { r = -ENOMEM; goto out; } r = crypt_pbkdf("pbkdf2", "sha256", passphrase, passphrase_len, - params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key->key, + params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key, FVAULT2_AES_KEY_SIZE, params->pbkdf2_iters, 0, 0); if (r < 0) goto out; - kek = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL); + kek = crypt_safe_alloc(FVAULT2_AES_KEY_SIZE); if (kek == NULL) { r = -ENOMEM; goto out; } - r = _unwrap_key(passphrase_key->key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek, - FVAULT2_WRAPPED_KEY_SIZE, kek->key, FVAULT2_AES_KEY_SIZE); + r = _unwrap_key(passphrase_key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek, + FVAULT2_WRAPPED_KEY_SIZE, kek, FVAULT2_AES_KEY_SIZE); if (r < 0) goto out; - *vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL); - if (*vol_key == NULL) { + vol_key = crypt_safe_alloc(FVAULT2_XTS_KEY_SIZE); + if (vol_key == NULL) { r = -ENOMEM; goto out; } - r = _unwrap_key(kek->key, FVAULT2_AES_KEY_SIZE, params->wrapped_vk, - FVAULT2_WRAPPED_KEY_SIZE, (*vol_key)->key, FVAULT2_AES_KEY_SIZE); + r = _unwrap_key(kek, FVAULT2_AES_KEY_SIZE, params->wrapped_vk, + FVAULT2_WRAPPED_KEY_SIZE, vol_key, FVAULT2_AES_KEY_SIZE); if (r < 0) goto out; r = crypt_hash_init(&hash, "sha256"); if (r < 0) goto out; - r = crypt_hash_write(hash, (*vol_key)->key, FVAULT2_AES_KEY_SIZE); + r = crypt_hash_write(hash, vol_key, FVAULT2_AES_KEY_SIZE); if (r < 0) goto out; r = crypt_hash_write(hash, (char *)family_uuid_bin, FVAULT2_UUID_BIN_SIZE); if (r < 0) goto out; - r = crypt_hash_final(hash, (*vol_key)->key + FVAULT2_AES_KEY_SIZE, + r = crypt_hash_final(hash, (char *)vol_key + FVAULT2_AES_KEY_SIZE, FVAULT2_AES_KEY_SIZE); if (r < 0) goto out; + + *r_vol_key = crypt_alloc_volume_key_by_safe_alloc(&vol_key); + if (!*r_vol_key) + r = -ENOMEM; out: - crypt_free_volume_key(passphrase_key); - crypt_free_volume_key(kek); - if (r < 0) { - crypt_free_volume_key(*vol_key); - *vol_key = NULL; - } + crypt_safe_free(passphrase_key); + crypt_safe_free(kek); + crypt_safe_free(vol_key); if (hash != NULL) crypt_hash_destroy(hash); return r; @@ -997,48 +1003,19 @@ int FVAULT2_dump( return 0; } -int FVAULT2_activate_by_passphrase( +int FVAULT2_activate_by_volume_key( struct crypt_device *cd, const char *name, - const char *passphrase, - size_t passphrase_len, + struct volume_key *vk, const struct fvault2_params *params, uint32_t flags) { - int r; - struct volume_key *vol_key = NULL; - - r = FVAULT2_get_volume_key(cd, passphrase, passphrase_len, params, &vol_key); - if (r < 0) - return r; + assert(crypt_volume_key_length(vk) == FVAULT2_XTS_KEY_SIZE); - if (name) - r = _activate(cd, name, vol_key, params, flags); - - crypt_free_volume_key(vol_key); - return r; + return _activate(cd, name, vk, params, flags); } -int FVAULT2_activate_by_volume_key( - struct crypt_device *cd, - const char *name, - const char *key, - size_t key_size, - const struct fvault2_params *params, - uint32_t flags) +size_t FVAULT2_volume_key_size(void) { - int r = 0; - struct volume_key *vol_key = NULL; - - if (key_size != FVAULT2_XTS_KEY_SIZE) - return -EINVAL; - - vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, key); - if (vol_key == NULL) - return -ENOMEM; - - r = _activate(cd, name, vol_key, params, flags); - - crypt_free_volume_key(vol_key); - return r; + return FVAULT2_XTS_KEY_SIZE; } diff --git a/lib/fvault2/fvault2.h b/lib/fvault2/fvault2.h index 8a03280..ad6ad5e 100644 --- a/lib/fvault2/fvault2.h +++ b/lib/fvault2/fvault2.h @@ -41,27 +41,20 @@ int FVAULT2_get_volume_key( const char *passphrase, size_t passphrase_len, const struct fvault2_params *params, - struct volume_key **vol_key); + struct volume_key **r_vol_key); int FVAULT2_dump( struct crypt_device *cd, struct device *device, const struct fvault2_params *params); -int FVAULT2_activate_by_passphrase( - struct crypt_device *cd, - const char *name, - const char *passphrase, - size_t passphrase_len, - const struct fvault2_params *params, - uint32_t flags); - int FVAULT2_activate_by_volume_key( struct crypt_device *cd, const char *name, - const char *key, - size_t key_size, + struct volume_key *vk, const struct fvault2_params *params, uint32_t flags); +size_t FVAULT2_volume_key_size(void); + #endif diff --git a/lib/integrity/integrity.c b/lib/integrity/integrity.c index 37d0737..a10050d 100644 --- a/lib/integrity/integrity.c +++ b/lib/integrity/integrity.c @@ -2,7 +2,7 @@ /* * Integrity volume handling * - * Copyright (C) 2016-2024 Milan Broz + * Copyright (C) 2016-2025 Milan Broz */ #include @@ -31,16 +31,22 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd, { int devfd, r; + log_dbg(cd, "Reading kernel dm-integrity metadata on %s.", device_path(device)); + devfd = device_open(cd, device, O_RDONLY); if(devfd < 0) return -EINVAL; if (read_lseek_blockwise(devfd, device_block_size(cd, device), - device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) || - memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic))) { + device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb)) { + log_dbg(cd, "Cannot read kernel dm-integrity metadata on %s.", device_path(device)); + return -EINVAL; + } + + if (memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic))) { log_dbg(cd, "No kernel dm-integrity metadata detected on %s.", device_path(device)); r = -EINVAL; - } else if (sb->version < SB_VERSION_1 || sb->version > SB_VERSION_5) { + } else if (sb->version < SB_VERSION_1 || sb->version > SB_VERSION_6) { log_err(cd, _("Incompatible kernel dm-integrity metadata (version %u) detected on %s."), sb->version, device_path(device)); r = -EINVAL; @@ -67,8 +73,10 @@ int INTEGRITY_read_sb(struct crypt_device *cd, if (r) return r; - params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block; - params->tag_size = sb.integrity_tag_size; + if (params) { + params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block; + params->tag_size = sb.integrity_tag_size; + } if (flags) *flags = sb.flags; @@ -79,28 +87,32 @@ int INTEGRITY_read_sb(struct crypt_device *cd, int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset) { struct superblock sb; + uint64_t sector_size; int r; r = INTEGRITY_read_superblock(cd, device, offset, &sb); if (r) return r; - log_std(cd, "Info for integrity device %s.\n", device_path(device)); - log_std(cd, "superblock_version %d\n", (unsigned)sb.version); - log_std(cd, "log2_interleave_sectors %d\n", sb.log2_interleave_sectors); - log_std(cd, "integrity_tag_size %u\n", sb.integrity_tag_size); - log_std(cd, "journal_sections %u\n", sb.journal_sections); - log_std(cd, "provided_data_sectors %" PRIu64 "\n", sb.provided_data_sectors); - log_std(cd, "sector_size %u\n", SECTOR_SIZE << sb.log2_sectors_per_block); + sector_size = (uint64_t)SECTOR_SIZE << sb.log2_sectors_per_block; + log_std(cd, "INTEGRITY header information for %s.\n", device_path(device)); + log_std(cd, "version: %d\n", (unsigned)sb.version); + log_std(cd, "tag size: %u [bytes]\n", sb.integrity_tag_size); + log_std(cd, "sector size: %" PRIu64 " [bytes]\n", sector_size); + log_std(cd, "data size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n", + sb.provided_data_sectors, sb.provided_data_sectors * SECTOR_SIZE); if (sb.version >= SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING)) - log_std(cd, "recalc_sector %" PRIu64 "\n", sb.recalc_sector); - log_std(cd, "log2_blocks_per_bitmap %u\n", sb.log2_blocks_per_bitmap_bit); - log_std(cd, "flags %s%s%s%s%s\n", + log_std(cd, "recalculate sector: %" PRIu64 "\n", sb.recalc_sector); + log_std(cd, "journal sections: %u\n", sb.journal_sections); + log_std(cd, "log2 interleave sectors: %d\n", sb.log2_interleave_sectors); + log_std(cd, "log2 blocks per bitmap: %u\n", sb.log2_blocks_per_bitmap_bit); + log_std(cd, "flags: %s%s%s%s%s%s\n", sb.flags & SB_FLAG_HAVE_JOURNAL_MAC ? "have_journal_mac " : "", sb.flags & SB_FLAG_RECALCULATING ? "recalculating " : "", sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "", sb.flags & SB_FLAG_FIXED_PADDING ? "fix_padding " : "", - sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : ""); + sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : "", + sb.flags & SB_FLAG_INLINE ? "inline " : ""); return 0; } @@ -120,26 +132,42 @@ int INTEGRITY_data_sectors(struct crypt_device *cd, return 0; } -int INTEGRITY_key_size(const char *integrity) +int INTEGRITY_key_size(const char *integrity, int required_key_size) { + int ks = 0; + + if (!integrity && required_key_size) + return -EINVAL; + if (!integrity) return 0; //FIXME: use crypto backend hash size if (!strcmp(integrity, "aead")) - return 0; + ks = 0; else if (!strcmp(integrity, "hmac(sha1)")) - return 20; + ks = required_key_size ?: 20; else if (!strcmp(integrity, "hmac(sha256)")) - return 32; + ks = required_key_size ?: 32; else if (!strcmp(integrity, "hmac(sha512)")) - return 64; + ks = required_key_size ?: 64; + else if (!strcmp(integrity, "phmac(sha1)")) + ks = required_key_size ?: -EINVAL; + else if (!strcmp(integrity, "phmac(sha256)")) + ks = required_key_size ?: -EINVAL; + else if (!strcmp(integrity, "phmac(sha512)")) + ks = required_key_size ?: -EINVAL; else if (!strcmp(integrity, "poly1305")) - return 0; + ks = 0; else if (!strcmp(integrity, "none")) - return 0; + ks = 0; + else + return -EINVAL; - return -EINVAL; + if (required_key_size && ks != required_key_size) + return -EINVAL; + + return ks; } /* Return hash or hmac(hash) size, if known */ @@ -158,6 +186,8 @@ int INTEGRITY_hash_tag_size(const char *integrity) return 8; r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash); + if (r != 1) + r = sscanf(integrity, "phmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash); if (r == 1) r = crypt_hash_size(hash); else @@ -200,6 +230,12 @@ int INTEGRITY_tag_size(const char *integrity, auth_tag_size = 32; else if (!strcmp(integrity, "hmac(sha512)")) auth_tag_size = 64; + else if (!strcmp(integrity, "phmac(sha1)")) + auth_tag_size = 20; + else if (!strcmp(integrity, "phmac(sha256)")) + auth_tag_size = 32; + else if (!strcmp(integrity, "phmac(sha512)")) + auth_tag_size = 64; else if (!strcmp(integrity, "poly1305")) { if (iv_tag_size) iv_tag_size = 12; @@ -230,6 +266,9 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd, if (sb_flags & SB_FLAG_RECALCULATING) dmd->flags |= CRYPT_ACTIVATE_RECALCULATE; + if (sb_flags & SB_FLAG_INLINE) + dmd->flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE); + r = INTEGRITY_data_sectors(cd, INTEGRITY_metadata_device(cd), crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size); if (r < 0) @@ -249,14 +288,15 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd, uint32_t sb_flags) { int r; - uint32_t dmi_flags; + uint64_t dmi_flags; struct dm_target *tgt = &dmd->segment; if (!single_segment(dmd) || tgt->type != DM_INTEGRITY) return -EINVAL; - log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d, provided sectors %" PRIu64".", - device_path(tgt->data_device), name, tgt->u.integrity.tag_size, dmd->size); + log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d%s, provided sectors %" PRIu64".", + device_path(tgt->data_device), name, tgt->u.integrity.tag_size, + (sb_flags & SB_FLAG_INLINE) ? " (inline)" :"", dmd->size); r = create_or_reload_device(cd, name, type, dmd); @@ -280,6 +320,12 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd, return -ENOTSUP; } + if (r < 0 && (sb_flags & SB_FLAG_INLINE) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) && + !(dmi_flags & DM_INTEGRITY_INLINE_MODE_SUPPORTED)) { + log_err(cd, _("Kernel does not support dm-integrity inline mode.")); + return -ENOTSUP; + } + return r; } @@ -372,11 +418,14 @@ static int _create_reduced_device(struct crypt_device *cd, int INTEGRITY_format(struct crypt_device *cd, const struct crypt_params_integrity *params, + struct volume_key *integrity_key, struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key, - uint64_t backing_device_sectors) + uint64_t backing_device_sectors, + uint32_t *sb_flags, + bool integrity_inline) { - uint32_t dmi_flags; + uint64_t dmi_flags; char reduced_device_name[70], tmp_name[64], tmp_uuid[40]; struct crypt_dm_active_device dmdi = { .size = 8, @@ -387,7 +436,6 @@ int INTEGRITY_format(struct crypt_device *cd, uuid_t tmp_uuid_bin; uint64_t data_offset_sectors; struct device *p_metadata_device, *p_data_device, *reduced_device = NULL; - struct volume_key *vk = NULL; uuid_generate(tmp_uuid_bin); uuid_unparse(tmp_uuid_bin, tmp_uuid); @@ -422,19 +470,18 @@ int INTEGRITY_format(struct crypt_device *cd, p_data_device = crypt_data_device(cd); } - /* There is no data area, we can actually use fake zeroed key */ - if (params && params->integrity_key_size) - vk = crypt_alloc_volume_key(params->integrity_key_size, NULL); + if (integrity_inline) + dmdi.flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE); r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, p_metadata_device, p_data_device, crypt_get_integrity_tag_size(cd), - data_offset_sectors, crypt_get_sector_size(cd), vk, + data_offset_sectors, crypt_get_sector_size(cd), integrity_key, journal_crypt_key, journal_mac_key, params); if (r < 0) goto err; - log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d.", - device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size); + log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d%s.", + device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size, integrity_inline ? " (inline)" : ""); r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL); if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) { @@ -455,9 +502,14 @@ int INTEGRITY_format(struct crypt_device *cd, goto err; r = dm_remove_device(cd, tmp_name, CRYPT_DEACTIVATE_FORCE); + if (r) + goto err; + + /* reload sb_flags from superblock (important for SB_FLAG_INLINE) */ + if (sb_flags) + r = INTEGRITY_read_sb(cd, NULL, sb_flags); err: dm_targets_free(cd, &dmdi); - crypt_free_volume_key(vk); if (reduced_device) { dm_remove_device(cd, reduced_device_name, CRYPT_DEACTIVATE_FORCE); device_free(cd, reduced_device); diff --git a/lib/integrity/integrity.h b/lib/integrity/integrity.h index 049a299..ff1293f 100644 --- a/lib/integrity/integrity.h +++ b/lib/integrity/integrity.h @@ -2,13 +2,14 @@ /* * Integrity header definition * - * Copyright (C) 2016-2024 Milan Broz + * Copyright (C) 2016-2025 Milan Broz */ #ifndef _CRYPTSETUP_INTEGRITY_H #define _CRYPTSETUP_INTEGRITY_H #include +#include struct crypt_device; struct device; @@ -23,12 +24,14 @@ struct crypt_dm_active_device; #define SB_VERSION_3 3 #define SB_VERSION_4 4 #define SB_VERSION_5 5 +#define SB_VERSION_6 6 #define SB_FLAG_HAVE_JOURNAL_MAC (1 << 0) #define SB_FLAG_RECALCULATING (1 << 1) /* V2 only */ #define SB_FLAG_DIRTY_BITMAP (1 << 2) /* V3 only */ #define SB_FLAG_FIXED_PADDING (1 << 3) /* V4 only */ #define SB_FLAG_FIXED_HMAC (1 << 4) /* V5 only */ +#define SB_FLAG_INLINE (1 << 5) /* V6 only */ struct superblock { uint8_t magic[8]; @@ -40,8 +43,10 @@ struct superblock { uint32_t flags; uint8_t log2_sectors_per_block; uint8_t log2_blocks_per_bitmap_bit; /* V3 only */ - uint8_t pad[2]; + uint8_t pad[2]; /* (padding) */ uint64_t recalc_sector; /* V2 only */ + uint8_t pad2[8]; /* (padding) */ + uint8_t salt[16]; /* for fixed hmac, V5 only */ } __attribute__ ((packed)); int INTEGRITY_read_sb(struct crypt_device *cd, @@ -53,7 +58,7 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs int INTEGRITY_data_sectors(struct crypt_device *cd, struct device *device, uint64_t offset, uint64_t *data_sectors); -int INTEGRITY_key_size(const char *integrity); +int INTEGRITY_key_size(const char *integrity, int required_key_size); int INTEGRITY_tag_size(const char *integrity, const char *cipher, const char *cipher_mode); @@ -61,9 +66,12 @@ int INTEGRITY_hash_tag_size(const char *integrity); int INTEGRITY_format(struct crypt_device *cd, const struct crypt_params_integrity *params, + struct volume_key *integrity_key, struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key, - uint64_t backing_device_sectors); + uint64_t backing_device_sectors, + uint32_t *sb_flags, + bool integrity_inline); int INTEGRITY_activate(struct crypt_device *cd, const char *name, diff --git a/lib/internal.h b/lib/internal.h index 765bf15..56efa46 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #ifndef INTERNAL_H @@ -48,24 +48,36 @@ struct crypt_device; struct luks2_reencrypt; +struct volume_key; -struct volume_key { - int id; - size_t keylength; - const char *key_description; - struct volume_key *next; - char key[]; -}; +typedef enum { + KEY_QUALITY_KEY = 0, + KEY_QUALITY_NORMAL, + KEY_QUALITY_EMPTY +} key_quality_info; struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key); -struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength); +struct volume_key *crypt_alloc_volume_key_by_safe_alloc(void **safe_alloc); +struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength, + key_quality_info quality); void crypt_free_volume_key(struct volume_key *vk); -int crypt_volume_key_set_description(struct volume_key *key, const char *key_description); +const char *crypt_volume_key_get_key(const struct volume_key *vk); +size_t crypt_volume_key_length(const struct volume_key *vk); +int crypt_volume_key_set_description(struct volume_key *key, + const char *key_description, key_type_t keyring_key_type); +int crypt_volume_key_set_description_by_name(struct volume_key *vk, const char *key_name); +key_type_t crypt_volume_key_kernel_key_type(const struct volume_key *vk); +const char *crypt_volume_key_description(const struct volume_key *vk); void crypt_volume_key_set_id(struct volume_key *vk, int id); int crypt_volume_key_get_id(const struct volume_key *vk); void crypt_volume_key_add_next(struct volume_key **vks, struct volume_key *vk); struct volume_key *crypt_volume_key_next(struct volume_key *vk); struct volume_key *crypt_volume_key_by_id(struct volume_key *vk, int id); +void crypt_volume_key_pass_safe_alloc(struct volume_key *vk, void **safe_alloc); +bool crypt_volume_key_is_set(const struct volume_key *vk); +bool crypt_volume_key_upload_kernel_key(struct volume_key *vk); +void crypt_volume_key_drop_uploaded_kernel_key(struct crypt_device *cd, struct volume_key *vk); +void crypt_volume_key_drop_kernel_key(struct crypt_device *cd, struct volume_key *vk); struct crypt_pbkdf_type *crypt_get_pbkdf(struct crypt_device *cd); int init_pbkdf_type(struct crypt_device *cd, @@ -86,7 +98,6 @@ int device_alloc_no_check(struct device **device, const char *path); void device_close(struct crypt_device *cd, struct device *device); void device_free(struct crypt_device *cd, struct device *device); const char *device_path(const struct device *device); -const char *device_dm_name(const struct device *device); const char *device_block_path(const struct device *device); void device_topology_alignment(struct crypt_device *cd, struct device *device, @@ -104,6 +115,7 @@ int device_is_identical(struct device *device1, struct device *device2); int device_is_rotational(struct device *device); int device_is_dax(struct device *device); int device_is_zoned(struct device *device); +int device_is_nop_dif(struct device *device, uint32_t *tag_size); size_t device_alignment(struct device *device); int device_direct_io(const struct device *device); int device_fallocate(struct device *device, uint64_t size); @@ -155,6 +167,7 @@ char *crypt_lookup_dev(const char *dev_id); int crypt_dev_is_rotational(int major, int minor); int crypt_dev_is_dax(int major, int minor); int crypt_dev_is_zoned(int major, int minor); +int crypt_dev_is_nop_dif(int major, int minor, uint32_t *tag_size); int crypt_dev_is_partition(const char *dev_path); char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size); int crypt_dev_get_partition_number(const char *dev_path); @@ -162,8 +175,6 @@ char *crypt_get_base_device(const char *dev_path); uint64_t crypt_dev_partition_offset(const char *dev_path); int lookup_by_disk_id(const char *dm_uuid); int lookup_by_sysfs_uuid_field(const char *dm_uuid); -int crypt_uuid_cmp(const char *dm_uuid, const char *hdr_uuid); -int crypt_uuid_type_cmp(const char *dm_uuid, const char *type); size_t crypt_getpagesize(void); unsigned crypt_cpusonline(void); @@ -217,7 +228,7 @@ int crypt_wipe_device(struct crypt_device *cd, /* Internal integrity helpers */ const char *crypt_get_integrity(struct crypt_device *cd); -int crypt_get_integrity_key_size(struct crypt_device *cd); +int crypt_get_integrity_key_size(struct crypt_device *cd, bool dm_compat); int crypt_get_integrity_tag_size(struct crypt_device *cd); int crypt_key_in_keyring(struct crypt_device *cd); @@ -231,9 +242,18 @@ int crypt_keyring_get_key_by_name(struct crypt_device *cd, const char *key_description, char **key, size_t *key_size); + +int crypt_keyring_get_keysize_by_name(struct crypt_device *cd, + const char *key_description, + size_t *r_key_size); + int crypt_use_keyring_for_vk(struct crypt_device *cd); -void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *key_description, key_type_t ktype); -void crypt_drop_keyring_key(struct crypt_device *cd, struct volume_key *vks); +void crypt_unlink_key_from_thread_keyring(struct crypt_device *cd, + key_serial_t key_id); +void crypt_unlink_key_by_description_from_thread_keyring(struct crypt_device *cd, + const char *key_description, + key_type_t ktype); +void crypt_drop_uploaded_keyring_key(struct crypt_device *cd, struct volume_key *vks); static inline uint64_t compact_version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release) { @@ -266,4 +286,6 @@ static inline bool uint64_mult_overflow(uint64_t *u, uint64_t b, size_t size) #define KEY_EXTERNAL_VERIFICATION -1 #define KEY_VERIFIED 0 +size_t crypt_safe_alloc_size(const void *data); + #endif /* INTERNAL_H */ diff --git a/lib/keyslot_context.c b/lib/keyslot_context.c index 5d8852f..1b13782 100644 --- a/lib/keyslot_context.c +++ b/lib/keyslot_context.c @@ -2,12 +2,14 @@ /* * LUKS - Linux Unified Key Setup, keyslot unlock helpers * - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2022-2024 Ondrej Kozina + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Ondrej Kozina */ #include +#include "bitlk/bitlk.h" +#include "fvault2/fvault2.h" #include "luks1/luks.h" #include "luks2/luks2.h" #include "keyslot_context.h" @@ -58,6 +60,44 @@ static int get_luks2_volume_key_by_passphrase(struct crypt_device *cd, return get_luks2_key_by_passphrase(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk); } +static int get_bitlk_volume_key_by_passphrase(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params, + struct volume_key **r_vk) +{ + int r; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); + assert(params); + assert(r_vk); + + r = BITLK_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + +static int get_fvault2_volume_key_by_passphrase(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params, + struct volume_key **r_vk) +{ + int r; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); + assert(params); + assert(r_vk); + + r = FVAULT2_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + static int get_passphrase_by_passphrase(struct crypt_device *cd, struct crypt_keyslot_context *kc, const char **r_passphrase, @@ -160,6 +200,56 @@ static int get_luks1_volume_key_by_keyfile(struct crypt_device *cd, return r; } +static int get_bitlk_volume_key_by_keyfile(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params, + struct volume_key **r_vk) +{ + int r; + const char *passphrase; + size_t passphrase_size; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); + assert(params); + assert(r_vk); + + r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; + + r = BITLK_get_volume_key(cd, passphrase, passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + +static int get_fvault2_volume_key_by_keyfile(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params, + struct volume_key **r_vk) +{ + int r; + const char *passphrase; + size_t passphrase_size; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); + assert(params); + assert(r_vk); + + r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; + + r = FVAULT2_get_volume_key(cd, passphrase, passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + static int get_key_by_key(struct crypt_device *cd __attribute__((unused)), struct crypt_keyslot_context *kc, int keyslot __attribute__((unused)), @@ -198,6 +288,22 @@ static int get_generic_volume_key_by_key(struct crypt_device *cd, return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); } +static int get_bitlk_volume_key_by_key(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params __attribute__((unused)), + struct volume_key **r_vk) +{ + return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); +} + +static int get_fvault2_volume_key_by_key(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params __attribute__((unused)), + struct volume_key **r_vk) +{ + return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); +} + static int get_generic_signed_key_by_key(struct crypt_device *cd, struct crypt_keyslot_context *kc, struct volume_key **r_vk, @@ -354,7 +460,7 @@ static int get_luks2_key_by_keyring(struct crypt_device *cd, if (r < 0) kc->error = r; - return 0; + return r; } static int get_luks2_volume_key_by_keyring(struct crypt_device *cd, @@ -373,7 +479,7 @@ static int get_luks1_volume_key_by_keyring(struct crypt_device *cd, int r; assert(cd); - assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); + assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING); assert(r_vk); r = get_passphrase_by_keyring(cd, kc, CONST_CAST(const char **) &kc->i_passphrase, @@ -414,9 +520,9 @@ static int get_key_by_vk_in_keyring(struct crypt_device *cd, return -EINVAL; } - *r_vk = crypt_alloc_volume_key(key_size, key); - crypt_safe_free(key); + *r_vk = crypt_alloc_volume_key_by_safe_alloc((void **)&key); if (!*r_vk) { + crypt_safe_free(key); kc->error = -ENOMEM; return kc->error; } @@ -432,16 +538,41 @@ static int get_volume_key_by_vk_in_keyring(struct crypt_device *cd, return get_key_by_vk_in_keyring(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); } -static void unlock_method_init_internal(struct crypt_keyslot_context *kc) +static void crypt_keyslot_context_init_common(struct crypt_keyslot_context *kc) { assert(kc); + kc->version = KC_VERSION_BASIC; kc->error = 0; kc->i_passphrase = NULL; kc->i_passphrase_size = 0; } -void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc, +static void keyring_context_free(struct crypt_keyslot_context *kc) +{ + assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING); + + free(kc->u.kr.i_key_description); +} + +static int keyring_get_key_size(struct crypt_device *cd, struct crypt_keyslot_context *kc, size_t *r_key_size) +{ + int r; + + assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING); + assert(r_key_size); + + if (!kc->u.vk_kr.i_key_size) { + r = crypt_keyring_get_keysize_by_name(cd, kc->u.vk_kr.key_description, &kc->u.vk_kr.i_key_size); + if (r < 0) + return r; + } + + *r_key_size = kc->u.vk_kr.i_key_size; + return 0; +} + +void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc, const char *key_description) { assert(kc); @@ -450,18 +581,32 @@ void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc, kc->u.kr.key_description = key_description; kc->get_luks2_key = get_luks2_key_by_keyring; - kc->get_luks2_volume_key = get_luks2_volume_key_by_keyring; kc->get_luks1_volume_key = get_luks1_volume_key_by_keyring; + kc->get_luks2_volume_key = get_luks2_volume_key_by_keyring; kc->get_passphrase = get_passphrase_by_keyring; - kc->get_plain_volume_key = NULL; - kc->get_bitlk_volume_key = NULL; - kc->get_fvault2_volume_key = NULL; - kc->get_verity_volume_key = NULL; - kc->get_integrity_volume_key = NULL; - unlock_method_init_internal(kc); + kc->context_free = keyring_context_free; + crypt_keyslot_context_init_common(kc); +} + +static void key_context_free(struct crypt_keyslot_context *kc) +{ + assert(kc && kc->type == CRYPT_KC_TYPE_KEY); + + crypt_free_volume_key(kc->u.k.i_vk); } -void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc, +static int key_get_key_size(struct crypt_device *cd __attribute__((unused)), + struct crypt_keyslot_context *kc, + size_t *r_key_size) +{ + assert(kc && kc->type == CRYPT_KC_TYPE_KEY); + assert(r_key_size); + + *r_key_size = kc->u.k.volume_key_size; + return 0; +} + +void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc, const char *volume_key, size_t volume_key_size) { @@ -470,19 +615,29 @@ void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc, kc->type = CRYPT_KC_TYPE_KEY; kc->u.k.volume_key = volume_key; kc->u.k.volume_key_size = volume_key_size; + kc->get_luks2_key = get_key_by_key; - kc->get_luks2_volume_key = get_volume_key_by_key; kc->get_luks1_volume_key = get_volume_key_by_key; - kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */ + kc->get_luks2_volume_key = get_volume_key_by_key; kc->get_plain_volume_key = get_generic_volume_key_by_key; - kc->get_bitlk_volume_key = get_generic_volume_key_by_key; - kc->get_fvault2_volume_key = get_generic_volume_key_by_key; + kc->get_bitlk_volume_key = get_bitlk_volume_key_by_key; + kc->get_fvault2_volume_key = get_fvault2_volume_key_by_key; kc->get_verity_volume_key = get_generic_signed_key_by_key; kc->get_integrity_volume_key = get_generic_volume_key_by_key; - unlock_method_init_internal(kc); + kc->get_key_size = key_get_key_size; + kc->context_free = key_context_free; + crypt_keyslot_context_init_common(kc); } -void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_context *kc, +static void signed_key_context_free(struct crypt_keyslot_context *kc) +{ + assert(kc && kc->type == CRYPT_KC_TYPE_SIGNED_KEY); + + crypt_free_volume_key(kc->u.ks.i_vk); + crypt_free_volume_key(kc->u.ks.i_vk_sig); +} + +void crypt_keyslot_context_init_by_signed_key_internal(struct crypt_keyslot_context *kc, const char *volume_key, size_t volume_key_size, const char *signature, @@ -495,19 +650,13 @@ void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_conte kc->u.ks.volume_key_size = volume_key_size; kc->u.ks.signature = signature; kc->u.ks.signature_size = signature_size; - kc->get_luks2_key = NULL; - kc->get_luks2_volume_key = NULL; - kc->get_luks1_volume_key = NULL; - kc->get_passphrase = NULL; - kc->get_plain_volume_key = NULL; - kc->get_bitlk_volume_key = NULL; - kc->get_fvault2_volume_key = NULL; + kc->get_verity_volume_key = get_generic_signed_key_by_key; - kc->get_integrity_volume_key = NULL; - unlock_method_init_internal(kc); + kc->context_free = signed_key_context_free; + crypt_keyslot_context_init_common(kc); } -void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_context *kc, const char *passphrase, size_t passphrase_size) { @@ -516,19 +665,24 @@ void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_conte kc->type = CRYPT_KC_TYPE_PASSPHRASE; kc->u.p.passphrase = passphrase; kc->u.p.passphrase_size = passphrase_size; + kc->get_luks2_key = get_luks2_key_by_passphrase; - kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase; kc->get_luks1_volume_key = get_luks1_volume_key_by_passphrase; + kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase; + kc->get_bitlk_volume_key = get_bitlk_volume_key_by_passphrase; + kc->get_fvault2_volume_key = get_fvault2_volume_key_by_passphrase; kc->get_passphrase = get_passphrase_by_passphrase; - kc->get_plain_volume_key = NULL; - kc->get_bitlk_volume_key = NULL; - kc->get_fvault2_volume_key = NULL; - kc->get_verity_volume_key = NULL; - kc->get_integrity_volume_key = NULL; - unlock_method_init_internal(kc); + crypt_keyslot_context_init_common(kc); +} + +static void keyfile_context_free(struct crypt_keyslot_context *kc) +{ + assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); + + free(kc->u.kf.i_keyfile); } -void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context *kc, const char *keyfile, size_t keyfile_size, uint64_t keyfile_offset) @@ -537,21 +691,28 @@ void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context kc->type = CRYPT_KC_TYPE_KEYFILE; kc->u.kf.keyfile = keyfile; - kc->u.kf.keyfile_size = keyfile_size; kc->u.kf.keyfile_offset = keyfile_offset; + kc->u.kf.keyfile_size = keyfile_size; + kc->get_luks2_key = get_luks2_key_by_keyfile; - kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile; kc->get_luks1_volume_key = get_luks1_volume_key_by_keyfile; + kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile; + kc->get_bitlk_volume_key = get_bitlk_volume_key_by_keyfile; + kc->get_fvault2_volume_key = get_fvault2_volume_key_by_keyfile; kc->get_passphrase = get_passphrase_by_keyfile; - kc->get_plain_volume_key = NULL; - kc->get_bitlk_volume_key = NULL; - kc->get_fvault2_volume_key = NULL; - kc->get_verity_volume_key = NULL; - kc->get_integrity_volume_key = NULL; - unlock_method_init_internal(kc); + kc->context_free = keyfile_context_free; + crypt_keyslot_context_init_common(kc); } -void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc, +static void token_context_free(struct crypt_keyslot_context *kc) +{ + assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN); + + free(kc->u.t.i_type); + crypt_safe_free(kc->u.t.i_pin); +} + +void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *kc, int token, const char *type, const char *pin, @@ -566,47 +727,30 @@ void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *k kc->u.t.pin = pin; kc->u.t.pin_size = pin_size; kc->u.t.usrptr = usrptr; + kc->get_luks2_key = get_luks2_key_by_token; kc->get_luks2_volume_key = get_luks2_volume_key_by_token; - kc->get_luks1_volume_key = NULL; /* LUKS1 is not supported */ kc->get_passphrase = get_passphrase_by_token; - kc->get_plain_volume_key = NULL; - kc->get_bitlk_volume_key = NULL; - kc->get_fvault2_volume_key = NULL; - kc->get_verity_volume_key = NULL; - kc->get_integrity_volume_key = NULL; - unlock_method_init_internal(kc); + kc->context_free = token_context_free; + crypt_keyslot_context_init_common(kc); } -void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc, - const char *key_description) +static void vk_in_keyring_context_free(struct crypt_keyslot_context *kc) { - assert(kc); - - kc->type = CRYPT_KC_TYPE_VK_KEYRING; - kc->u.vk_kr.key_description = key_description; + assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING); - kc->get_luks2_key = get_key_by_vk_in_keyring; - kc->get_luks2_volume_key = get_volume_key_by_vk_in_keyring; - kc->get_luks1_volume_key = NULL; - kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */ - kc->get_plain_volume_key = NULL; - kc->get_bitlk_volume_key = NULL; - kc->get_fvault2_volume_key = NULL; - kc->get_verity_volume_key = NULL; - kc->get_integrity_volume_key = NULL; - unlock_method_init_internal(kc); + free(kc->u.vk_kr.i_key_description); } - void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc) { if (!kc) return; + if (kc->context_free) + kc->context_free(kc); + crypt_safe_free(kc->i_passphrase); - kc->i_passphrase = NULL; - kc->i_passphrase_size = 0; } void crypt_keyslot_context_free(struct crypt_keyslot_context *kc) @@ -615,157 +759,443 @@ void crypt_keyslot_context_free(struct crypt_keyslot_context *kc) free(kc); } -int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd __attribute__((unused)), - const char *passphrase, +static int _crypt_keyslot_context_init_by_passphrase(const char *passphrase, size_t passphrase_size, - struct crypt_keyslot_context **kc) + struct crypt_keyslot_context **kc, + bool self_contained) { struct crypt_keyslot_context *tmp; + char *i_passphrase = NULL; if (!kc || !passphrase) return -EINVAL; - tmp = malloc(sizeof(*tmp)); + tmp = crypt_zalloc(sizeof(*tmp)); if (!tmp) return -ENOMEM; - crypt_keyslot_unlock_by_passphrase_init_internal(tmp, passphrase, passphrase_size); + if (self_contained) { + if (passphrase_size) { + i_passphrase = crypt_safe_alloc(passphrase_size); + if (!i_passphrase) { + free(tmp); + return -ENOMEM; + } + crypt_safe_memcpy(i_passphrase, passphrase, passphrase_size); + passphrase = i_passphrase; + } else + /* + * some crypto backend libraries expect a pointer even though + * passed passphrase size is set to zero. + */ + passphrase = ""; + } + + crypt_keyslot_context_init_by_passphrase_internal(tmp, passphrase, passphrase_size); + + if (self_contained) { + tmp->i_passphrase = i_passphrase; + tmp->i_passphrase_size = passphrase_size; + tmp->version = KC_VERSION_SELF_CONTAINED; + } *kc = tmp; return 0; } -int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd __attribute__((unused)), - const char *keyfile, +CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_passphrase, 2, 8, + /* crypt_keyslot_context_init_by_passphrase parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *passphrase, + size_t passphrase_size, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, true); +} + +CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_passphrase, 2, 6, + /* crypt_keyslot_context_init_by_passphrase parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *passphrase, + size_t passphrase_size, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, false); +} + +static int _crypt_keyslot_context_init_by_keyfile(const char *keyfile, size_t keyfile_size, uint64_t keyfile_offset, - struct crypt_keyslot_context **kc) + struct crypt_keyslot_context **kc, + bool self_contained) { + char *i_keyfile; struct crypt_keyslot_context *tmp; if (!kc || !keyfile) return -EINVAL; - tmp = malloc(sizeof(*tmp)); + tmp = crypt_zalloc(sizeof(*tmp)); if (!tmp) return -ENOMEM; - crypt_keyslot_unlock_by_keyfile_init_internal(tmp, keyfile, keyfile_size, keyfile_offset); + if (self_contained) { + i_keyfile = strdup(keyfile); + if (!i_keyfile) { + free(tmp); + return -ENOMEM; + } + keyfile = i_keyfile; + } + + crypt_keyslot_context_init_by_keyfile_internal(tmp, keyfile, keyfile_size, keyfile_offset); + + if (self_contained) { + tmp->u.kf.i_keyfile = i_keyfile; + tmp->version = KC_VERSION_SELF_CONTAINED; + } *kc = tmp; return 0; } -int crypt_keyslot_context_init_by_token(struct crypt_device *cd __attribute__((unused)), - int token, +CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyfile, 2, 8, + /* crypt_keyslot_context_init_by_keyfile parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *keyfile, + size_t keyfile_size, + uint64_t keyfile_offset, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, true); +} + +CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyfile, 2, 6, + /* crypt_keyslot_context_init_by_keyfile parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *keyfile, + size_t keyfile_size, + uint64_t keyfile_offset, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, false); +} + +static int _crypt_keyslot_context_init_by_token(int token, const char *type, const char *pin, size_t pin_size, void *usrptr, - struct crypt_keyslot_context **kc) + struct crypt_keyslot_context **kc, + bool self_contained) { + char *i_type = NULL, *i_pin = NULL; struct crypt_keyslot_context *tmp; - if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN)) + if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN) || + (pin && !pin_size)) return -EINVAL; - tmp = malloc(sizeof(*tmp)); + tmp = crypt_zalloc(sizeof(*tmp)); if (!tmp) return -ENOMEM; - crypt_keyslot_unlock_by_token_init_internal(tmp, token, type, pin, pin_size, usrptr); + if (self_contained && type) { + if (!(i_type = strdup(type))) + goto err; + type = i_type; + } + + if (self_contained && pin) { + if (!(i_pin = crypt_safe_alloc(pin_size))) + goto err; + crypt_safe_memcpy(i_pin, pin, pin_size); + pin = i_pin; + } + + crypt_keyslot_context_init_by_token_internal(tmp, token, type, pin, pin_size, usrptr); + + if (self_contained) { + tmp->u.t.i_pin = i_pin; + tmp->u.t.i_type = i_type; + tmp->version = KC_VERSION_SELF_CONTAINED; + } *kc = tmp; return 0; +err: + crypt_safe_free(i_pin); + free(i_type); + free(tmp); + + return -ENOMEM; } -int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd __attribute__((unused)), - const char *volume_key, - size_t volume_key_size, +CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_token, 2, 8, + /* crypt_keyslot_context_init_by_token parameters follows */ + struct crypt_device *cd __attribute__((unused)), + int token, + const char *type, + const char *pin, size_t pin_size, + void *usrptr, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, true); +} + +CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_token, 2, 6, + /* crypt_keyslot_context_init_by_token parameters follows */ + struct crypt_device *cd __attribute__((unused)), + int token, + const char *type, + const char *pin, size_t pin_size, + void *usrptr, struct crypt_keyslot_context **kc) { + return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, false); +} + +static int _crypt_keyslot_context_init_by_volume_key(const char *volume_key, + size_t volume_key_size, + struct crypt_keyslot_context **kc, + bool self_contained) +{ + struct volume_key *i_vk = NULL; struct crypt_keyslot_context *tmp; if (!kc) return -EINVAL; - tmp = malloc(sizeof(*tmp)); + tmp = crypt_zalloc(sizeof(*tmp)); if (!tmp) return -ENOMEM; - crypt_keyslot_unlock_by_key_init_internal(tmp, volume_key, volume_key_size); + if (self_contained && volume_key) { + if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key))) { + free(tmp); + return -ENOMEM; + } + volume_key = crypt_volume_key_get_key(i_vk); + } + + crypt_keyslot_context_init_by_key_internal(tmp, volume_key, volume_key_size); + + if (self_contained) { + tmp->u.k.i_vk = i_vk; + tmp->version = KC_VERSION_SELF_CONTAINED; + } *kc = tmp; return 0; } -int crypt_keyslot_context_init_by_signed_key(struct crypt_device *cd __attribute__((unused)), +CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_volume_key, 2, 8, + /* crypt_keyslot_context_init_by_volume_key parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *volume_key, + size_t volume_key_size, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, true); +} + +CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_volume_key, 2, 6, + /* crypt_keyslot_context_init_by_volume_key parameters follows */ + struct crypt_device *cd __attribute__((unused)), const char *volume_key, + size_t volume_key_size, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, false); +} + +static int _crypt_keyslot_context_init_by_signed_key(const char *volume_key, size_t volume_key_size, const char *signature, size_t signature_size, - struct crypt_keyslot_context **kc) + struct crypt_keyslot_context **kc, + bool self_contained) { + struct volume_key *i_vk = NULL, *i_vk_sig = NULL; struct crypt_keyslot_context *tmp; if (!kc) return -EINVAL; - tmp = malloc(sizeof(*tmp)); + tmp = crypt_zalloc(sizeof(*tmp)); if (!tmp) return -ENOMEM; - crypt_keyslot_unlock_by_signed_key_init_internal(tmp, volume_key, volume_key_size, + if (self_contained && volume_key) { + if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key))) + goto err; + volume_key = crypt_volume_key_get_key(i_vk); + } + + if (self_contained && signature) { + if (!(i_vk_sig = crypt_alloc_volume_key(signature_size, signature))) + goto err; + signature = crypt_volume_key_get_key(i_vk_sig); + } + + crypt_keyslot_context_init_by_signed_key_internal(tmp, volume_key, volume_key_size, signature, signature_size); + if (self_contained) { + tmp->u.ks.i_vk = i_vk; + tmp->u.ks.i_vk_sig = i_vk_sig; + tmp->version = KC_VERSION_SELF_CONTAINED; + } + *kc = tmp; return 0; +err: + crypt_free_volume_key(i_vk); + crypt_free_volume_key(i_vk_sig); + free(tmp); + + return -ENOMEM; } -int crypt_keyslot_context_init_by_keyring(struct crypt_device *cd __attribute__((unused)), - const char *key_description, +CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_signed_key, 2, 8, + /* crypt_keyslot_context_init_by_signed_key parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *volume_key, + size_t volume_key_size, + const char *signature, + size_t signature_size, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, true); +} + +CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_signed_key, 2, 7, + /* crypt_keyslot_context_init_by_signed_key parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *volume_key, + size_t volume_key_size, + const char *signature, + size_t signature_size, struct crypt_keyslot_context **kc) { + return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, false); +} + +static int _crypt_keyslot_context_init_by_keyring(const char *key_description, + struct crypt_keyslot_context **kc, + bool self_contained) +{ + char *i_key_description; struct crypt_keyslot_context *tmp; - if (!kc) + if (!kc || !key_description) return -EINVAL; - tmp = malloc(sizeof(*tmp)); + tmp = crypt_zalloc(sizeof(*tmp)); if (!tmp) return -ENOMEM; - crypt_keyslot_unlock_by_keyring_internal(tmp, key_description); + if (self_contained) { + if (!(i_key_description = strdup(key_description))) { + free(tmp); + return -ENOMEM; + } + key_description = i_key_description; + } + + crypt_keyslot_context_init_by_keyring_internal(tmp, key_description); + + if (self_contained) { + tmp->u.kr.i_key_description = i_key_description; + tmp->version = KC_VERSION_SELF_CONTAINED; + } *kc = tmp; return 0; } -int crypt_keyslot_context_init_by_vk_in_keyring(struct crypt_device *cd __attribute__((unused)), +CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyring, 2, 8, + /* crypt_keyslot_context_init_by_keyring parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *key_description, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_keyring(key_description, kc, true); +} + +CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyring, 2, 7, + /* crypt_keyslot_context_init_by_keyring parameters follows */ + struct crypt_device *cd __attribute__((unused)), const char *key_description, struct crypt_keyslot_context **kc) { + return _crypt_keyslot_context_init_by_keyring(key_description, kc, false); +} + +static int _crypt_keyslot_context_init_by_vk_in_keyring(const char *key_description, + struct crypt_keyslot_context **kc, + bool self_contained) +{ + char *i_key_description; struct crypt_keyslot_context *tmp; - if (!kc) + if (!kc || !key_description) return -EINVAL; - tmp = malloc(sizeof(*tmp)); + tmp = crypt_zalloc(sizeof(*tmp)); if (!tmp) return -ENOMEM; - crypt_keyslot_unlock_by_vk_in_keyring_internal(tmp, key_description); + if (self_contained) { + if (!(i_key_description = strdup(key_description))) { + free(tmp); + return -ENOMEM; + } + key_description = i_key_description; + } + + tmp->type = CRYPT_KC_TYPE_VK_KEYRING; + tmp->u.vk_kr.key_description = key_description; + + tmp->get_luks2_key = get_key_by_vk_in_keyring; + tmp->get_luks2_volume_key = get_volume_key_by_vk_in_keyring; + tmp->get_key_size = keyring_get_key_size; + tmp->context_free = vk_in_keyring_context_free; + crypt_keyslot_context_init_common(tmp); + + if (self_contained) { + tmp->u.vk_kr.i_key_description = i_key_description; + tmp->version = KC_VERSION_SELF_CONTAINED; + } *kc = tmp; return 0; } +CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 8, + /* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *key_description, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, true); +} + +CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 7, + /* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */ + struct crypt_device *cd __attribute__((unused)), + const char *key_description, + struct crypt_keyslot_context **kc) +{ + return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, false); +} + int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc) { return kc ? kc->error : -EINVAL; @@ -775,10 +1205,21 @@ int crypt_keyslot_context_set_pin(struct crypt_device *cd __attribute__((unused) const char *pin, size_t pin_size, struct crypt_keyslot_context *kc) { + char *i_pin = NULL; + if (!kc || kc->type != CRYPT_KC_TYPE_TOKEN) return -EINVAL; - kc->u.t.pin = pin; + if (kc->version >= KC_VERSION_SELF_CONTAINED && pin) { + if (!(i_pin = crypt_safe_alloc(pin_size))) + return -ENOMEM; + crypt_safe_memcpy(i_pin, pin, pin_size); + } + + crypt_safe_free(kc->u.t.i_pin); + kc->u.t.i_pin = i_pin; + + kc->u.t.pin = i_pin ?: pin; kc->u.t.pin_size = pin_size; kc->error = 0; diff --git a/lib/keyslot_context.h b/lib/keyslot_context.h index a7f834a..a2e42b2 100644 --- a/lib/keyslot_context.h +++ b/lib/keyslot_context.h @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup, keyslot unlock helpers * - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2022-2024 Ondrej Kozina + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Ondrej Kozina */ #ifndef KEYSLOT_CONTEXT_H @@ -14,6 +14,9 @@ #include "internal.h" +struct bitlk_metadata; +struct fvault2_params; + typedef int (*keyslot_context_get_key) ( struct crypt_device *cd, struct crypt_keyslot_context *kc, @@ -32,6 +35,19 @@ typedef int (*keyslot_context_get_generic_volume_key) ( struct crypt_keyslot_context *kc, struct volume_key **r_vk); +typedef int (*keyslot_context_get_bitlk_volume_key) ( + struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params, + struct volume_key **r_vk); + +typedef int (*keyslot_context_get_fvault2_volume_key) ( + struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params, + struct volume_key **r_vk); + + typedef int (*keyslot_context_get_generic_signed_key) ( struct crypt_device *cd, struct crypt_keyslot_context *kc, @@ -44,10 +60,28 @@ typedef int (*keyslot_context_get_passphrase) ( const char **r_passphrase, size_t *r_passphrase_size); +typedef void (*keyslot_context_free) ( + struct crypt_keyslot_context *kc); + +typedef int (*keyslot_context_get_key_size) ( + struct crypt_device *cd, + struct crypt_keyslot_context *kc, + size_t *r_key_size); + +#define KC_VERSION_BASIC UINT8_C(1) +#define KC_VERSION_SELF_CONTAINED UINT8_C(2) + /* crypt_keyslot_context */ struct crypt_keyslot_context { int type; + /* versions: + * v1: All passed pointers (e.g.: type, passphrase, keyfile,...) must + * be valid after ctx initialization. + * v2: Fully self-contained + */ + uint8_t version; + union { struct { const char *passphrase; @@ -55,31 +89,40 @@ struct crypt_keyslot_context { } p; struct { const char *keyfile; + char *i_keyfile; uint64_t keyfile_offset; size_t keyfile_size; } kf; struct { int id; const char *type; + char *i_type; const char *pin; + char *i_pin; size_t pin_size; void *usrptr; } t; struct { const char *volume_key; size_t volume_key_size; + struct volume_key *i_vk; } k; struct { const char *volume_key; size_t volume_key_size; + struct volume_key *i_vk; const char *signature; size_t signature_size; + struct volume_key *i_vk_sig; } ks; struct { const char *key_description; + char *i_key_description; } kr; struct { const char *key_description; + char *i_key_description; + size_t i_key_size; } vk_kr; } u; @@ -92,45 +135,44 @@ struct crypt_keyslot_context { keyslot_context_get_volume_key get_luks1_volume_key; keyslot_context_get_volume_key get_luks2_volume_key; keyslot_context_get_generic_volume_key get_plain_volume_key; - keyslot_context_get_generic_volume_key get_bitlk_volume_key; - keyslot_context_get_generic_volume_key get_fvault2_volume_key; + keyslot_context_get_bitlk_volume_key get_bitlk_volume_key; + keyslot_context_get_fvault2_volume_key get_fvault2_volume_key; keyslot_context_get_generic_signed_key get_verity_volume_key; keyslot_context_get_generic_volume_key get_integrity_volume_key; keyslot_context_get_passphrase get_passphrase; + keyslot_context_get_key_size get_key_size; + keyslot_context_free context_free; }; void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *method); -void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc, const char *volume_key, size_t volume_key_size); -void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_signed_key_internal(struct crypt_keyslot_context *kc, const char *volume_key, size_t volume_key_size, const char *signature, size_t signature_size); -void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_context *kc, const char *passphrase, size_t passphrase_size); -void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context *kc, const char *keyfile, size_t keyfile_size, uint64_t keyfile_offset); -void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *kc, int token, const char *type, const char *pin, size_t pin_size, void *usrptr); -void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc, - const char *key_description); - -void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc, +void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc, const char *key_description); const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc); diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index afc2a8d..e645b18 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ /** @@ -74,13 +74,13 @@ int crypt_init_data_device(struct crypt_device **cd, * and, optionally, from separate metadata (header) device * and check if provided device exists. * - * @return @e 0 on success or negative errno value otherwise. - * * @param cd returns crypt device handle for active device * @param name name of active crypt device * @param header_device optional device containing on-disk header * (@e NULL if it the same as underlying device on there is no on-disk header) * + * @return @e 0 on success or negative errno value otherwise. + * * @post In case @e device points to active LUKS device but header load fails, * context device type is set to @e NULL and @e 0 is returned as if it were successful. * Context with @e NULL device type can only be deactivated by crypt_deactivate @@ -137,7 +137,7 @@ void crypt_set_confirm_callback(struct crypt_device *cd, * @param cd crypt device handle * @param device path to device * - * @returns 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. */ int crypt_set_data_device(struct crypt_device *cd, const char *device); @@ -145,13 +145,13 @@ int crypt_set_data_device(struct crypt_device *cd, const char *device); * Set data device offset in 512-byte sectors. * Used for LUKS. * This function is replacement for data alignment fields in LUKS param struct. - * If set to 0 (default), old behaviour is preserved. + * If set to @e 0 (default), old behaviour is preserved. * This value is reset on @link crypt_load @endlink. * * @param cd crypt device handle * @param data_offset data offset in bytes * - * @returns 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Data offset must be aligned to multiple of 8 (alignment to 4096-byte sectors) * and must be big enough to accommodate the whole LUKS header with all keyslots. @@ -232,7 +232,6 @@ void crypt_logf(struct crypt_device *cd, int level, const char *format, ...); * * @param cd crypt device handle * @param rng_type kernel random number generator to use - * */ void crypt_set_rng_type(struct crypt_device *cd, int rng_type); @@ -240,8 +239,8 @@ void crypt_set_rng_type(struct crypt_device *cd, int rng_type); * Get which RNG (random number generator) is used for generating long term key. * * @param cd crypt device handle - * @return RNG type on success or negative errno value otherwise. * + * @return RNG type on success or negative errno value otherwise. */ int crypt_get_rng_type(struct crypt_device *cd); @@ -252,7 +251,7 @@ struct crypt_pbkdf_type { const char *type; /**< PBKDF algorithm */ const char *hash; /**< Hash algorithm */ uint32_t time_ms; /**< Requested time cost [milliseconds] */ - uint32_t iterations; /**< Iterations, 0 or benchmarked value. */ + uint32_t iterations; /**< Iterations, @e 0 or benchmarked value. */ uint32_t max_memory_kb; /**< Requested or benchmarked memory cost [kilobytes] */ uint32_t parallel_threads;/**< Requested parallel cost [threads] */ uint32_t flags; /**< CRYPT_PBKDF* flags */ @@ -277,7 +276,7 @@ struct crypt_pbkdf_type { * @param cd crypt device handle * @param pbkdf PBKDF parameters * - * @return 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note For LUKS1, only PBKDF2 is supported, other settings will be rejected. * @note For non-LUKS context types the call succeeds, but PBKDF is not used. @@ -290,8 +289,7 @@ int crypt_set_pbkdf_type(struct crypt_device *cd, * * @param pbkdf_type type of PBKDF * - * @return struct on success or NULL value otherwise. - * + * @return struct on success or @e NULL value otherwise. */ const struct crypt_pbkdf_type *crypt_get_pbkdf_type_params(const char *pbkdf_type); @@ -301,8 +299,7 @@ const struct crypt_pbkdf_type *crypt_get_pbkdf_type_params(const char *pbkdf_typ * * @param type type of device (see @link crypt-type @endlink) * - * @return struct on success or NULL value otherwise. - * + * @return struct on success or @e NULL value otherwise. */ const struct crypt_pbkdf_type *crypt_get_pbkdf_default(const char *type); @@ -312,8 +309,7 @@ const struct crypt_pbkdf_type *crypt_get_pbkdf_default(const char *type); * * @param cd crypt device handle * - * @return struct on success or NULL value otherwise. - * + * @return struct on success or @e NULL value otherwise. */ const struct crypt_pbkdf_type *crypt_get_pbkdf_type(struct crypt_device *cd); @@ -335,9 +331,9 @@ void crypt_set_iteration_time(struct crypt_device *cd, uint64_t iteration_time_m * \b Deprecated, only for backward compatibility. Memory with keys are locked automatically. * * @param cd crypt device handle, can be @e NULL - * @param lock 0 to unlock otherwise lock memory + * @param lock @e 0 to unlock otherwise lock memory * - * @returns Value indicating whether the memory is locked (function can be called multiple times). + * @return Value indicating whether the memory is locked (function can be called multiple times). * * @note Only root can do this. * @note It locks/unlocks all process memory, not only crypt context. @@ -348,9 +344,9 @@ int crypt_memory_lock(struct crypt_device *cd, int lock) __attribute__((deprecat * Set global lock protection for on-disk metadata (file-based locking). * * @param cd crypt device handle, can be @e NULL - * @param enable 0 to disable locking otherwise enable it (default) + * @param enable @e 0 to disable locking otherwise enable it (default) * - * @returns @e 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Locking applied only for some metadata formats (LUKS2). * @note The switch is global on the library level. @@ -366,7 +362,7 @@ int crypt_metadata_locking(struct crypt_device *cd, int enable); * @param metadata_size size in bytes of JSON area + 4k binary header * @param keyslots_size size in bytes of binary keyslots area * - * @returns @e 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note The metadata area is stored twice and both copies contain 4k binary header. * Only 16,32,64,128,256,512,1024,2048 and 4096 kB value is allowed (see LUKS2 specification). @@ -384,7 +380,7 @@ int crypt_set_metadata_size(struct crypt_device *cd, * @param metadata_size size in bytes of JSON area + 4k binary header * @param keyslots_size size in bytes of binary keyslots area * - * @returns @e 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. */ int crypt_get_metadata_size(struct crypt_device *cd, uint64_t *metadata_size, @@ -426,6 +422,7 @@ int crypt_get_metadata_size(struct crypt_device *cd, * Get device type * * @param cd crypt device handle + * * @return string according to device type or @e NULL if not known. */ const char *crypt_get_type(struct crypt_device *cd); @@ -454,14 +451,14 @@ const char *crypt_get_default_type(void); * Get HW encryption type * * @return HW encryption type (see @link crypt-hw-encryption-types @endlink) - * or negative errno otherwise. + * or negative errno value otherwise. */ int crypt_get_hw_encryption_type(struct crypt_device *cd); /** * Get HW encryption (like OPAL) key size (in bytes) * - * @return key size or 0 if no HW encryption is used. + * @return key size or @e 0 if no HW encryption is used. */ int crypt_get_hw_encryption_key_size(struct crypt_device *cd); @@ -499,7 +496,6 @@ struct crypt_params_luks1 { * Structure used as parameter for loop-AES device type. * * @see crypt_format - * */ struct crypt_params_loopaes { const char *hash; /**< key hash function */ @@ -512,7 +508,6 @@ struct crypt_params_loopaes { * Structure used as parameter for dm-verity device type. * * @see crypt_format, crypt_load - * */ struct crypt_params_verity { const char *hash_name; /**< hash function */ @@ -545,7 +540,6 @@ struct crypt_params_verity { * Structure used as parameter for TCRYPT device type. * * @see crypt_load - * */ struct crypt_params_tcrypt { const char *passphrase; /**< passphrase to unlock header (input only) */ @@ -593,8 +587,8 @@ struct crypt_params_integrity { uint32_t tag_size; /**< tag size per-sector in bytes */ uint32_t sector_size; /**< sector size in bytes */ uint32_t buffer_sectors; /**< number of sectors in one buffer */ - const char *integrity; /**< integrity algorithm, NULL for LUKS2 */ - uint32_t integrity_key_size; /**< integrity key size in bytes, info only, 0 for LUKS2 */ + const char *integrity; /**< integrity algorithm, @e NULL for LUKS2 */ + uint32_t integrity_key_size; /**< integrity key size in bytes, info only */ const char *journal_integrity; /**< journal integrity algorithm */ const char *journal_integrity_key; /**< journal integrity key, only for crypt_load */ @@ -612,7 +606,6 @@ struct crypt_params_integrity { * * @note during crypt_format @e data_device attribute determines * if the LUKS2 header is separated from encrypted payload device - * */ struct crypt_params_luks2 { const struct crypt_pbkdf_type *pbkdf; /**< PBKDF (and hash) parameters or @e NULL*/ @@ -620,7 +613,7 @@ struct crypt_params_luks2 { const struct crypt_params_integrity *integrity_params; /**< Data integrity parameters or @e NULL*/ size_t data_alignment; /**< data area alignment in 512B sectors, data offset is multiple of this */ const char *data_device; /**< detached encrypted data device or @e NULL */ - uint32_t sector_size; /**< encryption sector size, 0 triggers auto-detection for optimal encryption sector size */ + uint32_t sector_size; /**< encryption sector size, @e 0 triggers auto-detection for optimal encryption sector size */ const char *label; /**< header label or @e NULL*/ const char *subsystem; /**< header subsystem label or @e NULL*/ }; @@ -629,7 +622,6 @@ struct crypt_params_luks2 { * Structure used as parameter for OPAL (HW encrypted) device type. * * @see crypt_format_luks2_opal - * */ struct crypt_params_hw_opal { const char *admin_key; /**< admin key */ @@ -659,7 +651,7 @@ struct crypt_params_hw_opal { * @param volume_key_size size of volume key in bytes. * @param params crypt type specific parameters (see @link crypt-type @endlink) * - * @returns @e 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Note that crypt_format does not create LUKS keyslot (any version). To create keyslot * call any crypt_keyslot_add_* function. @@ -681,15 +673,15 @@ int crypt_format(struct crypt_device *cd, * @pre @e cd contains initialized and not formatted device context (device type must @b not be set) * * @param cd crypt device handle - * @param cipher for SW encryption (e.g. "aes") or NULL for HW encryption only - * @param cipher_mode including IV specification (e.g. "xts-plain") or NULL for HW encryption only + * @param cipher for SW encryption (e.g. "aes") or @e NULL for HW encryption only + * @param cipher_mode including IV specification (e.g. "xts-plain") or @e NULL for HW encryption only * @param uuid requested UUID or @e NULL if it should be generated * @param volume_keys pre-generated volume keys or @e NULL if it should be generated (only for LUKS2 SW encryption) * @param volume_keys_size size of volume keys in bytes (only for SW encryption). * @param params LUKS2 crypt type specific parameters (see @link crypt-type @endlink) * @param opal_params OPAL specific parameters * - * @returns @e 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Note that crypt_format_luks2_opal does not create LUKS keyslot. * To create keyslot call any crypt_keyslot_add_* function. @@ -703,6 +695,35 @@ int crypt_format_luks2_opal(struct crypt_device *cd, struct crypt_params_luks2 *params, struct crypt_params_hw_opal *opal_params); +/** + * Create (format) new integrity-protected device using integrity inline mode (HW sector tags). + * This can be used for @e INTEGRITY and @e LUKS2 with integrity protection + * + * @pre @e cd contains initialized and not formatted device context (device type must @b not be set) + * + * @param cd crypt device handle + * @param type type of device (optional params struct must be of this type) + * @param cipher (e.g. "aes") or @e NULL for @e INTEGRITY + * @param cipher_mode including IV specification (e.g. "xts-plain") or @e NULL for @e INTEGRITY + * @param uuid requested UUID or @e NULL if it should be generated + * @param volume_key pre-generated integrity/volume key (if needed) or @e NULL + * @param volume_key_size size of volume/integrity key in bytes. + * @param params crypt type specific parameters (see @link crypt-type @endlink) + * + * @return @e 0 on success or negative errno value otherwise. + * + * @note Journal parameters must be set to zero in integrity part of @e params. + * Only tag_size, sector_size, buffer_sectors, integrity options should be set. + */ +int crypt_format_inline(struct crypt_device *cd, + const char *type, + const char *cipher, + const char *cipher_mode, + const char *uuid, + const char *volume_key, + size_t volume_key_size, + void *params); + /** * Set format compatibility flags. * @@ -716,7 +737,7 @@ void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags); * * @param cd crypt device handle * - * @returns compatibility flags + * @return compatibility flags */ uint32_t crypt_get_compatibility(struct crypt_device *cd); @@ -734,7 +755,7 @@ uint32_t crypt_get_compatibility(struct crypt_device *cd); * @param type type of device (optional params struct must be of this type) * @param params crypt type specific parameters (see @link crypt-type @endlink) * - * @returns 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Currently, only LUKS1->LUKS2 and LUKS2->LUKS1 conversions are supported. * Not all LUKS2 devices may be converted back to LUKS1. To make such a conversion @@ -755,7 +776,7 @@ int crypt_convert(struct crypt_device *cd, * @param cd crypt device handle * @param uuid requested UUID or @e NULL if it should be generated * - * @returns 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Currently, only LUKS device type are supported */ @@ -769,7 +790,7 @@ int crypt_set_uuid(struct crypt_device *cd, * @param label requested label or @e NULL * @param subsystem requested subsystem label or @e NULL * - * @returns 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Currently, only LUKS2 device type is supported */ @@ -803,10 +824,10 @@ const char *crypt_get_subsystem(struct crypt_device *cd); * dm-crypt target. * * @param cd crypt device handle, can be @e NULL - * @param enable 0 to disable loading of volume keys via kernel keyring + * @param enable @e 0 to disable loading of volume keys via kernel keyring * (classical method) otherwise enable it (default) * - * @returns @e 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Currently loading of volume keys via kernel keyring is supported * (and enabled by default) only for LUKS2 devices. @@ -821,14 +842,13 @@ int crypt_volume_key_keyring(struct crypt_device *cd, int enable); * @param requested_type @link crypt-type @endlink or @e NULL for all known * @param params crypt type specific parameters (see @link crypt-type @endlink) * - * @returns 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @post In case LUKS header is read successfully but payload device is too small * error is returned and device type in context is set to @e NULL * * @note Note that load works only for device types with on-disk metadata. * @note Function does not print visible error message if metadata is not present. - * */ int crypt_load(struct crypt_device *cd, const char *requested_type, @@ -841,7 +861,7 @@ int crypt_load(struct crypt_device *cd, * @param requested_type @link crypt-type @endlink or @e NULL for all known * @param params crypt type specific parameters (see @link crypt-type @endlink) * - * @returns 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note For LUKS2 device crypt_repair bypass blkid checks and * perform auto-recovery even though there're third party device @@ -880,10 +900,9 @@ int crypt_resize(struct crypt_device *cd, * @param cd crypt device handle, can be @e NULL * @param name name of device to suspend * - * @return 0 on success or negative errno value otherwise. + * @return @e 0 on success or negative errno value otherwise. * * @note Only LUKS device type is supported - * */ int crypt_suspend(struct crypt_device *cd, const char *name); @@ -898,7 +917,7 @@ int crypt_suspend(struct crypt_device *cd, * @param passphrase passphrase used to unlock volume key * @param passphrase_size size of @e passphrase (binary data) * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. * * @note Only LUKS device type is supported */ @@ -915,10 +934,10 @@ int crypt_resume_by_passphrase(struct crypt_device *cd, * @param name name of device to resume * @param keyslot requested keyslot or CRYPT_ANY_SLOT * @param keyfile key file used to unlock volume key - * @param keyfile_size number of bytes to read from keyfile, 0 is unlimited + * @param keyfile_size number of bytes to read from keyfile, @e 0 is unlimited * @param keyfile_offset number of bytes to skip at start of keyfile * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. */ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd, const char *name, @@ -951,7 +970,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd, * @param cd crypt device handle * @param name name of device to resume * @param volume_key provided volume key - * @param volume_key_size size of volume_key + * @param volume_key_size size of volume_key in bytes * * @return @e 0 on success or negative errno value otherwise. */ @@ -969,7 +988,7 @@ int crypt_resume_by_volume_key(struct crypt_device *cd, * @param pin_size size of @e pin * @param usrptr provided identification in callback * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. * * @note EPERM errno means token provided passphrase successfully, but * passphrase did not unlock any keyslot associated with the token. @@ -978,7 +997,7 @@ int crypt_resume_by_volume_key(struct crypt_device *cd, * eligible to resume LUKS2 device. * * @note ENOANO errno means that token is PIN protected and was either missing - * (NULL) or wrong. + * (@e NULL) or wrong. * * @note Negative EAGAIN errno means token handler requires additional hardware * not present in the system to unlock keyslot. @@ -1007,7 +1026,7 @@ int crypt_resume_by_token_pin(struct crypt_device *cd, * @param kc keyslot context providing volume key or passphrase. * * @return unlocked key slot number for passphrase-based unlock, zero for other - * unlock methods (e.g. volume key context) or negative errno on error. + * unlock methods (e.g. volume key context) or negative errno value on error. */ int crypt_resume_by_keyslot_context(struct crypt_device *cd, const char *name, @@ -1036,7 +1055,7 @@ int crypt_resume_by_keyslot_context(struct crypt_device *cd, * @param new_passphrase passphrase for new keyslot * @param new_passphrase_size size of @e new_passphrase (binary data) * - * @return allocated key slot number or negative errno otherwise. + * @return allocated key slot number or negative errno value otherwise. */ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, int keyslot, @@ -1058,7 +1077,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, * @param new_passphrase passphrase for new keyslot * @param new_passphrase_size size of @e new_passphrase (binary data) * - * @return allocated key slot number or negative errno otherwise. + * @return allocated key slot number or negative errno value otherwise. */ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd, int keyslot_old, @@ -1082,7 +1101,7 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd, * @param new_keyfile_size number of bytes to read from @e new_keyfile, @e 0 is unlimited * @param new_keyfile_offset number of bytes to skip at start of new_keyfile * - * @return allocated key slot number or negative errno otherwise. + * @return allocated key slot number or negative errno value otherwise. */ int crypt_keyslot_add_by_keyfile_device_offset(struct crypt_device *cd, int keyslot, @@ -1123,11 +1142,11 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd, * @param cd crypt device handle * @param keyslot requested keyslot or CRYPT_ANY_SLOT * @param volume_key provided volume key or @e NULL if used after crypt_format - * @param volume_key_size size of volume_key + * @param volume_key_size size of volume_key in bytes * @param passphrase passphrase for new keyslot * @param passphrase_size size of passphrase * - * @return allocated key slot number or negative errno otherwise. + * @return allocated key slot number or negative errno value otherwise. */ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd, int keyslot, @@ -1153,12 +1172,12 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd, * @param cd crypt device handle * @param keyslot requested keyslot or CRYPT_ANY_SLOT * @param volume_key provided volume key or @e NULL (see note below) - * @param volume_key_size size of volume_key + * @param volume_key_size size of volume_key in bytes * @param passphrase passphrase for new keyslot * @param passphrase_size size of passphrase * @param flags key flags to set * - * @return allocated key slot number or negative errno otherwise. + * @return allocated key slot number or negative errno value otherwise. * * @note in case volume_key is @e NULL following first matching rule will apply: * @li if cd is device handle used in crypt_format() by current process, the volume @@ -1203,7 +1222,11 @@ void crypt_keyslot_context_free(struct crypt_keyslot_context *kc); * @param passphrase_size size of passphrase * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_PASSPHRASE * - * @return zero on success or negative errno otherwise. + * @return zero on success or negative errno value otherwise. + * + * @note The original buffer containing passphrase passed in parameters does + * not have to be valid after context initialization. The context + * contains copy of the original before freed with @link crypt_keyslot_context_free @endlink. */ int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd, const char *passphrase, @@ -1220,7 +1243,7 @@ int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd, * @param keyfile_offset number of bytes to skip at start of keyfile * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEYFILE * - * @return zero on success or negative errno otherwise. + * @return zero on success or negative errno value otherwise. */ int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd, const char *keyfile, @@ -1240,7 +1263,7 @@ int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd, * @param usrptr provided identification in callback * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_TOKEN * - * @return zero on success or negative errno otherwise. + * @return zero on success or negative errno value otherwise. */ int crypt_keyslot_context_init_by_token(struct crypt_device *cd, int token, @@ -1256,10 +1279,10 @@ int crypt_keyslot_context_init_by_token(struct crypt_device *cd, * * @param volume_key provided volume key or @e NULL if used after crypt_format * or with CRYPT_VOLUME_KEY_NO_SEGMENT flag - * @param volume_key_size size of volume_key + * @param volume_key_size size of volume_key in bytes * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEY * - * @return zero on success or negative errno otherwise. + * @return zero on success or negative errno value otherwise. */ int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd, const char *volume_key, @@ -1272,12 +1295,12 @@ int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd, * @param cd crypt device handle initialized to device context * * @param volume_key provided volume key - * @param volume_key_size size of volume_key + * @param volume_key_size size of volume_key in bytes * @param signature buffer with signature for the key - * @param signature_size bsize of signature buffer + * @param signature_size size of signature buffer * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_SIGNED_KEY * - * @return zero on success or negative errno otherwise. + * @return zero on success or negative errno value otherwise. * * @note currently supported only with VERITY devices. */ @@ -1297,7 +1320,7 @@ int crypt_keyslot_context_init_by_signed_key(struct crypt_device *cd, * for passphrase in * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEYRING * - * @return zero on success or negative errno otherwise. + * @return zero on success or negative errno value otherwise. */ int crypt_keyslot_context_init_by_keyring(struct crypt_device *cd, const char *key_description, @@ -1313,7 +1336,7 @@ int crypt_keyslot_context_init_by_keyring(struct crypt_device *cd, * or a text representation in the form "%:" * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEYRING * - * @return zero on success or negative errno otherwise. + * @return zero on success or negative errno value otherwise. */ int crypt_keyslot_context_init_by_vk_in_keyring(struct crypt_device *cd, const char *key_description, @@ -1343,7 +1366,7 @@ int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc); * @param pin_size size of @e pin * @param kc LUKS2 keyslot context (only @link CRYPT_KC_TYPE_TOKEN @endlink is allowed) * - * @return zero on success or negative errno otherwise + * @return zero on success or negative errno value otherwise */ int crypt_keyslot_context_set_pin(struct crypt_device *cd, const char *pin, size_t pin_size, @@ -1379,7 +1402,7 @@ int crypt_keyslot_context_set_pin(struct crypt_device *cd, * * @param kc keyslot context * - * @return crypt keyslot context type id (see @link crypt-keyslot-context-types @endlink) or negative errno otherwise. + * @return crypt keyslot context type id (see @link crypt-keyslot-context-types @endlink) or negative errno value otherwise. */ int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc); /** @} */ @@ -1398,7 +1421,7 @@ int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc); * @param new_kc keyslot context providing passphrase for new keyslot. * @param flags key flags to set * - * @return allocated key slot number or negative errno otherwise. + * @return allocated key slot number or negative errno value otherwise. * * @note new_kc can not be @e CRYPT_KC_TYPE_KEY type keyslot context. * @@ -1504,6 +1527,12 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot); #define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26) /** dm-verity: try to use tasklets */ #define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27) +/** dm-crypt: use high-priority workqueues */ +#define CRYPT_ACTIVATE_HIGH_PRIORITY (UINT32_C(1) << 28) +/** dm-verity: also restart/panic on error, use with RESTART_ON_CORRUPTION or PANIC_ON_CORRUPTION */ +#define CRYPT_ACTIVATE_ERROR_AS_CORRUPTION (UINT32_C(1) << 29) +/** dm-integrity: inline mode for compatible hardware profile */ +#define CRYPT_ACTIVATE_INLINE_MODE (UINT32_C(1) << 30) /** * Active device runtime attributes @@ -1523,7 +1552,6 @@ struct crypt_active_device { * @param cad preallocated active device attributes to fill * * @return @e 0 on success or negative errno value otherwise - * */ int crypt_get_active_device(struct crypt_device *cd, const char *name, @@ -1536,7 +1564,6 @@ int crypt_get_active_device(struct crypt_device *cd, * @param name name of active device * * @return number of integrity failures or @e 0 otherwise - * */ uint64_t crypt_get_active_integrity_failures(struct crypt_device *cd, const char *name); @@ -1557,6 +1584,8 @@ uint64_t crypt_get_active_integrity_failures(struct crypt_device *cd, #define CRYPT_REQUIREMENT_ONLINE_REENCRYPT (UINT32_C(1) << 1) /** Device configured with OPAL support */ #define CRYPT_REQUIREMENT_OPAL (UINT32_C(1) << 2) +/** Device configured with inline HW tags */ +#define CRYPT_REQUIREMENT_INLINE_HW_TAGS (UINT32_C(1) << 3) /** unknown requirement in header (output only) */ #define CRYPT_REQUIREMENT_UNKNOWN (UINT32_C(1) << 31) @@ -1579,9 +1608,11 @@ typedef enum { * * @note Valid only for LUKS2. * - * @note Not all activation flags can be stored. Only ALLOW_DISCARD, - * SAME_CPU_CRYPT, SUBMIT_FROM_CRYPT_CPU and NO_JOURNAL can be - * stored persistently. + * @note Not all activation flags can be stored. Only CRYPT_ACTIVATE_ALLOW_DISCARDS, + * CRYPT_ACTIVATE_SAME_CPU_CRYPT, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS, + * CRYPT_ACTIVATE_NO_JOURNAL, CRYPT_ACTIVATE_NO_READ_WORKQUEUE, + * CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE and CRYPT_ACTIVATE_HIGH_PRIORITY + * can be stored persistently. * * @note Only requirements flags recognised by current library may be set. * CRYPT_REQUIREMENT_UNKNOWN is illegal (output only) in set operation. @@ -1633,7 +1664,7 @@ int crypt_persistent_flags_get(struct crypt_device *cd, * @param flags activation flags * * @return unlocked key slot number for passphrase-based unlock, zero for other - * unlock methods (e.g. volume key context) or negative errno on error. + * unlock methods (e.g. volume key context) or negative errno value on error. */ int crypt_activate_by_keyslot_context(struct crypt_device *cd, const char *name, @@ -1653,7 +1684,7 @@ int crypt_activate_by_keyslot_context(struct crypt_device *cd, * @param passphrase_size size of @e passphrase * @param flags activation flags * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. */ int crypt_activate_by_passphrase(struct crypt_device *cd, const char *name, @@ -1669,11 +1700,11 @@ int crypt_activate_by_passphrase(struct crypt_device *cd, * @param name name of device to create, if @e NULL only check keyfile * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT * @param keyfile key file used to unlock volume key - * @param keyfile_size number of bytes to read from keyfile, 0 is unlimited + * @param keyfile_size number of bytes to read from keyfile, @e 0 is unlimited * @param keyfile_offset number of bytes to skip at start of keyfile * @param flags activation flags * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. */ int crypt_activate_by_keyfile_device_offset(struct crypt_device *cd, const char *name, @@ -1710,7 +1741,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd, * @param cd crypt device handle * @param name name of device to create, if @e NULL only check volume key * @param volume_key provided volume key (or @e NULL to use internal) - * @param volume_key_size size of volume_key + * @param volume_key_size size of volume_key in bytes * @param flags activation flags * * @return @e 0 on success or negative errno value otherwise. @@ -1721,7 +1752,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd, * @note For VERITY the volume key means root hash required for activation. * Because kernel dm-verity is always read only, you have to provide * CRYPT_ACTIVATE_READONLY flag always. - * @note For TCRYPT the volume key should be always NULL + * @note For TCRYPT the volume key should be always @e NULL * the key from decrypted header is used instead. * @note For BITLK the name cannot be @e NULL checking volume key is not * supported for BITLK, the device will be activated even if the @@ -1739,9 +1770,9 @@ int crypt_activate_by_volume_key(struct crypt_device *cd, * @param cd crypt device handle * @param name name of device to create * @param volume_key provided volume key - * @param volume_key_size size of volume_key + * @param volume_key_size size of volume_key in bytes * @param signature buffer with signature for the key - * @param signature_size bsize of signature buffer + * @param signature_size size of signature buffer * @param flags activation flags * * @return @e 0 on success or negative errno value otherwise. @@ -1797,7 +1828,6 @@ int crypt_activate_by_keyring(struct crypt_device *cd, * @param flags deactivation flags * * @return @e 0 on success or negative errno value otherwise. - * */ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, @@ -1822,11 +1852,11 @@ int crypt_deactivate(struct crypt_device *cd, const char *name); * @param keyslot use this keyslot or @e CRYPT_ANY_SLOT * @param volume_key buffer for volume key * @param volume_key_size on input, size of buffer @e volume_key, - * on output size of @e volume_key + * on output size of @e volume_key in bytes * @param passphrase passphrase used to unlock volume key * @param passphrase_size size of @e passphrase * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. * * @note For TCRYPT cipher chain is the volume key concatenated * for all ciphers in chain. @@ -1849,17 +1879,17 @@ int crypt_volume_key_get(struct crypt_device *cd, * @param keyslot use this keyslot or @e CRYPT_ANY_SLOT * @param volume_key buffer for volume key * @param volume_key_size on input, size of buffer @e volume_key, - * on output size of @e volume_key + * on output size of @e volume_key in bytes * @param kc keyslot context used to unlock volume key * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. * * @note See @link crypt-keyslot-context-types @endlink for info on keyslot * context initialization. * @note For TCRYPT cipher chain is the volume key concatenated - * for all ciphers in chain (kc may be NULL). + * for all ciphers in chain (kc may be @e NULL). * @note For VERITY the volume key means root hash used for activation - * (kc may be NULL). + * (kc may be @e NULL). * @note For LUKS devices, if kc is @e NULL and volume key is cached in * device context it returns the volume key generated in preceding * @link crypt_format @endlink call. @@ -1882,7 +1912,7 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, * * @param cd crypt device handle * @param volume_key provided volume key - * @param volume_key_size size of @e volume_key + * @param volume_key_size size of @e volume_key in bytes * * @return @e 0 on success or negative errno value otherwise. * @@ -1918,7 +1948,6 @@ typedef enum { * @param name crypt device name * * @return value defined by crypt_status_info. - * */ crypt_status_info crypt_status(struct crypt_device *cd, const char *name); @@ -1935,7 +1964,7 @@ int crypt_dump(struct crypt_device *cd); * Dump JSON-formatted information about LUKS2 device * * @param cd crypt device handle (only LUKS2 format supported) - * @param json buffer with JSON, if NULL use log callback for output + * @param json buffer with JSON, if @e NULL use log callback for output * @param flags dump flags (reserved) * * @return @e 0 on success or negative errno value otherwise. @@ -1948,7 +1977,6 @@ int crypt_dump_json(struct crypt_device *cd, const char **json, uint32_t flags); * @param cd crypt device handle * * @return used cipher, e.g. "aes" or @e NULL otherwise - * */ const char *crypt_get_cipher(struct crypt_device *cd); @@ -1958,7 +1986,6 @@ const char *crypt_get_cipher(struct crypt_device *cd); * @param cd crypt device handle * * @return used cipher mode e.g. "xts-plain" or @e otherwise - * */ const char *crypt_get_cipher_mode(struct crypt_device *cd); @@ -1968,7 +1995,6 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd); * @param cd crypt device handle * * @return device UUID or @e NULL if not set - * */ const char *crypt_get_uuid(struct crypt_device *cd); @@ -1978,7 +2004,6 @@ const char *crypt_get_uuid(struct crypt_device *cd); * @param cd crypt device handle * * @return path to underlying device name - * */ const char *crypt_get_device_name(struct crypt_device *cd); @@ -1988,7 +2013,6 @@ const char *crypt_get_device_name(struct crypt_device *cd); * @param cd crypt device handle * * @return path to underlying device name - * */ const char *crypt_get_metadata_device_name(struct crypt_device *cd); @@ -1998,7 +2022,6 @@ const char *crypt_get_metadata_device_name(struct crypt_device *cd); * @param cd crypt device handle * * @return device offset in sectors - * */ uint64_t crypt_get_data_offset(struct crypt_device *cd); @@ -2008,7 +2031,6 @@ uint64_t crypt_get_data_offset(struct crypt_device *cd); * @param cd crypt device handle * * @return IV offset - * */ uint64_t crypt_get_iv_offset(struct crypt_device *cd); @@ -2024,13 +2046,25 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd); */ int crypt_get_volume_key_size(struct crypt_device *cd); +/** + * Get size (in bytes) of old volume key for LUKS2 device in reencryption. + * + * @param cd crypt LUKS2 device handle + * + * @return old volume key size when device is in reencryption state + * + * @note For LUKS2, this function can be used only if there is at least + * one keyslot assigned to old data segment. Also with reencryption + * mode 'encrypt' there's no old volume key. + */ +int crypt_get_old_volume_key_size(struct crypt_device *cd); + /** * Get size (in bytes) of encryption sector for crypt device. * * @param cd crypt device handle * * @return sector size - * */ int crypt_get_sector_size(struct crypt_device *cd); @@ -2056,7 +2090,6 @@ int crypt_header_is_detached(struct crypt_device *cd); * @param vp verity device info * * @e 0 on success or negative errno value otherwise. - * */ int crypt_get_verity_info(struct crypt_device *cd, struct crypt_params_verity *vp); @@ -2068,7 +2101,6 @@ int crypt_get_verity_info(struct crypt_device *cd, * @param ip verity device info * * @e 0 on success or negative errno value otherwise. - * */ int crypt_get_integrity_info(struct crypt_device *cd, struct crypt_params_integrity *ip); @@ -2116,7 +2148,7 @@ int crypt_benchmark(struct crypt_device *cd, * @param password_size size of password * @param salt salt for benchmark * @param salt_size size of salt - * @param volume_key_size output volume key size + * @param volume_key_size output volume key size in bytes * @param progress callback function * @param usrptr provided identification in callback * @@ -2158,7 +2190,6 @@ typedef enum { * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT * * @return value defined by crypt_keyslot_info - * */ crypt_keyslot_info crypt_keyslot_status(struct crypt_device *cd, int keyslot); @@ -2198,7 +2229,7 @@ int crypt_keyslot_set_priority(struct crypt_device *cd, int keyslot, crypt_keysl * * @param type crypt device type * - * @return slot count or negative errno otherwise if device + * @return slot count or negative errno value otherwise if device * doesn't not support keyslots. */ int crypt_keyslot_max(const char *type); @@ -2212,7 +2243,6 @@ int crypt_keyslot_max(const char *type); * @param length length of keyslot area (in bytes) * * @return @e 0 on success or negative errno value otherwise. - * */ int crypt_keyslot_area(struct crypt_device *cd, int keyslot, @@ -2269,7 +2299,7 @@ int crypt_keyslot_get_pbkdf(struct crypt_device *cd, int keyslot, struct crypt_p * @return @e 0 on success or negative errno value otherwise. * * @note To reset to default keyslot encryption (the same as for data) - * set cipher to NULL and key size to 0. + * set cipher to @e NULL and key size to 0. */ int crypt_keyslot_set_encryption(struct crypt_device *cd, const char *cipher, @@ -2297,7 +2327,6 @@ const char *crypt_get_dir(void); * @param backup_file file to backup header to * * @return @e 0 on success or negative errno value otherwise. - * */ int crypt_header_backup(struct crypt_device *cd, const char *requested_type, @@ -2336,7 +2365,6 @@ int crypt_header_restore(struct crypt_device *cd, * Set the debug level for library * * @param level debug level - * */ void crypt_set_debug_level(int level); /** @} */ @@ -2353,8 +2381,8 @@ void crypt_set_debug_level(int level); * @param cd crypt device handle * @param keyfile keyfile to read * @param key buffer for key - * @param key_size_read size of read key - * @param keyfile_offset key offset in keyfile + * @param key_size_read size of read key in bytes + * @param keyfile_offset key offset in bytes in keyfile * @param key_size exact key length to read from file or 0 * @param flags keyfile read flags * @@ -2481,7 +2509,7 @@ int crypt_wipe_hw_opal(struct crypt_device *cd, * * @param type crypt device type * - * @return token count or negative errno otherwise if device + * @return token count or negative errno value otherwise if device * doesn't not support tokens. * * @note Real number of supported tokens for a particular device depends @@ -2499,7 +2527,7 @@ int crypt_token_max(const char *type); * @param token token id * @param json buffer with JSON * - * @return allocated token id or negative errno otherwise. + * @return allocated token id or negative errno value otherwise. */ int crypt_token_json_get(struct crypt_device *cd, int token, @@ -2512,7 +2540,7 @@ int crypt_token_json_get(struct crypt_device *cd, * @param token token id or @e CRYPT_ANY_TOKEN to allocate new one * @param json buffer with JSON or @e NULL to remove token * - * @return allocated token id or negative errno otherwise. + * @return allocated token id or negative errno value otherwise. * * @note The buffer must be in proper JSON format and must contain at least * string "type" with slot type and an array of string names "keyslots". @@ -2542,7 +2570,7 @@ typedef enum { * @param type pointer for returned type string * * @return token status info. For any returned status (besides CRYPT_TOKEN_INVALID - * and CRYPT_TOKEN_INACTIVE) and if type parameter is not NULL it will + * and CRYPT_TOKEN_INACTIVE) and if type parameter is not @e NULL it will * contain address of type string. * * @note if required, create a copy of string referenced in *type before calling next @@ -2554,7 +2582,6 @@ crypt_token_info crypt_token_status(struct crypt_device *cd, int token, const ch * LUKS2 keyring token parameters. * * @see crypt_token_builtin_set - * */ struct crypt_token_params_luks2_keyring { const char *key_description; /**< Reference in keyring */ @@ -2567,8 +2594,7 @@ struct crypt_token_params_luks2_keyring { * @param token token id or @e CRYPT_ANY_TOKEN to allocate new one * @param params luks2 keyring token params * - * @return allocated token id or negative errno otherwise. - * + * @return allocated token id or negative errno value otherwise. */ int crypt_token_luks2_keyring_set(struct crypt_device *cd, int token, @@ -2581,7 +2607,7 @@ int crypt_token_luks2_keyring_set(struct crypt_device *cd, * @param token existing luks2 keyring token id * @param params returned luks2 keyring token params * - * @return allocated token id or negative errno otherwise. + * @return allocated token id or negative errno value otherwise. * * @note do not call free() on params members. Members are valid only * until next libcryptsetup function is called. @@ -2595,11 +2621,11 @@ int crypt_token_luks2_keyring_get(struct crypt_device *cd, * (There can be more keyslots assigned to one token id.) * * @param cd crypt device handle - * @param token token id + * @param token specific token id * @param keyslot keyslot to be assigned to token (CRYPT_ANY SLOT * assigns all active keyslots to token) * - * @return allocated token id or negative errno otherwise. + * @return requested token id to be assigned or negative errno value otherwise. */ int crypt_token_assign_keyslot(struct crypt_device *cd, int token, @@ -2610,11 +2636,11 @@ int crypt_token_assign_keyslot(struct crypt_device *cd, * (There can be more keyslots assigned to one token id.) * * @param cd crypt device handle - * @param token token id + * @param token specific token id * @param keyslot keyslot to be unassigned from token (CRYPT_ANY SLOT * unassigns all active keyslots from token) * - * @return allocated token id or negative errno otherwise. + * @return requested token id to be unassigned or negative errno value otherwise. */ int crypt_token_unassign_keyslot(struct crypt_device *cd, int token, @@ -2627,9 +2653,9 @@ int crypt_token_unassign_keyslot(struct crypt_device *cd, * @param token token id * @param keyslot keyslot * - * @return 0 on success (token exists and is assigned to the keyslot), + * @return @e 0 on success (token exists and is assigned to the keyslot), * -ENOENT if token is not assigned to a keyslot (token, keyslot - * or both may be inactive) or other negative errno otherwise. + * or both may be inactive) or other negative errno value otherwise. */ int crypt_token_is_assigned(struct crypt_device *cd, int token, @@ -2647,8 +2673,8 @@ int crypt_token_is_assigned(struct crypt_device *cd, * @param buffer_len length of the buffer * @param usrptr user data in @link crypt_activate_by_token @endlink * - * @return 0 on success (token passed LUKS2 keyslot passphrase in buffer) or - * negative errno otherwise. + * @return @e 0 on success (token passed LUKS2 keyslot passphrase in buffer) or + * negative errno value otherwise. * * @note Negative ENOANO errno means that token is PIN protected and caller should * use @link crypt_activate_by_token_pin @endlink with PIN provided. @@ -2677,8 +2703,8 @@ typedef int (*crypt_token_open_func) ( * @param buffer_len length of the buffer * @param usrptr user data in @link crypt_activate_by_token @endlink * - * @return 0 on success (token passed LUKS2 keyslot passphrase in buffer) or - * negative errno otherwise. + * @return @e 0 on success (token passed LUKS2 keyslot passphrase in buffer) or + * negative errno value otherwise. * * @note Negative ENOANO errno means that token is PIN protected and PIN was * missing or wrong. @@ -2738,7 +2764,6 @@ typedef void (*crypt_token_dump_func) (struct crypt_device *cd, const char *json * * @note The returned string is advised to contain only version. * For example '1.0.0' or 'v1.2.3.4'. - * */ typedef const char * (*crypt_token_version_func) (void); @@ -2811,7 +2836,7 @@ void crypt_token_external_disable(void); * @param usrptr provided identification in callback * @param flags activation flags * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. * * @note EPERM errno means token provided passphrase successfully, but * passphrase did not unlock any keyslot associated with the token. @@ -2828,7 +2853,7 @@ void crypt_token_external_disable(void); * @note with @e token set to CRYPT_ANY_TOKEN libcryptsetup runs best effort loop * to unlock device using any available token. It may happen that various token handlers * return different error codes. At the end loop returns error codes in the following - * order (from the most significant to the least) any negative errno except those + * order (from the most significant to the least) any negative errno value except those * listed below, non negative token id (success), -ENOANO, -EAGAIN, -EPERM, -ENOENT. */ int crypt_activate_by_token(struct crypt_device *cd, @@ -2849,7 +2874,7 @@ int crypt_activate_by_token(struct crypt_device *cd, * @param usrptr provided identification in callback * @param flags activation flags * - * @return unlocked key slot number or negative errno otherwise. + * @return unlocked key slot number or negative errno value otherwise. * * @note EPERM errno means token provided passphrase successfully, but * passphrase did not unlock any keyslot associated with the token. @@ -2858,7 +2883,7 @@ int crypt_activate_by_token(struct crypt_device *cd, * eligible to unlock device. * * @note ENOANO errno means that token is PIN protected and was either missing - * (NULL) or wrong. + * (@e NULL) or wrong. * * @note Negative EAGAIN errno means token handler requires additional hardware * not present in the system. @@ -2866,7 +2891,7 @@ int crypt_activate_by_token(struct crypt_device *cd, * @note with @e token set to CRYPT_ANY_TOKEN libcryptsetup runs best effort loop * to unlock device using any available token. It may happen that various token handlers * return different error codes. At the end loop returns error codes in the following - * order (from the most significant to the least) any negative errno except those + * order (from the most significant to the least) any negative errno value except those * listed below, non negative token id (success), -ENOANO, -EAGAIN, -EPERM, -ENOENT. */ int crypt_activate_by_token_pin(struct crypt_device *cd, @@ -2899,6 +2924,12 @@ int crypt_activate_by_token_pin(struct crypt_device *cd, #define CRYPT_REENCRYPT_RECOVERY (UINT32_C(1) << 3) /** Reencryption requires metadata protection. (in/out) */ #define CRYPT_REENCRYPT_REPAIR_NEEDED (UINT32_C(1) << 4) +/** + * Calculate new (future) volume key digest directly during + * reencryption initialization. The keyslot context for new + * volume key must be CRYPT_KC_TYPE_KEY or + * CRYPT_KC_TYPE_VK_KEYRING. (in) */ +#define CRYPT_REENCRYPT_CREATE_NEW_DIGEST (UINT32_C(1) << 5) /** * Reencryption direction @@ -2955,7 +2986,7 @@ struct crypt_params_reencrypt { * @param cipher_mode cipher mode and IV (e.g. "xts-plain64") * @param params reencryption parameters @link crypt_params_reencrypt @endlink. * - * @return reencryption key slot number or negative errno otherwise. + * @return reencryption key slot number or negative errno value otherwise. */ int crypt_reencrypt_init_by_passphrase(struct crypt_device *cd, const char *name, @@ -2984,7 +3015,7 @@ int crypt_reencrypt_init_by_passphrase(struct crypt_device *cd, * @param cipher_mode cipher mode and IV (e.g. "xts-plain64") * @param params reencryption parameters @link crypt_params_reencrypt @endlink. * - * @return reencryption key slot number or negative errno otherwise. + * @return reencryption key slot number or negative errno value otherwise. */ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd, const char *name, @@ -2995,6 +3026,71 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd, const char *cipher_mode, const struct crypt_params_reencrypt *params); +/** + * + * Initialize or reload LUKS2 reencryption operation using keyslot contexts. + * + * The function can initialize reencryption on-disk metadata or reload reencryption + * context from on-disk LUSK2 metadata to resume interrupted operation. + * + * If the device is not in reencryption state (@link crypt_reencrypt_status @endlink + * returns @link CRYPT_REENCRYPT_NONE @endlink) the function initializes on-disk + * metadata to include all necessary reencryption segments and new encryption + * parameters (cipher, cipher mode, encryption sector size) according to the + * provided parameters. + * + * If on-disk metadata already describes reencryption operation + * (@link crypt_reencrypt_status @endlink returns @link CRYPT_REENCRYPT_CLEAN @endlink), + * it loads these parameters and internally initializes reencryption context. It also verifies + * if the device is eligible to resume reencryption operation. Some reencryption parameters + * (@link crypt_params_reencrypt @endlink) may be modified depending on the original values in + * the initialization call. When resuming the operation, all parameters may be omitted except + * @e cd, @e name (offline/online),@e kc_old and @e kc_new. + * + * If on-disk metadata describes reencryption operation requiring recovery + * (@link crypt_reencrypt_status @endlink returns @link CRYPT_REENCRYPT_CRASH @endlink), + * it can be recovered by adding @link CRYPT_REENCRYPT_RECOVERY @endlink flag in @link + * crypt_params_reencrypt @endlink parameter. + * + * @param cd crypt device handle + * @param name name of the active device or @e NULL for offline reencryption + * @param kc_old keyslot context providing access to volume key in keyslot id @e keyslot_old. + * @param kc_new keyslot context providing access to volume key in keyslot id @e keyslot_new. + * @param keyslot_old keyslot id containing current volume key for the device or CRYPT_ANY_SLOT + * @param keyslot_new keyslot id containing (unbound) future volume key in encryption or reencryption + * operation. It must be set in the initialization call except when initializing the decrypt + * operation. In reencryption operation it may contain also the current volume key in case the + * volume key change is not requested. + * @param cipher new cipher specification (e.g. "aes") or @e NULL in decryption. Relevant only + * during metadata initialization. + * @param cipher_mode cipher mode and IV (e.g. "xts-plain64") or @e NULL in decryption. + * Relevant only during metadata initialization. + * @param params reencryption parameters @link crypt_params_reencrypt @endlink. + * + * @return reencryption key slot number or negative errno value otherwise. + * + * @note Only after successful reencryption initialization you may run the operation with + * @link crypt_reencrypt_run @endlink. + * + * @note During @link CRYPT_REENCRYPT_REENCRYPT @endlink operation it is highly recommended + * to use same keyslot context (same passphrase, token, keyfile, etc) in both @e kc_old + * and @e kc_new parameters for at least one keyslot containing future volume key and one + * keyslot containing current volume key. If the same keyslot context can not be used + * to unlock any current or any future volume key it would be impossible to perform reencryption + * crash recovery during device activation for example after system reboot. Any keyslot + * passphrase may be changed in-before initializing reencryption operation via @link + * crypt_keyslot_change_by_passphrase @endlink. + */ +int crypt_reencrypt_init_by_keyslot_context(struct crypt_device *cd, + const char *name, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, + int keyslot_old, + int keyslot_new, + const char *cipher, + const char *cipher_mode, + const struct crypt_params_reencrypt *params); + /** * Legacy data reencryption function. * @@ -3089,6 +3185,15 @@ void *crypt_safe_realloc(void *data, size_t size); */ void crypt_safe_memzero(void *data, size_t size); +/** + * Memcpy helper to avoid spilling sensitive data through additional registers + * + * @param dst pointer to memory to be written + * @param src pointer to memory to be copied + * @param size size of memory in bytes + */ +void *crypt_safe_memcpy(void *dst, const void *src, size_t size); + /** @} */ /** @@ -3107,7 +3212,7 @@ void crypt_safe_memzero(void *data, size_t size); * * The @e old_key_description argument is required only for * devices that are in re-encryption and have two volume keys at the same time - * (old and new). You can set the @e old_key_description to NULL, + * (old and new). You can set the @e old_key_description to @e NULL, * but if you supply number of keys less than required, the function will * return -ESRCH. In that case you need to call the function again and set * the missing key description. When supplying just one key description, make diff --git a/lib/libcryptsetup.sym b/lib/libcryptsetup.sym index 89d6468..3a54431 100644 --- a/lib/libcryptsetup.sym +++ b/lib/libcryptsetup.sym @@ -180,3 +180,18 @@ CRYPTSETUP_2.7 { crypt_set_keyring_to_link; crypt_wipe_hw_opal; } CRYPTSETUP_2.6; + +CRYPTSETUP_2.8 { + global: + crypt_safe_memcpy; + crypt_keyslot_context_init_by_passphrase; + crypt_keyslot_context_init_by_keyfile; + crypt_keyslot_context_init_by_token; + crypt_keyslot_context_init_by_volume_key; + crypt_keyslot_context_init_by_signed_key; + crypt_keyslot_context_init_by_keyring; + crypt_keyslot_context_init_by_vk_in_keyring; + crypt_reencrypt_init_by_keyslot_context; + crypt_get_old_volume_key_size; + crypt_format_inline; +} CRYPTSETUP_2.7; diff --git a/lib/libcryptsetup_macros.h b/lib/libcryptsetup_macros.h index 00af58c..657c48f 100644 --- a/lib/libcryptsetup_macros.h +++ b/lib/libcryptsetup_macros.h @@ -2,8 +2,8 @@ /* * Definitions of common constant and generic macros of libcryptsetup * - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #ifndef _LIBCRYPTSETUP_MACROS_H @@ -49,9 +49,17 @@ #define DEFAULT_MEM_ALIGNMENT 4096 #define DM_UUID_LEN 129 +#define DM_NAME_LEN 128 #define DM_BY_ID_PREFIX "dm-uuid-" #define DM_BY_ID_PREFIX_LEN 8 #define DM_UUID_PREFIX "CRYPT-" #define DM_UUID_PREFIX_LEN 6 +#define OPAL_PSID_LEN 32 + +/* LUKS AF stripes, never set to any other value than 4000 */ +#ifndef LUKS_STRIPES +# define LUKS_STRIPES 4000 +#endif + #endif /* _LIBCRYPTSETUP_MACROS_H */ diff --git a/lib/libcryptsetup_symver.h b/lib/libcryptsetup_symver.h index 62d3018..6d18ab5 100644 --- a/lib/libcryptsetup_symver.h +++ b/lib/libcryptsetup_symver.h @@ -2,7 +2,7 @@ /* * Helpers for defining versioned symbols * - * Copyright (C) 2021-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2021-2025 Red Hat, Inc. All rights reserved. */ #ifndef _LIBCRYPTSETUP_SYMVER_H diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index d7eadc8..743efb9 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -15,7 +15,7 @@ #include #include #include -#ifdef HAVE_SYS_SYSMACROS_H +#if HAVE_SYS_SYSMACROS_H # include /* for major, minor */ #endif #include "internal.h" @@ -36,7 +36,7 @@ static bool _dm_integrity_checked = false; static bool _dm_zero_checked = false; static int _quiet_log = 0; -static uint32_t _dm_flags = 0; +static uint64_t _dm_flags = 0; static struct crypt_device *_context = NULL; static int _dm_use_count = 0; @@ -61,7 +61,7 @@ static int _dm_udev_wait(uint32_t cookie) { return 0; }; static int _dm_use_udev(void) { -#ifdef USE_UDEV /* cannot be enabled if devmapper is too old */ +#if USE_UDEV /* cannot be enabled if devmapper is too old */ return dm_udev_get_sync_support(); #else return 0; @@ -157,6 +157,12 @@ static void _dm_set_crypt_compat(struct crypt_device *cd, if (_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch)) _dm_flags |= DM_CRYPT_NO_WORKQUEUE_SUPPORTED; + if (_dm_satisfies_version(1, 26, 0, crypt_maj, crypt_min, crypt_patch)) + _dm_flags |= DM_CRYPT_HIGH_PRIORITY_SUPPORTED; + + if (_dm_satisfies_version(1, 28, 0, crypt_maj, crypt_min, crypt_patch)) + _dm_flags |= DM_CRYPT_INTEGRITY_KEY_SIZE_OPT_SUPPORTED; + _dm_crypt_checked = true; } @@ -194,6 +200,10 @@ static void _dm_set_verity_compat(struct crypt_device *cd, if (_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch)) _dm_flags |= DM_VERITY_TASKLETS_SUPPORTED; + /* There is actually no correct version set, just use the last available */ + if (_dm_satisfies_version(1, 10, 0, verity_maj, verity_min, verity_patch)) + _dm_flags |= DM_VERITY_ERROR_AS_CORRUPTION_SUPPORTED; + _dm_verity_checked = true; } @@ -228,6 +238,9 @@ static void _dm_set_integrity_compat(struct crypt_device *cd, if (_dm_satisfies_version(1, 8, 0, integrity_maj, integrity_min, integrity_patch)) _dm_flags |= DM_INTEGRITY_RESET_RECALC_SUPPORTED; + if (_dm_satisfies_version(1, 12, 0, integrity_maj, integrity_min, integrity_patch)) + _dm_flags |= DM_INTEGRITY_INLINE_MODE_SUPPORTED; + _dm_integrity_checked = true; } @@ -358,7 +371,7 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ return r; } -int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags) +int dm_flags(struct crypt_device *cd, dm_target_type target, uint64_t *flags) { _dm_check_versions(cd, target); *flags = _dm_flags; @@ -537,6 +550,7 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags) int r, max_size, null_cipher = 0, num_options = 0, keystr_len = 0; char *params = NULL, *hexkey = NULL; char sector_feature[32], features[512], integrity_dm[256], cipher_dm[256]; + char int_ksize_feature[32]; if (!tgt) return NULL; @@ -558,22 +572,29 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags) num_options++; if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) num_options++; + if (flags & CRYPT_ACTIVATE_HIGH_PRIORITY) + num_options++; if (tgt->u.crypt.integrity) num_options++; if (tgt->u.crypt.sector_size != SECTOR_SIZE) num_options++; + if (tgt->u.crypt.integrity && tgt->u.crypt.integrity_key_size) + num_options++; - if (num_options) { /* MAX length int32 + 15 + 15 + 23 + 18 + 19 + 17 + 13 + int32 + integrity_str */ - r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s%s", num_options, + if (num_options) { /* MAX length int32 + 15 + 15 + 23 + 18 + 19 + 17 + 14 + 13 + int32 + integrity_str + 21 + int32 */ + r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s%s%s%s", num_options, (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "", (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "", (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "", (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? " no_read_workqueue" : "", (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? " no_write_workqueue" : "", (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "", + (flags & CRYPT_ACTIVATE_HIGH_PRIORITY) ? " high_priority" : "", (tgt->u.crypt.sector_size != SECTOR_SIZE) ? _uf(sector_feature, sizeof(sector_feature), "sector_size", tgt->u.crypt.sector_size) : "", - integrity_dm); + integrity_dm, + (tgt->u.crypt.integrity && tgt->u.crypt.integrity_key_size) ? + _uf(int_ksize_feature, sizeof(int_ksize_feature), "integrity_key_size", tgt->u.crypt.integrity_key_size) : ""); if (r < 0 || (size_t)r >= sizeof(features)) goto out; } else @@ -582,19 +603,26 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags) if (crypt_is_cipher_null(cipher_dm)) null_cipher = 1; - if (null_cipher) + if (null_cipher || crypt_volume_key_length(tgt->u.crypt.vk) == 0) hexkey = crypt_bytes_to_hex(0, NULL); else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) { - keystr_len = strlen(tgt->u.crypt.vk->key_description) + int_log10(tgt->u.crypt.vk->keylength) + 10; + if (!crypt_volume_key_description(tgt->u.crypt.vk) || + crypt_volume_key_kernel_key_type(tgt->u.crypt.vk) == INVALID_KEY) + goto out; + keystr_len = strlen(crypt_volume_key_description(tgt->u.crypt.vk)) + + int_log10(crypt_volume_key_length(tgt->u.crypt.vk)) + + 24 /* type and separators */; hexkey = crypt_safe_alloc(keystr_len); if (!hexkey) goto out; - r = snprintf(hexkey, keystr_len, ":%zu:logon:%s", tgt->u.crypt.vk->keylength, - tgt->u.crypt.vk->key_description); + r = snprintf(hexkey, keystr_len, ":%zu:%s:%s", crypt_volume_key_length(tgt->u.crypt.vk), + key_type_name(crypt_volume_key_kernel_key_type(tgt->u.crypt.vk)), + crypt_volume_key_description(tgt->u.crypt.vk)); if (r < 0 || r >= keystr_len) goto out; } else - hexkey = crypt_bytes_to_hex(tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key); + hexkey = crypt_bytes_to_hex(crypt_volume_key_length(tgt->u.crypt.vk), + crypt_volume_key_get_key(tgt->u.crypt.vk)); if (!hexkey) goto out; @@ -646,6 +674,8 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags) num_options++; if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) num_options++; + if (flags & CRYPT_ACTIVATE_ERROR_AS_CORRUPTION) + num_options++; if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) num_options++; if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) @@ -683,10 +713,12 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags) *verity_verify_args = '\0'; if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 + 22 */ - r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s", num_options, + r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s", num_options, (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "", (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "", (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "", + (flags & CRYPT_ACTIVATE_ERROR_AS_CORRUPTION) ? ((flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? + " panic_on_error" : " restart_on_error") : "", (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "", (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "", (flags & CRYPT_ACTIVATE_TASKLETS) ? " try_verify_in_tasklet" : ""); @@ -742,13 +774,13 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags if (!tgt) return NULL; - max_integrity = (tgt->u.integrity.integrity && tgt->u.integrity.vk ? tgt->u.integrity.vk->keylength * 2 : 0) + + max_integrity = (tgt->u.integrity.integrity && tgt->u.integrity.vk ? crypt_volume_key_length(tgt->u.integrity.vk) * 2 : 0) + (tgt->u.integrity.integrity ? strlen(tgt->u.integrity.integrity) : 0) + 32; max_journal_integrity = (tgt->u.integrity.journal_integrity && tgt->u.integrity.journal_integrity_key ? - tgt->u.integrity.journal_integrity_key->keylength * 2 : 0) + + crypt_volume_key_length(tgt->u.integrity.journal_integrity_key) * 2 : 0) + (tgt->u.integrity.journal_integrity ? strlen(tgt->u.integrity.journal_integrity) : 0) + 32; max_journal_crypt = (tgt->u.integrity.journal_crypt && tgt->u.integrity.journal_crypt_key ? - tgt->u.integrity.journal_crypt_key->keylength * 2 : 0) + + crypt_volume_key_length(tgt->u.integrity.journal_crypt_key) * 2 : 0) + (tgt->u.integrity.journal_crypt ? strlen(tgt->u.integrity.journal_crypt) : 0) + 32; max_size = strlen(device_block_path(tgt->data_device)) + (tgt->u.integrity.meta_device ? strlen(device_block_path(tgt->u.integrity.meta_device)) : 0) + @@ -766,7 +798,8 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags num_options++; if (tgt->u.integrity.vk) { - hexkey = crypt_bytes_to_hex(tgt->u.integrity.vk->keylength, tgt->u.integrity.vk->key); + hexkey = crypt_bytes_to_hex(crypt_volume_key_length(tgt->u.integrity.vk), + crypt_volume_key_get_key(tgt->u.integrity.vk)); if (!hexkey) goto out; } else @@ -783,8 +816,8 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags num_options++; if (tgt->u.integrity.journal_integrity_key) { - hexkey = crypt_bytes_to_hex( tgt->u.integrity.journal_integrity_key->keylength, - tgt->u.integrity.journal_integrity_key->key); + hexkey = crypt_bytes_to_hex(crypt_volume_key_length(tgt->u.integrity.journal_integrity_key), + crypt_volume_key_get_key(tgt->u.integrity.journal_integrity_key)); if (!hexkey) goto out; } else @@ -801,8 +834,8 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags num_options++; if (tgt->u.integrity.journal_crypt_key) { - hexkey = crypt_bytes_to_hex(tgt->u.integrity.journal_crypt_key->keylength, - tgt->u.integrity.journal_crypt_key->key); + hexkey = crypt_bytes_to_hex(crypt_volume_key_length(tgt->u.integrity.journal_crypt_key), + crypt_volume_key_get_key(tgt->u.integrity.journal_crypt_key)); if (!hexkey) goto out; } else @@ -873,7 +906,9 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags if (r < 0 || r >= max_size) goto out; - if (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) + if (flags & CRYPT_ACTIVATE_INLINE_MODE) + mode = 'I'; + else if (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) mode = 'B'; else if (flags & CRYPT_ACTIVATE_RECOVERY) mode = 'R'; @@ -967,7 +1002,7 @@ static int _dm_remove(const char *name, int udev_wait, int deferred) return r; } -static int _dm_simple(int task, const char *name, uint32_t dmflags) +static int _dm_simple(int task, const char *name, uint64_t dmflags) { int r = 0; struct dm_task *dmt; @@ -992,7 +1027,7 @@ static int _dm_simple(int task, const char *name, uint32_t dmflags) return r; } -static int _dm_resume_device(const char *name, uint32_t flags); +static int _dm_resume_device(const char *name, uint64_t dmflags); static int _error_device(const char *name, size_t size) { @@ -1078,7 +1113,7 @@ int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags) int retries = (flags & CRYPT_DEACTIVATE_FORCE) ? RETRY_COUNT : 1; int deferred = (flags & CRYPT_DEACTIVATE_DEFERRED) ? 1 : 0; int error_target = 0; - uint32_t dmt_flags; + uint64_t dmt_flags; if (!name) return -EINVAL; @@ -1428,7 +1463,7 @@ static int _dm_create_device(struct crypt_device *cd, const char *name, const ch return r; } -static int _dm_resume_device(const char *name, uint32_t dmflags) +static int _dm_resume_device(const char *name, uint64_t dmflags) { struct dm_task *dmt; int r = -EINVAL; @@ -1610,7 +1645,7 @@ int dm_targets_allocate(struct dm_target *first, unsigned count) return 0; } -static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dmt_flags) +static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint64_t dmt_flags) { int ret = 0; @@ -1646,6 +1681,14 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm ret = 1; } + /* Drop high-priority workqueue options if not supported */ + if ((*dmd_flags & CRYPT_ACTIVATE_HIGH_PRIORITY) && + !(dmt_flags & DM_CRYPT_HIGH_PRIORITY_SUPPORTED)) { + log_dbg(cd, "dm-crypt does not support high-priority option"); + *dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_HIGH_PRIORITY; + ret = 1; + } + return ret; } @@ -1653,7 +1696,7 @@ int dm_create_device(struct crypt_device *cd, const char *name, const char *type, struct crypt_dm_active_device *dmd) { - uint32_t dmt_flags = 0; + uint64_t dmt_flags = 0; int r = -EINVAL; if (!type || !dmd) @@ -1698,6 +1741,12 @@ int dm_create_device(struct crypt_device *cd, const char *name, r = -EINVAL; } + if ((dmd->flags & CRYPT_ACTIVATE_ERROR_AS_CORRUPTION) && + !(dmt_flags & DM_VERITY_ERROR_AS_CORRUPTION_SUPPORTED)) { + log_err(cd, _("Requested dm-verity data corruption handling options are not supported.")); + r = -EINVAL; + } + if (dmd->flags & CRYPT_ACTIVATE_TASKLETS && !(dmt_flags & DM_VERITY_TASKLETS_SUPPORTED)) { log_err(cd, _("Requested dm-verity tasklets option is not supported.")); @@ -1730,6 +1779,10 @@ int dm_create_device(struct crypt_device *cd, const char *name, log_err(cd, _("The device size is not multiple of the requested sector size.")); r = -EINVAL; } + if (dmd->segment.u.crypt.integrity_key_size && !(dmt_flags & DM_CRYPT_INTEGRITY_KEY_SIZE_OPT_SUPPORTED)) { + log_err(cd, _("Requested integrity_key_size option is not supported.")); + r = -EINVAL; + } } if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) && @@ -1755,6 +1808,12 @@ int dm_create_device(struct crypt_device *cd, const char *name, log_err(cd, _("Requested dm-integrity bitmap mode is not supported.")); r = -EINVAL; } + + if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_INLINE_MODE) && + !(dmt_flags & DM_INTEGRITY_INLINE_MODE_SUPPORTED)) { + log_err(cd, _("Requested dm-integrity inline mode is not supported.")); + r = -EINVAL; + } out: /* * Print warning if activating dm-crypt cipher_null device unless it's reencryption helper or @@ -1769,10 +1828,10 @@ int dm_create_device(struct crypt_device *cd, const char *name, } int dm_reload_device(struct crypt_device *cd, const char *name, - struct crypt_dm_active_device *dmd, uint32_t dmflags, unsigned resume) + struct crypt_dm_active_device *dmd, uint64_t dmflags, unsigned resume) { int r; - uint32_t dmt_flags; + uint64_t dmt_flags; if (!dmd) return -EINVAL; @@ -1958,18 +2017,19 @@ int dm_status_integrity_failures(struct crypt_device *cd, const char *name, uint } /* FIXME use hex wrapper, user val wrappers for line parsing */ -static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags, +static int _dm_target_query_crypt(struct crypt_device *cd, uint64_t get_flags, char *params, struct dm_target *tgt, uint32_t *act_flags) { uint64_t val64; - char *rcipher, *rintegrity, *key_, *rdevice, *endp, buffer[3], *arg, *key_desc; + char *rcipher, *rintegrity, *key_, *rdevice, *endp, buffer[3], *arg, *key_desc, keyring[16]; unsigned int i, val; int r; size_t key_size; struct device *data_device = NULL; char *cipher = NULL, *integrity = NULL; struct volume_key *vk = NULL; + void *key = NULL; tgt->type = DM_CRYPT; tgt->direction = TARGET_QUERY; @@ -2039,12 +2099,16 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags, *act_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE; else if (!strcasecmp(arg, "iv_large_sectors")) *act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS; + else if (!strcasecmp(arg, "high_priority")) + *act_flags |= CRYPT_ACTIVATE_HIGH_PRIORITY; else if (sscanf(arg, "integrity:%u:", &val) == 1) { tgt->u.crypt.tag_size = val; rintegrity = strchr(arg + strlen("integrity:"), ':'); if (!rintegrity) goto err; rintegrity++; + } else if (sscanf(arg, "integrity_key_size:%u", &val) == 1) { + tgt->u.crypt.integrity_key_size = val; } else if (sscanf(arg, "sector_size:%u", &val) == 1) { tgt->u.crypt.sector_size = val; } else /* unknown option */ @@ -2086,25 +2150,35 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags, if (key_[0] == ':') { /* ::: */ key_desc = NULL; + r = -ENOMEM; endp = strpbrk(key_ + 1, ":"); - if (endp) - key_desc = strpbrk(endp + 1, ":"); - if (!key_desc) { + if (!endp) + goto err; + key_desc = strpbrk(endp + 1, ":"); + if (!key_desc) + goto err; + memcpy(keyring, endp + 1, key_desc - endp - 1); + keyring[key_desc - endp - 1] = '\0'; + key_desc++; + r = crypt_volume_key_set_description(vk, key_desc, key_type_by_name(keyring)); + if (r < 0) + goto err; + } else if (key_size) { + key = crypt_safe_alloc(key_size); + if (!key) { r = -ENOMEM; goto err; } - key_desc++; - crypt_volume_key_set_description(vk, key_desc); - } else { buffer[2] = '\0'; - for(i = 0; i < vk->keylength; i++) { - memcpy(buffer, &key_[i * 2], 2); - vk->key[i] = strtoul(buffer, &endp, 16); + for(i = 0; i < crypt_volume_key_length(vk); i++) { + crypt_safe_memcpy(buffer, &key_[i * 2], 2); + *((char *)key + i) = strtoul(buffer, &endp, 16); if (endp != &buffer[2]) { r = -EINVAL; goto err; } } + crypt_volume_key_pass_safe_alloc(vk, &key); } } } @@ -2123,12 +2197,13 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags, free(cipher); free(integrity); device_free(cd, data_device); + crypt_safe_free(key); crypt_free_volume_key(vk); return r; } static int _dm_target_query_verity(struct crypt_device *cd, - uint32_t get_flags, + uint64_t get_flags, char *params, struct dm_target *tgt, uint32_t *act_flags) @@ -2287,6 +2362,9 @@ static int _dm_target_query_verity(struct crypt_device *cd, *act_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION; else if (!strcasecmp(arg, "panic_on_corruption")) *act_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION; + else if (!strcasecmp(arg, "restart_on_error") || + !strcasecmp(arg, "panic_on_error")) + *act_flags |= CRYPT_ACTIVATE_ERROR_AS_CORRUPTION; else if (!strcasecmp(arg, "ignore_zero_blocks")) *act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS; else if (!strcasecmp(arg, "check_at_most_once")) @@ -2387,7 +2465,7 @@ static int _dm_target_query_verity(struct crypt_device *cd, } static int _dm_target_query_integrity(struct crypt_device *cd, - uint32_t get_flags, + uint64_t get_flags, char *params, struct dm_target *tgt, uint32_t *act_flags) @@ -2435,7 +2513,7 @@ static int _dm_target_query_integrity(struct crypt_device *cd, /* journal */ c = toupper(*(++params)); - if (!*params || *(++params) != ' ' || (c != 'D' && c != 'J' && c != 'R' && c != 'B')) + if (!*params || *(++params) != ' ' || (c != 'D' && c != 'J' && c != 'R' && c != 'B' && c != 'I')) goto err; if (c == 'D') *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL; @@ -2445,168 +2523,169 @@ static int _dm_target_query_integrity(struct crypt_device *cd, *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL; *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP; } + if (c == 'I') { + *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL; + *act_flags |= CRYPT_ACTIVATE_INLINE_MODE; + } tgt->u.integrity.sector_size = SECTOR_SIZE; - /* Features section */ - if (params) { - /* Number of arguments */ - val64 = strtoull(params, ¶ms, 10); - if (*params != ' ') - goto err; - params++; + /* Features section, number of arguments (always included) */ + val64 = strtoull(params, ¶ms, 10); + if (*params != ' ') + goto err; + params++; - features = (int)val64; - for (i = 0; i < features; i++) { - r = -EINVAL; - if (!params) + features = (int)val64; + for (i = 0; i < features; i++) { + r = -EINVAL; + if (!params) + goto err; + arg = strsep(¶ms, " "); + if (sscanf(arg, "journal_sectors:%u", &val) == 1) + tgt->u.integrity.journal_size = val * SECTOR_SIZE; + else if (sscanf(arg, "journal_watermark:%u", &val) == 1) + tgt->u.integrity.journal_watermark = val; + else if (sscanf(arg, "sectors_per_bit:%" PRIu64, &val64) == 1) { + if (val64 > UINT_MAX) goto err; - arg = strsep(¶ms, " "); - if (sscanf(arg, "journal_sectors:%u", &val) == 1) - tgt->u.integrity.journal_size = val * SECTOR_SIZE; - else if (sscanf(arg, "journal_watermark:%u", &val) == 1) - tgt->u.integrity.journal_watermark = val; - else if (sscanf(arg, "sectors_per_bit:%" PRIu64, &val64) == 1) { - if (val64 > UINT_MAX) + /* overloaded value for bitmap mode */ + tgt->u.integrity.journal_watermark = (unsigned int)val64; + } else if (sscanf(arg, "commit_time:%u", &val) == 1) + tgt->u.integrity.journal_commit_time = val; + else if (sscanf(arg, "bitmap_flush_interval:%u", &val) == 1) + /* overloaded value for bitmap mode */ + tgt->u.integrity.journal_commit_time = val; + else if (sscanf(arg, "interleave_sectors:%u", &val) == 1) + tgt->u.integrity.interleave_sectors = val; + else if (sscanf(arg, "block_size:%u", &val) == 1) + tgt->u.integrity.sector_size = val; + else if (sscanf(arg, "buffer_sectors:%u", &val) == 1) + tgt->u.integrity.buffer_sectors = val; + else if (!strncmp(arg, "internal_hash:", 14) && !integrity) { + str = &arg[14]; + arg = strsep(&str, ":"); + if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) { + integrity = strdup(arg); + if (!integrity) { + r = -ENOMEM; goto err; - /* overloaded value for bitmap mode */ - tgt->u.integrity.journal_watermark = (unsigned int)val64; - } else if (sscanf(arg, "commit_time:%u", &val) == 1) - tgt->u.integrity.journal_commit_time = val; - else if (sscanf(arg, "bitmap_flush_interval:%u", &val) == 1) - /* overloaded value for bitmap mode */ - tgt->u.integrity.journal_commit_time = val; - else if (sscanf(arg, "interleave_sectors:%u", &val) == 1) - tgt->u.integrity.interleave_sectors = val; - else if (sscanf(arg, "block_size:%u", &val) == 1) - tgt->u.integrity.sector_size = val; - else if (sscanf(arg, "buffer_sectors:%u", &val) == 1) - tgt->u.integrity.buffer_sectors = val; - else if (!strncmp(arg, "internal_hash:", 14) && !integrity) { - str = &arg[14]; - arg = strsep(&str, ":"); - if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) { - integrity = strdup(arg); - if (!integrity) { - r = -ENOMEM; - goto err; - } } + } - if (str) { - len = crypt_hex_to_bytes(str, &str2, 1); - if (len < 0) { - r = len; - goto err; - } - - r = 0; - if (get_flags & DM_ACTIVE_CRYPT_KEY) { - vk = crypt_alloc_volume_key(len, str2); - if (!vk) - r = -ENOMEM; - } else if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) { - vk = crypt_alloc_volume_key(len, NULL); - if (!vk) - r = -ENOMEM; - } - crypt_safe_free(str2); - if (r < 0) - goto err; - } - } else if (!strncmp(arg, "meta_device:", 12) && !meta_device) { - if (get_flags & DM_ACTIVE_DEVICE) { - str = crypt_lookup_dev(&arg[12]); - r = device_alloc(cd, &meta_device, str); - free(str); - if (r < 0 && r != -ENOTBLK) - goto err; + if (str) { + len = crypt_hex_to_bytes(str, &str2, 1); + if (len < 0) { + r = len; + goto err; } - } else if (!strncmp(arg, "journal_crypt:", 14) && !journal_crypt) { - str = &arg[14]; - arg = strsep(&str, ":"); - if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) { - journal_crypt = strdup(arg); - if (!journal_crypt) { + + r = 0; + if (get_flags & DM_ACTIVE_CRYPT_KEY) { + vk = crypt_alloc_volume_key(len, str2); + if (!vk) + r = -ENOMEM; + } else if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) { + vk = crypt_alloc_volume_key(len, NULL); + if (!vk) r = -ENOMEM; - goto err; - } } + crypt_safe_free(str2); + if (r < 0) + goto err; + } + } else if (!strncmp(arg, "meta_device:", 12) && !meta_device) { + if (get_flags & DM_ACTIVE_DEVICE) { + str = crypt_lookup_dev(&arg[12]); + r = device_alloc(cd, &meta_device, str); + free(str); + if (r < 0 && r != -ENOTBLK) + goto err; + } + } else if (!strncmp(arg, "journal_crypt:", 14) && !journal_crypt) { + str = &arg[14]; + arg = strsep(&str, ":"); + if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) { + journal_crypt = strdup(arg); + if (!journal_crypt) { + r = -ENOMEM; + goto err; + } + } - if (str) { - len = crypt_hex_to_bytes(str, &str2, 1); - if (len < 0) { - r = len; - goto err; - } - - r = 0; - if (get_flags & DM_ACTIVE_JOURNAL_CRYPT_KEY) { - journal_crypt_key = crypt_alloc_volume_key(len, str2); - if (!journal_crypt_key) - r = -ENOMEM; - } else if (get_flags & DM_ACTIVE_JOURNAL_CRYPT_KEYSIZE) { - journal_crypt_key = crypt_alloc_volume_key(len, NULL); - if (!journal_crypt_key) - r = -ENOMEM; - } - crypt_safe_free(str2); - if (r < 0) - goto err; + if (str) { + len = crypt_hex_to_bytes(str, &str2, 1); + if (len < 0) { + r = len; + goto err; } - } else if (!strncmp(arg, "journal_mac:", 12) && !journal_integrity) { - str = &arg[12]; - arg = strsep(&str, ":"); - if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) { - journal_integrity = strdup(arg); - if (!journal_integrity) { + + r = 0; + if (get_flags & DM_ACTIVE_JOURNAL_CRYPT_KEY) { + journal_crypt_key = crypt_alloc_volume_key(len, str2); + if (!journal_crypt_key) + r = -ENOMEM; + } else if (get_flags & DM_ACTIVE_JOURNAL_CRYPT_KEYSIZE) { + journal_crypt_key = crypt_alloc_volume_key(len, NULL); + if (!journal_crypt_key) r = -ENOMEM; - goto err; - } } + crypt_safe_free(str2); + if (r < 0) + goto err; + } + } else if (!strncmp(arg, "journal_mac:", 12) && !journal_integrity) { + str = &arg[12]; + arg = strsep(&str, ":"); + if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) { + journal_integrity = strdup(arg); + if (!journal_integrity) { + r = -ENOMEM; + goto err; + } + } - if (str) { - len = crypt_hex_to_bytes(str, &str2, 1); - if (len < 0) { - r = len; - goto err; - } - - r = 0; - if (get_flags & DM_ACTIVE_JOURNAL_MAC_KEY) { - journal_integrity_key = crypt_alloc_volume_key(len, str2); - if (!journal_integrity_key) - r = -ENOMEM; - } else if (get_flags & DM_ACTIVE_JOURNAL_MAC_KEYSIZE) { - journal_integrity_key = crypt_alloc_volume_key(len, NULL); - if (!journal_integrity_key) - r = -ENOMEM; - } - crypt_safe_free(str2); - if (r < 0) - goto err; + if (str) { + len = crypt_hex_to_bytes(str, &str2, 1); + if (len < 0) { + r = len; + goto err; } - } else if (!strcmp(arg, "recalculate")) { - *act_flags |= CRYPT_ACTIVATE_RECALCULATE; - } else if (!strcmp(arg, "reset_recalculate")) { - *act_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET; - } else if (!strcmp(arg, "fix_padding")) { - tgt->u.integrity.fix_padding = true; - } else if (!strcmp(arg, "fix_hmac")) { - tgt->u.integrity.fix_hmac = true; - } else if (!strcmp(arg, "legacy_recalculate")) { - tgt->u.integrity.legacy_recalc = true; - } else if (!strcmp(arg, "allow_discards")) { - *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS; - } else /* unknown option */ - goto err; - } - /* All parameters should be processed */ - if (params && *params) { - r = -EINVAL; + r = 0; + if (get_flags & DM_ACTIVE_JOURNAL_MAC_KEY) { + journal_integrity_key = crypt_alloc_volume_key(len, str2); + if (!journal_integrity_key) + r = -ENOMEM; + } else if (get_flags & DM_ACTIVE_JOURNAL_MAC_KEYSIZE) { + journal_integrity_key = crypt_alloc_volume_key(len, NULL); + if (!journal_integrity_key) + r = -ENOMEM; + } + crypt_safe_free(str2); + if (r < 0) + goto err; + } + } else if (!strcmp(arg, "recalculate")) { + *act_flags |= CRYPT_ACTIVATE_RECALCULATE; + } else if (!strcmp(arg, "reset_recalculate")) { + *act_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET; + } else if (!strcmp(arg, "fix_padding")) { + tgt->u.integrity.fix_padding = true; + } else if (!strcmp(arg, "fix_hmac")) { + tgt->u.integrity.fix_hmac = true; + } else if (!strcmp(arg, "legacy_recalculate")) { + tgt->u.integrity.legacy_recalc = true; + } else if (!strcmp(arg, "allow_discards")) { + *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS; + } else /* unknown option */ goto err; - } + } + + /* All parameters should be processed */ + if (params && *params) { + r = -EINVAL; + goto err; } if (data_device) @@ -2639,7 +2718,7 @@ static int _dm_target_query_integrity(struct crypt_device *cd, } static int _dm_target_query_linear(struct crypt_device *cd, struct dm_target *tgt, - uint32_t get_flags, char *params) + uint64_t get_flags, char *params) { uint64_t val64; char *rdevice, *arg; @@ -2701,7 +2780,7 @@ static int _dm_target_query_zero(struct dm_target *tgt) */ static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const uint64_t *start, const uint64_t *length, const char *target_type, - char *params, uint32_t get_flags, uint32_t *act_flags) + char *params, uint64_t get_flags, uint32_t *act_flags) { int r = -ENOTSUP; @@ -2727,7 +2806,7 @@ static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const } static int _dm_query_device(struct crypt_device *cd, const char *name, - uint32_t get_flags, struct crypt_dm_active_device *dmd) + uint64_t get_flags, struct crypt_dm_active_device *dmd) { struct dm_target *t; struct dm_task *dmt; @@ -2828,7 +2907,7 @@ static int _dm_query_device(struct crypt_device *cd, const char *name, } int dm_query_device(struct crypt_device *cd, const char *name, - uint32_t get_flags, struct crypt_dm_active_device *dmd) + uint64_t get_flags, struct crypt_dm_active_device *dmd) { int r; @@ -2980,9 +3059,9 @@ static int _dm_message(const char *name, const char *msg) return r; } -int dm_suspend_device(struct crypt_device *cd, const char *name, uint32_t dmflags) +int dm_suspend_device(struct crypt_device *cd, const char *name, uint64_t dmflags) { - uint32_t dmt_flags; + uint64_t dmt_flags; int r = -ENOTSUP; if (dm_init_context(cd, DM_UNKNOWN)) @@ -3014,7 +3093,7 @@ int dm_suspend_device(struct crypt_device *cd, const char *name, uint32_t dmflag return r; } -int dm_resume_device(struct crypt_device *cd, const char *name, uint32_t dmflags) +int dm_resume_device(struct crypt_device *cd, const char *name, uint64_t dmflags) { int r; @@ -3031,7 +3110,7 @@ int dm_resume_device(struct crypt_device *cd, const char *name, uint32_t dmflags int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name, const struct volume_key *vk) { - uint32_t dmt_flags; + uint64_t dmt_flags; int msg_size; char *msg = NULL, *key = NULL; int r = -ENOTSUP; @@ -3042,12 +3121,12 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name, if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED)) goto out; - if (!vk->keylength) + if (!crypt_volume_key_length(vk)) msg_size = 11; // key set - - else if (vk->key_description) - msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18; + else if (crypt_volume_key_description(vk)) + msg_size = strlen(crypt_volume_key_description(vk)) + int_log10(crypt_volume_key_length(vk)) + 18; else - msg_size = vk->keylength * 2 + 10; // key set + msg_size = crypt_volume_key_length(vk) * 2 + 10; // key set msg = crypt_safe_alloc(msg_size); if (!msg) { @@ -3055,11 +3134,15 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name, goto out; } - if (vk->key_description) { - r = snprintf(msg, msg_size, "key set :%zu:logon:%s", vk->keylength, - vk->key_description); - } else { - key = crypt_bytes_to_hex(vk->keylength, vk->key); + if (crypt_volume_key_description(vk)) { + r = snprintf(msg, msg_size, "key set :%zu:logon:%s", crypt_volume_key_length(vk), + crypt_volume_key_description(vk)); + } else { + if (!crypt_volume_key_length(vk)) + key = crypt_bytes_to_hex(0, NULL); + else + key = crypt_bytes_to_hex(crypt_volume_key_length(vk), + crypt_volume_key_get_key(vk)); if (!key) { r = -ENOMEM; goto out; @@ -3106,6 +3189,54 @@ int dm_get_iname(const char *name, char **iname, bool with_path) return r < 0 ? -ENOMEM : 0; } +char *dm_get_active_iname(struct crypt_device *cd, const char *name) +{ + struct crypt_dm_active_device dmd = {}, dmdi = {}; + struct dm_target *tgt = &dmd.segment, *tgti = &dmdi.segment; + char *ipath = NULL, *iname = NULL, *ret_iname = NULL; + struct stat st; + + if (!name) + return NULL; + + if (dm_query_device(cd, name, DM_ACTIVE_UUID, &dmd) < 0) + return NULL; + + if (!single_segment(&dmd)) + goto out; + + if (tgt->type != DM_CRYPT || tgt->u.crypt.tag_size == 0) + goto out; + + if (dm_get_iname(name, &iname, false) < 0) + goto out; + + if (dm_get_iname(name, &ipath, true) < 0) + goto out; + + if (stat(ipath, &st) < 0 || !S_ISBLK(st.st_mode)) + goto out; + + if (dm_query_device(cd, iname, DM_ACTIVE_UUID, &dmdi) < 0) + goto out; + + if (single_segment(&dmdi) && + tgti->type == DM_INTEGRITY && + dm_uuid_integrity_cmp(dmd.uuid, dmdi.uuid) == 0) { + ret_iname = iname; + iname = NULL; + } +out: + dm_targets_free(cd, &dmdi); + dm_targets_free(cd, &dmd); + free(CONST_CAST(void*)dmd.uuid); + free(CONST_CAST(void*)dmdi.uuid); + free(ipath); + free(iname); + + return ret_iname; +} + int dm_is_dm_device(int major) { return dm_is_dm_major((uint32_t)major); @@ -3116,9 +3247,96 @@ int dm_is_dm_kernel_name(const char *name) return strncmp(name, "dm-", 3) ? 0 : 1; } +/* + * compares UUIDs returned by device-mapper (striped by cryptsetup) and uuid in header + */ +int dm_uuid_cmp(const char *dm_uuid, const char *hdr_uuid) +{ + int i, j; + const char *str; + + if (!dm_uuid || !hdr_uuid) + return -EINVAL; + + /* skip beyond LUKS2_HW_OPAL prefix */ + if (!strncmp(dm_uuid, CRYPT_LUKS2_HW_OPAL, strlen(CRYPT_LUKS2_HW_OPAL))) + dm_uuid = dm_uuid + strlen(CRYPT_LUKS2_HW_OPAL); + + str = strchr(dm_uuid, '-'); + if (!str) + return -EINVAL; + + for (i = 0, j = 1; hdr_uuid[i]; i++) { + if (hdr_uuid[i] == '-') + continue; + + if (!str[j] || str[j] == '-') + return -EINVAL; + + if (str[j] != hdr_uuid[i]) + return -EINVAL; + j++; + } + + return 0; +} + +/* + * compares two UUIDs returned by device-mapper (striped by cryptsetup) + * used for stacked LUKS2 & INTEGRITY devices + */ +int dm_uuid_integrity_cmp(const char *dm_uuid, const char *dmi_uuid) +{ + int i; + const char *str, *stri; + + if (!dm_uuid || !dmi_uuid) + return -EINVAL; + + /* skip beyond LUKS2_HW_OPAL prefix */ + if (!strncmp(dm_uuid, CRYPT_LUKS2_HW_OPAL, strlen(CRYPT_LUKS2_HW_OPAL))) + dm_uuid = dm_uuid + strlen(CRYPT_LUKS2_HW_OPAL); + + str = strchr(dm_uuid, '-'); + if (!str) + return -EINVAL; + + stri = strchr(dmi_uuid, '-'); + if (!stri) + return -EINVAL; + + for (i = 1; str[i] && str[i] != '-'; i++) { + if (!stri[i]) + return -EINVAL; + + if (str[i] != stri[i]) + return -EINVAL; + } + + return 0; +} + +/* + * compares type of active device to provided string + */ +int dm_uuid_type_cmp(const char *dm_uuid, const char *type) +{ + size_t len; + + assert(type); + + len = strlen(type); + if (dm_uuid && strlen(dm_uuid) > len && + !strncmp(dm_uuid, type, len) && dm_uuid[len] == '-') + return 0; + + return -ENODEV; +} + int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size, struct device *data_device, struct volume_key *vk, const char *cipher, - uint64_t iv_offset, uint64_t data_offset, const char *integrity, uint32_t tag_size, + uint64_t iv_offset, uint64_t data_offset, + const char *integrity, uint32_t integrity_key_size, uint32_t tag_size, uint32_t sector_size) { char *dm_integrity = NULL; @@ -3144,6 +3362,7 @@ int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg tgt->u.crypt.offset = data_offset; tgt->u.crypt.tag_size = tag_size; tgt->u.crypt.sector_size = sector_size; + tgt->u.crypt.integrity_key_size = integrity_key_size; return 0; } @@ -3183,7 +3402,7 @@ int dm_integrity_target_set(struct crypt_device *cd, struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key, const struct crypt_params_integrity *ip) { - uint32_t dmi_flags; + uint64_t dmi_flags; if (!data_device) return -EINVAL; diff --git a/lib/loopaes/loopaes.c b/lib/loopaes/loopaes.c index 8aec3de..bdd9ded 100644 --- a/lib/loopaes/loopaes.c +++ b/lib/loopaes/loopaes.c @@ -2,8 +2,8 @@ /* * loop-AES compatible volume handling * - * Copyright (C) 2011-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2011-2024 Milan Broz + * Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2025 Milan Broz */ #include @@ -69,6 +69,7 @@ static int hash_keys(struct crypt_device *cd, char tweak, *key_ptr; unsigned int i; int r = 0; + void *key = NULL; hash_name = hash_override ?: get_hash(key_len_output); tweak = get_tweak(keys_count); @@ -79,24 +80,30 @@ static int hash_keys(struct crypt_device *cd, return -EINVAL; } - *vk = crypt_alloc_volume_key((size_t)key_len_output * keys_count, NULL); - if (!*vk) + key = crypt_safe_alloc((size_t)key_len_output * keys_count); + if (!key) return -ENOMEM; for (i = 0; i < keys_count; i++) { - key_ptr = &(*vk)->key[i * key_len_output]; + key_ptr = &((char *)key)[i * key_len_output]; r = hash_key(input_keys[i], key_len_input, key_ptr, key_len_output, hash_name); if (r < 0) - break; + goto err; key_ptr[0] ^= tweak; } - if (r < 0 && *vk) { - crypt_free_volume_key(*vk); - *vk = NULL; + *vk = crypt_alloc_volume_key_by_safe_alloc(&key); + if (!*vk) { + r = -ENOMEM; + goto err; } + + return 0; +err: + crypt_safe_free(key); + *vk = NULL; return r; } @@ -191,7 +198,7 @@ int LOOPAES_activate(struct crypt_device *cd, uint32_t flags) { int r; - uint32_t req_flags, dmc_flags; + uint64_t req_flags, dmc_flags; char *cipher = NULL; struct crypt_dm_active_device dmd = { .flags = flags, @@ -213,9 +220,8 @@ int LOOPAES_activate(struct crypt_device *cd, return -ENOMEM; r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd), - vk, cipher, crypt_get_iv_offset(cd), - crypt_get_data_offset(cd), crypt_get_integrity(cd), - crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd)); + vk, cipher, crypt_get_iv_offset(cd), crypt_get_data_offset(cd), + NULL, 0, 0, crypt_get_sector_size(cd)); if (r) { free(cipher); diff --git a/lib/loopaes/loopaes.h b/lib/loopaes/loopaes.h index 878f2da..425ca22 100644 --- a/lib/loopaes/loopaes.h +++ b/lib/loopaes/loopaes.h @@ -2,8 +2,8 @@ /* * loop-AES compatible volume handling * - * Copyright (C) 2011-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2011-2024 Milan Broz + * Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2025 Milan Broz */ #ifndef _LOOPAES_H diff --git a/lib/luks1/af.c b/lib/luks1/af.c index e312b30..7ab153d 100644 --- a/lib/luks1/af.c +++ b/lib/luks1/af.c @@ -3,7 +3,7 @@ * AFsplitter - Anti forensic information splitter * * Copyright (C) 2004 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. * * AFsplitter diffuses information over a large stripe of data, * therefore supporting secure data destruction. diff --git a/lib/luks1/af.h b/lib/luks1/af.h index 0dcd233..08f3757 100644 --- a/lib/luks1/af.h +++ b/lib/luks1/af.h @@ -3,7 +3,7 @@ * AFsplitter - Anti forensic information splitter * * Copyright (C) 2004 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. */ #ifndef INCLUDED_CRYPTSETUP_LUKS_AF_H diff --git a/lib/luks1/keyencryption.c b/lib/luks1/keyencryption.c index 63e47fc..de8aa30 100644 --- a/lib/luks1/keyencryption.c +++ b/lib/luks1/keyencryption.c @@ -3,8 +3,8 @@ * LUKS - Linux Unified Key Setup * * Copyright (C) 2004-2006 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Milan Broz */ #include @@ -18,7 +18,8 @@ static void _error_hint(struct crypt_device *ctx, const char *device, const char *cipher, const char *mode, size_t keyLength) { - char *c, cipher_spec[MAX_CIPHER_LEN * 3]; + const char *c; + char cipher_spec[MAX_CIPHER_LEN * 3]; if (snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", cipher, mode) < 0) return; @@ -88,7 +89,7 @@ static int LUKS_endec_template(char *src, size_t srcLength, r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_metadata_device(ctx), vk, cipher_spec, 0, sector, - NULL, 0, SECTOR_SIZE); + NULL, 0, 0, SECTOR_SIZE); if (r) goto out; @@ -96,7 +97,7 @@ static int LUKS_endec_template(char *src, size_t srcLength, if (r < 0) { if (r != -EACCES && r != -ENOTSUP) _error_hint(ctx, device_path(crypt_metadata_device(ctx)), - cipher, cipher_mode, vk->keylength * 8); + cipher, cipher_mode, crypt_volume_key_length(vk) * 8); r = -EIO; goto out; } @@ -140,7 +141,8 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength, return -EINVAL; /* Encrypt buffer */ - r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false); + r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk), false); if (r) log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).", @@ -153,7 +155,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength, if (r) { _error_hint(ctx, device_path(device), cipher, cipher_mode, - vk->keylength * 8); + crypt_volume_key_length(vk) * 8); return r; } @@ -205,7 +207,8 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength, if (MISALIGNED_512(dstLength)) return -EINVAL; - r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false); + r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk), false); if (r) log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).", @@ -218,7 +221,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength, if (r) { _error_hint(ctx, device_path(device), cipher, cipher_mode, - vk->keylength * 8); + crypt_volume_key_length(vk) * 8); return r; } diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 5d8fe96..3792981 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -3,8 +3,8 @@ * LUKS - Linux Unified Key Setup * * Copyright (C) 2004-2006 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2013-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2013-2025 Milan Broz */ #include @@ -378,7 +378,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx) { struct luks_phdr temp_phdr; const unsigned char *sector = (const unsigned char*)phdr; - struct volume_key *vk; + struct volume_key *fake_vk; int i, bad, r, need_write = 0; if (phdr->keyBytes != 16 && phdr->keyBytes != 32 && phdr->keyBytes != 64) { @@ -424,8 +424,8 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx) if (r < 0) return -EINVAL; - vk = crypt_alloc_volume_key(phdr->keyBytes, NULL); - if (!vk) + fake_vk = crypt_generate_volume_key(ctx, phdr->keyBytes, KEY_QUALITY_EMPTY); + if (!fake_vk) return -ENOMEM; log_verbose(ctx, _("Repairing keyslots.")); @@ -433,7 +433,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx) log_dbg(ctx, "Generating second header with the same parameters for check."); /* cipherName, cipherMode, hashSpec, uuid are already null terminated */ /* payloadOffset - cannot check */ - r = LUKS_generate_phdr(&temp_phdr, vk, phdr->cipherName, phdr->cipherMode, + r = LUKS_generate_phdr(&temp_phdr, fake_vk, phdr->cipherName, phdr->cipherMode, phdr->hashSpec, phdr->uuid, phdr->payloadOffset * SECTOR_SIZE, 0, 0, ctx); if (r < 0) @@ -492,7 +492,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx) out: if (r) log_err(ctx, _("Repair failed.")); - crypt_free_volume_key(vk); + crypt_free_volume_key(fake_vk); crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr)); return r; } @@ -710,14 +710,12 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci log_dbg(ctx, "Checking if cipher %s-%s is usable.", cipher, cipher_mode); - empty_key = crypt_alloc_volume_key(keylength, NULL); + /* No need to get KEY quality random but it must avoid known weak keys. */ + empty_key = crypt_generate_volume_key(ctx, keylength, KEY_QUALITY_NORMAL); if (!empty_key) return -ENOMEM; - /* No need to get KEY quality random but it must avoid known weak keys. */ - r = crypt_random_get(ctx, empty_key->key, empty_key->keylength, CRYPT_RND_NORMAL); - if (!r) - r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx); + r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx); crypt_free_volume_key(empty_key); crypt_safe_memzero(buf, sizeof(buf)); @@ -748,7 +746,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, memset(header, 0, sizeof(struct luks_phdr)); - keyslot_sectors = AF_split_sectors(vk->keylength, LUKS_STRIPES); + keyslot_sectors = AF_split_sectors(crypt_volume_key_length(vk), LUKS_STRIPES); header_sectors = LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE; for (i = 0; i < LUKS_NUMKEYS; i++) { @@ -795,7 +793,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L-1); _to_lower(header->hashSpec, LUKS_HASHSPEC_L); - header->keyBytes=vk->keylength; + header->keyBytes = crypt_volume_key_length(vk); log_dbg(ctx, "Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes", header->version, header->hashSpec ,header->cipherName, header->cipherMode, @@ -809,7 +807,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, /* Compute volume key digest */ pbkdf = crypt_get_pbkdf(ctx); - r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, vk->keylength); + r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk)); if (r < 0) return r; assert(pbkdf->iterations); @@ -824,7 +822,9 @@ int LUKS_generate_phdr(struct luks_phdr *header, header->mkDigestIterations = AT_LEAST((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN); assert(header->mkDigestIterations); - r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, vk->key,vk->keylength, + r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, + crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk), header->mkDigestSalt, LUKS_SALTSIZE, header->mkDigest,LUKS_DIGESTSIZE, header->mkDigestIterations, 0, 0); @@ -866,8 +866,9 @@ int LUKS_set_key(unsigned int keyIndex, struct luks_phdr *hdr, struct volume_key *vk, struct crypt_device *ctx) { - struct volume_key *derived_key; + struct volume_key *derived_vk = NULL; char *AfKey = NULL; + void *derived_key = NULL; size_t AFEKSize; struct crypt_pbkdf_type *pbkdf; int r; @@ -886,7 +887,7 @@ int LUKS_set_key(unsigned int keyIndex, log_dbg(ctx, "Calculating data for key slot %d", keyIndex); pbkdf = crypt_get_pbkdf(ctx); - r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, vk->keylength); + r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk)); if (r < 0) return r; assert(pbkdf->iterations); @@ -899,9 +900,11 @@ int LUKS_set_key(unsigned int keyIndex, log_dbg(ctx, "Key slot %d use %" PRIu32 " password iterations.", keyIndex, hdr->keyblock[keyIndex].passwordIterations); - derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL); - if (!derived_key) - return -ENOMEM; + derived_key = crypt_safe_alloc(hdr->keyBytes); + if (!derived_key) { + r = -ENOMEM; + goto out; + } r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE, CRYPT_RND_SALT); @@ -910,7 +913,7 @@ int LUKS_set_key(unsigned int keyIndex, r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen, hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE, - derived_key->key, hdr->keyBytes, + derived_key, hdr->keyBytes, hdr->keyblock[keyIndex].passwordIterations, 0, 0); if (r < 0) { if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) && @@ -919,11 +922,17 @@ int LUKS_set_key(unsigned int keyIndex, goto out; } + derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key); + if (!derived_vk) { + r = -ENOMEM; + goto out; + } + /* * AF splitting, the volume key stored in vk->key is split to AfKey */ - assert(vk->keylength == hdr->keyBytes); - AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE; + assert(crypt_volume_key_length(vk) == hdr->keyBytes); + AFEKSize = AF_split_sectors(crypt_volume_key_length(vk), hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE; AfKey = crypt_safe_alloc(AFEKSize); if (!AfKey) { r = -ENOMEM; @@ -932,7 +941,8 @@ int LUKS_set_key(unsigned int keyIndex, log_dbg(ctx, "Using hash %s for AF in key slot %d, %d stripes", hdr->hashSpec, keyIndex, hdr->keyblock[keyIndex].stripes); - r = AF_split(ctx, vk->key, AfKey, vk->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec); + r = AF_split(ctx, crypt_volume_key_get_key(vk), AfKey, crypt_volume_key_length(vk), + hdr->keyblock[keyIndex].stripes, hdr->hashSpec); if (r < 0) goto out; @@ -942,7 +952,7 @@ int LUKS_set_key(unsigned int keyIndex, r = LUKS_encrypt_to_storage(AfKey, AFEKSize, hdr->cipherName, hdr->cipherMode, - derived_key, + derived_vk, hdr->keyblock[keyIndex].keyMaterialOffset, ctx); if (r < 0) @@ -960,7 +970,8 @@ int LUKS_set_key(unsigned int keyIndex, r = 0; out: crypt_safe_free(AfKey); - crypt_free_volume_key(derived_key); + crypt_safe_free(derived_key); + crypt_free_volume_key(derived_vk); return r; } @@ -970,7 +981,8 @@ int LUKS_verify_volume_key(const struct luks_phdr *hdr, { char checkHashBuf[LUKS_DIGESTSIZE]; - if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, vk->key, vk->keylength, + if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk), hdr->mkDigestSalt, LUKS_SALTSIZE, checkHashBuf, LUKS_DIGESTSIZE, hdr->mkDigestIterations, 0, 0) < 0) @@ -987,12 +999,13 @@ static int LUKS_open_key(unsigned int keyIndex, const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct volume_key **vk, + struct volume_key **r_vk, struct crypt_device *ctx) { crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex); - struct volume_key *derived_key; + struct volume_key *derived_vk = NULL, *vk = NULL; char *AfKey = NULL; + void *key = NULL, *derived_key = NULL; size_t AFEKSize; int r; @@ -1002,12 +1015,12 @@ static int LUKS_open_key(unsigned int keyIndex, if (ki < CRYPT_SLOT_ACTIVE) return -ENOENT; - derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL); + derived_key = crypt_safe_alloc(hdr->keyBytes); if (!derived_key) return -ENOMEM; - *vk = crypt_alloc_volume_key(hdr->keyBytes, NULL); - if (!*vk) { + key = crypt_safe_alloc(hdr->keyBytes); + if (!key) { r = -ENOMEM; goto out; } @@ -1021,39 +1034,57 @@ static int LUKS_open_key(unsigned int keyIndex, r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen, hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE, - derived_key->key, hdr->keyBytes, + derived_key, hdr->keyBytes, hdr->keyblock[keyIndex].passwordIterations, 0, 0); if (r < 0) { log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec); goto out; } + derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key); + if (!derived_vk) { + r = -ENOMEM; + goto out; + } + log_dbg(ctx, "Reading key slot %d area.", keyIndex); r = LUKS_decrypt_from_storage(AfKey, AFEKSize, hdr->cipherName, hdr->cipherMode, - derived_key, + derived_vk, hdr->keyblock[keyIndex].keyMaterialOffset, ctx); if (r < 0) goto out; - r = AF_merge(AfKey, (*vk)->key, (*vk)->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec); + r = AF_merge(AfKey, key, hdr->keyBytes, hdr->keyblock[keyIndex].stripes, hdr->hashSpec); if (r < 0) goto out; - r = LUKS_verify_volume_key(hdr, *vk); + vk = crypt_alloc_volume_key_by_safe_alloc(&key); + if (!vk) { + r = -ENOMEM; + goto out; + } + + r = LUKS_verify_volume_key(hdr, vk); + if (r < 0) + goto out; /* Allow only empty passphrase with null cipher */ - if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen) + if (crypt_is_cipher_null(hdr->cipherName) && passwordLen) r = -EPERM; + else + *r_vk = vk; out: if (r < 0) { - crypt_free_volume_key(*vk); - *vk = NULL; + crypt_free_volume_key(vk); + *r_vk = NULL; } crypt_safe_free(AfKey); - crypt_free_volume_key(derived_key); + crypt_safe_free(key); + crypt_safe_free(derived_key); + crypt_free_volume_key(derived_vk); return r; } @@ -1204,8 +1235,7 @@ int LUKS1_activate(struct crypt_device *cd, r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd), vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd), - crypt_get_data_offset(cd), crypt_get_integrity(cd), - crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd)); + crypt_get_data_offset(cd), NULL, 0, 0, crypt_get_sector_size(cd)); if (!r) r = create_or_reload_device(cd, name, CRYPT_LUKS1, &dmd); diff --git a/lib/luks1/luks.h b/lib/luks1/luks.h index befdc3a..80f6544 100644 --- a/lib/luks1/luks.h +++ b/lib/luks1/luks.h @@ -3,7 +3,7 @@ * LUKS - Linux Unified Key Setup * * Copyright (C) 2004-2006 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. */ #ifndef INCLUDED_CRYPTSETUP_LUKS_LUKS_H diff --git a/lib/luks2/hw_opal/hw_opal.c b/lib/luks2/hw_opal/hw_opal.c index a56e882..3256393 100644 --- a/lib/luks2/hw_opal/hw_opal.c +++ b/lib/luks2/hw_opal/hw_opal.c @@ -3,7 +3,8 @@ * OPAL utilities * * Copyright (C) 2022-2023 Luca Boccassi - * 2023 Ondrej Kozina + * Copyright (C) 2023-2025 Ondrej Kozina + * Copyright (C) 2024-2025 Milan Broz */ #include @@ -16,7 +17,7 @@ #include #include #include -#ifdef HAVE_SYS_SYSMACROS_H +#if HAVE_SYS_SYSMACROS_H # include /* for major, minor */ #endif @@ -35,33 +36,32 @@ * Section 5.1.5: Method Status Codes * Names and values from table 166 */ typedef enum OpalStatus { - OPAL_STATUS_SUCCESS, - OPAL_STATUS_NOT_AUTHORIZED, - OPAL_STATUS_OBSOLETE0, /* Undefined but possible return values are called 'obsolete' */ - OPAL_STATUS_SP_BUSY, - OPAL_STATUS_SP_FAILED, - OPAL_STATUS_SP_DISABLED, - OPAL_STATUS_SP_FROZEN, - OPAL_STATUS_NO_SESSIONS_AVAILABLE, - OPAL_STATUS_UNIQUENESS_CONFLICT, - OPAL_STATUS_INSUFFICIENT_SPACE, - OPAL_STATUS_INSUFFICIENT_ROWS, - OPAL_STATUS_INVALID_PARAMETER, - OPAL_STATUS_OBSOLETE1, - OPAL_STATUS_OBSOLETE2, - OPAL_STATUS_TPER_MALFUNCTION, - OPAL_STATUS_TRANSACTION_FAILURE, - OPAL_STATUS_RESPONSE_OVERFLOW, - OPAL_STATUS_AUTHORITY_LOCKED_OUT, - OPAL_STATUS_FAIL = 0x3F, /* As defined by specification */ - _OPAL_STATUS_MAX, - _OPAL_STATUS_INVALID = -EINVAL, + OPAL_STATUS_SUCCESS = 0x00, + OPAL_STATUS_NOT_AUTHORIZED = 0x01, + OPAL_STATUS_OBSOLETE0 = 0x02, /* Undefined but possible return values are called 'obsolete' */ + OPAL_STATUS_SP_BUSY = 0x03, + OPAL_STATUS_SP_FAILED = 0x04, + OPAL_STATUS_SP_DISABLED = 0x05, + OPAL_STATUS_SP_FROZEN = 0x06, + OPAL_STATUS_NO_SESSIONS_AVAILABLE = 0x07, + OPAL_STATUS_UNIQUENESS_CONFLICT = 0x08, + OPAL_STATUS_INSUFFICIENT_SPACE = 0x09, + OPAL_STATUS_INSUFFICIENT_ROWS = 0x0a, + OPAL_STATUS_OBSOLETE1 = 0x0b, /* Undefined but possible return values are called 'obsolete' */ + OPAL_STATUS_INVALID_PARAMETER = 0x0c, + OPAL_STATUS_OBSOLETE2 = 0x0d, + OPAL_STATUS_OBSOLETE3 = 0x0e, + OPAL_STATUS_TPER_MALFUNCTION = 0x0f, + OPAL_STATUS_TRANSACTION_FAILURE = 0x10, + OPAL_STATUS_RESPONSE_OVERFLOW = 0x11, + OPAL_STATUS_AUTHORITY_LOCKED_OUT = 0x12, + _OPAL_STATUS_MAX = 0x13, } OpalStatus; static const char* const opal_status_table[_OPAL_STATUS_MAX] = { [OPAL_STATUS_SUCCESS] = "success", [OPAL_STATUS_NOT_AUTHORIZED] = "not authorized", - [OPAL_STATUS_OBSOLETE0] = "obsolete", + [OPAL_STATUS_OBSOLETE0] = "obsolete (0x02)", [OPAL_STATUS_SP_BUSY] = "SP busy", [OPAL_STATUS_SP_FAILED] = "SP failed", [OPAL_STATUS_SP_DISABLED] = "SP disabled", @@ -70,14 +70,14 @@ static const char* const opal_status_table[_OPAL_STATUS_MAX] = { [OPAL_STATUS_UNIQUENESS_CONFLICT] = "uniqueness conflict", [OPAL_STATUS_INSUFFICIENT_SPACE] = "insufficient space", [OPAL_STATUS_INSUFFICIENT_ROWS] = "insufficient rows", + [OPAL_STATUS_OBSOLETE1] = "obsolete (0x0b)", [OPAL_STATUS_INVALID_PARAMETER] = "invalid parameter", - [OPAL_STATUS_OBSOLETE1] = "obsolete", - [OPAL_STATUS_OBSOLETE2] = "obsolete", + [OPAL_STATUS_OBSOLETE2] = "obsolete (0x0d)", + [OPAL_STATUS_OBSOLETE3] = "obsolete (0x0e)", [OPAL_STATUS_TPER_MALFUNCTION] = "TPer malfunction", [OPAL_STATUS_TRANSACTION_FAILURE] = "transaction failure", [OPAL_STATUS_RESPONSE_OVERFLOW] = "response overflow", [OPAL_STATUS_AUTHORITY_LOCKED_OUT] = "authority locked out", - [OPAL_STATUS_FAIL] = "unknown failure", }; static const char *opal_status_to_string(int t) @@ -85,6 +85,10 @@ static const char *opal_status_to_string(int t) if (t < 0) return strerror(-t); + /* Fail, as defined by specification */ + if (t == 0x3f) + return "unknown failure"; + if (t >= _OPAL_STATUS_MAX) return "unknown error"; @@ -232,6 +236,8 @@ static int opal_ioctl(struct crypt_device *cd, int fd, unsigned long rq, void *a opal_ioctl_debug(cd, rq, args, false, 0); r = ioctl(fd, rq, args); + if (r < 0) + r = -errno; opal_ioctl_debug(cd, rq, args, true, r); return r; @@ -306,12 +312,13 @@ static int opal_range_check_attributes_fd(struct crypt_device *cd, .session = { .who = segment_number + 1, .opal_key = { - .key_len = vk->keylength, + .key_len = crypt_volume_key_length(vk), .lr = segment_number } } }; - memcpy(lrs->session.opal_key.key, vk->key, vk->keylength); + crypt_safe_memcpy(lrs->session.opal_key.key, crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk)); r = opal_ioctl(cd, fd, IOC_OPAL_GET_LR_STATUS, lrs); if (r != OPAL_STATUS_SUCCESS) { @@ -413,7 +420,7 @@ int opal_setup_ranges(struct crypt_device *cd, assert(dev); assert(vk); assert(admin_key); - assert(vk->keylength <= OPAL_KEY_MAX); + assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX); assert(opal_block_bytes >= SECTOR_SIZE); if (admin_key_len > OPAL_KEY_MAX) @@ -448,7 +455,7 @@ int opal_setup_ranges(struct crypt_device *cd, */ .lr = { 1, 2, 3, 4, 5, 6, 7, 8 }, }; - memcpy(activate->key.key, admin_key, admin_key_len); + crypt_safe_memcpy(activate->key.key, admin_key, admin_key_len); r = opal_ioctl(cd, fd, IOC_OPAL_TAKE_OWNERSHIP, &activate->key); if (r < 0) { @@ -470,6 +477,8 @@ int opal_setup_ranges(struct crypt_device *cd, } r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_LSP, activate); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { log_dbg(cd, "Failed to activate OPAL device '%s': %s", crypt_get_device_name(cd), opal_status_to_string(r)); @@ -490,19 +499,16 @@ int opal_setup_ranges(struct crypt_device *cd, .key_len = admin_key_len, }, }; - memcpy(user_session->opal_key.key, admin_key, admin_key_len); + crypt_safe_memcpy(user_session->opal_key.key, admin_key, admin_key_len); - r = opal_ioctl(cd, fd, IOC_OPAL_ERASE_LR, user_session); + r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { - log_dbg(cd, "Failed to reset (erase) OPAL locking range %u on device '%s': %s", + log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s", segment_number, crypt_get_device_name(cd), opal_status_to_string(r)); - r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session); - if (r != OPAL_STATUS_SUCCESS) { - log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s", - segment_number, crypt_get_device_name(cd), opal_status_to_string(r)); - r = -EINVAL; - goto out; - } + r = -EINVAL; + goto out; } } @@ -519,9 +525,11 @@ int opal_setup_ranges(struct crypt_device *cd, .key_len = admin_key_len, }, }; - memcpy(user_session->opal_key.key, admin_key, admin_key_len); + crypt_safe_memcpy(user_session->opal_key.key, admin_key, admin_key_len); r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_USR, user_session); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { log_dbg(cd, "Failed to activate OPAL user on device '%s': %s", crypt_get_device_name(cd), opal_status_to_string(r)); @@ -544,9 +552,11 @@ int opal_setup_ranges(struct crypt_device *cd, }, .l_state = OPAL_RO, }; - memcpy(user_add_to_lr->session.opal_key.key, admin_key, admin_key_len); + crypt_safe_memcpy(user_add_to_lr->session.opal_key.key, admin_key, admin_key_len); r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { log_dbg(cd, "Failed to add OPAL user to locking range %u (RO) on device '%s': %s", segment_number, crypt_get_device_name(cd), opal_status_to_string(r)); @@ -555,6 +565,8 @@ int opal_setup_ranges(struct crypt_device *cd, } user_add_to_lr->l_state = OPAL_RW; r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { log_dbg(cd, "Failed to add OPAL user to locking range %u (RW) on device '%s': %s", segment_number, crypt_get_device_name(cd), opal_status_to_string(r)); @@ -578,15 +590,18 @@ int opal_setup_ranges(struct crypt_device *cd, .new_user_pw = { .who = segment_number + 1, .opal_key = { - .key_len = vk->keylength, + .key_len = crypt_volume_key_length(vk), .lr = segment_number, }, }, }; - memcpy(new_pw->new_user_pw.opal_key.key, vk->key, vk->keylength); - memcpy(new_pw->session.opal_key.key, admin_key, admin_key_len); + crypt_safe_memcpy(new_pw->new_user_pw.opal_key.key, crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk)); + crypt_safe_memcpy(new_pw->session.opal_key.key, admin_key, admin_key_len); r = opal_ioctl(cd, fd, IOC_OPAL_SET_PW, new_pw); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { log_dbg(cd, "Failed to set OPAL user password on device '%s': (%d) %s", crypt_get_device_name(cd), r, opal_status_to_string(r)); @@ -616,9 +631,11 @@ int opal_setup_ranges(struct crypt_device *cd, }, }, }; - memcpy(setup->session.opal_key.key, admin_key, admin_key_len); + crypt_safe_memcpy(setup->session.opal_key.key, admin_key, admin_key_len); r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { log_dbg(cd, "Failed to setup locking range of length %llu at offset %llu on OPAL device '%s': %s", setup->range_length, setup->range_start, crypt_get_device_name(cd), opal_status_to_string(r)); @@ -638,14 +655,17 @@ int opal_setup_ranges(struct crypt_device *cd, .session = { .who = segment_number + 1, .opal_key = { - .key_len = vk->keylength, + .key_len = crypt_volume_key_length(vk), .lr = segment_number, }, } }; - memcpy(lock->session.opal_key.key, vk->key, vk->keylength); + crypt_safe_memcpy(lock->session.opal_key.key, crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk)); r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, lock); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { log_dbg(cd, "Failed to lock OPAL device '%s': %s", crypt_get_device_name(cd), opal_status_to_string(r)); @@ -696,10 +716,11 @@ static int opal_lock_unlock(struct crypt_device *cd, return -EIO; if (!lock) { - assert(vk->keylength <= OPAL_KEY_MAX); + assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX); - unlock.session.opal_key.key_len = vk->keylength; - memcpy(unlock.session.opal_key.key, vk->key, vk->keylength); + unlock.session.opal_key.key_len = crypt_volume_key_length(vk); + crypt_safe_memcpy(unlock.session.opal_key.key, crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk)); } r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, &unlock); @@ -734,6 +755,8 @@ static int opal_lock_unlock(struct crypt_device *cd, unlock.flags = OPAL_SAVE_FOR_LOCK; r = opal_ioctl(cd, fd, IOC_OPAL_SAVE, &unlock); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { if (!lock) log_std(cd, "Failed to prepare OPAL device '%s' for sleep resume, be aware before suspending: %s", @@ -787,11 +810,15 @@ int opal_factory_reset(struct crypt_device *cd, if (password_len > OPAL_KEY_MAX) return -EINVAL; - fd = device_open(cd, dev, O_RDONLY); + /* + * Submit PSID reset on R/W file descriptor so it + * triggers blkid rescan after we close it. + */ + fd = device_open(cd, dev, O_RDWR); if (fd < 0) return -EIO; - memcpy(reset.key, password, password_len); + crypt_safe_memcpy(reset.key, password, password_len); r = opal_ioctl(cd, fd, IOC_OPAL_PSID_REVERT_TPR, &reset); if (r < 0) { @@ -848,7 +875,7 @@ int opal_reset_segment(struct crypt_device *cd, .key_len = password_len, }, }; - memcpy(user_session->opal_key.key, password, password_len); + crypt_safe_memcpy(user_session->opal_key.key, password, password_len); fd = device_open(cd, dev, O_RDONLY); if (fd < 0) { @@ -856,42 +883,39 @@ int opal_reset_segment(struct crypt_device *cd, goto out; } - r = opal_ioctl(cd, fd, IOC_OPAL_ERASE_LR, user_session); + r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session); + if (r < 0) + goto out; if (r != OPAL_STATUS_SUCCESS) { - log_dbg(cd, "Failed to reset (erase) OPAL locking range %u on device '%s': %s", + log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s", segment_number, crypt_get_device_name(cd), opal_status_to_string(r)); - r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session); - if (r != OPAL_STATUS_SUCCESS) { - log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s", - segment_number, crypt_get_device_name(cd), opal_status_to_string(r)); - r = -EINVAL; - goto out; - } + r = -EINVAL; + goto out; + } - /* Unlike IOC_OPAL_ERASE_LR, IOC_OPAL_SECURE_ERASE_LR does not disable the locking range, - * we have to do that by hand. - */ - setup = crypt_safe_alloc(sizeof(struct opal_user_lr_setup)); - if (!setup) { - r = -ENOMEM; - goto out; - } - *setup = (struct opal_user_lr_setup) { - .range_start = 0, - .range_length = 0, - .session = { - .who = OPAL_ADMIN1, - .opal_key = user_session->opal_key, - }, - }; + /* Disable the locking range */ + setup = crypt_safe_alloc(sizeof(struct opal_user_lr_setup)); + if (!setup) { + r = -ENOMEM; + goto out; + } + *setup = (struct opal_user_lr_setup) { + .range_start = 0, + .range_length = 0, + .session = { + .who = OPAL_ADMIN1, + .opal_key = user_session->opal_key, + }, + }; - r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup); - if (r != OPAL_STATUS_SUCCESS) { - log_dbg(cd, "Failed to disable locking range on OPAL device '%s': %s", - crypt_get_device_name(cd), opal_status_to_string(r)); - r = -EINVAL; - goto out; - } + r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup); + if (r < 0) + goto out; + if (r != OPAL_STATUS_SUCCESS) { + log_dbg(cd, "Failed to disable locking range on OPAL device '%s': %s", + crypt_get_device_name(cd), opal_status_to_string(r)); + r = -EINVAL; + goto out; } out: crypt_safe_free(user_session); diff --git a/lib/luks2/hw_opal/hw_opal.h b/lib/luks2/hw_opal/hw_opal.h index f25c2b6..f0058a5 100644 --- a/lib/luks2/hw_opal/hw_opal.h +++ b/lib/luks2/hw_opal/hw_opal.h @@ -3,7 +3,8 @@ * OPAL utilities * * Copyright (C) 2022-2023 Luca Boccassi - * 2023 Ondrej Kozina + * Copyright (C) 2023-2025 Ondrej Kozina + * Copyright (C) 2024-2025 Milan Broz */ #ifndef _UTILS_OPAL diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h index 609162f..30568db 100644 --- a/lib/luks2/luks2.h +++ b/lib/luks2/luks2.h @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2 * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #ifndef _CRYPTSETUP_LUKS2_ONDISK_H @@ -37,6 +37,8 @@ #define LUKS2_DIGEST_MAX 8 +#define LUKS2_MIN_INTEGRITY_KEY_BYTES 16 + #define CRYPT_ANY_SEGMENT -1 #define CRYPT_DEFAULT_SEGMENT -2 #define CRYPT_ONE_SEGMENT -3 @@ -109,6 +111,7 @@ struct luks2_hdr { char uuid[LUKS2_UUID_L]; void *jobj; void *jobj_rollback; + size_t on_disk_json_end_offset; }; struct luks2_keyslot_params { @@ -196,11 +199,11 @@ int LUKS2_keyslot_open(struct crypt_device *cd, size_t password_len, struct volume_key **vk); -int LUKS2_keyslot_open_all_segments(struct crypt_device *cd, +int LUKS2_keyslot_context_open_all_segments(struct crypt_device *cd, int keyslot_old, int keyslot_new, - const char *password, - size_t password_len, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, struct volume_key **vks); int LUKS2_keyslot_store(struct crypt_device *cd, @@ -228,6 +231,24 @@ int LUKS2_keyslot_swap(struct crypt_device *cd, int keyslot, int keyslot2); +/* + * Segments + */ + +bool LUKS2_segment_set_size(struct luks2_hdr *hdr, + int segment, + const uint64_t *segment_size_bytes); + +bool LUKS2_segment_is_hw_opal(struct luks2_hdr *hdr, int segment); +bool LUKS2_segment_is_hw_opal_crypt(struct luks2_hdr *hdr, int segment); +bool LUKS2_segment_is_hw_opal_only(struct luks2_hdr *hdr, int segment); + +int LUKS2_get_opal_segment_number(struct luks2_hdr *hdr, int segment, + uint32_t *ret_opal_segment_number); +int LUKS2_get_opal_key_size(struct luks2_hdr *hdr, int segment); + +bool LUKS2_segments_dynamic_size(struct luks2_hdr *hdr); + /* * Generic LUKS2 token */ @@ -263,17 +284,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd, int token, const char **type); -int LUKS2_token_open_and_activate(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int token, - const char *name, - const char *type, - const char *pin, - size_t pin_size, - uint32_t flags, - void *usrptr); - int LUKS2_token_unlock_key(struct crypt_device *cd, struct luks2_hdr *hdr, int keyslot, @@ -307,8 +317,7 @@ void crypt_token_unload_external_all(struct crypt_device *cd); /* * Generic LUKS2 digest */ -int LUKS2_digest_any_matching(struct crypt_device *cd, - struct luks2_hdr *hdr, +int LUKS2_digest_verify_by_any_matching(struct crypt_device *cd, const struct volume_key *vk); int LUKS2_digest_verify_by_segment(struct crypt_device *cd, @@ -371,6 +380,7 @@ int LUKS2_generate_hdr( const struct volume_key *vk, const char *cipher_spec, const char *integrity, + uint32_t integrity_key_size, /* in bytes, only if separate (HMAC) */ const char *uuid, unsigned int sector_size, uint64_t data_offset, @@ -398,8 +408,10 @@ int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic); uint32_t LUKS2_get_sector_size(struct luks2_hdr *hdr); const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment); const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment); +int LUKS2_get_integrity_key_size(struct luks2_hdr *hdr, int segment); int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr, struct luks2_keyslot_params *params); +int LUKS2_get_old_volume_key_size(struct luks2_hdr *hdr); int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment); int LUKS2_get_keyslot_stored_key_size(struct luks2_hdr *hdr, int keyslot); const char *LUKS2_get_keyslot_cipher(struct luks2_hdr *hdr, int keyslot, size_t *key_size); @@ -427,7 +439,7 @@ int LUKS2_config_set_flags(struct crypt_device *cd, struct luks2_hdr *hdr, uint3 /* * Requirements for device activation or header modification */ -int LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs); +void LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs); int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs, bool commit); int LUKS2_config_set_requirement_version(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t req_id, uint8_t req_version, bool commit); @@ -435,12 +447,10 @@ int LUKS2_config_get_reencrypt_version(struct luks2_hdr *hdr, uint8_t *version); bool LUKS2_reencrypt_requirement_candidate(struct luks2_hdr *hdr); -int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet); +int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t reqs_mask, int quiet); int LUKS2_key_description_by_segment(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vk, int segment); -int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd, - struct luks2_hdr *hdr, struct volume_key *vk, int keyslot); int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd, struct volume_key *vk, int digest); @@ -454,13 +464,6 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, /* * LUKS2 reencryption */ -int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd, - int keyslot_old, - int keyslot_new, - const char *passphrase, - size_t passphrase_size, - struct volume_key **vks); - int LUKS2_reencrypt_locked_recovery_by_vks(struct crypt_device *cd, struct volume_key *vks); @@ -489,20 +492,10 @@ int LUKS2_reencrypt_check_device_size(struct crypt_device *cd, bool device_exclusive_check, bool dynamic); -void LUKS2_reencrypt_lookup_key_ids(struct crypt_device *cd, - struct luks2_hdr *hdr, - struct volume_key *vk); - int LUKS2_reencrypt_digest_verify(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks); -int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd, - struct luks2_hdr *hdr, - const struct reenc_protection *rp, - int reencrypt_keyslot, - uint64_t *r_length); - -void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp); +unsigned LUKS2_reencrypt_vks_count(struct luks2_hdr *hdr); #endif diff --git a/lib/luks2/luks2_digest.c b/lib/luks2/luks2_digest.c index a38a220..fb9a902 100644 --- a/lib/luks2/luks2_digest.c +++ b/lib/luks2/luks2_digest.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2, digest handling * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #include "luks2_internal.h" @@ -75,7 +75,7 @@ int LUKS2_digest_create(struct crypt_device *cd, log_dbg(cd, "Creating new digest %d (%s).", digest, type); - return dh->store(cd, digest, vk->key, vk->keylength) ?: digest; + return dh->store(cd, digest, crypt_volume_key_get_key(vk), crypt_volume_key_length(vk)) ?: digest; } int LUKS2_digest_by_keyslot(struct luks2_hdr *hdr, int keyslot) @@ -108,7 +108,7 @@ int LUKS2_digest_verify_by_digest(struct crypt_device *cd, if (!h) return -EINVAL; - r = h->verify(cd, digest, vk->key, vk->keylength); + r = h->verify(cd, digest, crypt_volume_key_get_key(vk), crypt_volume_key_length(vk)); if (r < 0) { log_dbg(cd, "Digest %d (%s) verify failed with %d.", digest, h->name, r); return r; @@ -143,8 +143,7 @@ int LUKS2_digest_dump(struct crypt_device *cd, int digest) return h->dump(cd, digest); } -int LUKS2_digest_any_matching(struct crypt_device *cd, - struct luks2_hdr *hdr __attribute__((unused)), +int LUKS2_digest_verify_by_any_matching(struct crypt_device *cd, const struct volume_key *vk) { int digest; @@ -161,7 +160,7 @@ int LUKS2_digest_verify_by_segment(struct crypt_device *cd, int segment, const struct volume_key *vk) { - int r = -EINVAL; + int r; unsigned s; if (segment == CRYPT_ANY_SEGMENT) { @@ -173,7 +172,11 @@ int LUKS2_digest_verify_by_segment(struct crypt_device *cd, return -EPERM; } - return LUKS2_digest_verify_by_digest(cd, LUKS2_digest_by_segment(hdr, segment), vk); + r = LUKS2_digest_by_segment(hdr, segment); + if (r < 0) + return r; + + return LUKS2_digest_verify_by_digest(cd, r, vk); } /* FIXME: segment can have more digests */ @@ -420,21 +423,7 @@ int LUKS2_key_description_by_segment(struct crypt_device *cd, char *desc = get_key_description_by_digest(cd, LUKS2_digest_by_segment(hdr, segment)); int r; - r = crypt_volume_key_set_description(vk, desc); - free(desc); - return r; -} - -int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd, - struct luks2_hdr *hdr, struct volume_key *vk, int keyslot) -{ - char *desc = get_key_description_by_digest(cd, LUKS2_digest_by_keyslot(hdr, keyslot)); - int r; - - r = crypt_volume_key_set_description(vk, desc); - if (!r) - r = crypt_volume_key_load_in_keyring(cd, vk); - + r = crypt_volume_key_set_description(vk, desc, LOGON_KEY); free(desc); return r; } @@ -445,7 +434,7 @@ int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd, char *desc = get_key_description_by_digest(cd, digest); int r; - r = crypt_volume_key_set_description(vk, desc); + r = crypt_volume_key_set_description(vk, desc, LOGON_KEY); if (!r) r = crypt_volume_key_load_in_keyring(cd, vk); diff --git a/lib/luks2/luks2_digest_pbkdf2.c b/lib/luks2/luks2_digest_pbkdf2.c index 3e88e6a..e5e06ee 100644 --- a/lib/luks2/luks2_digest_pbkdf2.c +++ b/lib/luks2/luks2_digest_pbkdf2.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2, PBKDF2 digest handler (LUKS1 compatible) * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #include "luks2_internal.h" diff --git a/lib/luks2/luks2_disk_metadata.c b/lib/luks2/luks2_disk_metadata.c index 5939aab..e649f89 100644 --- a/lib/luks2/luks2_disk_metadata.c +++ b/lib/luks2/luks2_disk_metadata.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2 * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #include "luks2_internal.h" @@ -289,22 +289,25 @@ static int hdr_read_disk(struct crypt_device *cd, */ static int hdr_write_disk(struct crypt_device *cd, struct device *device, struct luks2_hdr *hdr, - const char *json_area, int secondary) + const char *json_area, size_t write_area_len, + int secondary) { struct luks2_hdr_disk hdr_disk; uint64_t offset = secondary ? hdr->hdr_size : 0; size_t hdr_json_len; int devfd, r; + hdr_json_len = hdr->hdr_size - LUKS2_HDR_BIN_LEN; + + assert(write_area_len <= hdr_json_len); + log_dbg(cd, "Trying to write LUKS2 header (%zu bytes) at offset %" PRIu64 ".", - hdr->hdr_size, offset); + write_area_len, offset); devfd = device_open_locked(cd, device, O_RDWR); if (devfd < 0) return devfd == -1 ? -EINVAL : devfd; - hdr_json_len = hdr->hdr_size - LUKS2_HDR_BIN_LEN; - hdr_to_disk(hdr, &hdr_disk, secondary, offset); /* @@ -321,8 +324,8 @@ static int hdr_write_disk(struct crypt_device *cd, */ if (write_lseek_blockwise(devfd, device_block_size(cd, device), device_alignment(device), - CONST_CAST(char*)json_area, hdr_json_len, - LUKS2_HDR_BIN_LEN + offset) < (ssize_t)hdr_json_len) { + CONST_CAST(char*)json_area, write_area_len, + LUKS2_HDR_BIN_LEN + offset) < (ssize_t)write_area_len) { return -EIO; } @@ -401,7 +404,7 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct { char *json_area; const char *json_text; - size_t json_area_len; + size_t json_data_len, json_area_len, json_area_write_len; int r; if (hdr->version != 2) { @@ -413,29 +416,47 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct if (r) return r; - /* - * Allocate and zero JSON area (of proper header size). - */ - json_area_len = hdr->hdr_size - LUKS2_HDR_BIN_LEN; - json_area = crypt_zalloc(json_area_len); - if (!json_area) - return -ENOMEM; - /* * Generate text space-efficient JSON representation to json area. */ - json_text = json_object_to_json_string_ext(hdr->jobj, - JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE); + json_text = crypt_jobj_to_string_on_disk(hdr->jobj); if (!json_text || !*json_text) { log_dbg(cd, "Cannot parse JSON object to text representation."); - free(json_area); return -ENOMEM; } - if (strlen(json_text) > (json_area_len - 1)) { - log_dbg(cd, "JSON is too large (%zu > %zu).", strlen(json_text), json_area_len); - free(json_area); + + json_area_len = hdr->hdr_size - LUKS2_HDR_BIN_LEN; + json_area_write_len = json_data_len = strlen(json_text); + + if (json_data_len > (json_area_len - 1)) { + log_dbg(cd, "JSON is too large (%zu > %zu).", json_data_len, json_area_len - 1); return -EINVAL; } + + /* + * Allocate and zero JSON area (of proper header size). + */ + json_area = crypt_zalloc(json_area_len); + if (!json_area) + return -ENOMEM; + + /* + * If the metadata in 'json_area' buffer is smaller than last on-disk + * metadata we also have to erase the remaining bytes between the tail + * of current metadata and the on-disk metadata end pointer. Set write + * area length large enough to overwrite it. + * + * If seqid_check is turned off (during LUKS2 format) write entire + * LUKS2 metadata size instead. + * + * Turn off the optimization also during metadata upconversion + * (hdr->on_disk_json_end_offset == 0). + */ + if (seqid_check && (json_data_len < hdr->on_disk_json_end_offset)) + json_area_write_len = hdr->on_disk_json_end_offset; + else if (!seqid_check || !hdr->on_disk_json_end_offset) + json_area_write_len = json_area_len; + strncpy(json_area, json_text, json_area_len); if (seqid_check) @@ -451,13 +472,16 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct hdr->seqid++; /* Write primary and secondary header */ - r = hdr_write_disk(cd, device, hdr, json_area, 0); + r = hdr_write_disk(cd, device, hdr, json_area, json_area_write_len, 0); if (!r) - r = hdr_write_disk(cd, device, hdr, json_area, 1); + r = hdr_write_disk(cd, device, hdr, json_area, json_area_write_len, 1); if (r) log_dbg(cd, "LUKS2 header write failed (%d).", r); + /* store new json end pointer or reset it on error */ + hdr->on_disk_json_end_offset = r ? 0 : json_data_len; + device_write_unlock(cd, device); free(json_area); @@ -525,12 +549,15 @@ static int validate_luks2_json_object(struct crypt_device *cd, json_object *jobj } static json_object *parse_and_validate_json(struct crypt_device *cd, - const char *json_area, uint64_t hdr_size) + const char *json_area, uint64_t hdr_size, + uint64_t *json_area_end) { int json_len, r; json_object *jobj; uint64_t max_length; + assert(json_area_end); + if (hdr_size <= LUKS2_HDR_BIN_LEN || hdr_size > LUKS2_HDR_OFFSET_MAX) { log_dbg(cd, "LUKS2 header JSON has bogus size 0x%04" PRIx64 ".", hdr_size); return NULL; @@ -554,6 +581,8 @@ static json_object *parse_and_validate_json(struct crypt_device *cd, jobj = NULL; } + *json_area_end = json_len; + return jobj; } @@ -617,7 +646,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, json_object *jobj_hdr1 = NULL, *jobj_hdr2 = NULL; unsigned int i; int r; - uint64_t hdr_size; + uint64_t hdr_size, json_area_end1 = 0, json_area_end2 = 0; uint64_t hdr2_offsets[] = LUKS2_HDR2_OFFSETS; /* Skip auto-recovery if locks are disabled and we're not doing LUKS2 explicit repair */ @@ -632,7 +661,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, state_hdr1 = HDR_FAIL; r = hdr_read_disk(cd, device, &hdr_disk1, &json_area1, 0, 0); if (r == 0) { - jobj_hdr1 = parse_and_validate_json(cd, json_area1, be64_to_cpu(hdr_disk1.hdr_size)); + jobj_hdr1 = parse_and_validate_json(cd, json_area1, be64_to_cpu(hdr_disk1.hdr_size), &json_area_end1); state_hdr1 = jobj_hdr1 ? HDR_OK : HDR_OBSOLETE; } else if (r == -EIO) state_hdr1 = HDR_FAIL_IO; @@ -644,7 +673,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, if (state_hdr1 != HDR_FAIL && state_hdr1 != HDR_FAIL_IO) { r = hdr_read_disk(cd, device, &hdr_disk2, &json_area2, be64_to_cpu(hdr_disk1.hdr_size), 1); if (r == 0) { - jobj_hdr2 = parse_and_validate_json(cd, json_area2, be64_to_cpu(hdr_disk2.hdr_size)); + jobj_hdr2 = parse_and_validate_json(cd, json_area2, be64_to_cpu(hdr_disk2.hdr_size), &json_area_end2); state_hdr2 = jobj_hdr2 ? HDR_OK : HDR_OBSOLETE; } else if (r == -EIO) state_hdr2 = HDR_FAIL_IO; @@ -657,7 +686,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, r = hdr_read_disk(cd, device, &hdr_disk2, &json_area2, hdr2_offsets[i], 1); if (r == 0) { - jobj_hdr2 = parse_and_validate_json(cd, json_area2, be64_to_cpu(hdr_disk2.hdr_size)); + jobj_hdr2 = parse_and_validate_json(cd, json_area2, be64_to_cpu(hdr_disk2.hdr_size), &json_area_end2); state_hdr2 = jobj_hdr2 ? HDR_OK : HDR_OBSOLETE; } else if (r == -EIO) state_hdr2 = HDR_FAIL_IO; @@ -706,7 +735,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, log_dbg(cd, "Cannot generate header salt."); else { hdr_from_disk(&hdr_disk1, &hdr_disk2, hdr, 0); - r = hdr_write_disk(cd, device, hdr, json_area1, 1); + r = hdr_write_disk(cd, device, hdr, json_area1, hdr->hdr_size - LUKS2_HDR_BIN_LEN, 1); } if (r) log_dbg(cd, "Secondary LUKS2 header recovery failed."); @@ -727,7 +756,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, log_dbg(cd, "Cannot generate header salt."); else { hdr_from_disk(&hdr_disk2, &hdr_disk1, hdr, 1); - r = hdr_write_disk(cd, device, hdr, json_area2, 0); + r = hdr_write_disk(cd, device, hdr, json_area2, hdr->hdr_size - LUKS2_HDR_BIN_LEN, 0); } if (r) log_dbg(cd, "Primary LUKS2 header recovery failed."); @@ -756,6 +785,11 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, json_object_put(jobj_hdr1); } + if (json_area_end1 > json_area_end2) + hdr->on_disk_json_end_offset = json_area_end1; + else + hdr->on_disk_json_end_offset = json_area_end2; + /* * FIXME: should this fail? At least one header was read correctly. * r = (state_hdr1 == HDR_FAIL_IO || state_hdr2 == HDR_FAIL_IO) ? -EIO : -EINVAL; diff --git a/lib/luks2/luks2_internal.h b/lib/luks2/luks2_internal.h index 6f991c0..adaea91 100644 --- a/lib/luks2/luks2_internal.h +++ b/lib/luks2/luks2_internal.h @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * LUKS - Linux Unified Key Setup v2 + * LUKS - Linux Unified Key Setup v2 (with JSON internals) * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #ifndef _CRYPTSETUP_LUKS2_INTERNAL_H @@ -48,6 +48,16 @@ uint64_t crypt_jobj_get_uint64(json_object *jobj); uint32_t crypt_jobj_get_uint32(json_object *jobj); json_object *crypt_jobj_new_uint64(uint64_t value); +/* + * Generate json format string representation libcryptsetup uses + * to store json metadata on disk. + */ +static inline const char *crypt_jobj_to_string_on_disk(json_object *jobj) +{ + return json_object_to_json_string_ext(jobj, + JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE); +} + int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object *jobj_val); int json_object_object_add_by_uint_by_ref(json_object *jobj, unsigned key, json_object **jobj_val_ref); void json_object_object_del_by_uint(json_object *jobj, unsigned key); @@ -89,7 +99,7 @@ json_object *LUKS2_array_remove(json_object *array, const char *num); */ /** - * LUKS2 keyslots handlers (EXPERIMENTAL) + * LUKS2 keyslots handlers */ typedef int (*keyslot_alloc_func)(struct crypt_device *cd, int keyslot, size_t volume_key_len, @@ -152,7 +162,7 @@ struct reenc_protection { }; /** - * LUKS2 digest handlers (EXPERIMENTAL) + * LUKS2 digest handlers */ typedef int (*digest_verify_func)(struct crypt_device *cd, int digest, const char *volume_key, size_t volume_key_len); @@ -292,7 +302,7 @@ void json_segment_remove_flag(json_object *jobj_segment, const char *flag); uint64_t json_segments_get_minimal_offset(json_object *jobj_segments, unsigned blockwise); json_object *json_segment_create_linear(uint64_t offset, const uint64_t *length, unsigned reencryption); json_object *json_segment_create_crypt(uint64_t offset, uint64_t iv_offset, const uint64_t *length, - const char *cipher, const char *integrity, + const char *cipher, const char *integrity, uint32_t integrity_key_size, uint32_t sector_size, unsigned reencryption); json_object *json_segment_create_opal(uint64_t offset, const uint64_t *length, uint32_t segment_number, uint32_t key_size); @@ -337,10 +347,6 @@ uint64_t LUKS2_segment_size(struct luks2_hdr *hdr, int segment, unsigned blockwise); -bool LUKS2_segment_set_size(struct luks2_hdr *hdr, - int segment, - const uint64_t *segment_size_bytes); - uint64_t LUKS2_opal_segment_size(struct luks2_hdr *hdr, int segment, unsigned blockwise); @@ -349,14 +355,6 @@ int LUKS2_segment_is_type(struct luks2_hdr *hdr, int segment, const char *type); -bool LUKS2_segment_is_hw_opal(struct luks2_hdr *hdr, int segment); -bool LUKS2_segment_is_hw_opal_crypt(struct luks2_hdr *hdr, int segment); -bool LUKS2_segment_is_hw_opal_only(struct luks2_hdr *hdr, int segment); - -int LUKS2_get_opal_segment_number(struct luks2_hdr *hdr, int segment, - uint32_t *ret_opal_segment_number); -int LUKS2_get_opal_key_size(struct luks2_hdr *hdr, int segment); - int LUKS2_segment_by_type(struct luks2_hdr *hdr, const char *type); @@ -365,13 +363,20 @@ int LUKS2_last_segment_by_type(struct luks2_hdr *hdr, int LUKS2_get_default_segment(struct luks2_hdr *hdr); -bool LUKS2_segments_dynamic_size(struct luks2_hdr *hdr); - int LUKS2_reencrypt_digest_new(struct luks2_hdr *hdr); int LUKS2_reencrypt_digest_old(struct luks2_hdr *hdr); -unsigned LUKS2_reencrypt_vks_count(struct luks2_hdr *hdr); +int LUKS2_reencrypt_segment_new(struct luks2_hdr *hdr); +int LUKS2_reencrypt_segment_old(struct luks2_hdr *hdr); int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise); +int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd, + struct luks2_hdr *hdr, + const struct reenc_protection *rp, + int reencrypt_keyslot, + uint64_t *r_length); + +void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp); + /* * Generic LUKS2 digest */ diff --git a/lib/luks2/luks2_json_format.c b/lib/luks2/luks2_json_format.c index 2c7031c..2098028 100644 --- a/lib/luks2/luks2_json_format.c +++ b/lib/luks2/luks2_json_format.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2, LUKS2 header format code * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #include "luks2_internal.h" @@ -193,6 +193,7 @@ int LUKS2_generate_hdr( const struct volume_key *vk, const char *cipher_spec, const char *integrity, + uint32_t integrity_key_size, /* in bytes, only if separate (HMAC) */ const char *uuid, unsigned int sector_size, /* in bytes */ uint64_t data_offset, /* in bytes */ @@ -279,8 +280,8 @@ int LUKS2_generate_hdr( if (!opal_key_size) jobj_segment = json_segment_create_crypt(data_offset, 0, NULL, cipher_spec, - integrity, sector_size, - 0); + integrity, integrity_key_size, + sector_size, 0); else if (opal_key_size && cipher_spec) jobj_segment = json_segment_create_opal_crypt(data_offset, &device_size_bytes, opal_segment_number, opal_key_size, 0, diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c index d30d52d..15e83a8 100644 --- a/lib/luks2/luks2_json_metadata.c +++ b/lib/luks2/luks2_json_metadata.c @@ -2,9 +2,9 @@ /* * LUKS - Linux Unified Key Setup v2 * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz - * Copyright (C) 2015-2024 Ondrej Kozina + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz + * Copyright (C) 2015-2025 Ondrej Kozina */ #include "luks2_internal.h" @@ -13,8 +13,6 @@ #include #include -#define LUKS_STRIPES 4000 - struct interval { uint64_t offset; uint64_t length; @@ -467,8 +465,7 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj json_object_object_get_ex(hdr_jobj, "config", &jobj); json_object_object_get_ex(jobj, "json_size", &jobj1); - json = json_object_to_json_string_ext(hdr_jobj, - JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE); + json = crypt_jobj_to_string_on_disk(hdr_jobj); if (!json) return 1; @@ -636,6 +633,11 @@ static int reqs_opal(uint32_t reqs) return reqs & CRYPT_REQUIREMENT_OPAL; } +static int reqs_inline_hw_tags(uint32_t reqs) +{ + return reqs & CRYPT_REQUIREMENT_INLINE_HW_TAGS; +} + /* * Config section requirements object must be valid. * Also general segments section must be validated first. @@ -644,14 +646,12 @@ static int validate_reencrypt_segments(struct crypt_device *cd, json_object *hdr { json_object *jobj, *jobj_backup_previous = NULL, *jobj_backup_final = NULL; uint32_t reqs; - int i, r; + int i; struct luks2_hdr dummy = { .jobj = hdr_jobj }; - r = LUKS2_config_get_requirements(cd, &dummy, &reqs); - if (r) - return 1; + LUKS2_config_get_requirements(cd, &dummy, &reqs); if (reqs_reencrypt_online(reqs)) { for (i = first_backup; i < segments_count; i++) { @@ -1272,7 +1272,11 @@ int LUKS2_hdr_uuid(struct crypt_device *cd, struct luks2_hdr *hdr, const char *u int LUKS2_hdr_labels(struct crypt_device *cd, struct luks2_hdr *hdr, const char *label, const char *subsystem, int commit) { - //FIXME: check if the labels are the same and skip this. + if ((label && strlen(label) >= LUKS2_LABEL_L) || + (subsystem && strlen(subsystem) >= LUKS2_LABEL_L)) { + log_err(cd, _("Label is too long.")); + return -EINVAL; + } memset(hdr->label, 0, LUKS2_LABEL_L); if (label) @@ -1426,7 +1430,8 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr, } /* do not allow header restore from backup with unmet requirements */ - if (LUKS2_unmet_requirements(cd, &hdr_file, CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 1)) { + if (LUKS2_unmet_requirements(cd, &hdr_file, + CRYPT_REQUIREMENT_ONLINE_REENCRYPT | CRYPT_REQUIREMENT_INLINE_HW_TAGS, 1)) { log_err(cd, _("Forbidden LUKS2 requirements detected in backup %s."), backup_file); r = -ETXTBSY; @@ -1458,9 +1463,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr, r = LUKS2_hdr_read(cd, &tmp_hdr, 0); if (r == 0) { log_dbg(cd, "Device %s already contains LUKS2 header, checking UUID and requirements.", device_path(device)); - r = LUKS2_config_get_requirements(cd, &tmp_hdr, &reqs); - if (r) - goto out; + LUKS2_config_get_requirements(cd, &tmp_hdr, &reqs); if (memcmp(tmp_hdr.uuid, hdr_file.uuid, LUKS2_UUID_L)) diff_uuid = 1; @@ -1544,7 +1547,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr, * Persistent config flags */ static const struct { - uint32_t flag; + uint64_t flag; const char *description; } persistent_flags[] = { { CRYPT_ACTIVATE_ALLOW_DISCARDS, "allow-discards" }, @@ -1553,6 +1556,7 @@ static const struct { { CRYPT_ACTIVATE_NO_JOURNAL, "no-journal" }, { CRYPT_ACTIVATE_NO_READ_WORKQUEUE, "no-read-workqueue" }, { CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE, "no-write-workqueue" }, + { CRYPT_ACTIVATE_HIGH_PRIORITY, "high_priority" }, { 0, NULL } }; @@ -1642,6 +1646,7 @@ static const struct requirement_flag requirements_flags[] = { { CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 2, "online-reencrypt-v2" }, { CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 3, "online-reencrypt-v3" }, { CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 1, "online-reencrypt" }, + { CRYPT_REQUIREMENT_INLINE_HW_TAGS, 1, "inline-hw-tags" }, { CRYPT_REQUIREMENT_OPAL, 1, "opal" }, { 0, 0, NULL } }; @@ -1764,7 +1769,7 @@ static const struct requirement_flag *stored_requirement_name_by_id(struct luks2 /* * returns count of requirements (past cryptsetup 2.0 release) */ -int LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs) +void LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs) { json_object *jobj_mandatory, *jobj; int i, len; @@ -1777,11 +1782,11 @@ int LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr jobj_mandatory = mandatory_requirements_jobj(hdr); if (!jobj_mandatory) - return 0; + return; len = (int) json_object_array_length(jobj_mandatory); if (len <= 0) - return 0; + return; log_dbg(cd, "LUKS2 requirements detected:"); @@ -1792,8 +1797,6 @@ int LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr reqs_unknown(req->flag) ? "un" : ""); *reqs |= req->flag; } - - return 0; } int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs, bool commit) @@ -1801,7 +1804,7 @@ int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr json_object *jobj_config, *jobj_requirements, *jobj_mandatory, *jobj; int i, r = -EINVAL; const struct requirement_flag *req; - uint32_t req_id; + uint64_t req_id; if (!hdr) return -EINVAL; @@ -2128,6 +2131,10 @@ static void hdr_dump_segments(struct crypt_device *cd, json_object *hdr_jobj) json_object_object_get_ex(jobj1, "type", &jobj2)) log_std(cd, "\tintegrity: %s\n", json_object_get_string(jobj2)); + if (json_object_object_get_ex(jobj_segment, "integrity", &jobj1) && + json_object_object_get_ex(jobj1, "key_size", &jobj2)) + log_std(cd, "\tintegrity key size: %" PRIu32 " [bits]\n", crypt_jobj_get_uint32(jobj2) * 8); + if (json_object_object_get_ex(jobj_segment, "flags", &jobj1) && (flags = (int)json_object_array_length(jobj1)) > 0) { jobj2 = json_object_array_get_idx(jobj1, 0); @@ -2304,12 +2311,7 @@ crypt_reencrypt_info LUKS2_reencrypt_status(struct luks2_hdr *hdr) { uint32_t reqs; - /* - * Any unknown requirement or offline reencryption should abort - * anything related to online-reencryption handling - */ - if (LUKS2_config_get_requirements(NULL, hdr, &reqs)) - return CRYPT_REENCRYPT_INVALID; + LUKS2_config_get_requirements(NULL, hdr, &reqs); if (!reqs_reencrypt_online(reqs)) return CRYPT_REENCRYPT_NONE; @@ -2363,6 +2365,24 @@ const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment) return json_object_get_string(jobj3); } +int LUKS2_get_integrity_key_size(struct luks2_hdr *hdr, int segment) +{ + json_object *jobj1, *jobj2, *jobj3; + + jobj1 = LUKS2_get_segment_jobj(hdr, segment); + if (!jobj1) + return -1; + + if (!json_object_object_get_ex(jobj1, "integrity", &jobj2)) + return -1; + + /* The value is optional, do not fail if not present */ + if (!json_object_object_get_ex(jobj2, "key_size", &jobj3)) + return 0; + + return json_object_get_int(jobj3); +} + /* FIXME: this only ensures that once we have journal encryption, it is not ignored. */ /* implement segment count and type restrictions (crypt and only single crypt) */ static int LUKS2_integrity_compatible(struct luks2_hdr *hdr) @@ -2450,6 +2470,19 @@ int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment) return -1; } +int LUKS2_get_old_volume_key_size(struct luks2_hdr *hdr) +{ + int old_segment; + + assert(hdr); + + old_segment = LUKS2_reencrypt_segment_old(hdr); + if (old_segment < 0) + return old_segment; + + return LUKS2_get_volume_key_size(hdr, old_segment); +} + uint32_t LUKS2_get_sector_size(struct luks2_hdr *hdr) { return json_segment_get_sector_size(LUKS2_get_segment_jobj(hdr, CRYPT_DEFAULT_SEGMENT)); @@ -2518,7 +2551,7 @@ int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd, crypt_data_device(cd), vk, json_segment_get_cipher(jobj), json_segment_get_iv_offset(jobj), - segment_offset, "none", 0, + segment_offset, "none", 0, 0, json_segment_get_sector_size(jobj)); if (r) { log_err(cd, _("Failed to set dm-crypt segment.")); @@ -2632,7 +2665,7 @@ int LUKS2_activate(struct crypt_device *cd, { int r; bool dynamic, read_lock, write_lock, opal_lock_on_error = false; - uint32_t opal_segment_number; + uint32_t opal_segment_number, req_flags; uint64_t range_offset_sectors, range_length_sectors, device_length_bytes; struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); struct crypt_dm_active_device dmdi = {}, dmd = { @@ -2641,7 +2674,8 @@ int LUKS2_activate(struct crypt_device *cd, struct crypt_lock_handle *opal_lh = NULL; /* do not allow activation when particular requirements detected */ - if ((r = LUKS2_unmet_requirements(cd, hdr, CRYPT_REQUIREMENT_OPAL, 0))) + if ((r = LUKS2_unmet_requirements(cd, hdr, + CRYPT_REQUIREMENT_OPAL | CRYPT_REQUIREMENT_INLINE_HW_TAGS, 0))) return r; /* Check that cipher is in compatible format */ @@ -2714,7 +2748,7 @@ int LUKS2_activate(struct crypt_device *cd, crypt_key, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd), crypt_get_data_offset(cd), crypt_get_integrity(cd) ?: "none", - crypt_get_integrity_tag_size(cd), + crypt_get_integrity_key_size(cd, true), crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd)); } else r = dm_linear_target_set(&dmd.segment, 0, @@ -2730,7 +2764,13 @@ int LUKS2_activate(struct crypt_device *cd, dmd.flags |= flags; - if (crypt_get_integrity_tag_size(cd)) { + if (crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &req_flags)) { + r = -EINVAL; + goto out; + } + + if (crypt_get_integrity_tag_size(cd) && + !(req_flags & CRYPT_REQUIREMENT_INLINE_HW_TAGS)) { if (!LUKS2_integrity_compatible(hdr)) { log_err(cd, _("Unsupported device integrity configuration.")); r = -EINVAL; @@ -2810,14 +2850,14 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr struct crypt_dm_active_device dmdc; uint32_t opal_segment_number; char **dep, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 }; - const char *namei = NULL; + char *iname = NULL; struct crypt_lock_handle *reencrypt_lock = NULL, *opal_lh = NULL; if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1)) return -EINVAL; /* uuid mismatch with metadata (if available) */ - if (hdr && crypt_uuid_cmp(dmd->uuid, hdr->uuid)) + if (hdr && dm_uuid_cmp(dmd->uuid, hdr->uuid)) return -EINVAL; r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), CRYPT_SUBDEV "-%.32s", dmd->uuid + 6); @@ -2825,15 +2865,15 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr return -EINVAL; /* check if active device has LUKS2-OPAL dm uuid prefix */ - dm_opal_uuid = !crypt_uuid_type_cmp(dmd->uuid, CRYPT_LUKS2_HW_OPAL); + dm_opal_uuid = !dm_uuid_type_cmp(dmd->uuid, CRYPT_LUKS2_HW_OPAL); if (dm_opal_uuid && hdr && !LUKS2_segment_is_hw_opal(hdr, CRYPT_DEFAULT_SEGMENT)) return -EINVAL; tgt = &dmd->segment; /* TODO: We have LUKS2 dependencies now */ - if (single_segment(dmd) && tgt->type == DM_CRYPT && tgt->u.crypt.tag_size) - namei = device_dm_name(tgt->data_device); + if (tgt->type == DM_CRYPT && tgt->u.crypt.tag_size) + iname = dm_get_active_iname(cd, name); r = dm_device_deps(cd, name, deps_uuid_prefix, deps, ARRAY_SIZE(deps)); if (r < 0) @@ -2871,23 +2911,34 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr tgt = &dmdc.segment; while (tgt) { if (tgt->type == DM_CRYPT) - crypt_drop_keyring_key_by_description(cd, tgt->u.crypt.vk->key_description, - LOGON_KEY); + crypt_volume_key_drop_kernel_key(cd, tgt->u.crypt.vk); tgt = tgt->next; } } dm_targets_free(cd, &dmdc); /* TODO: We have LUKS2 dependencies now */ - if (r >= 0 && namei) { - log_dbg(cd, "Deactivating integrity device %s.", namei); - r = dm_remove_device(cd, namei, 0); + if (r >= 0 && iname) { + log_dbg(cd, "Deactivating integrity device %s.", iname); + r = dm_remove_device(cd, iname, 0); } if (!r) { ret = 0; dep = deps; while (*dep) { + /* + * FIXME: dm-integrity has now proper SUBDEV prefix so + * it would be deactivated here, but due to specific + * dm_remove_device(iname) above the iname device + * is no longer active. This will be fixed when + * we switch to SUBDEV deactivation after 2.8 release. + */ + if (iname && !strcmp(*dep, iname)) { + dep++; + continue; + } + log_dbg(cd, "Deactivating LUKS2 dependent device %s.", *dep); r = dm_query_device(cd, *dep, DM_ACTIVE_CRYPT_KEY | DM_ACTIVE_CRYPT_KEYSIZE, &dmdc); if (r < 0) { @@ -2907,8 +2958,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr tgt = &dmdc.segment; while (tgt) { if (tgt->type == DM_CRYPT) - crypt_drop_keyring_key_by_description(cd, tgt->u.crypt.vk->key_description, - LOGON_KEY); + crypt_volume_key_drop_kernel_key(cd, tgt->u.crypt.vk); tgt = tgt->next; } } @@ -2950,6 +3000,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr out: opal_exclusive_unlock(cd, opal_lh); LUKS2_reencrypt_unlock(cd, reencrypt_lock); + free(iname); dep = deps; while (*dep) free(*dep++); @@ -2957,16 +3008,11 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr return r; } -int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet) +int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t reqs_mask, int quiet) { uint32_t reqs; - int r = LUKS2_config_get_requirements(cd, hdr, &reqs); - if (r) { - if (!quiet) - log_err(cd, _("Failed to read LUKS2 requirements.")); - return r; - } + LUKS2_config_get_requirements(cd, hdr, &reqs); /* do not mask unknown requirements check */ if (reqs_unknown(reqs)) { @@ -2984,6 +3030,8 @@ int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uin log_err(cd, _("Operation incompatible with device marked for LUKS2 reencryption. Aborting.")); if (reqs_opal(reqs) && !quiet) log_err(cd, _("Operation incompatible with device using OPAL. Aborting.")); + if (reqs_inline_hw_tags(reqs) && !quiet) + log_err(cd, _("Operation incompatible with device using inline HW tags. Aborting.")); /* any remaining unmasked requirement fails the check */ return reqs ? -EINVAL : 0; @@ -3092,22 +3140,22 @@ int LUKS2_split_crypt_and_opal_keys(struct crypt_device *cd __attribute__((unuse if (r < 0) return -EINVAL; - if (vk->keylength < opal_user_key_size) + if (crypt_volume_key_length(vk) < opal_user_key_size) return -EINVAL; /* OPAL SEGMENT only */ - if (vk->keylength == opal_user_key_size) { + if (crypt_volume_key_length(vk) == opal_user_key_size) { *ret_crypt_key = NULL; *ret_opal_key = NULL; return 0; } - opal_key = crypt_alloc_volume_key(opal_user_key_size, vk->key); + opal_key = crypt_alloc_volume_key(opal_user_key_size, crypt_volume_key_get_key(vk)); if (!opal_key) return -ENOMEM; - crypt_key = crypt_alloc_volume_key(vk->keylength - opal_user_key_size, - vk->key + opal_user_key_size); + crypt_key = crypt_alloc_volume_key(crypt_volume_key_length(vk) - opal_user_key_size, + crypt_volume_key_get_key(vk) + opal_user_key_size); if (!crypt_key) { crypt_free_volume_key(opal_key); return -ENOMEM; diff --git a/lib/luks2/luks2_keyslot.c b/lib/luks2/luks2_keyslot.c index bb9d453..9072570 100644 --- a/lib/luks2/luks2_keyslot.c +++ b/lib/luks2/luks2_keyslot.c @@ -2,11 +2,12 @@ /* * LUKS - Linux Unified Key Setup v2, keyslot handling * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #include "luks2_internal.h" +#include "keyslot_context.h" /* Internal implementations */ extern const keyslot_handler luks2_keyslot; @@ -75,8 +76,38 @@ int LUKS2_keyslot_find_empty(struct crypt_device *cd, struct luks2_hdr *hdr, siz /* Check if a keyslot is assigned to specific segment */ static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment) { - int keyslot_digest, count = 0; + json_object *jobj_keyslots, *jobj; + crypt_keyslot_priority slot_priority; unsigned s; + int keyslot_digest, count = 0; + + /* + * Must not be called with both keyslot == CRYPT_ANY_SLOT + * and segment == CRYPT_ONE_SEGMENT. The CRYPT_DEFAULT_SEGMENT + * and CRYPT_ANY_SEGMENT are handled properly in upper layer. + */ + assert(keyslot >= 0 || segment >= 0); + + if (keyslot == CRYPT_ANY_SLOT) { + json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots); + + json_object_object_foreach(jobj_keyslots, slot, val) { + if (!json_object_object_get_ex(val, "priority", &jobj)) + slot_priority = CRYPT_SLOT_PRIORITY_NORMAL; + else + slot_priority = json_object_get_int(jobj); + + if (slot_priority < CRYPT_SLOT_PRIORITY_NORMAL) + continue; + + keyslot_digest = LUKS2_digest_by_keyslot(hdr, atoi(slot)); + if (keyslot_digest >= 0 && + keyslot_digest == LUKS2_digest_by_segment(hdr, segment)) + return 1; + } + + return 0; + } keyslot_digest = LUKS2_digest_by_keyslot(hdr, keyslot); if (keyslot_digest < 0) @@ -93,16 +124,6 @@ static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment) return count; } -static int _keyslot_for_digest(struct luks2_hdr *hdr, int keyslot, int digest) -{ - int r = -EINVAL; - - r = LUKS2_digest_by_keyslot(hdr, keyslot); - if (r < 0) - return r; - return r == digest ? 0 : -ENOENT; -} - int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment) { int r = -EINVAL; @@ -144,7 +165,17 @@ int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd, const char *ciphe { char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN]; - if (!cipher_spec || crypt_is_cipher_null(cipher_spec)) + if (!cipher_spec) + return 1; + + /* + * Do not allow capi format for keyslots + * Note: It always failed in ivsize check later anyway. + */ + if (!strncmp(cipher_spec, "capi:", 5)) + return 1; + + if (crypt_is_cipher_null(cipher_spec)) return 1; if (crypt_parse_name_and_mode(cipher_spec, cipher, NULL, cipher_mode) < 0) @@ -318,61 +349,43 @@ static int _open_and_verify(struct crypt_device *cd, int keyslot, const char *password, size_t password_len, - struct volume_key **vk) + struct volume_key **r_vk) { int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot); + struct volume_key *vk = NULL; + void *key = NULL; if (key_size < 0) return -EINVAL; - *vk = crypt_alloc_volume_key(key_size, NULL); - if (!*vk) + key = crypt_safe_alloc(key_size); + if (!key) return -ENOMEM; - r = h->open(cd, keyslot, password, password_len, (*vk)->key, (*vk)->keylength); - if (r < 0) - log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r); - else - r = LUKS2_digest_verify(cd, hdr, *vk, keyslot); - + r = h->open(cd, keyslot, password, password_len, key, key_size); if (r < 0) { - crypt_free_volume_key(*vk); - *vk = NULL; + log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r); + goto err; } - crypt_volume_key_set_id(*vk, r); - - return r < 0 ? r : keyslot; -} - -static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int digest, - const char *password, - size_t password_len, - struct volume_key **vk) -{ - const keyslot_handler *h; - int r; - - if (!(h = LUKS2_keyslot_handler(cd, keyslot))) - return -ENOENT; - - r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot)); - if (r) { - log_dbg(cd, "Keyslot %d validation failed.", keyslot); - return r; + vk = crypt_alloc_volume_key_by_safe_alloc(&key); + if (!vk) { + r = -ENOMEM; + goto err; } - r = _keyslot_for_digest(hdr, keyslot, digest); - if (r) { - if (r == -ENOENT) - log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest); - return r; - } + r = LUKS2_digest_verify(cd, hdr, vk, keyslot); + if (r < 0) + goto err; - return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk); + crypt_volume_key_set_id(vk, r); + *r_vk = vk; + return keyslot; +err: + crypt_safe_free(key); + crypt_free_volume_key(vk); + + return r; } static int LUKS2_open_and_verify(struct crypt_device *cd, @@ -405,12 +418,12 @@ static int LUKS2_open_and_verify(struct crypt_device *cd, return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk); } -static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd, +static int LUKS2_keyslot_open_priority(struct crypt_device *cd, struct luks2_hdr *hdr, crypt_keyslot_priority priority, const char *password, size_t password_len, - int digest, + int segment, struct volume_key **vk) { json_object *jobj_keyslots, *jobj; @@ -434,7 +447,7 @@ static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd, continue; } - r = LUKS2_open_and_verify_by_digest(cd, hdr, keyslot, digest, password, password_len, vk); + r = LUKS2_open_and_verify(cd, hdr, keyslot, segment, password, password_len, vk); /* Do not retry for errors that are no -EPERM or -ENOENT, former meaning password wrong, latter key slot unusable for segment */ @@ -448,113 +461,83 @@ static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd, return r; } -static int LUKS2_keyslot_open_priority(struct crypt_device *cd, - struct luks2_hdr *hdr, - crypt_keyslot_priority priority, - const char *password, - size_t password_len, - int segment, - struct volume_key **vk) +static int keyslot_context_open_all_segments(struct crypt_device *cd, + int keyslot_old, + int keyslot_new, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, + struct volume_key **r_vks) { - json_object *jobj_keyslots, *jobj; - crypt_keyslot_priority slot_priority; - int keyslot, r = -ENOENT, r_old; - - json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots); - - json_object_object_foreach(jobj_keyslots, slot, val) { - r_old = r; - - if (!json_object_object_get_ex(val, "priority", &jobj)) - slot_priority = CRYPT_SLOT_PRIORITY_NORMAL; - else - slot_priority = json_object_get_int(jobj); - - keyslot = atoi(slot); - if (slot_priority != priority) { - log_dbg(cd, "Keyslot %d priority %d != %d (required), skipped.", - keyslot, slot_priority, priority); - continue; - } + int segment_old, segment_new, digest_old = -1, digest_new = -1, r = -ENOENT; + struct luks2_hdr *hdr; + struct volume_key *vk = NULL; - r = LUKS2_open_and_verify(cd, hdr, keyslot, segment, password, password_len, vk); + assert(cd); + assert(!kc_old || kc_old->get_luks2_key); + assert(!kc_new || kc_new->get_luks2_key); + assert(r_vks); - /* Do not retry for errors that are no -EPERM or -ENOENT, - former meaning password wrong, latter key slot unusable for segment */ - if ((r != -EPERM) && (r != -ENOENT)) - break; - /* If a previous keyslot failed with EPERM (bad password) prefer it */ - if (r_old == -EPERM && r == -ENOENT) - r = -EPERM; - } + hdr = crypt_get_hdr(cd, CRYPT_LUKS2); - return r; -} + segment_old = LUKS2_reencrypt_segment_old(hdr); + segment_new = LUKS2_reencrypt_segment_new(hdr); -static int LUKS2_keyslot_open_by_digest(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int digest, - const char *password, - size_t password_len, - struct volume_key **vk) -{ - int r_prio, r = -EINVAL; + if (segment_old < 0 || segment_new < 0) + return -EINVAL; - if (digest < 0) - return r; + digest_old = LUKS2_digest_by_segment(hdr, segment_old); + digest_new = LUKS2_digest_by_segment(hdr, segment_new); - if (keyslot == CRYPT_ANY_SLOT) { - r_prio = LUKS2_keyslot_open_priority_digest(cd, hdr, CRYPT_SLOT_PRIORITY_PREFER, - password, password_len, digest, vk); - if (r_prio >= 0) - r = r_prio; - else if (r_prio != -EPERM && r_prio != -ENOENT) - r = r_prio; - else - r = LUKS2_keyslot_open_priority_digest(cd, hdr, CRYPT_SLOT_PRIORITY_NORMAL, - password, password_len, digest, vk); - /* Prefer password wrong to no entry from priority slot */ - if (r_prio == -EPERM && r == -ENOENT) - r = r_prio; - } else - r = LUKS2_open_and_verify_by_digest(cd, hdr, keyslot, digest, password, password_len, vk); + if (digest_old >= 0 && digest_new >= 0 && digest_old != digest_new && (!kc_old || !kc_new)) + return -ESRCH; - return r; -} + if (digest_old >= 0 && kc_old) { + log_dbg(cd, "Checking current volume key (digest %d, segment: %d) using keyslot %d.", + digest_old, segment_old, keyslot_old); -int LUKS2_keyslot_open_all_segments(struct crypt_device *cd, - int keyslot_old, - int keyslot_new, - const char *password, - size_t password_len, - struct volume_key **vks) -{ - struct volume_key *vk = NULL; - int digest_old, digest_new, r = -EINVAL; - struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); + /* key and key in keyring types do not have association with any keyslot */ + if (kc_old->type != CRYPT_KC_TYPE_KEY && kc_old->type != CRYPT_KC_TYPE_VK_KEYRING) { + r = LUKS2_keyslot_for_segment(hdr, keyslot_old, segment_old); + if (r < 0) + goto out; + } - digest_old = LUKS2_reencrypt_digest_old(hdr); - if (digest_old >= 0) { - log_dbg(cd, "Trying to unlock volume key (digest: %d) using keyslot %d.", digest_old, keyslot_old); - r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk); + r = kc_old->get_luks2_key(cd, kc_old, keyslot_old, segment_old, &vk); if (r < 0) goto out; - crypt_volume_key_add_next(vks, vk); + crypt_volume_key_add_next(r_vks, vk); + if (crypt_volume_key_get_id(vk) < 0 && LUKS2_digest_verify_by_digest(cd, digest_old, vk) == digest_old) + crypt_volume_key_set_id(vk, digest_old); + if (crypt_volume_key_get_id(vk) != digest_old) { + r = -EPERM; + goto out; + } } - digest_new = LUKS2_reencrypt_digest_new(hdr); - if (digest_new >= 0 && digest_old != digest_new) { - log_dbg(cd, "Trying to unlock volume key (digest: %d) using keyslot %d.", digest_new, keyslot_new); - r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_new, digest_new, password, password_len, &vk); + if (digest_new >= 0 && digest_old != digest_new && kc_new) { + log_dbg(cd, "Checking new volume key (digest %d, segment: %d) using keyslot %d.", + digest_new, segment_new, keyslot_new); + + /* key and key in keyring types do not have association with any keyslot */ + if (kc_new->type != CRYPT_KC_TYPE_KEY && kc_new->type != CRYPT_KC_TYPE_VK_KEYRING) { + r = LUKS2_keyslot_for_segment(hdr, keyslot_new, segment_new); + if (r < 0) + goto out; + } + + r = kc_new->get_luks2_key(cd, kc_new, keyslot_new, segment_new, &vk); if (r < 0) goto out; - crypt_volume_key_add_next(vks, vk); + crypt_volume_key_add_next(r_vks, vk); + if (crypt_volume_key_get_id(vk) < 0 && LUKS2_digest_verify_by_digest(cd, digest_new, vk) == digest_new) + crypt_volume_key_set_id(vk, digest_new); + if (crypt_volume_key_get_id(vk) != digest_new) + r = -EPERM; } out: if (r < 0) { - crypt_free_volume_key(*vks); - *vks = NULL; + crypt_free_volume_key(*r_vks); + *r_vks = NULL; if (r == -ENOMEM) log_err(cd, _("Not enough available memory to open a keyslot.")); @@ -564,6 +547,25 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd, return r; } +int LUKS2_keyslot_context_open_all_segments(struct crypt_device *cd, + int keyslot1, + int keyslot2, + struct crypt_keyslot_context *kc1, + struct crypt_keyslot_context *kc2, + struct volume_key **r_vks) +{ + int r, r2; + + r = keyslot_context_open_all_segments(cd, keyslot1, keyslot2, kc1, kc2, r_vks); + if (r == -EPERM || r == -ENOENT) { + r2 = keyslot_context_open_all_segments(cd, keyslot2, keyslot1, kc2, kc1, r_vks); + if (r2 != -ENOENT) + r = r2; + } + + return r; +} + int LUKS2_keyslot_open(struct crypt_device *cd, int keyslot, int segment, @@ -646,7 +648,7 @@ int LUKS2_keyslot_store(struct crypt_device *cd, if (!h) return -EINVAL; - r = h->alloc(cd, keyslot, vk->keylength, params); + r = h->alloc(cd, keyslot, crypt_volume_key_length(vk), params); if (r) return r; } else { @@ -670,7 +672,7 @@ int LUKS2_keyslot_store(struct crypt_device *cd, return -EINVAL; return h->store(cd, keyslot, password, password_len, - vk->key, vk->keylength); + crypt_volume_key_get_key(vk), crypt_volume_key_length(vk)); } int LUKS2_keyslot_wipe(struct crypt_device *cd, @@ -861,8 +863,7 @@ int LUKS2_keyslots_validate(struct crypt_device *cd, json_object *hdr_jobj) if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots)) return -EINVAL; - if (LUKS2_config_get_requirements(cd, &dummy, &reqs)) - return -EINVAL; + LUKS2_config_get_requirements(cd, &dummy, &reqs); json_object_object_foreach(jobj_keyslots, slot, val) { keyslot = atoi(slot); diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c index 2040fdc..ec68236 100644 --- a/lib/luks2/luks2_keyslot_luks2.c +++ b/lib/luks2/luks2_keyslot_luks2.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2, LUKS2 type keyslot handler * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Milan Broz */ #include @@ -14,7 +14,6 @@ #define LUKS_SALTSIZE 32 #define LUKS_SLOT_ITERATIONS_MIN 1000 -#define LUKS_STRIPES 4000 /* Serialize memory-hard keyslot access: optional workaround for parallel processing */ #define MIN_MEMORY_FOR_SERIALIZE_LOCK_KB 32*1024 /* 32MB */ @@ -25,7 +24,7 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength, struct volume_key *vk, unsigned int sector, struct crypt_device *cd) { -#ifndef ENABLE_AF_ALG /* Support for old kernel without Crypto API */ +#if !ENABLE_AF_ALG /* Support for old kernel without Crypto API */ return LUKS_encrypt_to_storage(src, srcLength, cipher, cipher_mode, vk, sector, cd); #else struct crypt_storage *s; @@ -37,7 +36,8 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength, return -EINVAL; /* Encrypt buffer */ - r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false); + r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, + crypt_volume_key_get_key(vk), crypt_volume_key_length(vk), false); if (r) { log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode); return r; @@ -75,7 +75,7 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength, unsigned int sector, struct crypt_device *cd) { struct device *device = crypt_metadata_device(cd); -#ifndef ENABLE_AF_ALG /* Support for old kernel without Crypto API */ +#if !ENABLE_AF_ALG /* Support for old kernel without Crypto API */ int r = device_read_lock(cd, device); if (r) { log_err(cd, _("Failed to acquire read lock on device %s."), device_path(device)); @@ -92,7 +92,9 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength, if (MISALIGNED_512(dstLength)) return -EINVAL; - r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false); + r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, + crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk), false); if (r) { log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode); return r; @@ -190,7 +192,6 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, const char *password, size_t passwordLen, const char *volume_key, size_t volume_key_len) { - struct volume_key *derived_key; char *salt = NULL, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN]; char *AfKey = NULL; const char *af_hash = NULL; @@ -199,6 +200,8 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, uint64_t area_offset; struct crypt_pbkdf_type pbkdf; int r; + struct volume_key *derived_vk = NULL; + void *derived_key = NULL; if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf) || !json_object_object_get_ex(jobj_keyslot, "af", &jobj_af) || @@ -236,7 +239,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, /* * Allocate derived key storage. */ - derived_key = crypt_alloc_volume_key(keyslot_key_len, NULL); + derived_key = crypt_safe_alloc(keyslot_key_len); if (!derived_key) { free(salt); return -ENOMEM; @@ -247,7 +250,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, log_dbg(cd, "Running keyslot key derivation."); r = crypt_pbkdf(pbkdf.type, pbkdf.hash, password, passwordLen, salt, LUKS_SALTSIZE, - derived_key->key, derived_key->keylength, + derived_key, keyslot_key_len, pbkdf.iterations, pbkdf.max_memory_kb, pbkdf.parallel_threads); free(salt); @@ -255,16 +258,17 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) && pbkdf.iterations > INT_MAX) log_err(cd, _("PBKDF2 iteration value overflow.")); - crypt_free_volume_key(derived_key); - return r; + if (r == -ENOMEM) + log_err(cd, _("Not enough memory for keyslot key derivation.")); + goto out; } // FIXME: verity key_size to AFEKSize AFEKSize = AF_split_sectors(volume_key_len, LUKS_STRIPES) * SECTOR_SIZE; AfKey = crypt_safe_alloc(AFEKSize); if (!AfKey) { - crypt_free_volume_key(derived_key); - return -ENOMEM; + r = -ENOMEM; + goto out; } r = crypt_hash_size(af_hash); @@ -273,15 +277,23 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, else r = AF_split(cd, volume_key, AfKey, volume_key_len, LUKS_STRIPES, af_hash); - if (r == 0) { - log_dbg(cd, "Updating keyslot area [0x%04" PRIx64 "].", area_offset); - /* FIXME: sector_offset should be size_t, fix LUKS_encrypt... accordingly */ - r = luks2_encrypt_to_storage(AfKey, AFEKSize, cipher, cipher_mode, - derived_key, (unsigned)(area_offset / SECTOR_SIZE), cd); + if (r < 0) + goto out; + + derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key); + if (!derived_vk) { + r = -ENOMEM; + goto out; } + log_dbg(cd, "Updating keyslot area [0x%04" PRIx64 "].", area_offset); + /* FIXME: sector_offset should be size_t, fix LUKS_encrypt... accordingly */ + r = luks2_encrypt_to_storage(AfKey, AFEKSize, cipher, cipher_mode, + derived_vk, (unsigned)(area_offset / SECTOR_SIZE), cd); +out: crypt_safe_free(AfKey); - crypt_free_volume_key(derived_key); + crypt_safe_free(derived_key); + crypt_free_volume_key(derived_vk); if (r < 0) return r; @@ -293,8 +305,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, const char *password, size_t passwordLen, char *volume_key, size_t volume_key_len) { - struct volume_key *derived_key = NULL; - struct crypt_pbkdf_type pbkdf, *cd_pbkdf; + struct crypt_pbkdf_type pbkdf; char *AfKey = NULL; size_t AFEKSize; const char *af_hash = NULL; @@ -304,6 +315,8 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, size_t keyslot_key_len; bool try_serialize_lock = false; int r; + struct volume_key *derived_vk = NULL; + void *derived_key = NULL; if (!json_object_object_get_ex(jobj_keyslot, "af", &jobj_af) || !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area)) @@ -323,6 +336,10 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, if (r < 0) return r; + /* Allow only empty passphrase with null cipher */ + if (crypt_is_cipher_null(cipher) && passwordLen) + return -EPERM; + if (!json_object_object_get_ex(jobj_area, "key_size", &jobj2)) return -EINVAL; keyslot_key_len = json_object_get_int(jobj2); @@ -334,7 +351,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, /* * Allocate derived key storage space. */ - derived_key = crypt_alloc_volume_key(keyslot_key_len, NULL); + derived_key = crypt_safe_alloc(keyslot_key_len); if (!derived_key) { r = -ENOMEM; goto out; @@ -347,16 +364,6 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, goto out; } - /* - * Print warning when keyslot requires more memory than available - * (if maximum memory was adjusted - no swap, not enough memory), - * but be silent if user set keyslot memory cost above default limit intentionally. - */ - cd_pbkdf = crypt_get_pbkdf(cd); - if (cd_pbkdf->max_memory_kb && pbkdf.max_memory_kb > cd_pbkdf->max_memory_kb && - pbkdf.max_memory_kb <= DEFAULT_LUKS2_MEMORY_KB) - log_std(cd, _("Warning: keyslot operation could fail as it requires more than available memory.\n")); - /* * If requested, serialize unlocking for memory-hard KDF. Usually NOOP. */ @@ -371,20 +378,27 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, log_dbg(cd, "Running keyslot key derivation."); r = crypt_pbkdf(pbkdf.type, pbkdf.hash, password, passwordLen, salt, LUKS_SALTSIZE, - derived_key->key, derived_key->keylength, + derived_key, keyslot_key_len, pbkdf.iterations, pbkdf.max_memory_kb, pbkdf.parallel_threads); if (try_serialize_lock) crypt_serialize_unlock(cd); - if (r == 0) { - log_dbg(cd, "Reading keyslot area [0x%04" PRIx64 "].", area_offset); - /* FIXME: sector_offset should be size_t, fix LUKS_decrypt... accordingly */ - r = luks2_decrypt_from_storage(AfKey, AFEKSize, cipher, cipher_mode, - derived_key, (unsigned)(area_offset / SECTOR_SIZE), cd); + if (r < 0) + goto out; + + derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key); + if (!derived_vk) { + r = -ENOMEM; + goto out; } + log_dbg(cd, "Reading keyslot area [0x%04" PRIx64 "].", area_offset); + /* FIXME: sector_offset should be size_t, fix LUKS_decrypt... accordingly */ + r = luks2_decrypt_from_storage(AfKey, AFEKSize, cipher, cipher_mode, + derived_vk, (unsigned)(area_offset / SECTOR_SIZE), cd); + if (r == 0) { r = crypt_hash_size(af_hash); if (r < 0) @@ -394,8 +408,9 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, } out: free(salt); - crypt_free_volume_key(derived_key); + crypt_free_volume_key(derived_vk); crypt_safe_free(AfKey); + crypt_safe_free(derived_key); return r; } diff --git a/lib/luks2/luks2_keyslot_reenc.c b/lib/luks2/luks2_keyslot_reenc.c index 79b96f6..180ac56 100644 --- a/lib/luks2/luks2_keyslot_reenc.c +++ b/lib/luks2/luks2_keyslot_reenc.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2, reencryption keyslot handler * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Ondrej Kozina + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Ondrej Kozina */ #include "luks2_internal.h" diff --git a/lib/luks2/luks2_luks1_convert.c b/lib/luks2/luks2_luks1_convert.c index d652761..6c75f16 100644 --- a/lib/luks2/luks2_luks1_convert.c +++ b/lib/luks2/luks2_luks1_convert.c @@ -2,9 +2,9 @@ /* * LUKS - Linux Unified Key Setup v2, LUKS1 conversion code * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Ondrej Kozina - * Copyright (C) 2015-2024 Milan Broz + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Ondrej Kozina + * Copyright (C) 2015-2025 Milan Broz */ #include "luks2_internal.h" @@ -570,6 +570,7 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct json_object *jobj = NULL; size_t buf_size, buf_offset, luks1_size, luks1_shift = 2 * LUKS2_HDR_16K_LEN - LUKS_ALIGN_KEYSLOTS; uint64_t required_size, max_size = crypt_get_data_offset(cd) * SECTOR_SIZE; + char cipher_spec[MAX_CAPI_LEN]; /* for detached headers max size == device size */ if (!max_size && (r = device_size(crypt_metadata_device(cd), &max_size))) @@ -591,6 +592,15 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct return -EINVAL; } + r = snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", hdr1->cipherName, hdr1->cipherMode); + if (r < 0 || (size_t)r >= sizeof(cipher_spec)) + return -EINVAL; + if (LUKS2_keyslot_cipher_incompatible(cd, cipher_spec)) { + log_err(cd, _("Unable to use cipher specification %s-%s for LUKS2 keyslot."), + hdr1->cipherName, hdr1->cipherMode); + return -EINVAL; + } + if (luksmeta_header_present(cd, luks1_size)) return -EINVAL; @@ -687,30 +697,54 @@ static int keyslot_LUKS1_compatible(struct crypt_device *cd, struct luks2_hdr *h if (!jobj_keyslot) return 1; - if (!json_object_object_get_ex(jobj_keyslot, "type", &jobj) || - strcmp(json_object_get_string(jobj), "luks2")) + /* Keyslot type */ + if (!json_object_object_get_ex(jobj_keyslot, "type", &jobj)) + return 0; + if (strcmp(json_object_get_string(jobj), "luks2")) { + log_dbg(cd, "Keyslot %d type %s is not compatible.", + keyslot, json_object_get_string(jobj)); return 0; + } - /* Using PBKDF2, this implies memory and parallel is not used. */ + /* Keyslot uses PBKDF2, this implies memory and parallel is not used. */ jobj = NULL; if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf) || - !json_object_object_get_ex(jobj_kdf, "type", &jobj) || - strcmp(json_object_get_string(jobj), CRYPT_KDF_PBKDF2) || - !json_object_object_get_ex(jobj_kdf, "hash", &jobj) || - strcmp(json_object_get_string(jobj), hash)) + !json_object_object_get_ex(jobj_kdf, "type", &jobj)) + return 0; + if (strcmp(json_object_get_string(jobj), CRYPT_KDF_PBKDF2)) { + log_dbg(cd, "Keyslot %d does not use PBKDF2.", keyslot); + return 0; + } + + /* Keyslot KDF hash is the same as the digest hash. */ + jobj = NULL; + if (!json_object_object_get_ex(jobj_kdf, "hash", &jobj)) + return 0; + if (strcmp(json_object_get_string(jobj), hash)) { + log_dbg(cd, "Keyslot %d PBKDF uses different hash %s than digest hash %s.", + keyslot, json_object_get_string(jobj), hash); return 0; + } + /* Keyslot AF use compatible striptes. */ jobj = NULL; if (!json_object_object_get_ex(jobj_keyslot, "af", &jobj_af) || - !json_object_object_get_ex(jobj_af, "stripes", &jobj) || - json_object_get_int(jobj) != LUKS_STRIPES) + !json_object_object_get_ex(jobj_af, "stripes", &jobj)) + return 0; + if (json_object_get_int(jobj) != LUKS_STRIPES) { + log_dbg(cd, "Keyslot %d AF uses incompatible stripes count.", keyslot); return 0; + } + /* Keyslot AF hash is the same as the digest hash. */ jobj = NULL; - if (!json_object_object_get_ex(jobj_af, "hash", &jobj) || - (crypt_hash_size(json_object_get_string(jobj)) < 0) || - strcmp(json_object_get_string(jobj), hash)) + if (!json_object_object_get_ex(jobj_af, "hash", &jobj)) + return 0; + if (strcmp(json_object_get_string(jobj), hash)) { + log_dbg(cd, "Keyslot %d AF uses different hash %s than digest hash %s.", + keyslot, json_object_get_string(jobj), hash); return 0; + } ks_cipher = LUKS2_get_keyslot_cipher(hdr, keyslot, &ks_key_size); data_cipher = LUKS2_get_cipher(hdr, CRYPT_DEFAULT_SEGMENT); @@ -743,6 +777,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct int i, r, last_active = 0; uint64_t offset, area_length; char *buf, luksMagic[] = LUKS_MAGIC; + crypt_keyslot_info ki; jobj_digest = LUKS2_get_digest_jobj(hdr2, 0); if (!jobj_digest) @@ -767,6 +802,8 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct if (!json_object_object_get_ex(jobj_digest, "hash", &jobj2)) return -EINVAL; hash = json_object_get_string(jobj2); + if (crypt_hash_size(hash) < 0) + return -EINVAL; r = crypt_parse_name_and_mode(LUKS2_get_cipher(hdr2, CRYPT_DEFAULT_SEGMENT), cipher, NULL, cipher_mode); if (r < 0) @@ -791,19 +828,28 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct } r = LUKS2_get_volume_key_size(hdr2, 0); - if (r < 0) + if (r < 0) { + log_err(cd, _("Cannot convert to LUKS1 format - there are no active keyslots."), r); return -EINVAL; + } key_size = r; for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) { - if (LUKS2_keyslot_info(hdr2, i) == CRYPT_SLOT_INACTIVE) + ki = LUKS2_keyslot_info(hdr2, i); + + if (ki == CRYPT_SLOT_INACTIVE) continue; - if (LUKS2_keyslot_info(hdr2, i) == CRYPT_SLOT_INVALID) { + if (ki == CRYPT_SLOT_INVALID) { log_err(cd, _("Cannot convert to LUKS1 format - keyslot %u is in invalid state."), i); return -EINVAL; } + if (ki == CRYPT_SLOT_UNBOUND) { + log_err(cd, _("Cannot convert to LUKS1 format - keyslot %u is unbound."), i); + return -EINVAL; + } + if (i >= LUKS_NUMKEYS) { log_err(cd, _("Cannot convert to LUKS1 format - slot %u (over maximum slots) is still active."), i); return -EINVAL; diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c index 05f69d1..3210b58 100644 --- a/lib/luks2/luks2_reencrypt.c +++ b/lib/luks2/luks2_reencrypt.c @@ -2,12 +2,13 @@ /* * LUKS - Linux Unified Key Setup v2, reencryption helpers * - * Copyright (C) 2015-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2015-2024 Ondrej Kozina + * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2015-2025 Ondrej Kozina */ #include "luks2_internal.h" #include "utils_device_locking.h" +#include "keyslot_context.h" struct luks2_reencrypt { /* reencryption window attributes */ @@ -53,6 +54,8 @@ struct luks2_reencrypt { uint32_t wflags1; uint32_t wflags2; + struct device *hotzone_device; + struct crypt_lock_handle *reenc_lock; }; #if USE_LUKS2_REENCRYPTION @@ -170,6 +173,16 @@ int LUKS2_reencrypt_digest_old(struct luks2_hdr *hdr) return reencrypt_digest(hdr, 0); } +int LUKS2_reencrypt_segment_new(struct luks2_hdr *hdr) +{ + return LUKS2_get_segment_id_by_flag(hdr, "backup-final"); +} + +int LUKS2_reencrypt_segment_old(struct luks2_hdr *hdr) +{ + return LUKS2_get_segment_id_by_flag(hdr, "backup-previous"); +} + unsigned LUKS2_reencrypt_vks_count(struct luks2_hdr *hdr) { int digest_old, digest_new; @@ -299,7 +312,7 @@ static json_object *reencrypt_make_hot_segments_encrypt_shift(struct luks2_hdr * rh->offset >> SECTOR_SHIFT, &rh->length, reencrypt_segment_cipher_new(hdr), - NULL, /* integrity */ + NULL, 0, /* integrity */ reencrypt_get_sector_size_new(hdr), 1); @@ -355,7 +368,7 @@ static json_object *reencrypt_make_segment_new(struct crypt_device *cd, crypt_get_iv_offset(cd) + (iv_offset >> SECTOR_SHIFT), segment_length, reencrypt_segment_cipher_new(hdr), - NULL, /* integrity */ + NULL, 0, /* integrity */ reencrypt_get_sector_size_new(hdr), 0); case CRYPT_REENCRYPT_DECRYPT: return json_segment_create_linear(data_offset + segment_offset, segment_length, 0); @@ -467,7 +480,7 @@ static json_object *reencrypt_make_segment_reencrypt(struct crypt_device *cd, crypt_get_iv_offset(cd) + (iv_offset >> SECTOR_SHIFT), segment_length, reencrypt_segment_cipher_new(hdr), - NULL, /* integrity */ + NULL, 0, /* integrity */ reencrypt_get_sector_size_new(hdr), 1); case CRYPT_REENCRYPT_DECRYPT: return json_segment_create_linear(data_offset + segment_offset, segment_length, 1); @@ -492,7 +505,7 @@ static json_object *reencrypt_make_segment_old(struct crypt_device *cd, crypt_get_iv_offset(cd) + (segment_offset >> SECTOR_SHIFT), segment_length, reencrypt_segment_cipher_old(hdr), - NULL, /* integrity */ + NULL, 0, /* integrity */ reencrypt_get_sector_size_old(hdr), 0); break; @@ -871,11 +884,13 @@ void LUKS2_reencrypt_free(struct crypt_device *cd, struct luks2_reencrypt *rh) rh->cw1 = NULL; crypt_storage_wrapper_destroy(rh->cw2); rh->cw2 = NULL; + device_free(cd, rh->hotzone_device); + rh->hotzone_device = NULL; free(rh->device_name); free(rh->overlay_name); free(rh->hotzone_name); - crypt_drop_keyring_key(cd, rh->vks); + crypt_drop_uploaded_keyring_key(cd, rh->vks); crypt_free_volume_key(rh->vks); device_release_excl(cd, crypt_data_device(cd)); crypt_unlock_internal(cd, rh->reenc_lock); @@ -1471,8 +1486,7 @@ static int reencrypt_update_flag(struct crypt_device *cd, uint8_t version, return LUKS2_config_set_requirement_version(cd, hdr, CRYPT_REQUIREMENT_ONLINE_REENCRYPT, version, commit); } - if (LUKS2_config_get_requirements(cd, hdr, &reqs)) - return -EINVAL; + LUKS2_config_get_requirements(cd, hdr, &reqs); reqs &= ~CRYPT_REQUIREMENT_ONLINE_REENCRYPT; @@ -1920,14 +1934,13 @@ static int reencrypt_assign_segments(struct crypt_device *cd, } static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_hdr *hdr, - uint64_t dev_size, uint64_t data_shift, bool move_first_segment, + uint64_t dev_size, uint64_t data_size, uint64_t data_shift, bool move_first_segment, crypt_reencrypt_direction_info di) { int r; uint64_t first_segment_offset, first_segment_length, second_segment_offset, second_segment_length, - data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT, - data_size = dev_size - data_shift; + data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT; json_object *jobj_segment_first = NULL, *jobj_segment_second = NULL, *jobj_segments; if (dev_size < data_shift) @@ -1994,13 +2007,17 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd, uint64_t moved_segment_length, crypt_reencrypt_direction_info di) { - int r; + int digest, r; uint64_t data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT; json_object *jobj_segment_first = NULL, *jobj_segment_second = NULL, *jobj_segments; if (di == CRYPT_REENCRYPT_BACKWARD) return -ENOTSUP; + digest = LUKS2_digest_by_segment(hdr, CRYPT_DEFAULT_SEGMENT); + if (digest < 0) + return -EINVAL; + /* * future data_device layout: * [encrypted first segment (max data shift size)][gap (data shift size)][second encrypted data segment] @@ -2012,7 +2029,7 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd, r = -EINVAL; jobj_segment_first = json_segment_create_crypt(0, crypt_get_iv_offset(cd), &moved_segment_length, crypt_get_cipher_spec(cd), - NULL, crypt_get_sector_size(cd), 0); + NULL, 0, crypt_get_sector_size(cd), 0); if (!jobj_segment_first) { log_dbg(cd, "Failed generate 1st segment."); @@ -2028,7 +2045,7 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd, crypt_get_iv_offset(cd) + (moved_segment_length >> SECTOR_SHIFT), NULL, crypt_get_cipher_spec(cd), - NULL, /* integrity */ + NULL, 0, /* integrity */ crypt_get_sector_size(cd), 0); if (!jobj_segment_second) { r = -EINVAL; @@ -2042,7 +2059,7 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd, } if (!(r = LUKS2_segments_set(cd, hdr, jobj_segments, 0))) - return LUKS2_digest_segment_assign(cd, hdr, CRYPT_ANY_SEGMENT, 0, 1, 0); + return LUKS2_digest_segment_assign(cd, hdr, CRYPT_ANY_SEGMENT, digest, 1, 0); err: json_object_put(jobj_segment_first); json_object_put(jobj_segment_second); @@ -2099,8 +2116,7 @@ static int reencrypt_make_targets(struct crypt_device *cd, json_segment_get_cipher(jobj), json_segment_get_iv_offset(jobj), segment_offset, - "none", - 0, + "none", 0, 0, json_segment_get_sector_size(jobj)); if (r) { log_err(cd, _("Failed to set dm-crypt segment.")); @@ -2130,34 +2146,22 @@ static int reencrypt_make_targets(struct crypt_device *cd, * 2) can't we derive hotzone device name from crypt context? (unlocked name, device uuid, etc?) */ static int reencrypt_load_overlay_device(struct crypt_device *cd, struct luks2_hdr *hdr, - const char *overlay, const char *hotzone, struct volume_key *vks, uint64_t size, + const char *overlay, struct device *hotzone_device, struct volume_key *vks, uint64_t size, uint32_t flags) { - char hz_path[PATH_MAX]; int r; - struct device *hz_dev = NULL; struct crypt_dm_active_device dmd = { .flags = flags, }; log_dbg(cd, "Loading new table for overlay device %s.", overlay); - r = snprintf(hz_path, PATH_MAX, "%s/%s", dm_get_dir(), hotzone); - if (r < 0 || r >= PATH_MAX) { - r = -EINVAL; - goto out; - } - - r = device_alloc(cd, &hz_dev, hz_path); - if (r) - goto out; - r = dm_targets_allocate(&dmd.segment, LUKS2_segments_count(hdr)); if (r) goto out; - r = reencrypt_make_targets(cd, hdr, hz_dev, vks, &dmd.segment, size); + r = reencrypt_make_targets(cd, hdr, hotzone_device, vks, &dmd.segment, size); if (r < 0) goto out; @@ -2166,7 +2170,6 @@ static int reencrypt_load_overlay_device(struct crypt_device *cd, struct luks2_h /* what else on error here ? */ out: dm_targets_free(cd, &dmd); - device_free(cd, hz_dev); return r; } @@ -2175,7 +2178,7 @@ static int reencrypt_replace_device(struct crypt_device *cd, const char *target, { int r, exists = 1; struct crypt_dm_active_device dmd_source, dmd_target = {}; - uint32_t dmflags = DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH; + uint64_t dmflags = DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH; log_dbg(cd, "Replacing table in device %s with table from device %s.", target, source); @@ -2293,9 +2296,13 @@ static int reencrypt_activate_hotzone_device(struct crypt_device *cd, const char } static int reencrypt_init_device_stack(struct crypt_device *cd, - const struct luks2_reencrypt *rh) + struct luks2_reencrypt *rh) { int r; + char hz_path[PATH_MAX]; + + assert(rh); + assert(!rh->hotzone_device); /* Activate hotzone device 1:1 linear mapping to data_device */ r = reencrypt_activate_hotzone_device(cd, rh->hotzone_name, rh->device_size, CRYPT_ACTIVATE_PRIVATE); @@ -2304,6 +2311,18 @@ static int reencrypt_init_device_stack(struct crypt_device *cd, return r; } + r = snprintf(hz_path, PATH_MAX, "%s/%s", dm_get_dir(), rh->hotzone_name); + if (r < 0 || r >= PATH_MAX) { + r = -EINVAL; + goto err; + } + + r = device_alloc(cd, &rh->hotzone_device, hz_path); + if (r) { + log_err(cd, _("Failed to allocate hotzone device %s."), rh->hotzone_name); + goto err; + } + /* * Activate overlay device with exactly same table as original 'name' mapping. * Note that within this step the 'name' device may already include a table @@ -2383,11 +2402,12 @@ static int reencrypt_refresh_overlay_devices(struct crypt_device *cd, struct luks2_hdr *hdr, const char *overlay, const char *hotzone, + struct device *hotzone_device, struct volume_key *vks, uint64_t device_size, uint32_t flags) { - int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone, vks, device_size, flags); + int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone_device, vks, device_size, flags); if (r) { log_err(cd, _("Failed to reload device %s."), overlay); return REENC_ERR; @@ -2455,23 +2475,20 @@ static int reencrypt_move_data(struct crypt_device *cd, static int reencrypt_make_backup_segments(struct crypt_device *cd, struct luks2_hdr *hdr, - int keyslot_new, + int digest_new, const char *cipher, uint64_t data_offset, const struct crypt_params_reencrypt *params) { const char *type; - int r, segment, moved_segment = -1, digest_old = -1, digest_new = -1; + int r, segment, moved_segment = -1, digest_old = -1; json_object *jobj_tmp, *jobj_segment_new = NULL, *jobj_segment_old = NULL, *jobj_segment_bcp = NULL; uint32_t sector_size = params->luks2 ? params->luks2->sector_size : SECTOR_SIZE; uint64_t segment_offset, tmp, data_shift = params->data_shift << SECTOR_SHIFT, device_size = params->device_size << SECTOR_SHIFT; - if (params->mode != CRYPT_REENCRYPT_DECRYPT) { - digest_new = LUKS2_digest_by_keyslot(hdr, keyslot_new); - if (digest_new < 0) - return -EINVAL; - } + if (params->mode != CRYPT_REENCRYPT_DECRYPT && digest_new < 0) + return -EINVAL; if (params->mode != CRYPT_REENCRYPT_ENCRYPT) { digest_old = LUKS2_digest_by_segment(hdr, CRYPT_DEFAULT_SEGMENT); @@ -2518,7 +2535,7 @@ static int reencrypt_make_backup_segments(struct crypt_device *cd, json_segment_get_iv_offset(jobj_tmp), device_size ? &device_size : NULL, json_segment_get_cipher(jobj_tmp), - NULL, /* integrity */ + NULL, 0, /* integrity */ json_segment_get_sector_size(jobj_tmp), 0); } else { @@ -2565,7 +2582,7 @@ static int reencrypt_make_backup_segments(struct crypt_device *cd, } jobj_segment_new = json_segment_create_crypt(segment_offset, crypt_get_iv_offset(cd), - NULL, cipher, NULL, sector_size, 0); + NULL, cipher, NULL, 0, sector_size, 0); } else if (params->mode == CRYPT_REENCRYPT_DECRYPT) { segment_offset = data_offset; if (modify_offset(&segment_offset, data_shift, params->direction)) { @@ -2668,7 +2685,7 @@ static int reencrypt_upload_keys(struct crypt_device *cd, if (digest_old >= 0 && !crypt_is_cipher_null(reencrypt_segment_cipher_old(hdr)) && (r = reencrypt_upload_single_key(cd, digest_old, vks))) { - crypt_drop_keyring_key(cd, vks); + crypt_drop_uploaded_keyring_key(cd, vks); return r; } @@ -2779,8 +2796,7 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd, uint32_t sector_size, uint64_t data_size, uint64_t data_offset, - const char *passphrase, - size_t passphrase_size, + struct crypt_keyslot_context *kc_old, int keyslot_old, const struct crypt_params_reencrypt *params, struct volume_key **vks) @@ -2839,7 +2855,7 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd, if (r) goto out; - r = reencrypt_make_backup_segments(cd, hdr, CRYPT_ANY_SLOT, NULL, data_offset, params); + r = reencrypt_make_backup_segments(cd, hdr, CRYPT_ANY_DIGEST, NULL, data_offset, params); if (r) { log_dbg(cd, "Failed to create reencryption backup device segments."); goto out; @@ -2875,8 +2891,8 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd, goto out; } - r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, CRYPT_ANY_SLOT, - passphrase, passphrase_size, vks); + r = LUKS2_keyslot_context_open_all_segments(cd, keyslot_old, CRYPT_ANY_SLOT, + kc_old, NULL, vks); if (r < 0) goto out; @@ -2900,6 +2916,8 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd, jobj_segments_old = reencrypt_segments_old(hdr); if (!jobj_segments_old) { + dm_targets_free(cd, &dmd_target); + free(CONST_CAST(void*)dmd_target.uuid); r = -EINVAL; goto out; } @@ -2971,8 +2989,8 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd, static int reencrypt_init(struct crypt_device *cd, const char *name, struct luks2_hdr *hdr, - const char *passphrase, - size_t passphrase_size, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, int keyslot_old, int keyslot_new, const char *cipher, @@ -2983,8 +3001,9 @@ static int reencrypt_init(struct crypt_device *cd, bool move_first_segment; char _cipher[128]; uint32_t check_sector_size, new_sector_size, old_sector_size; - int r, reencrypt_keyslot, devfd = -1; - uint64_t data_offset, data_size = 0; + int digest_new, r, reencrypt_keyslot, devfd = -1; + uint64_t data_offset_bytes, data_size_bytes, data_shift_bytes, device_size_bytes; + struct volume_key *vk; struct crypt_dm_active_device dmd_target, dmd_source = { .uuid = crypt_get_uuid(cd), .flags = CRYPT_ACTIVATE_SHARED /* turn off exclusive open checks */ @@ -2997,7 +3016,8 @@ static int reencrypt_init(struct crypt_device *cd, return -EINVAL; if (params->mode != CRYPT_REENCRYPT_DECRYPT && - (!params->luks2 || !(cipher && cipher_mode) || keyslot_new < 0)) + (!params->luks2 || !(cipher && cipher_mode) || + (keyslot_new < 0 && !(params->flags & CRYPT_REENCRYPT_CREATE_NEW_DIGEST)))) return -EINVAL; log_dbg(cd, "Initializing reencryption (mode: %s) in LUKS2 metadata.", @@ -3024,31 +3044,54 @@ static int reencrypt_init(struct crypt_device *cd, if (r < 0 || (size_t)r >= sizeof(_cipher)) return -EINVAL; - data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT; + data_offset_bytes = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT; r = device_check_access(cd, crypt_data_device(cd), DEV_OK); if (r) return r; - r = device_check_size(cd, crypt_data_device(cd), data_offset, 1); + r = device_check_size(cd, crypt_data_device(cd), data_offset_bytes, 1); if (r) return r; - r = device_size(crypt_data_device(cd), &data_size); + r = device_size(crypt_data_device(cd), &device_size_bytes); if (r) return r; - data_size -= data_offset; + if (move_first_segment && params->mode == CRYPT_REENCRYPT_ENCRYPT && + params->data_shift < LUKS2_get_data_offset(hdr)) { + log_err(cd, _("Data shift (%" PRIu64 " sectors) is less than future data offset (%" PRIu64 " sectors)."), + params->data_shift, LUKS2_get_data_offset(hdr)); + return -EINVAL; + } + + device_size_bytes -= data_offset_bytes; + data_shift_bytes = params->data_shift << SECTOR_SHIFT; + data_size_bytes = params->device_size << SECTOR_SHIFT; + + if (device_size_bytes < data_shift_bytes && params->direction == CRYPT_REENCRYPT_BACKWARD) { + log_err(cd, _("Device %s is too small."), device_path(crypt_data_device(cd))); + return -EINVAL; + } - if (params->device_size) { - if ((params->device_size << SECTOR_SHIFT) > data_size) { + if (data_size_bytes > device_size_bytes) { + log_err(cd, _("Reduced data size is larger than real device size.")); + return -EINVAL; + } + + if (data_size_bytes && params->mode == CRYPT_REENCRYPT_ENCRYPT && + move_first_segment && data_shift_bytes) { + if (data_size_bytes > device_size_bytes - data_shift_bytes) { log_err(cd, _("Reduced data size is larger than real device size.")); return -EINVAL; - } else - data_size = params->device_size << SECTOR_SHIFT; - } + } + } else if (!data_size_bytes && params->mode == CRYPT_REENCRYPT_ENCRYPT && + move_first_segment && data_shift_bytes) + data_size_bytes = device_size_bytes - data_shift_bytes; + else if (!data_size_bytes) + data_size_bytes = device_size_bytes; - if (MISALIGNED(data_size, check_sector_size)) { + if (MISALIGNED(data_size_bytes, check_sector_size)) { log_err(cd, _("Data device is not aligned to encryption sector size (%" PRIu32 " bytes)."), check_sector_size); return -EINVAL; } @@ -3059,34 +3102,23 @@ static int reencrypt_init(struct crypt_device *cd, return -EINVAL; } - if (params->mode == CRYPT_REENCRYPT_DECRYPT && (params->data_shift > 0) && move_first_segment) + if (params->mode == CRYPT_REENCRYPT_DECRYPT && data_shift_bytes && move_first_segment) return reencrypt_decrypt_with_datashift_init(cd, name, hdr, reencrypt_keyslot, check_sector_size, - data_size, - data_offset, - passphrase, - passphrase_size, + data_size_bytes, + data_offset_bytes, + kc_old, keyslot_old, params, vks); - /* * We must perform data move with exclusive open data device * to exclude another cryptsetup process to colide with * encryption initialization (or mount) */ if (move_first_segment) { - if (data_size < (params->data_shift << SECTOR_SHIFT)) { - log_err(cd, _("Device %s is too small."), device_path(crypt_data_device(cd))); - return -EINVAL; - } - if (params->data_shift < LUKS2_get_data_offset(hdr)) { - log_err(cd, _("Data shift (%" PRIu64 " sectors) is less than future data offset (%" PRIu64 " sectors)."), - params->data_shift, LUKS2_get_data_offset(hdr)); - return -EINVAL; - } devfd = device_open_excl(cd, crypt_data_device(cd), O_RDWR); if (devfd < 0) { if (devfd == -EBUSY) @@ -3098,15 +3130,33 @@ static int reencrypt_init(struct crypt_device *cd, if (params->mode == CRYPT_REENCRYPT_ENCRYPT) { /* in-memory only */ - r = reencrypt_set_encrypt_segments(cd, hdr, data_size, - params->data_shift << SECTOR_SHIFT, + r = reencrypt_set_encrypt_segments(cd, hdr, device_size_bytes, data_size_bytes, + data_shift_bytes, move_first_segment, params->direction); if (r) goto out; } - r = reencrypt_make_backup_segments(cd, hdr, keyslot_new, _cipher, data_offset, params); + if (params->flags & CRYPT_REENCRYPT_CREATE_NEW_DIGEST) { + assert(kc_new->get_luks2_key); + r = kc_new->get_luks2_key(cd, kc_new, CRYPT_ANY_SLOT, CRYPT_ANY_SEGMENT, &vk); + if (r < 0) + goto out; + + /* do not create new digest in case it matches the current one */ + r = LUKS2_digest_verify_by_segment(cd, hdr, CRYPT_DEFAULT_SEGMENT, vk); + if (r == -EPERM || r == -ENOENT) + r = LUKS2_digest_create(cd, "pbkdf2", hdr, vk); + + crypt_free_volume_key(vk); + if (r < 0) + goto out; + digest_new = r; + } else + digest_new = LUKS2_digest_by_keyslot(hdr, keyslot_new); + + r = reencrypt_make_backup_segments(cd, hdr, digest_new, _cipher, data_offset_bytes, params); if (r) { log_dbg(cd, "Failed to create reencryption backup device segments."); goto out; @@ -3121,7 +3171,7 @@ static int reencrypt_init(struct crypt_device *cd, if (r < 0) goto out; - r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, keyslot_new, passphrase, passphrase_size, vks); + r = LUKS2_keyslot_context_open_all_segments(cd, keyslot_old, keyslot_new, kc_old, kc_new, vks); if (r < 0) goto out; @@ -3155,12 +3205,12 @@ static int reencrypt_init(struct crypt_device *cd, goto out; } - if (move_first_segment && reencrypt_move_data(cd, devfd, params->data_shift << SECTOR_SHIFT, params->mode)) { + if (move_first_segment && reencrypt_move_data(cd, devfd, data_shift_bytes, params->mode)) { r = -EIO; goto out; } - /* This must be first and only write in LUKS2 metadata during _reencrypt_init */ + /* This must be first and only write in LUKS2 metadata during reencrypt_init */ r = reencrypt_update_flag(cd, LUKS2_REENCRYPT_REQ_VERSION, true, true); if (r) { log_dbg(cd, "Failed to set online-reencryption requirement."); @@ -3356,7 +3406,7 @@ int LUKS2_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid dm_uuid + 6, dm_uuid + 14, dm_uuid + 18, dm_uuid + 22, dm_uuid + 26); if (r < 0 || (size_t)r != (sizeof(hdr_uuid) - 1)) return -EINVAL; - } else if (crypt_uuid_cmp(dm_uuid, uuid)) + } else if (dm_uuid_cmp(dm_uuid, uuid)) return -EINVAL; return reencrypt_lock_internal(cd, uuid, reencrypt_lock); @@ -3385,10 +3435,8 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr * struct crypt_lock_handle *h; ri = LUKS2_reencrypt_status(hdr); - if (ri == CRYPT_REENCRYPT_INVALID) { - log_err(cd, _("Failed to get reencryption state.")); + if (ri == CRYPT_REENCRYPT_INVALID) return -EINVAL; - } if (ri < CRYPT_REENCRYPT_CLEAN) { log_err(cd, _("Device is not in reencryption.")); return -EINVAL; @@ -3421,10 +3469,10 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr * return -EINVAL; } -static int reencrypt_load_by_passphrase(struct crypt_device *cd, +static int reencrypt_load_by_keyslot_context(struct crypt_device *cd, const char *name, - const char *passphrase, - size_t passphrase_size, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, int keyslot_old, int keyslot_new, struct volume_key **vks, @@ -3504,7 +3552,8 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd, r = reencrypt_verify_keys(cd, LUKS2_reencrypt_digest_old(hdr), LUKS2_reencrypt_digest_new(hdr), *vks); if (r == -ENOENT) { log_dbg(cd, "Keys are not ready. Unlocking all volume keys."); - r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, keyslot_new, passphrase, passphrase_size, vks); + r = LUKS2_keyslot_context_open_all_segments(cd, keyslot_old, keyslot_new, + kc_old, kc_new, vks); } if (r < 0) @@ -3530,7 +3579,7 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd, * above. The code checks if new VK is eligible for keyring. */ vk = crypt_volume_key_by_id(*vks, LUKS2_reencrypt_digest_new(hdr)); - if (vk && vk->key_description && crypt_is_cipher_null(reencrypt_segment_cipher_old(hdr))) { + if (vk && crypt_volume_key_description(vk) && crypt_is_cipher_null(reencrypt_segment_cipher_old(hdr))) { flags |= CRYPT_ACTIVATE_KEYRING_KEY; dmd_source.flags |= CRYPT_ACTIVATE_KEYRING_KEY; } @@ -3629,12 +3678,37 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd, return r; } -static int reencrypt_recovery_by_passphrase(struct crypt_device *cd, +static int reencrypt_locked_recovery(struct crypt_device *cd, + int keyslot_old, + int keyslot_new, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, + struct volume_key **r_vks) +{ + int keyslot, r = -EINVAL; + struct volume_key *_vks = NULL; + + r = LUKS2_keyslot_context_open_all_segments(cd, keyslot_old, keyslot_new, + kc_old, kc_new, &_vks); + if (r < 0) + return r; + keyslot = r; + + r = LUKS2_reencrypt_locked_recovery_by_vks(cd, _vks); + if (!r && r_vks) + MOVE_REF(*r_vks, _vks); + + crypt_free_volume_key(_vks); + + return r < 0 ? r : keyslot; +} + +static int reencrypt_recovery_by_keyslot_context(struct crypt_device *cd, struct luks2_hdr *hdr, int keyslot_old, int keyslot_new, - const char *passphrase, - size_t passphrase_size) + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new) { int r; crypt_reencrypt_info ri; @@ -3661,8 +3735,8 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd, } if (ri == CRYPT_REENCRYPT_CRASH) { - r = LUKS2_reencrypt_locked_recovery_by_passphrase(cd, keyslot_old, keyslot_new, - passphrase, passphrase_size, NULL); + r = reencrypt_locked_recovery(cd, keyslot_old, keyslot_new, + kc_old, kc_new, NULL); if (r < 0) log_err(cd, _("LUKS2 reencryption recovery failed.")); } else { @@ -3674,13 +3748,13 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd, return r; } -static int reencrypt_repair_by_passphrase( +static int reencrypt_repair( struct crypt_device *cd, struct luks2_hdr *hdr, int keyslot_old, int keyslot_new, - const char *passphrase, - size_t passphrase_size) + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new) { int r; struct crypt_lock_handle *reencrypt_lock; @@ -3745,7 +3819,7 @@ static int reencrypt_repair_by_passphrase( else requirement_version = LUKS2_REENCRYPT_REQ_VERSION; - r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, keyslot_new, passphrase, passphrase_size, &vks); + r = LUKS2_keyslot_context_open_all_segments(cd, keyslot_old, keyslot_new, kc_old, kc_new, &vks); if (r < 0) goto out; @@ -3764,10 +3838,10 @@ static int reencrypt_repair_by_passphrase( } -static int reencrypt_init_by_passphrase(struct crypt_device *cd, +static int reencrypt_init_by_keyslot_context(struct crypt_device *cd, const char *name, - const char *passphrase, - size_t passphrase_size, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, int keyslot_old, int keyslot_new, const char *cipher, @@ -3776,30 +3850,42 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd, { int r; crypt_reencrypt_info ri; + size_t key_length; struct volume_key *vks = NULL; uint32_t flags = params ? params->flags : 0; struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); + if (params && (params->flags & CRYPT_REENCRYPT_CREATE_NEW_DIGEST) && + (!kc_new || !kc_new->get_luks2_key || !kc_new->get_key_size || + (params->flags & CRYPT_REENCRYPT_RESUME_ONLY))) + return -EINVAL; + /* short-circuit in reencryption metadata update and finish immediately. */ if (flags & CRYPT_REENCRYPT_REPAIR_NEEDED) - return reencrypt_repair_by_passphrase(cd, hdr, keyslot_old, keyslot_new, passphrase, passphrase_size); + return reencrypt_repair(cd, hdr, keyslot_old, keyslot_new, kc_old, kc_new); /* short-circuit in recovery and finish immediately. */ if (flags & CRYPT_REENCRYPT_RECOVERY) - return reencrypt_recovery_by_passphrase(cd, hdr, keyslot_old, keyslot_new, passphrase, passphrase_size); + return reencrypt_recovery_by_keyslot_context(cd, hdr, keyslot_old, keyslot_new, kc_old, kc_new); if (name && !device_direct_io(crypt_data_device(cd))) { log_dbg(cd, "Device %s does not support direct I/O.", device_path(crypt_data_device(cd))); - /* FIXME: Add more specific error mesage for translation later. */ + /* FIXME: Add more specific error message for translation later. */ log_err(cd, _("Failed to initialize reencryption device stack.")); return -EINVAL; } if (cipher && !crypt_cipher_wrapped_key(cipher, cipher_mode)) { - r = crypt_keyslot_get_key_size(cd, keyslot_new); + if (keyslot_new == CRYPT_ANY_SLOT && kc_new && kc_new->get_key_size) + r = kc_new->get_key_size(cd, kc_new, &key_length); + else { + r = crypt_keyslot_get_key_size(cd, keyslot_new); + if (r >= 0) + key_length = r; + } if (r < 0) return r; - r = LUKS2_check_cipher(cd, r, cipher, cipher_mode); + r = LUKS2_check_cipher(cd, key_length, cipher, cipher_mode); if (r < 0) { log_err(cd, _("Unable to use cipher specification %s-%s for LUKS2."), cipher, cipher_mode); return r; @@ -3823,7 +3909,8 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd, } if (ri == CRYPT_REENCRYPT_NONE && !(flags & CRYPT_REENCRYPT_RESUME_ONLY)) { - r = reencrypt_init(cd, name, hdr, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params, &vks); + r = reencrypt_init(cd, name, hdr, kc_old, kc_new, keyslot_old, + keyslot_new, cipher, cipher_mode, params, &vks); if (r < 0) log_err(cd, _("Failed to initialize LUKS2 reencryption in metadata.")); } else if (ri > CRYPT_REENCRYPT_NONE) { @@ -3836,18 +3923,19 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd, if (r < 0 || (flags & CRYPT_REENCRYPT_INITIALIZE_ONLY)) goto out; - r = reencrypt_load_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, &vks, params); + r = reencrypt_load_by_keyslot_context(cd, name, kc_old, kc_new, keyslot_old, + keyslot_new, &vks, params); out: if (r < 0) - crypt_drop_keyring_key(cd, vks); + crypt_drop_uploaded_keyring_key(cd, vks); crypt_free_volume_key(vks); return r < 0 ? r : LUKS2_find_keyslot(hdr, "reencrypt"); } #else -static int reencrypt_init_by_passphrase(struct crypt_device *cd, +static int reencrypt_init_by_keyslot_context(struct crypt_device *cd, const char *name __attribute__((unused)), - const char *passphrase __attribute__((unused)), - size_t passphrase_size __attribute__((unused)), + struct crypt_keyslot_context *kc_old __attribute__((unused)), + struct crypt_keyslot_context *kc_new __attribute__((unused)), int keyslot_old __attribute__((unused)), int keyslot_new __attribute__((unused)), const char *cipher __attribute__((unused)), @@ -3869,8 +3957,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd, const struct crypt_params_reencrypt *params) { int r; - char *passphrase; - size_t passphrase_size; + struct crypt_keyslot_context kc = {0}; if (onlyLUKS2reencrypt(cd) || !passphrase_description) return -EINVAL; @@ -3882,17 +3969,11 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd, return -EINVAL; } - r = crypt_keyring_get_user_key(cd, passphrase_description, &passphrase, &passphrase_size); - if (r < 0) { - log_dbg(cd, "crypt_keyring_get_user_key failed (error %d)", r); - log_err(cd, _("Failed to read passphrase from keyring.")); - return -EINVAL; - } - - r = reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params); + crypt_keyslot_context_init_by_keyring_internal(&kc, passphrase_description); + r = reencrypt_init_by_keyslot_context(cd, name, &kc, &kc, keyslot_old, + keyslot_new, cipher, cipher_mode, params); - crypt_safe_memzero(passphrase, passphrase_size); - free(passphrase); + crypt_keyslot_context_destroy_internal(&kc); return r; } @@ -3907,6 +3988,9 @@ int crypt_reencrypt_init_by_passphrase(struct crypt_device *cd, const char *cipher_mode, const struct crypt_params_reencrypt *params) { + int r; + struct crypt_keyslot_context kc = {0}; + if (onlyLUKS2reencrypt(cd) || !passphrase) return -EINVAL; if (params && (params->flags & CRYPT_REENCRYPT_INITIALIZE_ONLY) && (params->flags & CRYPT_REENCRYPT_RESUME_ONLY)) @@ -3917,7 +4001,37 @@ int crypt_reencrypt_init_by_passphrase(struct crypt_device *cd, return -EINVAL; } - return reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params); + crypt_keyslot_context_init_by_passphrase_internal(&kc, passphrase, passphrase_size); + + r = reencrypt_init_by_keyslot_context(cd, name, &kc, &kc, keyslot_old, + keyslot_new, cipher, cipher_mode, params); + + crypt_keyslot_context_destroy_internal(&kc); + + return r; +} + +int crypt_reencrypt_init_by_keyslot_context(struct crypt_device *cd, + const char *name, + struct crypt_keyslot_context *kc_old, + struct crypt_keyslot_context *kc_new, + int keyslot_old, + int keyslot_new, + const char *cipher, + const char *cipher_mode, + const struct crypt_params_reencrypt *params) +{ + if (onlyLUKS2reencrypt(cd) || (!kc_old && !kc_new)) + return -EINVAL; + if (params && (params->flags & CRYPT_REENCRYPT_INITIALIZE_ONLY) && (params->flags & CRYPT_REENCRYPT_RESUME_ONLY)) + return -EINVAL; + + if (device_is_dax(crypt_data_device(cd)) > 0) { + log_err(cd, _("Reencryption is not supported for DAX (persistent memory) devices.")); + return -EINVAL; + } + + return reencrypt_init_by_keyslot_context(cd, name, kc_old, kc_new, keyslot_old, keyslot_new, cipher, cipher_mode, params); } #if USE_LUKS2_REENCRYPTION @@ -3977,7 +4091,8 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd, } if (online) { - r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name, rh->vks, rh->device_size, rh->flags); + r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name, + rh->hotzone_device, rh->vks, rh->device_size, rh->flags); /* Teardown overlay devices with dm-error. None bio shall pass! */ if (r != REENC_OK) return r; @@ -4103,7 +4218,7 @@ static int reencrypt_wipe_unused_device_area(struct crypt_device *cd, struct luk static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr, struct luks2_reencrypt *rh) { int i, r; - uint32_t dmt_flags; + uint64_t dmt_flags; bool finished = !(rh->device_size > rh->progress); if (rh->rp.type == REENC_PROTECTION_NONE && @@ -4386,76 +4501,17 @@ int LUKS2_reencrypt_check_device_size(struct crypt_device *cd, struct luks2_hdr } #if USE_LUKS2_REENCRYPTION /* returns keyslot number on success (>= 0) or negative errnor otherwise */ -int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd, - int keyslot_old, - int keyslot_new, - const char *passphrase, - size_t passphrase_size, - struct volume_key **vks) -{ - uint64_t minimal_size, device_size; - int keyslot, r = -EINVAL; - struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); - struct volume_key *vk = NULL, *_vks = NULL; - - log_dbg(cd, "Entering reencryption crash recovery."); - - if (LUKS2_get_data_size(hdr, &minimal_size, NULL)) - return r; - - r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, keyslot_new, - passphrase, passphrase_size, &_vks); - if (r < 0) - goto out; - keyslot = r; - - if (crypt_use_keyring_for_vk(cd)) - vk = _vks; - - while (vk) { - r = LUKS2_volume_key_load_in_keyring_by_digest(cd, vk, crypt_volume_key_get_id(vk)); - if (r < 0) - goto out; - vk = crypt_volume_key_next(vk); - } - - if (LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, true, false)) - goto out; - - r = reencrypt_recovery(cd, hdr, device_size, _vks); - - if (!r && vks) - MOVE_REF(*vks, _vks); -out: - if (r < 0) - crypt_drop_keyring_key(cd, _vks); - crypt_free_volume_key(_vks); - - return r < 0 ? r : keyslot; -} - int LUKS2_reencrypt_locked_recovery_by_vks(struct crypt_device *cd, struct volume_key *vks) { uint64_t minimal_size, device_size; int r = -EINVAL; struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); - struct volume_key *vk = NULL; log_dbg(cd, "Entering reencryption crash recovery."); if (LUKS2_get_data_size(hdr, &minimal_size, NULL)) return r; - - if (crypt_use_keyring_for_vk(cd)) - vk = vks; - while (vk) { - r = LUKS2_volume_key_load_in_keyring_by_digest(cd, vk, crypt_volume_key_get_id(vk)); - if (r < 0) - goto out; - vk = crypt_volume_key_next(vk); - } - if (LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, true, false)) goto out; @@ -4463,7 +4519,7 @@ int LUKS2_reencrypt_locked_recovery_by_vks(struct crypt_device *cd, out: if (r < 0) - crypt_drop_keyring_key(cd, vks); + crypt_drop_uploaded_keyring_key(cd, vks); return r; } #endif diff --git a/lib/luks2/luks2_reencrypt_digest.c b/lib/luks2/luks2_reencrypt_digest.c index 94e77be..9db88a4 100644 --- a/lib/luks2/luks2_reencrypt_digest.c +++ b/lib/luks2/luks2_reencrypt_digest.c @@ -2,9 +2,9 @@ /* * LUKS - Linux Unified Key Setup v2, reencryption digest helpers * - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2022-2024 Ondrej Kozina - * Copyright (C) 2022-2024 Milan Broz + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Ondrej Kozina + * Copyright (C) 2022-2025 Milan Broz */ #include "luks2_internal.h" @@ -240,10 +240,10 @@ static size_t reenc_keyslot_serialize(struct luks2_hdr *hdr, uint8_t *buffer) return srs(j, buffer); } -static size_t blob_serialize(void *blob, size_t length, uint8_t *buffer) +static size_t blob_serialize(const void *blob, size_t length, uint8_t *buffer) { if (buffer) - memcpy(buffer, blob, length); + crypt_safe_memcpy(buffer, blob, length); return length; } @@ -252,12 +252,13 @@ static int reencrypt_assembly_verification_data(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks, uint8_t version, - struct volume_key **verification_data) + struct volume_key **r_verification_data) { uint8_t *ptr; - int digest_new, digest_old; - struct volume_key *data = NULL, *vk_old = NULL, *vk_new = NULL; + int digest_new, digest_old, r = -EINVAL; + struct volume_key *verification_data = NULL, *vk_old = NULL, *vk_new = NULL; size_t keyslot_data_len, segments_data_len, data_len = 2; + void *data = NULL; /* * This works up to (including) version v207. @@ -274,7 +275,7 @@ static int reencrypt_assembly_verification_data(struct crypt_device *cd, log_dbg(cd, "Key (digest id %d) required but not unlocked.", digest_old); return -EINVAL; } - data_len += blob_serialize(vk_old->key, vk_old->keylength, NULL); + data_len += blob_serialize(crypt_volume_key_get_key(vk_old), crypt_volume_key_length(vk_old), NULL); } if (digest_new >= 0 && digest_old != digest_new) { @@ -283,7 +284,7 @@ static int reencrypt_assembly_verification_data(struct crypt_device *cd, log_dbg(cd, "Key (digest id %d) required but not unlocked.", digest_new); return -EINVAL; } - data_len += blob_serialize(vk_new->key, vk_new->keylength, NULL); + data_len += blob_serialize(crypt_volume_key_get_key(vk_new), crypt_volume_key_length(vk_new), NULL); } if (data_len == 2) @@ -299,20 +300,22 @@ static int reencrypt_assembly_verification_data(struct crypt_device *cd, data_len += segments_data_len; /* Alloc and fill serialization data */ - data = crypt_alloc_volume_key(data_len, NULL); + data = crypt_safe_alloc(data_len); if (!data) return -ENOMEM; - ptr = (uint8_t*)data->key; + ptr = (uint8_t*)data; *ptr++ = 0x76; *ptr++ = 0x30 + version; if (vk_old) - ptr += blob_serialize(vk_old->key, vk_old->keylength, ptr); + ptr += blob_serialize(crypt_volume_key_get_key(vk_old), + crypt_volume_key_length(vk_old), ptr); if (vk_new) - ptr += blob_serialize(vk_new->key, vk_new->keylength, ptr); + ptr += blob_serialize(crypt_volume_key_get_key(vk_new), + crypt_volume_key_length(vk_new), ptr); if (!reenc_keyslot_serialize(hdr, ptr)) goto bad; @@ -322,14 +325,20 @@ static int reencrypt_assembly_verification_data(struct crypt_device *cd, goto bad; ptr += segments_data_len; - assert((size_t)(ptr - (uint8_t*)data->key) == data_len); + assert((size_t)(ptr - (uint8_t*)data) == data_len); - *verification_data = data; + verification_data = crypt_alloc_volume_key_by_safe_alloc(&data); + if (!verification_data) { + r = -ENOMEM; + goto bad; + } + *r_verification_data = verification_data; return 0; bad: - crypt_free_volume_key(data); - return -EINVAL; + crypt_safe_free(data); + crypt_free_volume_key(verification_data); + return r; } int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd, @@ -362,22 +371,6 @@ int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd, return LUKS2_digest_assign(cd, hdr, keyslot_reencrypt, digest_reencrypt, 1, 0); } -void LUKS2_reencrypt_lookup_key_ids(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vk) -{ - int digest_old, digest_new; - - digest_old = LUKS2_reencrypt_digest_old(hdr); - digest_new = LUKS2_reencrypt_digest_new(hdr); - - while (vk) { - if (digest_old >= 0 && LUKS2_digest_verify_by_digest(cd, digest_old, vk) == digest_old) - crypt_volume_key_set_id(vk, digest_old); - if (digest_new >= 0 && LUKS2_digest_verify_by_digest(cd, digest_new, vk) == digest_new) - crypt_volume_key_set_id(vk, digest_new); - vk = vk->next; - } -} - int LUKS2_reencrypt_digest_verify(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks) diff --git a/lib/luks2/luks2_segment.c b/lib/luks2/luks2_segment.c index c2feb92..6284ca8 100644 --- a/lib/luks2/luks2_segment.c +++ b/lib/luks2/luks2_segment.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2, internal segment handling * - * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2018-2024 Ondrej Kozina + * Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2025 Ondrej Kozina */ #include "luks2_internal.h" @@ -270,7 +270,7 @@ json_object *json_segment_create_linear(uint64_t offset, const uint64_t *length, } static bool json_add_crypt_fields(json_object *jobj_segment, uint64_t iv_offset, - const char *cipher, const char *integrity, + const char *cipher, const char *integrity, uint32_t integrity_key_size, uint32_t sector_size, unsigned reencryption) { json_object *jobj_integrity; @@ -289,6 +289,8 @@ static bool json_add_crypt_fields(json_object *jobj_segment, uint64_t iv_offset, json_object_object_add(jobj_integrity, "type", json_object_new_string(integrity)); json_object_object_add(jobj_integrity, "journal_encryption", json_object_new_string("none")); json_object_object_add(jobj_integrity, "journal_integrity", json_object_new_string("none")); + if (integrity_key_size) + json_object_object_add(jobj_integrity, "key_size", json_object_new_int(integrity_key_size)); json_object_object_add(jobj_segment, "integrity", jobj_integrity); } @@ -300,7 +302,7 @@ static bool json_add_crypt_fields(json_object *jobj_segment, uint64_t iv_offset, json_object *json_segment_create_crypt(uint64_t offset, uint64_t iv_offset, const uint64_t *length, - const char *cipher, const char *integrity, + const char *cipher, const char *integrity, uint32_t integrity_key_size, uint32_t sector_size, unsigned reencryption) { json_object *jobj = _segment_create_generic("crypt", offset, length); @@ -308,7 +310,7 @@ json_object *json_segment_create_crypt(uint64_t offset, if (!jobj) return NULL; - if (json_add_crypt_fields(jobj, iv_offset, cipher, integrity, sector_size, reencryption)) + if (json_add_crypt_fields(jobj, iv_offset, cipher, integrity, integrity_key_size, sector_size, reencryption)) return jobj; json_object_put(jobj); @@ -350,7 +352,7 @@ json_object *json_segment_create_opal_crypt(uint64_t offset, const uint64_t *len json_add_opal_fields(jobj, length, segment_number, key_size); - if (json_add_crypt_fields(jobj, iv_offset, cipher, integrity, sector_size, reencryption)) + if (json_add_crypt_fields(jobj, iv_offset, cipher, integrity, 0, sector_size, reencryption)) return jobj; json_object_put(jobj); diff --git a/lib/luks2/luks2_token.c b/lib/luks2/luks2_token.c index 83bf089..89e7682 100644 --- a/lib/luks2/luks2_token.c +++ b/lib/luks2/luks2_token.c @@ -2,16 +2,16 @@ /* * LUKS - Linux Unified Key Setup v2, token handling * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Milan Broz + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Milan Broz */ #include -#include #include "luks2_internal.h" #if USE_EXTERNAL_TOKENS +#include #define TOKENS_PATH_MAX PATH_MAX static bool external_tokens_enabled = true; static char external_tokens_path[TOKENS_PATH_MAX] = EXTERNAL_LUKS2_TOKENS_PATH; @@ -101,10 +101,11 @@ static void *token_dlvsym(struct crypt_device *cd, char *error; void *sym; -#ifdef HAVE_DLVSYM +#if HAVE_DLVSYM log_dbg(cd, "Loading symbol %s@%s.", symbol, version); sym = dlvsym(handle, symbol, version); #else + UNUSED(version); log_dbg(cd, "Loading default version of symbol %s.", symbol); sym = dlsym(handle, symbol); #endif @@ -443,12 +444,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd, return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL_UNKNOWN : CRYPT_TOKEN_EXTERNAL_UNKNOWN; } -static const char *token_json_to_string(json_object *jobj_token) -{ - return json_object_to_json_string_ext(jobj_token, - JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE); -} - static int token_is_usable(struct luks2_hdr *hdr, json_object *jobj_token, int keyslot, int segment, crypt_keyslot_priority minimal_priority, bool requires_keyslot) { @@ -548,7 +543,7 @@ static int token_open(struct crypt_device *cd, if (!(h = LUKS2_token_handler(cd, token))) return -ENOENT; - if (h->validate && h->validate(cd, token_json_to_string(jobj_token))) { + if (h->validate && h->validate(cd, crypt_jobj_to_string_on_disk(jobj_token))) { log_dbg(cd, "Token %d (%s) validation failed.", token, h->name); return -ENOENT; } @@ -842,71 +837,6 @@ int LUKS2_token_unlock_key(struct crypt_device *cd, return r; } -int LUKS2_token_open_and_activate(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int token, - const char *name, - const char *type, - const char *pin, - size_t pin_size, - uint32_t flags, - void *usrptr) -{ - bool use_keyring; - int r, segment; - struct volume_key *p_crypt, *p_opal, *crypt_key = NULL, *opal_key = NULL, *vk = NULL; - - if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) - segment = CRYPT_ANY_SEGMENT; - else - segment = CRYPT_DEFAULT_SEGMENT; - - r = LUKS2_token_unlock_key(cd, hdr, keyslot, token, type, pin, pin_size, segment, usrptr, &vk); - if (r < 0) - return r; - - assert(vk); - - keyslot = r; - - if (LUKS2_segment_is_hw_opal(hdr, CRYPT_DEFAULT_SEGMENT)) { - r = LUKS2_split_crypt_and_opal_keys(cd, hdr, vk, &crypt_key, &opal_key); - if (r < 0) { - crypt_free_volume_key(vk); - return r; - } - - p_crypt = crypt_key; - p_opal = opal_key ?: vk; - } else { - p_crypt = vk; - p_opal = NULL; - } - - if (!crypt_use_keyring_for_vk(cd) || !p_crypt) - use_keyring = false; - else - use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) || - (flags & CRYPT_ACTIVATE_KEYRING_KEY)); - - if (use_keyring) { - if (!(r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, p_crypt, keyslot))) - flags |= CRYPT_ACTIVATE_KEYRING_KEY; - } - - if (r >= 0 && name) - r = LUKS2_activate(cd, name, p_crypt, p_opal, flags); - - if (r < 0) - crypt_drop_keyring_key(cd, p_crypt); - crypt_free_volume_key(vk); - crypt_free_volume_key(crypt_key); - crypt_free_volume_key(opal_key); - - return r < 0 ? r : keyslot; -} - void LUKS2_token_dump(struct crypt_device *cd, int token) { const crypt_token_handler *h; @@ -916,8 +846,7 @@ void LUKS2_token_dump(struct crypt_device *cd, int token) if (h && h->dump) { jobj_token = LUKS2_get_token_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), token); if (jobj_token) - h->dump(cd, json_object_to_json_string_ext(jobj_token, - JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE)); + h->dump(cd, crypt_jobj_to_string_on_disk(jobj_token)); } } @@ -929,7 +858,7 @@ int LUKS2_token_json_get(struct luks2_hdr *hdr, int token, const char **json) if (!jobj_token) return -EINVAL; - *json = token_json_to_string(jobj_token); + *json = crypt_jobj_to_string_on_disk(jobj_token); return 0; } @@ -1137,7 +1066,7 @@ int LUKS2_token_unlock_passphrase(struct crypt_device *cd, if (!r) { *passphrase = crypt_safe_alloc(buffer_size); if (*passphrase) { - memcpy(*passphrase, buffer, buffer_size); + crypt_safe_memcpy(*passphrase, buffer, buffer_size); *passphrase_size = buffer_size; } else r = -ENOMEM; diff --git a/lib/luks2/luks2_token_keyring.c b/lib/luks2/luks2_token_keyring.c index c455aa0..c8a33a5 100644 --- a/lib/luks2/luks2_token_keyring.c +++ b/lib/luks2/luks2_token_keyring.c @@ -2,8 +2,8 @@ /* * LUKS - Linux Unified Key Setup v2, kernel keyring token * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Ondrej Kozina + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Ondrej Kozina */ #include "luks2_internal.h" diff --git a/lib/nls.h b/lib/nls.h index 39760b1..64a271f 100644 --- a/lib/nls.h +++ b/lib/nls.h @@ -5,14 +5,14 @@ #define LOCALEDIR "/usr/share/locale" #endif -#ifdef HAVE_LOCALE_H +#if HAVE_LOCALE_H # include #else # undef setlocale # define setlocale(Category, Locale) /* empty */ #endif -#ifdef ENABLE_NLS +#if ENABLE_NLS # include # define _(Text) gettext (Text) # ifdef gettext_noop diff --git a/lib/random.c b/lib/random.c index 4720daf..06d2713 100644 --- a/lib/random.c +++ b/lib/random.c @@ -2,7 +2,7 @@ /* * cryptsetup kernel RNG access functions * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/lib/setup.c b/lib/setup.c index 66044f4..f1e8d92 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -18,7 +18,6 @@ #include "libcryptsetup.h" #include "luks1/luks.h" #include "luks2/luks2.h" -#include "luks2/luks2_internal.h" #include "loopaes/loopaes.h" #include "verity/verity.h" #include "tcrypt/tcrypt.h" @@ -290,16 +289,17 @@ static int process_key(struct crypt_device *cd, const char *hash_name, struct volume_key **vk) { int r; + void *key = NULL; if (!key_size) return -EINVAL; - *vk = crypt_alloc_volume_key(key_size, NULL); - if (!*vk) - return -ENOMEM; - if (hash_name) { - r = crypt_plain_hash(cd, hash_name, (*vk)->key, key_size, pass, passLen); + key = crypt_safe_alloc(key_size); + if (!key) + return -ENOMEM; + + r = crypt_plain_hash(cd, hash_name, key, key_size, pass, passLen); if (r < 0) { if (r == -ENOENT) log_err(cd, _("Hash algorithm %s not supported."), @@ -307,17 +307,27 @@ static int process_key(struct crypt_device *cd, const char *hash_name, else log_err(cd, _("Key processing error (using hash %s)."), hash_name); - crypt_free_volume_key(*vk); - *vk = NULL; + crypt_safe_free(key); return -EINVAL; } - } else if (passLen > key_size) { - memcpy((*vk)->key, pass, key_size); + *vk = crypt_alloc_volume_key_by_safe_alloc(&key); + } else if (passLen >= key_size) { + *vk = crypt_alloc_volume_key(key_size, pass); } else { - memcpy((*vk)->key, pass, passLen); + key = crypt_safe_alloc(key_size); + if (!key) + return -ENOMEM; + + crypt_safe_memcpy(key, pass, passLen); + + *vk = crypt_alloc_volume_key_by_safe_alloc(&key); } - return 0; + r = *vk ? 0 : -ENOMEM; + + crypt_safe_free(key); + + return r; } static int isPLAIN(const char *type) @@ -404,7 +414,7 @@ static int onlyLUKSnoRequirements(struct crypt_device *cd) static int onlyLUKS(struct crypt_device *cd) { - return _onlyLUKS(cd, 0, CRYPT_REQUIREMENT_OPAL); + return _onlyLUKS(cd, 0, CRYPT_REQUIREMENT_OPAL | CRYPT_REQUIREMENT_INLINE_HW_TAGS); } static int _onlyLUKS2(struct crypt_device *cd, uint32_t cdflags, uint32_t mask) @@ -437,7 +447,7 @@ static int onlyLUKS2unrestricted(struct crypt_device *cd) /* Internal only */ int onlyLUKS2(struct crypt_device *cd) { - return _onlyLUKS2(cd, 0, CRYPT_REQUIREMENT_OPAL); + return _onlyLUKS2(cd, 0, CRYPT_REQUIREMENT_OPAL | CRYPT_REQUIREMENT_INLINE_HW_TAGS); } /* Internal only */ @@ -502,92 +512,6 @@ static int keyslot_verify_or_find_empty(struct crypt_device *cd, int *keyslot) return 0; } -/* - * compares UUIDs returned by device-mapper (striped by cryptsetup) and uuid in header - */ -int crypt_uuid_cmp(const char *dm_uuid, const char *hdr_uuid) -{ - int i, j; - char *str; - - if (!dm_uuid || !hdr_uuid) - return -EINVAL; - - /* skip beyond LUKS2_HW_OPAL prefix */ - if (!strncmp(dm_uuid, CRYPT_LUKS2_HW_OPAL, strlen(CRYPT_LUKS2_HW_OPAL))) - dm_uuid = dm_uuid + strlen(CRYPT_LUKS2_HW_OPAL); - - str = strchr(dm_uuid, '-'); - if (!str) - return -EINVAL; - - for (i = 0, j = 1; hdr_uuid[i]; i++) { - if (hdr_uuid[i] == '-') - continue; - - if (!str[j] || str[j] == '-') - return -EINVAL; - - if (str[j] != hdr_uuid[i]) - return -EINVAL; - j++; - } - - return 0; -} - -/* - * compares two UUIDs returned by device-mapper (striped by cryptsetup) - * used for stacked LUKS2 & INTEGRITY devices - */ -static int crypt_uuid_integrity_cmp(const char *dm_uuid, const char *dmi_uuid) -{ - int i; - char *str, *stri; - - if (!dm_uuid || !dmi_uuid) - return -EINVAL; - - /* skip beyond LUKS2_HW_OPAL prefix */ - if (!strncmp(dm_uuid, CRYPT_LUKS2_HW_OPAL, strlen(CRYPT_LUKS2_HW_OPAL))) - dm_uuid = dm_uuid + strlen(CRYPT_LUKS2_HW_OPAL); - - str = strchr(dm_uuid, '-'); - if (!str) - return -EINVAL; - - stri = strchr(dmi_uuid, '-'); - if (!stri) - return -EINVAL; - - for (i = 1; str[i] && str[i] != '-'; i++) { - if (!stri[i]) - return -EINVAL; - - if (str[i] != stri[i]) - return -EINVAL; - } - - return 0; -} - -/* - * compares type of active device to provided string - */ -int crypt_uuid_type_cmp(const char *dm_uuid, const char *type) -{ - size_t len; - - assert(type); - - len = strlen(type); - if (dm_uuid && strlen(dm_uuid) > len && - !strncmp(dm_uuid, type, len) && dm_uuid[len] == '-') - return 0; - - return -ENODEV; -} - int PLAIN_activate(struct crypt_device *cd, const char *name, struct volume_key *vk, @@ -610,8 +534,7 @@ int PLAIN_activate(struct crypt_device *cd, r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd), vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd), - crypt_get_data_offset(cd), crypt_get_integrity(cd), - crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd)); + crypt_get_data_offset(cd), NULL, 0, 0, crypt_get_sector_size(cd)); if (r < 0) return r; @@ -1264,7 +1187,7 @@ static int _init_by_name_crypt_none(struct crypt_device *cd) r = -EINVAL; else { cd->u.none.cipher_mode = cd->u.none.cipher_spec + strlen(cd->u.none.cipher) + 1; - cd->u.none.key_size = tgt->u.crypt.vk->keylength; + cd->u.none.key_size = crypt_volume_key_length(tgt->u.crypt.vk); r = 0; } } @@ -1301,7 +1224,8 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) bool found = false; char **dep, *cipher_spec = NULL, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN]; char deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = {}; - const char *dev, *namei; + const char *dev; + char *iname = NULL; int key_nums, r; struct crypt_dm_active_device dmd, dmdi = {}, dmdep = {}; struct dm_target *tgt = &dmd.segment, *tgti = &dmdi.segment; @@ -1349,16 +1273,13 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) dep = deps; - if (tgt->type == DM_CRYPT && tgt->u.crypt.integrity && (namei = device_dm_name(tgt->data_device))) { - r = dm_query_device(cd, namei, DM_ACTIVE_DEVICE, &dmdi); + if (tgt->type == DM_CRYPT && tgt->u.crypt.tag_size && + (iname = dm_get_active_iname(cd, name))) { + + r = dm_query_device(cd, iname, DM_ACTIVE_DEVICE, &dmdi); + free(iname); if (r < 0) goto out; - if (!single_segment(&dmdi) || tgti->type != DM_INTEGRITY) { - log_dbg(cd, "Unsupported device table detected in %s.", namei); - r = -EINVAL; - goto out; - } - /* * Data device for crypt with integrity is not dm-integrity device, * but always the device underlying dm-integrity. @@ -1409,19 +1330,21 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) cd->u.plain.hdr.offset = tgt->u.crypt.offset; cd->u.plain.hdr.skip = tgt->u.crypt.iv_offset; cd->u.plain.hdr.sector_size = tgt->u.crypt.sector_size; - cd->u.plain.key_size = tgt->u.crypt.vk->keylength; + cd->u.plain.key_size = crypt_volume_key_length(tgt->u.crypt.vk); cd->u.plain.cipher = strdup(cipher); MOVE_REF(cd->u.plain.cipher_spec, cipher_spec); cd->u.plain.cipher_mode = cd->u.plain.cipher_spec + strlen(cipher) + 1; + if (dmd.flags & CRYPT_ACTIVATE_KEYRING_KEY) + crypt_set_key_in_keyring(cd, 1); } else if (isLOOPAES(cd->type) && single_segment(&dmd) && tgt->type == DM_CRYPT) { cd->u.loopaes.hdr.offset = tgt->u.crypt.offset; cd->u.loopaes.cipher = strdup(cipher); MOVE_REF(cd->u.loopaes.cipher_spec, cipher_spec); cd->u.loopaes.cipher_mode = cd->u.loopaes.cipher_spec + strlen(cipher) + 1; /* version 3 uses last key for IV */ - if (tgt->u.crypt.vk->keylength % key_nums) + if (crypt_volume_key_length(tgt->u.crypt.vk) % key_nums) key_nums++; - cd->u.loopaes.key_size = tgt->u.crypt.vk->keylength / key_nums; + cd->u.loopaes.key_size = crypt_volume_key_length(tgt->u.crypt.vk) / key_nums; } else if (isLUKS1(cd->type) || isLUKS2(cd->type)) { if (crypt_metadata_device(cd)) { r = _crypt_load_luks(cd, cd->type, true, false); @@ -1434,7 +1357,7 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) goto out; } /* check whether UUIDs match each other */ - r = crypt_uuid_cmp(dmd.uuid, LUKS_UUID(cd)); + r = dm_uuid_cmp(dmd.uuid, LUKS_UUID(cd)); if (r < 0) { log_dbg(cd, "LUKS device header uuid: %s mismatches DM returned uuid %s", LUKS_UUID(cd), dmd.uuid); @@ -1558,11 +1481,11 @@ static int _init_by_name_integrity(struct crypt_device *cd, const char *name) MOVE_REF(cd->u.integrity.params.journal_crypt, tgt->u.integrity.journal_crypt); if (tgt->u.integrity.vk) - cd->u.integrity.params.integrity_key_size = tgt->u.integrity.vk->keylength; + cd->u.integrity.params.integrity_key_size = crypt_volume_key_length(tgt->u.integrity.vk); if (tgt->u.integrity.journal_integrity_key) - cd->u.integrity.params.journal_integrity_key_size = tgt->u.integrity.journal_integrity_key->keylength; + cd->u.integrity.params.journal_integrity_key_size = crypt_volume_key_length(tgt->u.integrity.journal_integrity_key); if (tgt->u.integrity.journal_crypt_key) - cd->u.integrity.params.integrity_key_size = tgt->u.integrity.journal_crypt_key->keylength; + cd->u.integrity.params.journal_crypt_key_size = crypt_volume_key_length(tgt->u.integrity.journal_crypt_key); MOVE_REF(cd->metadata_device, tgt->u.integrity.meta_device); } out: @@ -1796,7 +1719,7 @@ static int _crypt_format_luks1(struct crypt_device *cd, cd->volume_key = crypt_alloc_volume_key(volume_key_size, volume_key); else - cd->volume_key = crypt_generate_volume_key(cd, volume_key_size); + cd->volume_key = crypt_generate_volume_key(cd, volume_key_size, KEY_QUALITY_KEY); if (!cd->volume_key) return -ENOMEM; @@ -1886,9 +1809,11 @@ static int LUKS2_check_encryption_params(struct crypt_device *cd, const char *cipher, const char *cipher_mode, const char *integrity, + size_t required_integrity_key_size, size_t volume_key_size, const struct crypt_params_luks2 *params, - const char **ret_integrity) + const char **ret_integrity, + size_t *ret_integrity_key_size) { int r, integrity_key_size = 0; @@ -1899,8 +1824,7 @@ static int LUKS2_check_encryption_params(struct crypt_device *cd, if (integrity) { if (params->integrity_params) { /* Standalone dm-integrity must not be used */ - if (params->integrity_params->integrity || - params->integrity_params->integrity_key_size) + if (params->integrity_params->integrity) return -EINVAL; /* FIXME: journal encryption and MAC is here not yet supported */ if (params->integrity_params->journal_crypt || @@ -1914,15 +1838,19 @@ static int LUKS2_check_encryption_params(struct crypt_device *cd, else return -EINVAL; } - integrity_key_size = INTEGRITY_key_size(integrity); + integrity_key_size = INTEGRITY_key_size(integrity, required_integrity_key_size); if ((integrity_key_size < 0) || (integrity_key_size >= (int)volume_key_size)) { log_err(cd, _("Volume key is too small for encryption with integrity extensions.")); return -EINVAL; } + if (integrity_key_size && integrity_key_size < LUKS2_MIN_INTEGRITY_KEY_BYTES) { + log_err(cd, _("Integrity key size is too small.")); + return -EINVAL; + } } /* FIXME: allow this later also for normal ciphers (check AF_ALG availability. */ - if (integrity && !integrity_key_size) { + if (integrity && integrity_key_size == 0) { r = crypt_cipher_check_kernel(cipher, cipher_mode, integrity, volume_key_size); if (r < 0) { log_err(cd, _("Cipher %s-%s (key size %zd bits) is not available."), @@ -1940,6 +1868,8 @@ static int LUKS2_check_encryption_params(struct crypt_device *cd, } *ret_integrity = integrity; + if (ret_integrity_key_size) + *ret_integrity_key_size = required_integrity_key_size ? integrity_key_size : 0; return 0; } @@ -1948,7 +1878,7 @@ static int LUKS2_check_encryption_sector(struct crypt_device *cd, uint64_t devic uint64_t data_offset_bytes, uint32_t sector_size, bool modify_sector_size, bool verify_data_area_alignment, uint32_t *ret_sector_size) { - uint32_t dmc_flags; + uint64_t dmc_flags; assert(ret_sector_size); @@ -1999,7 +1929,7 @@ static int _crypt_format_luks2(struct crypt_device *cd, const char *volume_key, size_t volume_key_size, struct crypt_params_luks2 *params, - bool sector_size_autodetect) + bool sector_size_autodetect, bool integrity_inline) { int r; unsigned long required_alignment = DEFAULT_DISK_ALIGNMENT; @@ -2007,6 +1937,8 @@ static int _crypt_format_luks2(struct crypt_device *cd, unsigned int sector_size; char cipher_spec[2*MAX_CAPI_ONE_LEN]; const char *integrity = params ? params->integrity : NULL; + size_t integrity_key_size = 0; /* only for independent, separate key in HMAC */ + struct volume_key *integrity_key = NULL; uint64_t data_offset_bytes, dev_size, metadata_size_bytes, keyslots_size_bytes; cd->u.luks2.hdr.jobj = NULL; @@ -2066,7 +1998,7 @@ static int _crypt_format_luks2(struct crypt_device *cd, cd->volume_key = crypt_alloc_volume_key(volume_key_size, volume_key); else - cd->volume_key = crypt_generate_volume_key(cd, volume_key_size); + cd->volume_key = crypt_generate_volume_key(cd, volume_key_size, KEY_QUALITY_KEY); if (!cd->volume_key) return -ENOMEM; @@ -2091,8 +2023,11 @@ static int _crypt_format_luks2(struct crypt_device *cd, &required_alignment, &alignment_offset, DEFAULT_DISK_ALIGNMENT); - r = LUKS2_check_encryption_params(cd, cipher, cipher_mode, integrity, - volume_key_size, params, &integrity); + if (params && params->integrity_params && params->integrity_params->integrity_key_size) + integrity_key_size = params->integrity_params->integrity_key_size; + + r = LUKS2_check_encryption_params(cd, cipher, cipher_mode, integrity, integrity_key_size, + volume_key_size, params, &integrity, &integrity_key_size); if (r < 0) goto out; @@ -2122,7 +2057,8 @@ static int _crypt_format_luks2(struct crypt_device *cd, r = LUKS2_generate_hdr(cd, &cd->u.luks2.hdr, cd->volume_key, cipher_spec, - integrity, uuid, + integrity, integrity_key_size, + uuid, sector_size, data_offset_bytes, metadata_size_bytes, keyslots_size_bytes, @@ -2130,6 +2066,14 @@ static int _crypt_format_luks2(struct crypt_device *cd, if (r < 0) goto out; + if (integrity_inline) { + log_dbg(cd, "Adding LUKS2 inline HW tags requirement flag."); + r = LUKS2_config_set_requirement_version(cd, &cd->u.luks2.hdr, + CRYPT_REQUIREMENT_INLINE_HW_TAGS, 1, false); + if (r < 0) + goto out; + } + if (params && (params->label || params->subsystem)) { r = LUKS2_hdr_labels(cd, &cd->u.luks2.hdr, params->label, params->subsystem, 0); @@ -2167,11 +2111,24 @@ static int _crypt_format_luks2(struct crypt_device *cd, goto out; } + } - r = INTEGRITY_format(cd, params ? params->integrity_params : NULL, NULL, NULL, 0); + /* Format underlying virtual dm-integrity device */ + if (!integrity_inline && crypt_get_integrity_tag_size(cd)) { + if (integrity_key_size) { + integrity_key = crypt_alloc_volume_key(integrity_key_size, + crypt_volume_key_get_key(cd->volume_key) + volume_key_size - integrity_key_size); + if (!integrity_key) { + r = -ENOMEM; + goto out; + } + } + r = INTEGRITY_format(cd, params ? params->integrity_params : NULL, + integrity_key, NULL, NULL, 0, NULL, false); if (r) log_err(cd, _("Cannot format integrity for device %s."), data_device_path(cd)); + crypt_free_volume_key(integrity_key); } if (r < 0) @@ -2336,6 +2293,8 @@ int crypt_format_luks2_opal(struct crypt_device *cd, int r; char cipher_spec[128]; const char *integrity = params ? params->integrity : NULL; + size_t integrity_key_size = 0; /* only for independent, separate key in HMAC */ + struct volume_key *integrity_key = NULL; uint32_t sector_size, opal_block_bytes, opal_segment_number = 1; /* We'll use the partition number if available later */ uint64_t alignment_offset_bytes, data_offset_bytes, device_size_bytes, opal_alignment_granularity_blocks, partition_offset_sectors, range_offset_blocks, range_size_bytes, @@ -2415,7 +2374,7 @@ int crypt_format_luks2_opal(struct crypt_device *cd, if (volume_keys) cd->volume_key = crypt_alloc_volume_key(volume_keys_size, volume_keys); else - cd->volume_key = crypt_generate_volume_key(cd, volume_keys_size); + cd->volume_key = crypt_generate_volume_key(cd, volume_keys_size, KEY_QUALITY_KEY); if (!cd->volume_key) { r = -ENOMEM; @@ -2423,7 +2382,7 @@ int crypt_format_luks2_opal(struct crypt_device *cd, } if (cipher) { - user_key = crypt_alloc_volume_key(opal_params->user_key_size, cd->volume_key->key); + user_key = crypt_alloc_volume_key(opal_params->user_key_size, crypt_volume_key_get_key(cd->volume_key)); if (!user_key) { r = -ENOMEM; goto out; @@ -2475,9 +2434,12 @@ int crypt_format_luks2_opal(struct crypt_device *cd, opal_segment_number = r; if (cipher) { - r = LUKS2_check_encryption_params(cd, cipher, cipher_mode, integrity, + if (params->integrity_params && params->integrity_params->integrity_key_size) + integrity_key_size = params->integrity_params->integrity_key_size; + + r = LUKS2_check_encryption_params(cd, cipher, cipher_mode, integrity, 0, volume_keys_size - opal_params->user_key_size, - params, &integrity); + params, &integrity, &integrity_key_size); if (r < 0) goto out; } @@ -2524,7 +2486,9 @@ int crypt_format_luks2_opal(struct crypt_device *cd, } r = LUKS2_generate_hdr(cd, &cd->u.luks2.hdr, cd->volume_key, - cipher ? cipher_spec : NULL, integrity, uuid, + cipher ? cipher_spec : NULL, + integrity, integrity_key_size, + uuid, sector_size, data_offset_bytes, metadata_size_bytes, keyslots_size_bytes, @@ -2603,15 +2567,27 @@ int crypt_format_luks2_opal(struct crypt_device *cd, goto out; } - r = INTEGRITY_format(cd, params->integrity_params, NULL, NULL, + if (integrity_key_size) { + integrity_key = crypt_alloc_volume_key(integrity_key_size, + crypt_volume_key_get_key(cd->volume_key) + volume_keys_size - integrity_key_size); + + if (!integrity_key) { + r = -ENOMEM; + goto out; + } + } + + r = INTEGRITY_format(cd, params->integrity_params, integrity_key, NULL, NULL, /* * Create reduced dm-integrity device only if locking range size does * not match device size. */ - device_size_bytes != range_size_bytes ? range_size_bytes / SECTOR_SIZE : 0); + device_size_bytes != range_size_bytes ? range_size_bytes / SECTOR_SIZE : 0, NULL, false); if (r) log_err(cd, _("Cannot format integrity for device %s."), data_device_path(cd)); + + crypt_free_volume_key(integrity_key); if (r < 0) goto out; @@ -2887,12 +2863,14 @@ static int _crypt_format_verity(struct crypt_device *cd, static int _crypt_format_integrity(struct crypt_device *cd, const char *uuid, - struct crypt_params_integrity *params) + struct crypt_params_integrity *params, + const char *integrity_key, size_t integrity_key_size, + bool integrity_inline) { int r; uint32_t integrity_tag_size; char *integrity = NULL, *journal_integrity = NULL, *journal_crypt = NULL; - struct volume_key *journal_crypt_key = NULL, *journal_mac_key = NULL; + struct volume_key *journal_crypt_key = NULL, *journal_mac_key = NULL, *ik = NULL; if (!params) return -EINVAL; @@ -2902,6 +2880,11 @@ static int _crypt_format_integrity(struct crypt_device *cd, return -EINVAL; } + if (integrity_key_size && integrity_key_size != params->integrity_key_size) { + log_err(cd, _("Integrity key size mismatch.")); + return -EINVAL; + } + r = device_check_access(cd, crypt_metadata_device(cd), DEV_EXCL); if (r < 0) return r; @@ -2968,10 +2951,24 @@ static int _crypt_format_integrity(struct crypt_device *cd, cd->u.integrity.params.journal_integrity = journal_integrity; cd->u.integrity.params.journal_crypt = journal_crypt; - r = INTEGRITY_format(cd, params, cd->u.integrity.journal_crypt_key, cd->u.integrity.journal_mac_key, 0); + if (params->integrity_key_size) { + if (!integrity_key) + ik = crypt_generate_volume_key(cd, params->integrity_key_size, KEY_QUALITY_EMPTY); + else + ik = crypt_alloc_volume_key(params->integrity_key_size, integrity_key); + if (!ik) { + r = -ENOMEM; + goto out; + } + } + + r = INTEGRITY_format(cd, params, ik, cd->u.integrity.journal_crypt_key, + cd->u.integrity.journal_mac_key, 0, &cd->u.integrity.sb_flags, + integrity_inline); if (r) - log_err(cd, _("Cannot format integrity for device %s."), - mdata_device_path(cd)); + log_err(cd, _("Cannot format integrity for device %s."), mdata_device_path(cd)); + + crypt_free_volume_key(ik); out: if (r) { crypt_free_volume_key(journal_crypt_key); @@ -2984,6 +2981,128 @@ static int _crypt_format_integrity(struct crypt_device *cd, return r; } +int crypt_format_inline(struct crypt_device *cd, + const char *type, + const char *cipher, + const char *cipher_mode, + const char *uuid, + const char *volume_key, + size_t volume_key_size, + void *params) +{ + struct crypt_params_luks2 *lparams; + const struct crypt_params_integrity *iparams; + uint32_t device_tag_size, required_tag_size; + struct device *idevice; + size_t sector_size, required_sector_size; + int r; + + if (!cd || !params) + return -EINVAL; + + if (cd->type) { + log_dbg(cd, "Context already formatted as %s.", cd->type); + return -EINVAL; + } + + log_dbg(cd, "Formatting device %s as type %s with inline tags.", mdata_device_path(cd) ?: "(none)", type); + + crypt_reset_null_type(cd); + + r = init_crypto(cd); + if (r < 0) + return r; + + if (isINTEGRITY(type)) { + lparams = NULL; + iparams = params; + idevice = crypt_metadata_device(cd); + required_sector_size = iparams->sector_size; + required_tag_size = iparams->tag_size; + + /* Unused in standalone integrity */ + if (cipher || cipher_mode) + return -EINVAL; + } else if (isLUKS2(type)) { + lparams = params; + iparams = lparams->integrity_params; + + if (lparams->data_device) { + if (!cd->metadata_device) + cd->metadata_device = cd->device; + else + device_free(cd, cd->device); + cd->device = NULL; + if (device_alloc(cd, &cd->device, lparams->data_device) < 0) + return -ENOMEM; + } + + idevice = crypt_data_device(cd); + required_sector_size = lparams->sector_size; + + if (!lparams->integrity || !idevice) + return -EINVAL; + + required_tag_size = INTEGRITY_tag_size(lparams->integrity, cipher, cipher_mode); + } else { + log_err(cd, _("Unknown or unsupported device type %s requested."), type); + return -EINVAL; + } + + /* In inline mode journal will be never used, check that params are not set */ + if (iparams && (iparams->journal_size || iparams->journal_watermark || iparams->journal_commit_time || + iparams->interleave_sectors || iparams->journal_integrity || iparams->journal_integrity_key || + iparams->journal_integrity_key_size || iparams->journal_crypt || iparams->journal_crypt_key || + iparams->journal_integrity_key_size)) + return -EINVAL; + + r = device_is_nop_dif(idevice, &device_tag_size); + if (r < 0) + return r; + + if (!r) { + log_err(cd, _("Device %s does not provide inline integrity data fields."), mdata_device_path(cd)); + return -EINVAL; + } + + /* We can get device_tag_size = 0 as kernel provides this info only for some block devices */ + if (device_tag_size > 0 && device_tag_size < required_tag_size) { + log_err(cd, _("Inline tag size %" PRIu32 " [bytes] is larger than %" PRIu32 " provided by device %s."), + required_tag_size, device_tag_size, mdata_device_path(cd)); + return -EINVAL; + } + log_dbg(cd, "Inline integrity is supported (%" PRIu32 ").", device_tag_size); + + /* Inline must use sectors size as hardware device */ + sector_size = device_block_size(cd, idevice); + if (!sector_size) + return -EINVAL; + + /* No autodetection, use device sector size */ + if (isLUKS2(type) && lparams && !required_sector_size) + lparams->sector_size = sector_size; + else if (sector_size != required_sector_size) { + log_err(cd, _("Sector must be the same as device hardware sector (%zu bytes)."), sector_size); + return -EINVAL; + } + + if (isINTEGRITY(type)) + r = _crypt_format_integrity(cd, uuid, params, volume_key, volume_key_size, true); + else if (isLUKS2(type)) + r = _crypt_format_luks2(cd, cipher, cipher_mode, + uuid, volume_key, volume_key_size, params, false, true); + else + r = -EINVAL; + + if (r < 0) { + crypt_set_null_type(cd); + crypt_free_volume_key(cd->volume_key); + cd->volume_key = NULL; + } + + return r; +} + static int _crypt_format(struct crypt_device *cd, const char *type, const char *cipher, @@ -3020,15 +3139,15 @@ static int _crypt_format(struct crypt_device *cd, uuid, volume_key, volume_key_size, params); else if (isLUKS2(type)) r = _crypt_format_luks2(cd, cipher, cipher_mode, - uuid, volume_key, volume_key_size, params, sector_size_autodetect); + uuid, volume_key, volume_key_size, params, sector_size_autodetect, false); else if (isLOOPAES(type)) r = _crypt_format_loopaes(cd, cipher, uuid, volume_key_size, params); else if (isVERITY(type)) r = _crypt_format_verity(cd, uuid, params); else if (isINTEGRITY(type)) - r = _crypt_format_integrity(cd, uuid, params); + r = _crypt_format_integrity(cd, uuid, params, volume_key, volume_key_size, false); else { - log_err(cd, _("Unknown crypt device type %s requested."), type); + log_err(cd, _("Unknown or unsupported device type %s requested."), type); r = -EINVAL; } @@ -3102,22 +3221,62 @@ int crypt_repair(struct crypt_device *cd, } /* compare volume keys */ -static int _compare_volume_keys(struct volume_key *svk, unsigned skeyring_only, - struct volume_key *tvk, unsigned tkeyring_only) +static int _compare_volume_keys(struct volume_key *svk, struct volume_key *tvk) +{ + if (svk == tvk) + return 0; + + if (!svk || !tvk) + return 1; + + if (crypt_volume_key_length(svk) != crypt_volume_key_length(tvk)) + return 1; + + /* No switch between keyring and direct key specification */ + if ((!crypt_volume_key_description(svk) && crypt_volume_key_description(tvk)) || + (crypt_volume_key_description(svk) && !crypt_volume_key_description(tvk)) || + (!crypt_volume_key_is_set(svk) && crypt_volume_key_is_set(tvk)) || + (crypt_volume_key_is_set(svk) && !crypt_volume_key_is_set(tvk))) + return 1; + + if (crypt_volume_key_description(svk) && + (crypt_volume_key_kernel_key_type(svk) != crypt_volume_key_kernel_key_type(tvk) || + strcmp(crypt_volume_key_description(svk), crypt_volume_key_description(tvk)))) + return 1; + + if (crypt_volume_key_is_set(svk) && + crypt_backend_memeq(crypt_volume_key_get_key(svk), + crypt_volume_key_get_key(tvk), + crypt_volume_key_length(svk))) + return 1; + + return 0; +} + +static int _compare_volume_keys_luks2(struct volume_key *svk, struct volume_key *tvk) { - if (!svk && !tvk) + if (svk == tvk) return 0; - else if (!svk || !tvk) + + if (!svk || !tvk) return 1; - if (svk->keylength != tvk->keylength) + if (crypt_volume_key_length(svk) != crypt_volume_key_length(tvk)) return 1; - if (!skeyring_only && !tkeyring_only) - return crypt_backend_memeq(svk->key, tvk->key, svk->keylength); + if ((!crypt_volume_key_is_set(svk) && !crypt_volume_key_description(svk)) || + (!crypt_volume_key_is_set(tvk) && !crypt_volume_key_description(tvk))) + return 1; + + if (crypt_volume_key_is_set(svk) && crypt_volume_key_is_set(tvk) && + crypt_backend_memeq(crypt_volume_key_get_key(svk), + crypt_volume_key_get_key(tvk), + crypt_volume_key_length(svk))) + return 1; - if (svk->key_description && tvk->key_description) - return strcmp(svk->key_description, tvk->key_description); + if (crypt_volume_key_description(svk) && crypt_volume_key_description(tvk)) + return (crypt_volume_key_kernel_key_type(svk) != crypt_volume_key_kernel_key_type(tvk) || + strcmp(crypt_volume_key_description(svk), crypt_volume_key_description(tvk))); return 0; } @@ -3131,14 +3290,22 @@ static int _compare_device_types(struct crypt_device *cd, return -EINVAL; } - if (isLUKS2(cd->type) && !strncmp("INTEGRITY-", tgt->uuid, strlen("INTEGRITY-"))) { - if (crypt_uuid_cmp(tgt->uuid, src->uuid)) { + /* + * FIXME: The CRYPT_SUBDEV prefix should be enough but we need + * to keep INTEGRITY- for dm-integrity subdevices opened with + * cryptsetup version < 2.8.0. Drop the INTEGRITY condition + * in next Y release. + */ + if (isLUKS2(cd->type) && + (!strncmp("INTEGRITY-", tgt->uuid, strlen("INTEGRITY-")) || + !strncmp(CRYPT_SUBDEV, tgt->uuid, strlen(CRYPT_SUBDEV)))) { + if (dm_uuid_cmp(tgt->uuid, src->uuid)) { log_dbg(cd, "LUKS UUID mismatch."); return -EINVAL; } } else if (isLUKS(cd->type)) { if (!src->uuid || strncmp(cd->type, tgt->uuid, strlen(cd->type)) || - crypt_uuid_cmp(tgt->uuid, src->uuid)) { + dm_uuid_cmp(tgt->uuid, src->uuid)) { log_dbg(cd, "LUKS UUID mismatch."); return -EINVAL; } @@ -3183,9 +3350,14 @@ static int _compare_crypt_devices(struct crypt_device *cd, goto out; } - if (tgt->u.crypt.vk->keylength == 0 && crypt_is_cipher_null(tgt->u.crypt.cipher)) + if (crypt_volume_key_length(tgt->u.crypt.vk) == 0 && crypt_is_cipher_null(tgt->u.crypt.cipher)) log_dbg(cd, "Existing device uses cipher null. Skipping key comparison."); - else if (_compare_volume_keys(src->u.crypt.vk, 0, tgt->u.crypt.vk, tgt->u.crypt.vk->key_description != NULL)) { + else if (cd && isLUKS2(cd->type)) { + if (_compare_volume_keys_luks2(src->u.crypt.vk, tgt->u.crypt.vk)) { + log_dbg(cd, "Keys in LUKS2 context and target device do not match."); + goto out; + } + } else if (_compare_volume_keys(src->u.crypt.vk, tgt->u.crypt.vk)) { log_dbg(cd, "Keys in context and target device do not match."); goto out; } @@ -3245,9 +3417,9 @@ static int _compare_integrity_devices(struct crypt_device *cd, } /* unfortunately dm-integrity doesn't support keyring */ - if (_compare_volume_keys(src->u.integrity.vk, 0, tgt->u.integrity.vk, 0) || - _compare_volume_keys(src->u.integrity.journal_integrity_key, 0, tgt->u.integrity.journal_integrity_key, 0) || - _compare_volume_keys(src->u.integrity.journal_crypt_key, 0, tgt->u.integrity.journal_crypt_key, 0)) { + if (_compare_volume_keys(src->u.integrity.vk, tgt->u.integrity.vk) || + _compare_volume_keys(src->u.integrity.journal_integrity_key, tgt->u.integrity.journal_integrity_key) || + _compare_volume_keys(src->u.integrity.journal_crypt_key, tgt->u.integrity.journal_crypt_key)) { log_dbg(cd, "Journal keys do not match."); return -EINVAL; } @@ -3313,15 +3485,20 @@ int crypt_compare_dm_devices(struct crypt_device *cd, } static int _reload_device(struct crypt_device *cd, const char *name, - struct crypt_dm_active_device *sdmd, uint32_t dmflags) + struct crypt_dm_active_device *sdmd, uint64_t dmflags) { int r; struct crypt_dm_active_device tdmd; struct dm_target *src, *tgt = &tdmd.segment; - if (!cd || !cd->type || !name || !(sdmd->flags & CRYPT_ACTIVATE_REFRESH)) + assert(cd); + assert(sdmd); + + if (!cd->type || !name || !(sdmd->flags & CRYPT_ACTIVATE_REFRESH)) return -EINVAL; + src = &sdmd->segment; + r = dm_query_device(cd, name, DM_ACTIVE_DEVICE | DM_ACTIVE_CRYPT_CIPHER | DM_ACTIVE_UUID | DM_ACTIVE_CRYPT_KEYSIZE | DM_ACTIVE_CRYPT_KEY | DM_ACTIVE_INTEGRITY_PARAMS | @@ -3345,25 +3522,24 @@ static int _reload_device(struct crypt_device *cd, const char *name, goto out; } - src = &sdmd->segment; - /* Changing read only flag for active device makes no sense */ if (tdmd.flags & CRYPT_ACTIVATE_READONLY) sdmd->flags |= CRYPT_ACTIVATE_READONLY; else sdmd->flags &= ~CRYPT_ACTIVATE_READONLY; - if (tgt->type == DM_CRYPT && sdmd->flags & CRYPT_ACTIVATE_KEYRING_KEY) { - r = crypt_volume_key_set_description(tgt->u.crypt.vk, src->u.crypt.vk->key_description); - if (r) - goto out; - } else if (tgt->type == DM_CRYPT) { + /* + * Only LUKS2 allows altering between volume key + * passed by hexbyte representation and reference + * to kernel keyring service. + * + * To make it easier pass src key directly after + * it was properly verified in crypt_compare_dm_devices + * call above. + */ + if (isLUKS2(cd->type) && tgt->type == DM_CRYPT && src->u.crypt.vk) { crypt_free_volume_key(tgt->u.crypt.vk); - tgt->u.crypt.vk = crypt_alloc_volume_key(src->u.crypt.vk->keylength, src->u.crypt.vk->key); - if (!tgt->u.crypt.vk) { - r = -ENOMEM; - goto out; - } + tgt->u.crypt.vk = src->u.crypt.vk; } if (tgt->type == DM_CRYPT) @@ -3383,6 +3559,10 @@ static int _reload_device(struct crypt_device *cd, const char *name, r = dm_reload_device(cd, name, &tdmd, dmflags, 1); out: + /* otherwise dm_targets_free would free src key */ + if (src->u.crypt.vk == tgt->u.crypt.vk) + tgt->u.crypt.vk = NULL; + dm_targets_free(cd, &tdmd); free(CONST_CAST(void*)tdmd.uuid); @@ -3402,9 +3582,16 @@ static int _reload_device_with_integrity(struct crypt_device *cd, struct device *data_device = NULL; bool clear = false; - if (!cd || !cd->type || !name || !iname || !(sdmd->flags & CRYPT_ACTIVATE_REFRESH)) + assert(cd); + assert(sdmd); + assert(sdmdi); + + if (!cd->type || !name || !iname || !(sdmd->flags & CRYPT_ACTIVATE_REFRESH)) return -EINVAL; + src = &sdmd->segment; + srci = &sdmdi->segment; + r = dm_query_device(cd, name, DM_ACTIVE_DEVICE | DM_ACTIVE_CRYPT_CIPHER | DM_ACTIVE_UUID | DM_ACTIVE_CRYPT_KEYSIZE | DM_ACTIVE_CRYPT_KEY, &tdmd); @@ -3439,11 +3626,10 @@ static int _reload_device_with_integrity(struct crypt_device *cd, } /* unsupported underneath dm-crypt with auth. encryption */ - if (sdmdi->segment.u.integrity.meta_device || tdmdi.segment.u.integrity.meta_device) - return -ENOTSUP; - - src = &sdmd->segment; - srci = &sdmdi->segment; + if (sdmdi->segment.u.integrity.meta_device || tdmdi.segment.u.integrity.meta_device) { + r = -ENOTSUP; + goto out; + } r = device_alloc(cd, &data_device, ipath); if (r < 0) @@ -3473,18 +3659,13 @@ static int _reload_device_with_integrity(struct crypt_device *cd, else sdmdi->flags &= ~CRYPT_ACTIVATE_READONLY; - if (sdmd->flags & CRYPT_ACTIVATE_KEYRING_KEY) { - r = crypt_volume_key_set_description(tgt->u.crypt.vk, src->u.crypt.vk->key_description); - if (r) - goto out; - } else { - crypt_free_volume_key(tgt->u.crypt.vk); - tgt->u.crypt.vk = crypt_alloc_volume_key(src->u.crypt.vk->keylength, src->u.crypt.vk->key); - if (!tgt->u.crypt.vk) { - r = -ENOMEM; - goto out; - } - } + /* + * To make it easier pass src key directly after + * it was properly verified in crypt_compare_dm_devices + * call above. + */ + crypt_free_volume_key(tgt->u.crypt.vk); + tgt->u.crypt.vk = src->u.crypt.vk; r = device_block_adjust(cd, src->data_device, DEV_OK, src->u.crypt.offset, &sdmd->size, NULL); @@ -3550,6 +3731,9 @@ static int _reload_device_with_integrity(struct crypt_device *cd, dm_resume_device(cd, iname, 0); } + /* otherwise dm_targets_free would free src key */ + if (tgt->u.crypt.vk == src->u.crypt.vk) + tgt->u.crypt.vk = NULL; dm_targets_free(cd, &tdmd); dm_targets_free(cd, &tdmdi); free(CONST_CAST(void*)tdmdi.uuid); @@ -3564,7 +3748,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) struct crypt_dm_active_device dmdq, dmd = {}; struct dm_target *tgt = &dmdq.segment; struct crypt_params_integrity params = {}; - uint32_t supported_flags = 0, dmflags = 0; + uint64_t supported_flags = 0, dmflags = 0; uint64_t old_size; int r; @@ -3582,6 +3766,11 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) return -EINVAL; } + if (isLUKS2(cd->type) && crypt_get_integrity_tag_size(cd)) { + log_err(cd, _("Resize of LUKS2 device with integrity protection is not supported.")); + return -ENOTSUP; + } + if (new_size) log_dbg(cd, "Resizing device %s to %" PRIu64 " sectors.", name, new_size); else @@ -3606,13 +3795,14 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) } if (crypt_key_in_keyring(cd)) { - if (!isLUKS2(cd->type)) { + if (isLUKS2(cd->type)) + r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr, + tgt->u.crypt.vk, CRYPT_DEFAULT_SEGMENT); + else if (isPLAIN(cd->type)) + r = 0; /* key description was set on table load */ + else r = -EINVAL; - goto out; - } - r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr, - tgt->u.crypt.vk, CRYPT_DEFAULT_SEGMENT); - if (r) + if (r < 0) goto out; dmdq.flags |= CRYPT_ACTIVATE_KEYRING_KEY; @@ -3695,7 +3885,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size) r = dm_crypt_target_set(&dmd.segment, 0, new_size, crypt_data_device(cd), tgt->u.crypt.vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd), crypt_get_data_offset(cd), - crypt_get_integrity(cd), crypt_get_integrity_tag_size(cd), + crypt_get_integrity(cd), crypt_get_integrity_key_size(cd, true), crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd)); if (r < 0) goto out; @@ -3927,24 +4117,6 @@ void crypt_free(struct crypt_device *cd) free(cd); } -static char *crypt_get_device_key_description(struct crypt_device *cd, const char *name) -{ - char *desc = NULL; - struct crypt_dm_active_device dmd; - struct dm_target *tgt = &dmd.segment; - - if (dm_query_device(cd, name, DM_ACTIVE_CRYPT_KEY | DM_ACTIVE_CRYPT_KEYSIZE, &dmd) < 0) - return NULL; - - if (single_segment(&dmd) && tgt->type == DM_CRYPT && - (dmd.flags & CRYPT_ACTIVATE_KEYRING_KEY) && tgt->u.crypt.vk->key_description) - desc = strdup(tgt->u.crypt.vk->key_description); - - dm_targets_free(cd, &dmd); - - return desc; -} - int crypt_suspend(struct crypt_device *cd, const char *name) { @@ -3952,9 +4124,10 @@ int crypt_suspend(struct crypt_device *cd, crypt_status_info ci; int r; struct crypt_dm_active_device dmd, dmdi = {}; - uint32_t opal_segment_number = 1, dmflags = DM_SUSPEND_WIPE_KEY; + uint32_t opal_segment_number = 1; + uint64_t dmflags = DM_SUSPEND_WIPE_KEY; struct dm_target *tgt = &dmd.segment; - char *key_desc = NULL, *iname = NULL; + char *iname = NULL; struct crypt_lock_handle *opal_lh = NULL; if (!cd || !name) @@ -3971,15 +4144,17 @@ int crypt_suspend(struct crypt_device *cd, return -EINVAL; } - r = dm_query_device(cd, name, DM_ACTIVE_UUID, &dmd); + r = dm_query_device(cd, name, + DM_ACTIVE_UUID | DM_ACTIVE_CRYPT_KEY | DM_ACTIVE_CRYPT_KEYSIZE, + &dmd); if (r < 0) return r; log_dbg(cd, "Checking if active device %s has UUID type LUKS.", name); - r = crypt_uuid_type_cmp(dmd.uuid, CRYPT_LUKS2); + r = dm_uuid_type_cmp(dmd.uuid, CRYPT_LUKS2); if (r < 0) - r = crypt_uuid_type_cmp(dmd.uuid, CRYPT_LUKS1); + r = dm_uuid_type_cmp(dmd.uuid, CRYPT_LUKS1); if (r < 0) { log_err(cd, _("This operation is supported only for LUKS device.")); @@ -3988,45 +4163,32 @@ int crypt_suspend(struct crypt_device *cd, r = -EINVAL; - if (isLUKS2(cd->type) && crypt_uuid_type_cmp(dmd.uuid, CRYPT_LUKS2)) { + if (isLUKS2(cd->type) && dm_uuid_type_cmp(dmd.uuid, CRYPT_LUKS2)) { log_dbg(cd, "LUKS device header type: %s mismatches DM device type.", cd->type); goto out; } - if (isLUKS1(cd->type) && crypt_uuid_type_cmp(dmd.uuid, CRYPT_LUKS1)) { + if (isLUKS1(cd->type) && dm_uuid_type_cmp(dmd.uuid, CRYPT_LUKS1)) { log_dbg(cd, "LUKS device header type: %s mismatches DM device type.", cd->type); goto out; } /* check if active device has LUKS2-OPAL dm uuid prefix */ - dm_opal_uuid = !crypt_uuid_type_cmp(dmd.uuid, CRYPT_LUKS2_HW_OPAL); + dm_opal_uuid = !dm_uuid_type_cmp(dmd.uuid, CRYPT_LUKS2_HW_OPAL); if (!dm_opal_uuid && isLUKS2(cd->type) && LUKS2_segment_is_hw_opal(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT)) goto out; - if (cd->type && (r = crypt_uuid_cmp(dmd.uuid, LUKS_UUID(cd))) < 0) { + if (cd->type && (r = dm_uuid_cmp(dmd.uuid, LUKS_UUID(cd))) < 0) { log_dbg(cd, "LUKS device header uuid: %s mismatches DM returned uuid %s", LUKS_UUID(cd), dmd.uuid); goto out; } /* check UUID of integrity device underneath crypt device */ - if (crypt_get_integrity_tag_size(cd)) { - r = dm_get_iname(name, &iname, false); - if (r) - goto out; - - r = dm_query_device(cd, iname, DM_ACTIVE_UUID, &dmdi); - if (r < 0) - goto out; - - r = crypt_uuid_integrity_cmp(dmd.uuid, dmdi.uuid); - if (r < 0) { - log_dbg(cd, "Integrity device uuid: %s mismatches crypt device uuid %s", dmdi.uuid, dmd.uuid); - goto out; - } - } + if (crypt_get_integrity_tag_size(cd)) + iname = dm_get_active_iname(cd, name); r = dm_status_suspended(cd, name); if (r < 0) @@ -4038,8 +4200,6 @@ int crypt_suspend(struct crypt_device *cd, goto out; } - key_desc = crypt_get_device_key_description(cd, name); - if (dm_opal_uuid && crypt_data_device(cd)) { if (isLUKS2(cd->type)) { r = LUKS2_get_opal_segment_number(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, &opal_segment_number); @@ -4068,13 +4228,14 @@ int crypt_suspend(struct crypt_device *cd, } /* Suspend integrity device underneath; keep crypt suspended if it fails */ - if (crypt_get_integrity_tag_size(cd)) { + if (iname) { r = dm_suspend_device(cd, iname, 0); if (r) log_err(cd, _("Error during suspending device %s."), iname); } - crypt_drop_keyring_key_by_description(cd, key_desc, cd->keyring_key_type); + if (single_segment(&dmd) && tgt->type == DM_CRYPT) + crypt_volume_key_drop_kernel_key(cd, tgt->u.crypt.vk); if (dm_opal_uuid && crypt_data_device(cd)) { r = opal_exclusive_lock(cd, crypt_data_device(cd), &opal_lh); @@ -4088,7 +4249,6 @@ int crypt_suspend(struct crypt_device *cd, log_err(cd, _("Device %s was suspended but hardware OPAL device cannot be locked."), name); out: opal_exclusive_unlock(cd, opal_lh); - free(key_desc); free(iname); dm_targets_free(cd, &dmd); dm_targets_free(cd, &dmdi); @@ -4141,7 +4301,9 @@ static void crypt_unlink_key_from_custom_keyring(struct crypt_device *cd, key_se log_err(cd, _("Failed to unlink volume key from user specified keyring.")); } -static key_serial_t crypt_single_volume_key_load_in_user_keyring(struct crypt_device *cd, struct volume_key *vk, const char *user_key_name) +static key_serial_t crypt_single_volume_key_load_in_custom_keyring(struct crypt_device *cd, + struct volume_key *vk, + const char *user_key_name) { key_serial_t kid; const char *type_name; @@ -4155,15 +4317,20 @@ static key_serial_t crypt_single_volume_key_load_in_user_keyring(struct crypt_de log_dbg(cd, "Linking volume key (type %s, name %s) to the specified keyring", type_name, user_key_name); - kid = keyring_add_key_to_custom_keyring(cd->keyring_key_type, user_key_name, vk->key, vk->keylength, cd->keyring_to_link_vk); - if (kid <= 0) { - log_dbg(cd, "The keyring_link_key_to_keyring function failed (error %d).", errno); - } + kid = keyring_add_key_to_keyring(cd->keyring_key_type, user_key_name, + crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk), + cd->keyring_to_link_vk); + if (kid <= 0) + log_dbg(cd, "The keyring_add_key_to_keyring function failed (error %d).", errno); return kid; } -static int crypt_volume_key_load_in_user_keyring(struct crypt_device *cd, struct volume_key *vk, key_serial_t *kid1_out, key_serial_t *kid2_out) +static int crypt_volume_key_load_in_custom_keyring(struct crypt_device *cd, + struct volume_key *vk, + key_serial_t *kid1_out, + key_serial_t *kid2_out) { key_serial_t kid1, kid2 = 0; @@ -4174,14 +4341,14 @@ static int crypt_volume_key_load_in_user_keyring(struct crypt_device *cd, struct if (!vk || !key_type_name(cd->keyring_key_type)) return -EINVAL; - kid1 = crypt_single_volume_key_load_in_user_keyring(cd, vk, cd->user_key_name1); + kid1 = crypt_single_volume_key_load_in_custom_keyring(cd, vk, cd->user_key_name1); if (kid1 <= 0) return -EINVAL; - vk = vk->next; + vk = crypt_volume_key_next(vk); if (vk) { assert(cd->user_key_name2); - kid2 = crypt_single_volume_key_load_in_user_keyring(cd, vk, cd->user_key_name2); + kid2 = crypt_single_volume_key_load_in_custom_keyring(cd, vk, cd->user_key_name2); if (kid2 <= 0) { crypt_unlink_key_from_custom_keyring(cd, kid1); return -EINVAL; @@ -4251,7 +4418,7 @@ static int resume_luks2_by_volume_key(struct crypt_device *cd, /* upload volume key in custom keyring if requested */ if (cd->link_vk_to_keyring) { - r = crypt_volume_key_load_in_user_keyring(cd, vk, &kid1, &kid2); + r = crypt_volume_key_load_in_custom_keyring(cd, vk, &kid1, &kid2); if (r < 0) { log_err(cd, _("Failed to link volume key in user defined keyring.")); goto out; @@ -4273,14 +4440,12 @@ static int resume_luks2_by_volume_key(struct crypt_device *cd, } } - if (crypt_get_integrity_tag_size(cd)) { - r = dm_get_iname(name, &iname, false); - if (r) - goto out; - + if (crypt_get_integrity_tag_size(cd) && + (iname = dm_get_active_iname(cd, name))) { r = dm_resume_device(cd, iname, 0); if (r) log_err(cd, _("Error during resuming device %s."), iname); + free(iname); } if (enc_type == CRYPT_OPAL_HW_ONLY) @@ -4295,7 +4460,7 @@ static int resume_luks2_by_volume_key(struct crypt_device *cd, out: if (r < 0) { - crypt_drop_keyring_key(cd, p_crypt); + crypt_drop_uploaded_keyring_key(cd, p_crypt); if (cd->link_vk_to_keyring && kid1) crypt_unlink_key_from_custom_keyring(cd, kid1); if (cd->link_vk_to_keyring && kid2) @@ -4309,7 +4474,6 @@ static int resume_luks2_by_volume_key(struct crypt_device *cd, crypt_free_volume_key(zerokey); crypt_free_volume_key(opal_key); crypt_free_volume_key(crypt_key); - free(iname); return r; } @@ -4395,9 +4559,9 @@ int crypt_resume_by_passphrase(struct crypt_device *cd, size_t passphrase_size) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_passphrase_init_internal(&kc, passphrase, passphrase_size); + crypt_keyslot_context_init_by_passphrase_internal(&kc, passphrase, passphrase_size); r = crypt_resume_by_keyslot_context(cd, name, keyslot, &kc); crypt_keyslot_context_destroy_internal(&kc); @@ -4412,9 +4576,9 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd, uint64_t keyfile_offset) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_keyfile_init_internal(&kc, keyfile, keyfile_size, keyfile_offset); + crypt_keyslot_context_init_by_keyfile_internal(&kc, keyfile, keyfile_size, keyfile_offset); r = crypt_resume_by_keyslot_context(cd, name, keyslot, &kc); crypt_keyslot_context_destroy_internal(&kc); @@ -4448,9 +4612,9 @@ int crypt_resume_by_volume_key(struct crypt_device *cd, size_t volume_key_size) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_key_init_internal(&kc, volume_key, volume_key_size); + crypt_keyslot_context_init_by_key_internal(&kc, volume_key, volume_key_size); r = crypt_resume_by_keyslot_context(cd, name, CRYPT_ANY_SLOT /* unused */, &kc); crypt_keyslot_context_destroy_internal(&kc); @@ -4465,9 +4629,9 @@ int crypt_resume_by_token_pin(struct crypt_device *cd, const char *name, void *usrptr) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_token_init_internal(&kc, token, type, pin, pin_size, usrptr); + crypt_keyslot_context_init_by_token_internal(&kc, token, type, pin, pin_size, usrptr); r = crypt_resume_by_keyslot_context(cd, name, CRYPT_ANY_SLOT, &kc); crypt_keyslot_context_destroy_internal(&kc); @@ -4485,13 +4649,13 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, size_t new_passphrase_size) { int r; - struct crypt_keyslot_context kc, new_kc; + struct crypt_keyslot_context kc = {}, new_kc = {}; if (!passphrase || !new_passphrase) return -EINVAL; - crypt_keyslot_unlock_by_passphrase_init_internal(&kc, passphrase, passphrase_size); - crypt_keyslot_unlock_by_passphrase_init_internal(&new_kc, new_passphrase, new_passphrase_size); + crypt_keyslot_context_init_by_passphrase_internal(&kc, passphrase, passphrase_size); + crypt_keyslot_context_init_by_passphrase_internal(&new_kc, new_passphrase, new_passphrase_size); r = crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, &kc, keyslot, &new_kc, 0); @@ -4545,21 +4709,21 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd, } keyslot_old = r; - if (isLUKS2(cd->type)) { + if (isLUKS1(cd->type)) { + if (keyslot_new == CRYPT_ANY_SLOT) { + keyslot_new = LUKS_keyslot_find_empty(&cd->u.luks1.hdr); + if (keyslot_new < 0) + keyslot_new = keyslot_old; + } + } else if (isLUKS2(cd->type)) { /* If there is a free keyslot (both id and binary area) avoid in-place keyslot area overwrite */ if (keyslot_new == CRYPT_ANY_SLOT || keyslot_new == keyslot_old) { - keyslot_new = LUKS2_keyslot_find_empty(cd, &cd->u.luks2.hdr, vk->keylength); + keyslot_new = LUKS2_keyslot_find_empty(cd, &cd->u.luks2.hdr, crypt_volume_key_length(vk)); if (keyslot_new < 0) keyslot_new = keyslot_old; else keyslot_swap = true; } - } else if (isLUKS1(cd->type)) { - if (keyslot_new == CRYPT_ANY_SLOT) { - keyslot_new = LUKS_keyslot_find_empty(&cd->u.luks1.hdr); - if (keyslot_new < 0) - keyslot_new = keyslot_old; - } } log_dbg(cd, "Key change, old slot %d, new slot %d.", keyslot_old, keyslot_new); @@ -4629,13 +4793,13 @@ int crypt_keyslot_add_by_keyfile_device_offset(struct crypt_device *cd, uint64_t new_keyfile_offset) { int r; - struct crypt_keyslot_context kc, new_kc; + struct crypt_keyslot_context kc = {}, new_kc = {}; if (!keyfile || !new_keyfile) return -EINVAL; - crypt_keyslot_unlock_by_keyfile_init_internal(&kc, keyfile, keyfile_size, keyfile_offset); - crypt_keyslot_unlock_by_keyfile_init_internal(&new_kc, new_keyfile, new_keyfile_size, new_keyfile_offset); + crypt_keyslot_context_init_by_keyfile_internal(&kc, keyfile, keyfile_size, keyfile_offset); + crypt_keyslot_context_init_by_keyfile_internal(&new_kc, new_keyfile, new_keyfile_size, new_keyfile_offset); r = crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, &kc, keyslot, &new_kc, 0); @@ -4679,13 +4843,13 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd, size_t passphrase_size) { int r; - struct crypt_keyslot_context kc, new_kc; + struct crypt_keyslot_context kc = {}, new_kc = {}; if (!passphrase) return -EINVAL; - crypt_keyslot_unlock_by_key_init_internal(&kc, volume_key, volume_key_size); - crypt_keyslot_unlock_by_passphrase_init_internal(&new_kc, passphrase, passphrase_size); + crypt_keyslot_context_init_by_key_internal(&kc, volume_key, volume_key_size); + crypt_keyslot_context_init_by_passphrase_internal(&new_kc, passphrase, passphrase_size); r = crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, &kc, keyslot, &new_kc, 0); @@ -4786,7 +4950,7 @@ static int _create_device_with_integrity(struct crypt_device *cd, device_check = dmd->flags & CRYPT_ACTIVATE_SHARED ? DEV_OK : DEV_EXCL; - r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi, 0); + r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_SUBDEV, dmdi, 0); if (r) return r; @@ -4835,8 +4999,7 @@ int create_or_reload_device(struct crypt_device *cd, const char *name, int r; enum devcheck device_check; struct dm_target *tgt; - uint64_t offset; - uint32_t dmflags = 0; + uint64_t offset, dmflags = 0; if (!type || !name || !single_segment(dmd)) return -EINVAL; @@ -4919,86 +5082,6 @@ int create_or_reload_device_with_integrity(struct crypt_device *cd, const char * return r; } -static int _open_and_activate(struct crypt_device *cd, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - bool use_keyring; - int r; - struct volume_key *p_crypt = NULL, *p_opal = NULL, *crypt_key = NULL, *opal_key = NULL, *vk = NULL; - key_serial_t kid1 = 0, kid2 = 0; - - r = LUKS2_keyslot_open(cd, keyslot, - (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ? - CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT, - passphrase, passphrase_size, &vk); - if (r < 0) - return r; - keyslot = r; - - /* split the key only if we do activation */ - if (name && LUKS2_segment_is_hw_opal(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT)) { - r = LUKS2_split_crypt_and_opal_keys(cd, &cd->u.luks2.hdr, - vk, &crypt_key, - &opal_key); - if (r < 0) - goto out; - - /* copy volume key digest id in crypt subkey */ - crypt_volume_key_set_id(crypt_key, crypt_volume_key_get_id(vk)); - - p_crypt = crypt_key; - p_opal = opal_key ?: vk; - } else - p_crypt = vk; - - if (!crypt_use_keyring_for_vk(cd)) - use_keyring = false; - else - use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) || - (flags & CRYPT_ACTIVATE_KEYRING_KEY)); - - if (use_keyring) { - /* upload dm-crypt part of volume key in thread keyring if requested */ - if (p_crypt) { - r = LUKS2_volume_key_load_in_keyring_by_digest(cd, p_crypt, - crypt_volume_key_get_id(p_crypt)); - if (r < 0) - goto out; - flags |= CRYPT_ACTIVATE_KEYRING_KEY; - } - - /* upload the volume key in custom user keyring if requested */ - if (cd->link_vk_to_keyring) { - r = crypt_volume_key_load_in_user_keyring(cd, vk, &kid1, &kid2); - if (r < 0) { - log_err(cd, _("Failed to link volume key in user defined keyring.")); - goto out; - } - } - } - - if (name) - r = LUKS2_activate(cd, name, p_crypt, p_opal, flags); -out: - if (r < 0) { - crypt_drop_keyring_key(cd, p_crypt); - if (cd->link_vk_to_keyring && kid1) - crypt_unlink_key_from_custom_keyring(cd, kid1); - if (cd->link_vk_to_keyring && kid2) - crypt_unlink_key_from_custom_keyring(cd, kid2); - } - crypt_free_volume_key(vk); - crypt_free_volume_key(crypt_key); - crypt_free_volume_key(opal_key); - - return r < 0 ? r : keyslot; -} - -#if USE_LUKS2_REENCRYPTION static int load_all_keys(struct crypt_device *cd, struct volume_key *vks) { int r; @@ -5014,55 +5097,8 @@ static int load_all_keys(struct crypt_device *cd, struct volume_key *vks) return 0; } -static int _open_all_keys(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - const char *passphrase, - size_t passphrase_size, - uint32_t flags, - struct volume_key **vks) -{ - int r, segment; - struct volume_key *_vks = NULL; - crypt_reencrypt_info ri = LUKS2_reencrypt_status(hdr); - - segment = (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ? CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT; - - switch (ri) { - case CRYPT_REENCRYPT_NONE: - r = LUKS2_keyslot_open(cd, keyslot, segment, passphrase, passphrase_size, &_vks); - break; - case CRYPT_REENCRYPT_CLEAN: - case CRYPT_REENCRYPT_CRASH: - if (segment == CRYPT_ANY_SEGMENT) - r = LUKS2_keyslot_open(cd, keyslot, segment, passphrase, - passphrase_size, &_vks); - else - r = LUKS2_keyslot_open_all_segments(cd, keyslot, - keyslot, passphrase, passphrase_size, - &_vks); - break; - default: - r = -EINVAL; - } - - if (keyslot == CRYPT_ANY_SLOT) - keyslot = r; - - if (r >= 0 && (flags & CRYPT_ACTIVATE_KEYRING_KEY)) - r = load_all_keys(cd, _vks); - - if (r >= 0 && vks) - MOVE_REF(*vks, _vks); - - if (r < 0) - crypt_drop_keyring_key(cd, _vks); - crypt_free_volume_key(_vks); - - return r < 0 ? r : keyslot; -} - -static int _open_and_activate_reencrypt_device_by_vk(struct crypt_device *cd, +#if USE_LUKS2_REENCRYPTION +static int _activate_reencrypt_device_by_vk(struct crypt_device *cd, struct luks2_hdr *hdr, const char *name, struct volume_key *vks, @@ -5073,14 +5109,10 @@ static int _open_and_activate_reencrypt_device_by_vk(struct crypt_device *cd, uint64_t minimal_size, device_size; int r = 0; struct crypt_lock_handle *reencrypt_lock = NULL; - key_serial_t kid1 = 0, kid2 = 0; struct volume_key *vk; - if (!vks) - return -EINVAL; - - if (crypt_use_keyring_for_vk(cd)) - flags |= CRYPT_ACTIVATE_KEYRING_KEY; + assert(hdr); + assert(vks); r = LUKS2_reencrypt_lock(cd, &reencrypt_lock); if (r) { @@ -5095,17 +5127,29 @@ static int _open_and_activate_reencrypt_device_by_vk(struct crypt_device *cd, goto out; ri = LUKS2_reencrypt_status(hdr); + if (ri == CRYPT_REENCRYPT_INVALID) { + r = -EINVAL; + goto out; + } - if (ri == CRYPT_REENCRYPT_CRASH) { - r = LUKS2_reencrypt_locked_recovery_by_vks(cd, vks); - if (r < 0) { - log_err(cd, _("LUKS2 reencryption recovery using volume key(s) failed.")); + if (ri > CRYPT_REENCRYPT_NONE) { + /* it's sufficient to force re-verify the reencrypt digest only */ + r = LUKS2_reencrypt_digest_verify(cd, &cd->u.luks2.hdr, vks); + if (r < 0) goto out; - } - ri = LUKS2_reencrypt_status(hdr); + if (ri == CRYPT_REENCRYPT_CRASH) { + r = LUKS2_reencrypt_locked_recovery_by_vks(cd, vks); + if (r < 0) { + log_err(cd, _("LUKS2 reencryption recovery using volume key(s) failed.")); + goto out; + } + + ri = LUKS2_reencrypt_status(hdr); + } } - /* recovery finished reencryption or it's already finished */ + + /* recovery finished reencryption or it was already finished after metadata reload */ if (ri == CRYPT_REENCRYPT_NONE) { vk = crypt_volume_key_by_id(vks, LUKS2_digest_by_segment(hdr, CRYPT_DEFAULT_SEGMENT)); if (!vk) { @@ -5114,13 +5158,6 @@ static int _open_and_activate_reencrypt_device_by_vk(struct crypt_device *cd, } r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk); - if (r == -EPERM || r == -ENOENT) - log_err(cd, _("Volume key does not match the volume.")); - if (r >= 0 && cd->link_vk_to_keyring) { - kid1 = crypt_single_volume_key_load_in_user_keyring(cd, vk, cd->user_key_name1); - if (kid1 <= 0) - r = -EINVAL; - } if (r >= 0) r = LUKS2_activate(cd, name, vk, NULL, flags); goto out; @@ -5130,185 +5167,26 @@ static int _open_and_activate_reencrypt_device_by_vk(struct crypt_device *cd, goto out; } - if ((flags & CRYPT_ACTIVATE_KEYRING_KEY)) { - r = load_all_keys(cd, vks); - if (r < 0) - goto out; - } - if ((r = LUKS2_get_data_size(hdr, &minimal_size, &dynamic_size))) goto out; - r = LUKS2_reencrypt_digest_verify(cd, hdr, vks); - if (r < 0) - goto out; - log_dbg(cd, "Entering clean reencryption state mode."); - r = LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, true, dynamic_size); + r = LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, + !(flags & CRYPT_ACTIVATE_SHARED), + dynamic_size); if (r < 0) goto out; - if (cd->link_vk_to_keyring) { - r = crypt_volume_key_load_in_user_keyring(cd, vks, &kid1, &kid2); - if (r < 0) { - log_err(cd, _("Failed to link volume keys in user defined keyring.")); - goto out; - } - } r = LUKS2_activate_multi(cd, name, vks, device_size >> SECTOR_SHIFT, flags); out: LUKS2_reencrypt_unlock(cd, reencrypt_lock); - crypt_drop_keyring_key(cd, vks); return r; } -static int _open_and_activate_reencrypt_device(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - bool dynamic_size; - crypt_reencrypt_info ri; - uint64_t minimal_size, device_size; - struct volume_key *vks = NULL; - int r = 0; - struct crypt_lock_handle *reencrypt_lock = NULL; - key_serial_t kid1 = 0, kid2 = 0; - - if (crypt_use_keyring_for_vk(cd)) - flags |= CRYPT_ACTIVATE_KEYRING_KEY; - - r = LUKS2_reencrypt_lock(cd, &reencrypt_lock); - if (r) { - if (r == -EBUSY) - log_err(cd, _("Reencryption in-progress. Cannot activate device.")); - else - log_err(cd, _("Failed to get reencryption lock.")); - return r; - } - - if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) - goto out; - - ri = LUKS2_reencrypt_status(hdr); - - if (ri == CRYPT_REENCRYPT_CRASH) { - r = LUKS2_reencrypt_locked_recovery_by_passphrase(cd, keyslot, - keyslot, passphrase, passphrase_size, &vks); - if (r < 0) { - log_err(cd, _("LUKS2 reencryption recovery failed.")); - goto out; - } - keyslot = r; - - ri = LUKS2_reencrypt_status(hdr); - } - - /* recovery finished reencryption or it's already finished */ - if (ri == CRYPT_REENCRYPT_NONE) { - crypt_drop_keyring_key(cd, vks); - crypt_free_volume_key(vks); - LUKS2_reencrypt_unlock(cd, reencrypt_lock); - return _open_and_activate(cd, keyslot, name, passphrase, passphrase_size, flags); - } - - if (ri > CRYPT_REENCRYPT_CLEAN) { - r = -EINVAL; - goto out; - } - - if (LUKS2_get_data_size(hdr, &minimal_size, &dynamic_size)) - goto out; - - if (!vks) { - r = _open_all_keys(cd, hdr, keyslot, passphrase, passphrase_size, flags, &vks); - if (r >= 0) - keyslot = r; - } - - if (r >= 0) { - r = LUKS2_reencrypt_digest_verify(cd, hdr, vks); - if (r < 0) - goto out; - } - - log_dbg(cd, "Entering clean reencryption state mode."); - - if (cd->link_vk_to_keyring) { - r = crypt_volume_key_load_in_user_keyring(cd, vks, &kid1, &kid2); - if (r < 0) { - log_err(cd, _("Failed to link volume keys in user defined keyring.")); - goto out; - } - } - - if (r >= 0) - r = LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, - !(flags & CRYPT_ACTIVATE_SHARED), - dynamic_size); - - if (r >= 0) - r = LUKS2_activate_multi(cd, name, vks, device_size >> SECTOR_SHIFT, flags); -out: - LUKS2_reencrypt_unlock(cd, reencrypt_lock); - if (r < 0) { - crypt_drop_keyring_key(cd, vks); - if (cd->link_vk_to_keyring && kid1) - crypt_unlink_key_from_custom_keyring(cd, kid1); - if (cd->link_vk_to_keyring && kid2) - crypt_unlink_key_from_custom_keyring(cd, kid2); - } - - crypt_free_volume_key(vks); - - return r < 0 ? r : keyslot; -} - /* * Activation/deactivation of a device */ -static int _open_and_activate_luks2(struct crypt_device *cd, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - crypt_reencrypt_info ri; - int r, rv; - struct luks2_hdr *hdr = &cd->u.luks2.hdr; - struct volume_key *vks = NULL; - - ri = LUKS2_reencrypt_status(hdr); - if (ri == CRYPT_REENCRYPT_INVALID) - return -EINVAL; - - if (ri > CRYPT_REENCRYPT_NONE) { - if (name) - r = _open_and_activate_reencrypt_device(cd, hdr, keyslot, name, passphrase, - passphrase_size, flags); - else { - r = _open_all_keys(cd, hdr, keyslot, passphrase, - passphrase_size, flags, &vks); - if (r < 0) - return r; - - rv = LUKS2_reencrypt_digest_verify(cd, hdr, vks); - crypt_free_volume_key(vks); - if (rv < 0) - return rv; - } - } else - r = _open_and_activate(cd, keyslot, name, passphrase, - passphrase_size, flags); - - return r; -} - static int _activate_luks2_by_volume_key(struct crypt_device *cd, const char *name, struct volume_key *vk, @@ -5317,27 +5195,13 @@ static int _activate_luks2_by_volume_key(struct crypt_device *cd, { int r; crypt_reencrypt_info ri; - int digest_new, digest_old; - struct volume_key *vk_old = NULL, *vk_new = NULL; ri = LUKS2_reencrypt_status(&cd->u.luks2.hdr); if (ri == CRYPT_REENCRYPT_INVALID) return -EINVAL; if (ri > CRYPT_REENCRYPT_NONE) { - digest_new = LUKS2_reencrypt_digest_new(&cd->u.luks2.hdr); - digest_old = LUKS2_reencrypt_digest_old(&cd->u.luks2.hdr); - - if (digest_new >= 0) { - vk_new = crypt_volume_key_by_id(vk, digest_new); - assert(vk_new); - assert(crypt_volume_key_get_id(vk_new) == digest_new); - } - if (digest_old >= 0) { - vk_old = crypt_volume_key_by_id(vk, digest_old); - assert(vk_old); - assert(crypt_volume_key_get_id(vk_old) == digest_old); - } - r = _open_and_activate_reencrypt_device_by_vk(cd, &cd->u.luks2.hdr, name, vk, flags); + /* reencryption must reverify keys after taking the reencryption lock and reloading metadata */ + r = _activate_reencrypt_device_by_vk(cd, &cd->u.luks2.hdr, name, vk, flags); } else { /* hw-opal data segment type does not require volume key for activation */ assert(!vk || crypt_volume_key_get_id(vk) == LUKS2_digest_by_segment(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT)); @@ -5347,27 +5211,6 @@ static int _activate_luks2_by_volume_key(struct crypt_device *cd, return r; } #else -static int _open_and_activate_luks2(struct crypt_device *cd, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - crypt_reencrypt_info ri; - - ri = LUKS2_reencrypt_status(&cd->u.luks2.hdr); - if (ri == CRYPT_REENCRYPT_INVALID) - return -EINVAL; - - if (ri > CRYPT_REENCRYPT_NONE) { - log_err(cd, _("This operation is not supported for this device type.")); - return -ENOTSUP; - } - - return _open_and_activate(cd, keyslot, name, passphrase, passphrase_size, flags); -} - static int _activate_luks2_by_volume_key(struct crypt_device *cd, const char *name, struct volume_key *vk, @@ -5392,76 +5235,6 @@ static int _activate_luks2_by_volume_key(struct crypt_device *cd, } #endif -static int _activate_by_passphrase(struct crypt_device *cd, - const char *name, - int keyslot, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - int r; - struct volume_key *vk = NULL; - - if ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd)) - return -EINVAL; - - if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name) - return -EINVAL; - - r = _check_header_data_overlap(cd, name); - if (r < 0) - return r; - - if (flags & CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF) - cd->memory_hard_pbkdf_lock_enabled = true; - - /* plain, use hashed passphrase */ - if (isPLAIN(cd->type)) { - r = -EINVAL; - if (!name) - goto out; - - r = process_key(cd, cd->u.plain.hdr.hash, - cd->u.plain.key_size, - passphrase, passphrase_size, &vk); - if (r < 0) - goto out; - - r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags); - keyslot = 0; - } else if (isLUKS1(cd->type)) { - r = LUKS_open_key_with_hdr(keyslot, passphrase, - passphrase_size, &cd->u.luks1.hdr, &vk, cd); - if (r >= 0) { - keyslot = r; - if (name) - r = LUKS1_activate(cd, name, vk, flags); - } - } else if (isLUKS2(cd->type)) { - r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags); - keyslot = r; - } else if (isBITLK(cd->type)) { - r = BITLK_activate_by_passphrase(cd, name, passphrase, passphrase_size, - &cd->u.bitlk.params, flags); - keyslot = 0; - } else if (isFVAULT2(cd->type)) { - r = FVAULT2_activate_by_passphrase(cd, name, passphrase, passphrase_size, - &cd->u.fvault2.params, flags); - keyslot = 0; - } else { - log_err(cd, _("Device type is not properly initialized.")); - r = -EINVAL; - } -out: - if (r < 0) - crypt_drop_keyring_key(cd, vk); - crypt_free_volume_key(vk); - - cd->memory_hard_pbkdf_lock_enabled = false; - - return r < 0 ? r : keyslot; -} - static int _activate_loopaes(struct crypt_device *cd, const char *name, const char *buffer, @@ -5476,7 +5249,7 @@ static int _activate_loopaes(struct crypt_device *cd, buffer_copy = crypt_safe_alloc(buffer_size); if (!buffer_copy) return -ENOMEM; - memcpy(buffer_copy, buffer, buffer_size); + crypt_safe_memcpy(buffer_copy, buffer, buffer_size); r = LOOPAES_parse_keyfile(cd, &vk, cd->u.loopaes.hdr.hash, &key_count, buffer_copy, buffer_size); @@ -5515,45 +5288,45 @@ static int _activate_check_status(struct crypt_device *cd, const char *name, uns return r; } +static int _verify_reencrypt_keys(struct crypt_device *cd, struct volume_key *vks) +{ + int r; + + assert(cd && (isLUKS2(cd->type))); + + r = LUKS2_reencrypt_digest_verify(cd, &cd->u.luks2.hdr, vks); + if (r == -EPERM || r == -ENOENT || r == -EINVAL) + log_err(cd, _("Reencryption volume keys do not match the volume.")); + + return r; +} + static int _verify_key(struct crypt_device *cd, - int segment, + bool unbound_key, struct volume_key *vk) { int r = -EINVAL; - crypt_reencrypt_info ri; - struct luks2_hdr *hdr = &cd->u.luks2.hdr; assert(cd); if (isPLAIN(cd->type)) { - if (vk && vk->keylength == cd->u.plain.key_size) { + if (vk && crypt_volume_key_length(vk) == cd->u.plain.key_size) { r = KEY_VERIFIED; } else log_err(cd, _("Incorrect volume key specified for plain device.")); } else if (isLUKS1(cd->type)) { + if (!vk) + return -EINVAL; + r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk); - if (r == -EPERM) - log_err(cd, _("Volume key does not match the volume.")); } else if (isLUKS2(cd->type)) { - ri = LUKS2_reencrypt_status(hdr); - if (ri == CRYPT_REENCRYPT_INVALID) + if (!vk) return -EINVAL; - if (ri > CRYPT_REENCRYPT_NONE) { - LUKS2_reencrypt_lookup_key_ids(cd, hdr, vk); - r = LUKS2_reencrypt_digest_verify(cd, hdr, vk); - if (r == -EPERM || r == -ENOENT || r == -EINVAL) - log_err(cd, _("Reencryption volume keys do not match the volume.")); - return r; - } - - if (segment == CRYPT_ANY_SEGMENT) - r = LUKS2_digest_any_matching(cd, &cd->u.luks2.hdr, vk); - else { - r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, segment, vk); - if (r == -EPERM || r == -ENOENT) - log_err(cd, _("Volume key does not match the volume.")); - } + if (unbound_key) + r = LUKS2_digest_verify_by_any_matching(cd, vk); + else + r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk); } else if (isVERITY(cd->type)) r = KEY_VERIFIED; else if (isTCRYPT(cd->type)) @@ -5562,7 +5335,10 @@ static int _verify_key(struct crypt_device *cd, r = KEY_VERIFIED; else if (isBITLK(cd->type)) r = KEY_VERIFIED; - else + else if (isFVAULT2(cd->type)) { + if (vk && crypt_volume_key_length(vk) == FVAULT2_volume_key_size()) + r = KEY_VERIFIED; + } else log_err(cd, _("Device type is not properly initialized.")); if (r >= KEY_VERIFIED) @@ -5617,8 +5393,12 @@ static int _activate_by_volume_key(struct crypt_device *cd, cd->u.integrity.sb_flags); } else if (isBITLK(cd->type)) { assert(!external_key); - r = BITLK_activate_by_volume_key(cd, name, vk->key, vk->keylength, - &cd->u.bitlk.params, flags); + assert(crypt_volume_key_get_id(vk) == KEY_VERIFIED); + r = BITLK_activate_by_volume_key(cd, name, vk, &cd->u.bitlk.params, flags); + } else if (isFVAULT2(cd->type)) { + assert(!external_key); + assert(crypt_volume_key_get_id(vk) == KEY_VERIFIED); + r = FVAULT2_activate_by_volume_key(cd, name, vk, &cd->u.fvault2.params, flags); } else { log_err(cd, _("Device type is not properly initialized.")); r = -EINVAL; @@ -5628,19 +5408,19 @@ static int _activate_by_volume_key(struct crypt_device *cd, } int crypt_activate_by_keyslot_context(struct crypt_device *cd, -const char *name, + const char *name, int keyslot, struct crypt_keyslot_context *kc, int additional_keyslot, struct crypt_keyslot_context *additional_kc, uint32_t flags) { - bool use_keyring; + bool use_keyring, luks2_reencryption = false; struct volume_key *p_ext_key, *crypt_key = NULL, *opal_key = NULL, *vk = NULL, *vk_sign = NULL, *p_crypt = NULL; size_t passphrase_size; const char *passphrase = NULL; - int unlocked_keyslot, required_keys, unlocked_keys = 0, r = -EINVAL; + int unlocked_keyslot, r = -EINVAL; key_serial_t kid1 = 0, kid2 = 0; struct luks2_hdr *hdr = &cd->u.luks2.hdr; @@ -5655,6 +5435,8 @@ const char *name, return -EINVAL; if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name) return -EINVAL; + if (!additional_kc && (additional_keyslot != CRYPT_ANY_SLOT)) + return -EINVAL; if ((kc->type == CRYPT_KC_TYPE_KEYRING) && !kernel_keyring_support()) { log_err(cd, _("Kernel keyring is not supported by the kernel.")); return -EINVAL; @@ -5670,61 +5452,67 @@ const char *name, if (r < 0) return r; - /* for TCRYPT and token skip passphrase activation */ - if (kc->get_passphrase && kc->type != CRYPT_KC_TYPE_TOKEN && !isTCRYPT(cd->type)) { + if (kc->get_passphrase && kc->type != CRYPT_KC_TYPE_TOKEN && + isLOOPAES(cd->type)) { r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); if (r < 0) return r; - /* TODO: Only loopaes should by activated by passphrase method */ - if (passphrase) { - if (isLOOPAES(cd->type)) - return _activate_loopaes(cd, name, passphrase, passphrase_size, flags); - else - return _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags); - } + + return _activate_loopaes(cd, name, passphrase, passphrase_size, flags); } - /* only passphrase unlock is supported with loopaes */ - if (isLOOPAES(cd->type)) - return -EINVAL; - /* activate by volume key */ + if (flags & CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF) + cd->memory_hard_pbkdf_lock_enabled = true; + + /* acquire the volume key(s) */ r = -EINVAL; if (isLUKS1(cd->type)) { if (kc->get_luks1_volume_key) r = kc->get_luks1_volume_key(cd, kc, keyslot, &vk); } else if (isLUKS2(cd->type)) { - required_keys = LUKS2_reencrypt_vks_count(hdr); - - if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY && kc->get_luks2_key) - r = kc->get_luks2_key(cd, kc, keyslot, CRYPT_ANY_SEGMENT, &vk); - else if (kc->get_luks2_volume_key) - r = kc->get_luks2_volume_key(cd, kc, keyslot, &vk); - if (r >= 0) { - unlocked_keys++; - - if (required_keys > 1 && vk && additional_kc) { - if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY && additional_kc->get_luks2_key) - r = additional_kc->get_luks2_key(cd, additional_kc, additional_keyslot, CRYPT_ANY_SEGMENT, &vk->next); - else if (additional_kc->get_luks2_volume_key) - r = additional_kc->get_luks2_volume_key(cd, additional_kc, additional_keyslot, &vk->next); - if (r >= 0) - unlocked_keys++; + if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) { + if (kc->get_luks2_key) + r = kc->get_luks2_key(cd, kc, keyslot, CRYPT_ANY_SEGMENT, &vk); + } else { + switch (LUKS2_reencrypt_status(hdr)) { + case CRYPT_REENCRYPT_NONE: + if (kc->get_luks2_volume_key) + r = kc->get_luks2_volume_key(cd, kc, keyslot, &vk); + break; + case CRYPT_REENCRYPT_CLEAN: /* fall-through */ + case CRYPT_REENCRYPT_CRASH: + luks2_reencryption = true; + r = LUKS2_keyslot_context_open_all_segments(cd, keyslot, additional_keyslot, kc, additional_kc, &vk); + /* fall-through */ + default: + break; } - - if (unlocked_keys < required_keys) - r = -ESRCH; } } else if (isTCRYPT(cd->type)) { r = 0; } else if (name && isPLAIN(cd->type)) { - if (kc->get_plain_volume_key) + if (kc->type == CRYPT_KC_TYPE_VK_KEYRING) { + vk = crypt_alloc_volume_key(cd->u.plain.key_size, NULL); + if (!vk) + return -ENOMEM; + r = crypt_volume_key_set_description_by_name(vk, kc->u.vk_kr.key_description); + if (r < 0) + log_err(cd, _("Cannot use keyring key %s."), kc->u.vk_kr.key_description); + } else if (kc->get_passphrase && kc->type != CRYPT_KC_TYPE_TOKEN) { + r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; + r = process_key(cd, cd->u.plain.hdr.hash, + cd->u.plain.key_size, + passphrase, passphrase_size, &vk); + } else if (kc->get_plain_volume_key) r = kc->get_plain_volume_key(cd, kc, &vk); - } else if (name && isBITLK(cd->type)) { - if (kc->get_bitlk_volume_key) - r = kc->get_bitlk_volume_key(cd, kc, &vk); + } else if (isBITLK(cd->type)) { + if (kc->get_bitlk_volume_key && (name || kc->type != CRYPT_KC_TYPE_KEY)) + r = kc->get_bitlk_volume_key(cd, kc, &cd->u.bitlk.params, &vk); } else if (isFVAULT2(cd->type)) { if (kc->get_fvault2_volume_key) - r = kc->get_fvault2_volume_key(cd, kc, &vk); + r = kc->get_fvault2_volume_key(cd, kc, &cd->u.fvault2.params, &vk); } else if (isVERITY(cd->type) && (name || kc->type != CRYPT_KC_TYPE_SIGNED_KEY)) { if (kc->get_verity_volume_key) r = kc->get_verity_volume_key(cd, kc, &vk, &vk_sign); @@ -5744,7 +5532,8 @@ const char *name, unlocked_keyslot = r; if (r == -ENOENT && isLUKS(cd->type) && cd->volume_key) { - vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key); + vk = crypt_alloc_volume_key(crypt_volume_key_length(cd->volume_key), + crypt_volume_key_get_key(cd->volume_key)); r = vk ? 0 : -ENOMEM; } if (r == -ENOENT && isINTEGRITY(cd->type)) @@ -5753,9 +5542,11 @@ const char *name, if (r < 0) goto out; - r = _verify_key(cd, - flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY ? CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT, - vk); + if (luks2_reencryption) + r = _verify_reencrypt_keys(cd, vk); + else + r = _verify_key(cd, flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY, vk); + if (r < 0) goto out; @@ -5781,13 +5572,14 @@ const char *name, if (!crypt_use_keyring_for_vk(cd)) use_keyring = false; else - use_keyring = (name && !crypt_is_cipher_null(crypt_get_cipher(cd))) || + /* Force keyring use for activation of LUKS2 device in reencryption */ + use_keyring = (name && (luks2_reencryption || !crypt_is_cipher_null(crypt_get_cipher(cd)))) || (flags & CRYPT_ACTIVATE_KEYRING_KEY); if (use_keyring) { /* upload dm-crypt part of volume key in thread keyring if requested */ if (p_crypt) { - r = LUKS2_volume_key_load_in_keyring_by_digest(cd, p_crypt, crypt_volume_key_get_id(p_crypt)); + r = load_all_keys(cd, p_crypt); if (r < 0) goto out; flags |= CRYPT_ACTIVATE_KEYRING_KEY; @@ -5795,7 +5587,7 @@ const char *name, /* upload the volume key in custom user keyring if requested */ if (cd->link_vk_to_keyring) { - r = crypt_volume_key_load_in_user_keyring(cd, vk, &kid1, &kid2); + r = crypt_volume_key_load_in_custom_keyring(cd, vk, &kid1, &kid2); if (r < 0) { log_err(cd, _("Failed to link volume key in user defined keyring.")); goto out; @@ -5814,8 +5606,8 @@ const char *name, r = unlocked_keyslot; out: if (r < 0) { - crypt_drop_keyring_key(cd, vk); - crypt_drop_keyring_key(cd, p_crypt); + crypt_drop_uploaded_keyring_key(cd, vk); + crypt_drop_uploaded_keyring_key(cd, crypt_key); if (cd->link_vk_to_keyring && kid1) crypt_unlink_key_from_custom_keyring(cd, kid1); if (cd->link_vk_to_keyring && kid2) @@ -5837,10 +5629,10 @@ int crypt_activate_by_passphrase(struct crypt_device *cd, uint32_t flags) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_passphrase_init_internal(&kc, passphrase, passphrase_size); - r = crypt_activate_by_keyslot_context(cd, name, keyslot, &kc, CRYPT_ANY_SLOT, NULL, flags); + crypt_keyslot_context_init_by_passphrase_internal(&kc, passphrase, passphrase_size); + r = crypt_activate_by_keyslot_context(cd, name, keyslot, &kc, CRYPT_ANY_SLOT, &kc, flags); crypt_keyslot_context_destroy_internal(&kc); return r; @@ -5855,10 +5647,10 @@ int crypt_activate_by_keyfile_device_offset(struct crypt_device *cd, uint32_t flags) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_keyfile_init_internal(&kc, keyfile, keyfile_size, keyfile_offset); - r = crypt_activate_by_keyslot_context(cd, name, keyslot, &kc, CRYPT_ANY_SLOT, NULL, flags); + crypt_keyslot_context_init_by_keyfile_internal(&kc, keyfile, keyfile_size, keyfile_offset); + r = crypt_activate_by_keyslot_context(cd, name, keyslot, &kc, CRYPT_ANY_SLOT, &kc, flags); crypt_keyslot_context_destroy_internal(&kc); return r; @@ -5894,10 +5686,10 @@ int crypt_activate_by_volume_key(struct crypt_device *cd, uint32_t flags) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_key_init_internal(&kc, volume_key, volume_key_size); - r = crypt_activate_by_keyslot_context(cd, name, CRYPT_ANY_SLOT /* unused */, &kc, CRYPT_ANY_SLOT, NULL, flags); + crypt_keyslot_context_init_by_key_internal(&kc, volume_key, volume_key_size); + r = crypt_activate_by_keyslot_context(cd, name, CRYPT_ANY_SLOT /* unused */, &kc, CRYPT_ANY_SLOT, &kc, flags); crypt_keyslot_context_destroy_internal(&kc); return r; @@ -5912,7 +5704,7 @@ int crypt_activate_by_signed_key(struct crypt_device *cd, uint32_t flags) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; if (!cd || !isVERITY(cd->type)) return -EINVAL; @@ -5923,10 +5715,10 @@ int crypt_activate_by_signed_key(struct crypt_device *cd, } if (signature) - crypt_keyslot_unlock_by_signed_key_init_internal(&kc, volume_key, volume_key_size, + crypt_keyslot_context_init_by_signed_key_internal(&kc, volume_key, volume_key_size, signature, signature_size); else - crypt_keyslot_unlock_by_key_init_internal(&kc, volume_key, volume_key_size); + crypt_keyslot_context_init_by_key_internal(&kc, volume_key, volume_key_size); r = crypt_activate_by_keyslot_context(cd, name, -2 /* unused */, &kc, CRYPT_ANY_SLOT, NULL, flags); crypt_keyslot_context_destroy_internal(&kc); @@ -5939,7 +5731,7 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t struct luks2_hdr *hdr2 = NULL; struct crypt_dm_active_device dmd = {}; int r; - uint32_t get_flags = DM_ACTIVE_DEVICE | DM_ACTIVE_UUID | DM_ACTIVE_HOLDERS; + uint64_t get_flags = DM_ACTIVE_DEVICE | DM_ACTIVE_UUID | DM_ACTIVE_HOLDERS; if (!name) return -EINVAL; @@ -5957,13 +5749,10 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t } if (flags & (CRYPT_DEACTIVATE_DEFERRED | CRYPT_DEACTIVATE_DEFERRED_CANCEL)) { - struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); - if (hdr) { - json_object *jobj = json_segments_get_segment(LUKS2_get_segments_jobj(hdr), 0); - if (jobj && !strcmp(json_segment_type(jobj), "hw-opal")) { - log_err(cd, _("OPAL does not support deferred deactivation.")); - return -EINVAL; - } + r = crypt_get_hw_encryption_type(cd); + if (r == CRYPT_SW_AND_OPAL_HW || r == CRYPT_OPAL_HW_ONLY) { + log_err(cd, _("OPAL does not support deferred deactivation.")); + return -EINVAL; } } @@ -5974,13 +5763,6 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t switch (crypt_status(cd, name)) { case CRYPT_ACTIVE: case CRYPT_BUSY: - if (flags & CRYPT_DEACTIVATE_DEFERRED_CANCEL) { - r = dm_cancel_deferred_removal(name); - if (r < 0) - log_err(cd, _("Could not cancel deferred remove from device %s."), name); - break; - } - r = dm_query_device(cd, name, get_flags, &dmd); if (r >= 0) { if (dmd.holders) { @@ -5990,8 +5772,23 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t } } - if (isLUKS2(cd->type)) - hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2); + /* For detached header case or missing metadata we need to check for OPAL2 devices + * from DM UUID */ + if (dmd.uuid && (flags & (CRYPT_DEACTIVATE_DEFERRED | CRYPT_DEACTIVATE_DEFERRED_CANCEL)) && + !strncmp(CRYPT_LUKS2_HW_OPAL, dmd.uuid, sizeof(CRYPT_LUKS2_HW_OPAL)-1)) { + log_err(cd, _("OPAL does not support deferred deactivation.")); + r = -EINVAL; + break; + } + + if (flags & CRYPT_DEACTIVATE_DEFERRED_CANCEL) { + r = dm_cancel_deferred_removal(name); + if (r < 0) + log_err(cd, _("Could not cancel deferred remove from device %s."), name); + break; + } + + hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2); if ((dmd.uuid && !strncmp(CRYPT_LUKS2, dmd.uuid, sizeof(CRYPT_LUKS2)-1)) || hdr2) r = LUKS2_deactivate(cd, name, hdr2, &dmd, flags); @@ -6030,7 +5827,7 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name, { int r; struct crypt_dm_active_device dmd, dmdi = {}; - const char *namei = NULL; + char *iname = NULL; struct dm_target *tgt = &dmd.segment; uint64_t min_offset = UINT64_MAX; @@ -6041,11 +5838,18 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name, if (r < 0) return r; - /* For LUKS2 with integrity we need flags from underlying dm-integrity */ - if (isLUKS2(cd->type) && crypt_get_integrity_tag_size(cd) && single_segment(&dmd)) { - namei = device_dm_name(tgt->data_device); - if (namei && dm_query_device(cd, namei, 0, &dmdi) >= 0) - dmd.flags |= dmdi.flags; + /* + * For integrity and LUKS2 (and detached header where context is NULL) + * we need flags from underlying dm-integrity device. + * This check must be skipped for non-LUKS2 integrity device. + */ + if ((isLUKS2(cd->type) || !cd->type) && crypt_get_integrity_tag_size(cd)) { + if ((iname = dm_get_active_iname(cd, name))) { + if (dm_query_device(cd, iname, 0, &dmdi) >= 0) + dmd.flags |= dmdi.flags; + free(iname); + } else + dmd.flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE); } if (cd && isTCRYPT(cd->type)) { @@ -6111,12 +5915,12 @@ int crypt_volume_key_get(struct crypt_device *cd, size_t passphrase_size) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; if (!passphrase) return crypt_volume_key_get_by_keyslot_context(cd, keyslot, volume_key, volume_key_size, NULL); - crypt_keyslot_unlock_by_passphrase_init_internal(&kc, passphrase, passphrase_size); + crypt_keyslot_context_init_by_passphrase_internal(&kc, passphrase, passphrase_size); r = crypt_volume_key_get_by_keyslot_context(cd, keyslot, volume_key, volume_key_size, &kc); @@ -6137,7 +5941,7 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, struct volume_key *vk = NULL; if (!cd || !volume_key || !volume_key_size || - (!kc && !isLUKS(cd->type) && !isTCRYPT(cd->type) && !isVERITY(cd->type))) + (!kc && !isLUKS(cd->type) && !isTCRYPT(cd->type) && !isVERITY(cd->type) && !isBITLK(cd->type))) return -EINVAL; if (isLUKS2(cd->type) && keyslot != CRYPT_ANY_SLOT) @@ -6156,12 +5960,6 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, if (kc && (!kc->get_passphrase || kc->type == CRYPT_KC_TYPE_KEY)) return -EINVAL; - if (kc) { - r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); - if (r < 0) - return r; - } - r = -EINVAL; if (isLUKS2(cd->type)) { @@ -6180,16 +5978,20 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, r = -ENOENT; else r = kc->get_luks1_volume_key(cd, kc, keyslot, &vk); - } else if (isPLAIN(cd->type)) { - if (passphrase && cd->u.plain.hdr.hash) + } else if (isPLAIN(cd->type) && cd->u.plain.hdr.hash) { + if (kc && kc->get_passphrase && kc->type != CRYPT_KC_TYPE_TOKEN) { + r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; r = process_key(cd, cd->u.plain.hdr.hash, key_len, passphrase, passphrase_size, &vk); + } if (r < 0) log_err(cd, _("Cannot retrieve volume key for plain device.")); } else if (isVERITY(cd->type)) { /* volume_key == root hash */ if (cd->u.verity.root_hash) { - memcpy(volume_key, cd->u.verity.root_hash, cd->u.verity.root_hash_size); + crypt_safe_memcpy(volume_key, cd->u.verity.root_hash, cd->u.verity.root_hash_size); *volume_key_size = cd->u.verity.root_hash_size; r = 0; } else @@ -6197,26 +5999,29 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, } else if (isTCRYPT(cd->type)) { r = TCRYPT_get_volume_key(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params, &vk); } else if (isBITLK(cd->type)) { - if (passphrase) - r = BITLK_get_volume_key(cd, passphrase, passphrase_size, &cd->u.bitlk.params, &vk); + if (kc && kc->get_bitlk_volume_key) + r = kc->get_bitlk_volume_key(cd, kc, &cd->u.bitlk.params, &vk); + else if (!kc) + r = BITLK_get_volume_key(cd, NULL, 0, &cd->u.bitlk.params, &vk); if (r < 0) log_err(cd, _("Cannot retrieve volume key for BITLK device.")); } else if (isFVAULT2(cd->type)) { - if (passphrase) - r = FVAULT2_get_volume_key(cd, passphrase, passphrase_size, &cd->u.fvault2.params, &vk); + if (kc && kc->get_fvault2_volume_key) + r = kc->get_fvault2_volume_key(cd, kc, &cd->u.fvault2.params, &vk); if (r < 0) log_err(cd, _("Cannot retrieve volume key for FVAULT2 device.")); } else log_err(cd, _("This operation is not supported for %s crypt device."), cd->type ?: "(none)"); if (r == -ENOENT && isLUKS(cd->type) && cd->volume_key) { - vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key); + vk = crypt_alloc_volume_key(crypt_volume_key_length(cd->volume_key), + crypt_volume_key_get_key(cd->volume_key)); r = vk ? 0 : -ENOMEM; } if (r >= 0 && vk) { - memcpy(volume_key, vk->key, vk->keylength); - *volume_key_size = vk->keylength; + crypt_safe_memcpy(volume_key, crypt_volume_key_get_key(vk), crypt_volume_key_length(vk)); + *volume_key_size = crypt_volume_key_length(vk); } crypt_free_volume_key(vk); @@ -6518,12 +6323,20 @@ const char *crypt_get_integrity(struct crypt_device *cd) } /* INTERNAL only */ -int crypt_get_integrity_key_size(struct crypt_device *cd) +int crypt_get_integrity_key_size(struct crypt_device *cd, bool dm_compat) { int key_size = 0; - if (isINTEGRITY(cd->type) || isLUKS2(cd->type) || !cd->type) - key_size = INTEGRITY_key_size(crypt_get_integrity(cd)); + if (isLUKS2(cd->type)) { + key_size = INTEGRITY_key_size(crypt_get_integrity(cd), + LUKS2_get_integrity_key_size(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT)); + if (dm_compat && key_size > 0 && + key_size == INTEGRITY_key_size(crypt_get_integrity(cd), 0)) + return 0; + } + + if (isINTEGRITY(cd->type) || !cd->type) + key_size = INTEGRITY_key_size(crypt_get_integrity(cd), 0); return key_size > 0 ? key_size : 0; } @@ -6628,7 +6441,7 @@ int crypt_get_volume_key_size(struct crypt_device *cd) if (isLUKS2(cd->type)) { r = LUKS2_get_volume_key_size(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT); if (r < 0 && cd->volume_key) - r = cd->volume_key->keylength; + r = crypt_volume_key_length(cd->volume_key); return r < 0 ? 0 : r; } @@ -6653,6 +6466,19 @@ int crypt_get_volume_key_size(struct crypt_device *cd) return 0; } +int crypt_get_old_volume_key_size(struct crypt_device *cd) +{ + int r = _onlyLUKS2(cd, CRYPT_CD_QUIET, + CRYPT_REQUIREMENT_ONLINE_REENCRYPT | CRYPT_REQUIREMENT_OPAL); + + if (r < 0) + return 0; + + r = LUKS2_get_old_volume_key_size(&cd->u.luks2.hdr); + + return r < 0 ? 0 : r; +} + int crypt_get_hw_encryption_key_size(struct crypt_device *cd) { if (!cd || !isLUKS2(cd->type)) @@ -7002,7 +6828,7 @@ int crypt_get_integrity_info(struct crypt_device *cd, ip->buffer_sectors = cd->u.integrity.params.buffer_sectors; ip->integrity = cd->u.integrity.params.integrity; - ip->integrity_key_size = crypt_get_integrity_key_size(cd); + ip->integrity_key_size = crypt_get_integrity_key_size(cd, false); ip->journal_integrity = cd->u.integrity.params.journal_integrity; ip->journal_integrity_key_size = cd->u.integrity.params.journal_integrity_key_size; @@ -7021,7 +6847,7 @@ int crypt_get_integrity_info(struct crypt_device *cd, ip->buffer_sectors = 0; // FIXME ip->integrity = LUKS2_get_integrity(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT); - ip->integrity_key_size = crypt_get_integrity_key_size(cd); + ip->integrity_key_size = crypt_get_integrity_key_size(cd, false); ip->tag_size = INTEGRITY_tag_size(ip->integrity, crypt_get_cipher(cd), crypt_get_cipher_mode(cd)); ip->journal_integrity = NULL; @@ -7035,7 +6861,7 @@ int crypt_get_integrity_info(struct crypt_device *cd, } else if (!cd->type) { memset(ip, 0, sizeof(*ip)); ip->integrity = crypt_get_integrity(cd); - ip->integrity_key_size = crypt_get_integrity_key_size(cd); + ip->integrity_key_size = crypt_get_integrity_key_size(cd, false); ip->tag_size = crypt_get_integrity_tag_size(cd); } @@ -7081,12 +6907,11 @@ int crypt_convert(struct crypt_device *cd, /* Internal access function to header pointer */ void *crypt_get_hdr(struct crypt_device *cd, const char *type) { - /* One type can be OPAL */ - if (isLUKS2(type) && isLUKS2(cd->type)) - return &cd->u.luks2.hdr; + assert(cd); + assert(type); /* If requested type differs, ignore it */ - if (strcmp(cd->type, type)) + if (!cd->type || strcmp(cd->type, type)) return NULL; if (isPLAIN(cd->type)) @@ -7095,6 +6920,9 @@ void *crypt_get_hdr(struct crypt_device *cd, const char *type) if (isLUKS1(cd->type)) return &cd->u.luks1.hdr; + if (isLUKS2(type)) + return &cd->u.luks2.hdr; + if (isLOOPAES(cd->type)) return &cd->u.loopaes; @@ -7127,10 +6955,10 @@ int crypt_activate_by_token_pin(struct crypt_device *cd, const char *name, void *usrptr, uint32_t flags) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; - crypt_keyslot_unlock_by_token_init_internal(&kc, token, type, pin, pin_size, usrptr); - r = crypt_activate_by_keyslot_context(cd, name, CRYPT_ANY_SLOT, &kc, CRYPT_ANY_SLOT, NULL, flags); + crypt_keyslot_context_init_by_token_internal(&kc, token, type, pin, pin_size, usrptr); + r = crypt_activate_by_keyslot_context(cd, name, CRYPT_ANY_SLOT, &kc, CRYPT_ANY_SLOT, &kc, flags); crypt_keyslot_context_destroy_internal(&kc); return r; @@ -7252,6 +7080,9 @@ int crypt_token_assign_keyslot(struct crypt_device *cd, int token, int keyslot) if ((r = onlyLUKS2(cd))) return r; + if (token == CRYPT_ANY_TOKEN) + return -EINVAL; + return LUKS2_token_assign(cd, &cd->u.luks2.hdr, keyslot, token, 1, 1); } @@ -7262,6 +7093,9 @@ int crypt_token_unassign_keyslot(struct crypt_device *cd, int token, int keyslot if ((r = onlyLUKS2(cd))) return r; + if (token == CRYPT_ANY_TOKEN) + return -EINVAL; + return LUKS2_token_assign(cd, &cd->u.luks2.hdr, keyslot, token, 0, 1); } @@ -7319,8 +7153,10 @@ int crypt_persistent_flags_get(struct crypt_device *cd, crypt_flags_type type, u if (type == CRYPT_FLAGS_ACTIVATION) return LUKS2_config_get_flags(cd, &cd->u.luks2.hdr, flags); - if (type == CRYPT_FLAGS_REQUIREMENTS) - return LUKS2_config_get_requirements(cd, &cd->u.luks2.hdr, flags); + if (type == CRYPT_FLAGS_REQUIREMENTS) { + LUKS2_config_get_requirements(cd, &cd->u.luks2.hdr, flags); + return 0; + } return -EINVAL; } @@ -7483,17 +7319,22 @@ static int keyslot_add_by_key(struct crypt_device *cd, digest = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk); if (digest >= 0) /* if key matches volume key digest tear down new vk flag */ flags &= ~CRYPT_VOLUME_KEY_SET; - else { + else if (digest == -EPERM) { /* if key matches any existing digest, do not create new digest */ if ((flags & CRYPT_VOLUME_KEY_DIGEST_REUSE)) - digest = LUKS2_digest_any_matching(cd, &cd->u.luks2.hdr, vk); + digest = LUKS2_digest_verify_by_any_matching(cd, vk); + + /* Anything other than -EPERM or -ENOENT suggests broken metadata. Abort */ + if (digest < 0 && digest != -ENOENT && digest != -EPERM) + return digest; /* no segment flag or new vk flag requires new key digest */ if (flags & (CRYPT_VOLUME_KEY_NO_SEGMENT | CRYPT_VOLUME_KEY_SET)) { if (digest < 0 || !(flags & CRYPT_VOLUME_KEY_DIGEST_REUSE)) digest = LUKS2_digest_create(cd, "pbkdf2", &cd->u.luks2.hdr, vk); } - } + } else /* Anything other than -EPERM suggests broken metadata. Abort */ + return digest; r = digest; if (r < 0) { @@ -7524,7 +7365,7 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd, uint32_t flags) { int r; - struct crypt_keyslot_context kc, new_kc; + struct crypt_keyslot_context kc = {}, new_kc = {}; if (!passphrase || ((flags & CRYPT_VOLUME_KEY_NO_SEGMENT) && (flags & CRYPT_VOLUME_KEY_SET))) @@ -7536,9 +7377,9 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd, if ((flags & CRYPT_VOLUME_KEY_SET) && crypt_keyslot_status(cd, keyslot) > CRYPT_SLOT_INACTIVE && isLUKS2(cd->type)) { if (volume_key) - crypt_keyslot_unlock_by_key_init_internal(&kc, volume_key, volume_key_size); + crypt_keyslot_context_init_by_key_internal(&kc, volume_key, volume_key_size); else - crypt_keyslot_unlock_by_passphrase_init_internal(&kc, passphrase, passphrase_size); + crypt_keyslot_context_init_by_passphrase_internal(&kc, passphrase, passphrase_size); r = verify_and_update_segment_digest(cd, &cd->u.luks2.hdr, keyslot, &kc); @@ -7547,8 +7388,8 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd, return r; } - crypt_keyslot_unlock_by_key_init_internal(&kc, volume_key, volume_key_size); - crypt_keyslot_unlock_by_passphrase_init_internal(&new_kc, passphrase, passphrase_size); + crypt_keyslot_context_init_by_key_internal(&kc, volume_key, volume_key_size); + crypt_keyslot_context_init_by_passphrase_internal(&new_kc, passphrase, passphrase_size); r = crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, &kc, keyslot, &new_kc, flags); @@ -7614,11 +7455,12 @@ int crypt_keyslot_add_by_keyslot_context(struct crypt_device *cd, if (r == -ENOENT) { if ((flags & CRYPT_VOLUME_KEY_NO_SEGMENT) && kc->type == CRYPT_KC_TYPE_KEY) { - if (!(vk = crypt_generate_volume_key(cd, kc->u.k.volume_key_size))) + if (!(vk = crypt_generate_volume_key(cd, kc->u.k.volume_key_size, KEY_QUALITY_KEY))) return -ENOMEM; r = 0; } else if (cd->volume_key) { - if (!(vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key))) + if (!(vk = crypt_alloc_volume_key(crypt_volume_key_length(cd->volume_key), + crypt_volume_key_get_key(cd->volume_key)))) return -ENOMEM; r = 0; } else if (active_slots == 0) { @@ -7652,10 +7494,13 @@ int crypt_keyslot_add_by_keyslot_context(struct crypt_device *cd, */ int crypt_use_keyring_for_vk(struct crypt_device *cd) { - uint32_t dmc_flags; + uint64_t dmc_flags; /* dm backend must be initialized */ - if (!cd || !isLUKS2(cd->type)) + if (!cd) + return 0; + + if (!isPLAIN(cd->type) && !isLUKS2(cd->type)) return 0; if (!_vk_via_keyring || !kernel_keyring_support()) @@ -7676,26 +7521,25 @@ int crypt_volume_key_keyring(struct crypt_device *cd __attribute__((unused)), in /* internal only */ int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk) { - key_serial_t kid; - if (!vk || !cd) return -EINVAL; - if (!vk->key_description) { + if (!crypt_volume_key_description(vk)) { log_dbg(cd, "Invalid key description"); return -EINVAL; } - log_dbg(cd, "Loading key (type logon, name %s) in thread keyring.", vk->key_description); + log_dbg(cd, "Loading key (type logon, name %s) in thread keyring.", + crypt_volume_key_description(vk)); - kid = keyring_add_key_in_thread_keyring(LOGON_KEY, vk->key_description, vk->key, vk->keylength); - if (kid < 0) { + if (crypt_volume_key_upload_kernel_key(vk)) { + crypt_set_key_in_keyring(cd, 1); + return 0; + } else { log_dbg(cd, "keyring_add_key_in_thread_keyring failed (error %d)", errno); log_err(cd, _("Failed to load key in kernel keyring.")); - } else - crypt_set_key_in_keyring(cd, 1); - - return kid < 0 ? -EINVAL : 0; + return -EINVAL; + } } /* internal only */ @@ -7742,7 +7586,34 @@ int crypt_keyring_get_key_by_name(struct crypt_device *cd, if (!key_description || !key || !key_size) return -EINVAL; - log_dbg(cd, "Searching for key by name %s.", key_description); + log_dbg(cd, "Searching for kernel key by name %s.", key_description); + + kid = keyring_find_key_id_by_name(key_description); + if (kid == 0) { + log_dbg(cd, "keyring_find_key_id_by_name failed with errno %d.", errno); + return -ENOENT; + } + + log_dbg(cd, "Reading content of kernel key (id %" PRIi32 ").", kid); + + r = keyring_read_key(kid, key, key_size); + if (r < 0) + log_dbg(cd, "keyring_read_key failed with errno %d.", errno); + + return r; +} + +int crypt_keyring_get_keysize_by_name(struct crypt_device *cd, + const char *key_description, + size_t *r_key_size) +{ + int r; + key_serial_t kid; + + if (!key_description || !r_key_size) + return -EINVAL; + + log_dbg(cd, "Searching for kernel key by name %s.", key_description); kid = keyring_find_key_id_by_name(key_description); if (kid == -ENOTSUP) { @@ -7759,9 +7630,9 @@ int crypt_keyring_get_key_by_name(struct crypt_device *cd, log_dbg(cd, "Reading content of kernel key (id %" PRIi32 ").", kid); - r = keyring_read_key(kid, key, key_size); + r = keyring_read_keysize(kid, r_key_size); if (r < 0) - log_dbg(cd, "keyring_read_key failed with errno %d.", errno); + log_dbg(cd, "keyring_read_keysize failed with errno %d.", errno); return r; } @@ -7782,7 +7653,18 @@ void crypt_set_key_in_keyring(struct crypt_device *cd, unsigned key_in_keyring) } /* internal only */ -void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *key_description, key_type_t ktype) +void crypt_unlink_key_from_thread_keyring(struct crypt_device *cd, + key_serial_t key_id) +{ + log_dbg(cd, "Unlinking volume key (id: %" PRIi32 ") from thread keyring.", key_id); + + if (keyring_unlink_key_from_thread_keyring(key_id)) + log_dbg(cd, "keyring_unlink_key_from_thread_keyring failed with errno %d.", errno); +} + +void crypt_unlink_key_by_description_from_thread_keyring(struct crypt_device *cd, + const char *key_description, + key_type_t ktype) { key_serial_t kid; const char *type_name = key_type_name(ktype); @@ -7790,7 +7672,7 @@ void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char * if (!key_description || !type_name) return; - log_dbg(cd, "Requesting kernel key %s (type %s) for unlink from thread keyring.", key_description, type_name); + log_dbg(cd, "Requesting kernel key %s (type %s).", key_description, type_name); crypt_set_key_in_keyring(cd, 0); @@ -7803,14 +7685,7 @@ void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char * return; } - log_dbg(cd, "Unlinking volume key (id: %" PRIi32 ") from thread keyring.", kid); - - if (!keyring_unlink_key_from_thread_keyring(kid)) - return; - - log_dbg(cd, "keyring_unlink_key_from_thread_keyring failed with errno %d.", errno); - log_err(cd, _("Failed to unlink volume key from thread keyring.")); - + crypt_unlink_key_from_thread_keyring(cd, kid); } int crypt_set_keyring_to_link(struct crypt_device *cd, const char *key_description, @@ -7877,12 +7752,12 @@ int crypt_set_keyring_to_link(struct crypt_device *cd, const char *key_descripti } /* internal only */ -void crypt_drop_keyring_key(struct crypt_device *cd, struct volume_key *vks) +void crypt_drop_uploaded_keyring_key(struct crypt_device *cd, struct volume_key *vks) { struct volume_key *vk = vks; while (vk) { - crypt_drop_keyring_key_by_description(cd, vk->key_description, LOGON_KEY); + crypt_volume_key_drop_uploaded_kernel_key(cd, vk); vk = crypt_volume_key_next(vk); } } @@ -7894,13 +7769,13 @@ int crypt_activate_by_keyring(struct crypt_device *cd, uint32_t flags) { int r; - struct crypt_keyslot_context kc; + struct crypt_keyslot_context kc = {}; if (!cd || !key_description) return -EINVAL; - crypt_keyslot_unlock_by_keyring_internal(&kc, key_description); - r = crypt_activate_by_keyslot_context(cd, name, keyslot, &kc, CRYPT_ANY_SLOT, NULL, flags); + crypt_keyslot_context_init_by_keyring_internal(&kc, key_description); + r = crypt_activate_by_keyslot_context(cd, name, keyslot, &kc, CRYPT_ANY_SLOT, &kc, flags); crypt_keyslot_context_destroy_internal(&kc); return r; diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c index f1ed858..8fbe651 100644 --- a/lib/tcrypt/tcrypt.c +++ b/lib/tcrypt/tcrypt.c @@ -2,8 +2,8 @@ /* * TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling * - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2024 Milan Broz + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Milan Broz */ #include @@ -17,30 +17,30 @@ /* TCRYPT PBKDF variants */ static const struct { - unsigned int legacy:1; - unsigned int veracrypt:1; + bool legacy; + bool veracrypt; const char *name; const char *hash; unsigned int iterations; uint32_t veracrypt_pim_const; uint32_t veracrypt_pim_mult; } tcrypt_kdf[] = { - { 0, 0, "pbkdf2", "ripemd160", 2000, 0, 0 }, - { 0, 0, "pbkdf2", "ripemd160", 1000, 0, 0 }, - { 0, 0, "pbkdf2", "sha512", 1000, 0, 0 }, - { 0, 0, "pbkdf2", "whirlpool", 1000, 0, 0 }, - { 1, 0, "pbkdf2", "sha1", 2000, 0, 0 }, - { 0, 1, "pbkdf2", "sha512", 500000, 15000, 1000 }, - { 0, 1, "pbkdf2", "whirlpool", 500000, 15000, 1000 }, - { 0, 1, "pbkdf2", "sha256", 500000, 15000, 1000 }, // VeraCrypt 1.0f - { 0, 1, "pbkdf2", "sha256", 200000, 0, 2048 }, // boot only - { 0, 1, "pbkdf2", "blake2s-256", 500000, 15000, 1000 }, // VeraCrypt 1.26.2 - { 0, 1, "pbkdf2", "blake2s-256", 200000, 0, 2048 }, // boot only - { 0, 1, "pbkdf2", "ripemd160", 655331, 15000, 1000 }, - { 0, 1, "pbkdf2", "ripemd160", 327661, 0, 2048 }, // boot only - { 0, 1, "pbkdf2", "stribog512",500000, 15000, 1000 }, -// { 0, 1, "pbkdf2", "stribog512",200000, 0, 2048 }, // boot only - { 0, 0, NULL, NULL, 0, 0, 0 } + { false, false, "pbkdf2", "ripemd160", 2000, 0, 0 }, + { false, false, "pbkdf2", "ripemd160", 1000, 0, 0 }, + { false, false, "pbkdf2", "sha512", 1000, 0, 0 }, + { false, false, "pbkdf2", "whirlpool", 1000, 0, 0 }, + { true, false, "pbkdf2", "sha1", 2000, 0, 0 }, + { false, true, "pbkdf2", "sha512", 500000, 15000, 1000 }, + { false, true, "pbkdf2", "whirlpool", 500000, 15000, 1000 }, + { false, true, "pbkdf2", "sha256", 500000, 15000, 1000 }, // VeraCrypt 1.0f + { false, true, "pbkdf2", "sha256", 200000, 0, 2048 }, // boot only + { false, true, "pbkdf2", "blake2s-256", 500000, 15000, 1000 }, // VeraCrypt 1.26.2 + { false, true, "pbkdf2", "blake2s-256", 200000, 0, 2048 }, // boot only + { false, true, "pbkdf2", "ripemd160", 655331, 15000, 1000 }, + { false, true, "pbkdf2", "ripemd160", 327661, 0, 2048 }, // boot only + { false, true, "pbkdf2", "stribog512",500000, 15000, 1000 }, +// { false, true, "pbkdf2", "stribog512",200000, 0, 2048 }, // boot only + { false, false, NULL, NULL, 0, 0, 0 } }; struct tcrypt_alg { @@ -53,95 +53,95 @@ struct tcrypt_alg { }; struct tcrypt_algs { - unsigned int legacy:1; + bool legacy; unsigned int chain_count; unsigned int chain_key_size; const char *long_name; const char *mode; - struct tcrypt_alg cipher[3]; + const struct tcrypt_alg cipher[3]; }; /* TCRYPT cipher variants */ -static struct tcrypt_algs tcrypt_cipher[] = { +static const struct tcrypt_algs tcrypt_cipher[] = { /* XTS mode */ -{0,1,64,"aes","xts-plain64", +{false,1,64,"aes","xts-plain64", {{"aes", 64,16,0,32,0}}}, -{0,1,64,"serpent","xts-plain64", +{false,1,64,"serpent","xts-plain64", {{"serpent",64,16,0,32,0}}}, -{0,1,64,"twofish","xts-plain64", +{false,1,64,"twofish","xts-plain64", {{"twofish",64,16,0,32,0}}}, -{0,2,128,"twofish-aes","xts-plain64", +{false,2,128,"twofish-aes","xts-plain64", {{"twofish",64,16, 0,64,0}, {"aes", 64,16,32,96,0}}}, -{0,3,192,"serpent-twofish-aes","xts-plain64", +{false,3,192,"serpent-twofish-aes","xts-plain64", {{"serpent",64,16, 0, 96,0}, {"twofish",64,16,32,128,0}, {"aes", 64,16,64,160,0}}}, -{0,2,128,"aes-serpent","xts-plain64", +{false,2,128,"aes-serpent","xts-plain64", {{"aes", 64,16, 0,64,0}, {"serpent",64,16,32,96,0}}}, -{0,3,192,"aes-twofish-serpent","xts-plain64", +{false,3,192,"aes-twofish-serpent","xts-plain64", {{"aes", 64,16, 0, 96,0}, {"twofish",64,16,32,128,0}, {"serpent",64,16,64,160,0}}}, -{0,2,128,"serpent-twofish","xts-plain64", +{false,2,128,"serpent-twofish","xts-plain64", {{"serpent",64,16, 0,64,0}, {"twofish",64,16,32,96,0}}}, -{0,1,64,"camellia","xts-plain64", +{false,1,64,"camellia","xts-plain64", {{"camellia", 64,16,0,32,0}}}, -{0,1,64,"kuznyechik","xts-plain64", +{false,1,64,"kuznyechik","xts-plain64", {{"kuznyechik", 64,16,0,32,0}}}, -{0,2,128,"kuznyechik-camellia","xts-plain64", +{false,2,128,"kuznyechik-camellia","xts-plain64", {{"kuznyechik",64,16, 0,64,0}, {"camellia", 64,16,32,96,0}}}, -{0,2,128,"twofish-kuznyechik","xts-plain64", +{false,2,128,"twofish-kuznyechik","xts-plain64", {{"twofish", 64,16, 0,64,0}, {"kuznyechik",64,16,32,96,0}}}, -{0,2,128,"serpent-camellia","xts-plain64", +{false,2,128,"serpent-camellia","xts-plain64", {{"serpent", 64,16, 0,64,0}, {"camellia", 64,16,32,96,0}}}, -{0,2,128,"aes-kuznyechik","xts-plain64", +{false,2,128,"aes-kuznyechik","xts-plain64", {{"aes", 64,16, 0,64,0}, {"kuznyechik",64,16,32,96,0}}}, -{0,3,192,"camellia-serpent-kuznyechik","xts-plain64", +{false,3,192,"camellia-serpent-kuznyechik","xts-plain64", {{"camellia", 64,16, 0, 96,0}, {"serpent", 64,16,32,128,0}, {"kuznyechik",64,16,64,160,0}}}, /* LRW mode */ -{0,1,48,"aes","lrw-benbi", +{false,1,48,"aes","lrw-benbi", {{"aes", 48,16,32,0,0}}}, -{0,1,48,"serpent","lrw-benbi", +{false,1,48,"serpent","lrw-benbi", {{"serpent",48,16,32,0,0}}}, -{0,1,48,"twofish","lrw-benbi", +{false,1,48,"twofish","lrw-benbi", {{"twofish",48,16,32,0,0}}}, -{0,2,96,"twofish-aes","lrw-benbi", +{false,2,96,"twofish-aes","lrw-benbi", {{"twofish",48,16,32,0,0}, {"aes", 48,16,64,0,0}}}, -{0,3,144,"serpent-twofish-aes","lrw-benbi", +{false,3,144,"serpent-twofish-aes","lrw-benbi", {{"serpent",48,16,32,0,0}, {"twofish",48,16,64,0,0}, {"aes", 48,16,96,0,0}}}, -{0,2,96,"aes-serpent","lrw-benbi", +{false,2,96,"aes-serpent","lrw-benbi", {{"aes", 48,16,32,0,0}, {"serpent",48,16,64,0,0}}}, -{0,3,144,"aes-twofish-serpent","lrw-benbi", +{false,3,144,"aes-twofish-serpent","lrw-benbi", {{"aes", 48,16,32,0,0}, {"twofish",48,16,64,0,0}, {"serpent",48,16,96,0,0}}}, -{0,2,96,"serpent-twofish", "lrw-benbi", +{false,2,96,"serpent-twofish", "lrw-benbi", {{"serpent",48,16,32,0,0}, {"twofish",48,16,64,0,0}}}, /* Kernel LRW block size is fixed to 16 bytes for GF(2^128) * thus cannot be used with blowfish where block is 8 bytes. * There also no GF(2^64) support. -{1,1,64,"blowfish_le","lrw-benbi", +{true,1,64,"blowfish_le","lrw-benbi", {{"blowfish_le",64,8,32,0,0}}}, -{1,2,112,"blowfish_le-aes","lrw-benbi", +{true,2,112,"blowfish_le-aes","lrw-benbi", {{"blowfish_le",64, 8,32,0,0}, {"aes", 48,16,88,0,0}}}, -{1,3,160,"serpent-blowfish_le-aes","lrw-benbi", +{true,3,160,"serpent-blowfish_le-aes","lrw-benbi", {{"serpent", 48,16, 32,0,0}, {"blowfish_le",64, 8, 64,0,0}, {"aes", 48,16,120,0,0}}},*/ @@ -150,39 +150,39 @@ static struct tcrypt_algs tcrypt_cipher[] = { * CBC + "outer" CBC (both with whitening) * chain_key_size: alg_keys_bytes + IV_seed_bytes + whitening_bytes */ -{1,1,32+16+16,"aes","cbc-tcw", +{true,1,32+16+16,"aes","cbc-tcw", {{"aes", 32,16,32,0,32}}}, -{1,1,32+16+16,"serpent","cbc-tcw", +{true,1,32+16+16,"serpent","cbc-tcw", {{"serpent",32,16,32,0,32}}}, -{1,1,32+16+16,"twofish","cbc-tcw", +{true,1,32+16+16,"twofish","cbc-tcw", {{"twofish",32,16,32,0,32}}}, -{1,2,64+16+16,"twofish-aes","cbci-tcrypt", +{true,2,64+16+16,"twofish-aes","cbci-tcrypt", {{"twofish",32,16,32,0,0}, {"aes", 32,16,64,0,32}}}, -{1,3,96+16+16,"serpent-twofish-aes","cbci-tcrypt", +{true,3,96+16+16,"serpent-twofish-aes","cbci-tcrypt", {{"serpent",32,16,32,0,0}, {"twofish",32,16,64,0,0}, {"aes", 32,16,96,0,32}}}, -{1,2,64+16+16,"aes-serpent","cbci-tcrypt", +{true,2,64+16+16,"aes-serpent","cbci-tcrypt", {{"aes", 32,16,32,0,0}, {"serpent",32,16,64,0,32}}}, -{1,3,96+16+16,"aes-twofish-serpent", "cbci-tcrypt", +{true,3,96+16+16,"aes-twofish-serpent", "cbci-tcrypt", {{"aes", 32,16,32,0,0}, {"twofish",32,16,64,0,0}, {"serpent",32,16,96,0,32}}}, -{1,2,64+16+16,"serpent-twofish", "cbci-tcrypt", +{true,2,64+16+16,"serpent-twofish", "cbci-tcrypt", {{"serpent",32,16,32,0,0}, {"twofish",32,16,64,0,32}}}, -{1,1,16+8+16,"cast5","cbc-tcw", +{true,1,16+8+16,"cast5","cbc-tcw", {{"cast5", 16,8,32,0,24}}}, -{1,1,24+8+16,"des3_ede","cbc-tcw", +{true,1,24+8+16,"des3_ede","cbc-tcw", {{"des3_ede",24,8,32,0,24}}}, -{1,1,56+8+16,"blowfish_le","cbc-tcrypt", +{true,1,56+8+16,"blowfish_le","cbc-tcrypt", {{"blowfish_le",56,8,32,0,24}}}, -{1,2,88+16+16,"blowfish_le-aes","cbc-tcrypt", +{true,2,88+16+16,"blowfish_le-aes","cbc-tcrypt", {{"blowfish_le",56, 8,32,0,0}, {"aes", 32,16,88,0,32}}}, -{1,3,120+16+16,"serpent-blowfish_le-aes","cbc-tcrypt", +{true,3,120+16+16,"serpent-blowfish_le-aes","cbc-tcrypt", {{"serpent", 32,16, 32,0,0}, {"blowfish_le",56, 8, 64,0,0}, {"aes", 32,16,120,0,32}}}, @@ -258,7 +258,7 @@ static void TCRYPT_swab_le(char *buf) *r = swab32(*r); } -static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg, +static int decrypt_blowfish_le_cbc(const struct tcrypt_alg *alg, const char *key, char *buf) { int bs = alg->iv_size; @@ -301,27 +301,27 @@ static void TCRYPT_remove_whitening(char *buf, const char *key) buf[j] ^= key[j % 8]; } -static void TCRYPT_copy_key(struct tcrypt_alg *alg, const char *mode, +static void TCRYPT_copy_key(const struct tcrypt_alg *alg, const char *mode, char *out_key, const char *key) { int ks2; if (!strncmp(mode, "xts", 3)) { ks2 = alg->key_size / 2; - memcpy(out_key, &key[alg->key_offset], ks2); - memcpy(&out_key[ks2], &key[alg->iv_offset], ks2); + crypt_safe_memcpy(out_key, &key[alg->key_offset], ks2); + crypt_safe_memcpy(&out_key[ks2], &key[alg->iv_offset], ks2); } else if (!strncmp(mode, "lrw", 3)) { ks2 = alg->key_size - TCRYPT_LRW_IKEY_LEN; - memcpy(out_key, &key[alg->key_offset], ks2); - memcpy(&out_key[ks2], key, TCRYPT_LRW_IKEY_LEN); + crypt_safe_memcpy(out_key, &key[alg->key_offset], ks2); + crypt_safe_memcpy(&out_key[ks2], key, TCRYPT_LRW_IKEY_LEN); } else if (!strncmp(mode, "cbc", 3)) { - memcpy(out_key, &key[alg->key_offset], alg->key_size); + crypt_safe_memcpy(out_key, &key[alg->key_offset], alg->key_size); /* IV + whitening */ - memcpy(&out_key[alg->key_size], &key[alg->iv_offset], + crypt_safe_memcpy(&out_key[alg->key_size], &key[alg->iv_offset], alg->key_extra_size); } } -static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode, +static int TCRYPT_decrypt_hdr_one(const struct tcrypt_alg *alg, const char *mode, const char *key,struct tcrypt_phdr *hdr) { char backend_key[TCRYPT_HDR_KEY_LEN]; @@ -365,7 +365,7 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode, * For chained ciphers and CBC mode we need "outer" decryption. * Backend doesn't provide this, so implement it here directly using ECB. */ -static int TCRYPT_decrypt_cbci(struct tcrypt_algs *ciphers, +static int TCRYPT_decrypt_cbci(const struct tcrypt_algs *ciphers, const char *key, struct tcrypt_phdr *hdr) { struct crypt_cipher *cipher[3]; @@ -606,7 +606,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd, if ((r < 0 && skipped && skipped == i) || r == -ENOTSUP) { log_err(cd, _("Required kernel crypto interface not available.")); -#ifdef ENABLE_AF_ALG +#if ENABLE_AF_ALG log_err(cd, _("Ensure you have algif_skcipher kernel module loaded.")); #endif r = -ENOTSUP; @@ -707,7 +707,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd, return r; } -static struct tcrypt_algs *TCRYPT_get_algs(const char *cipher, const char *mode) +static const struct tcrypt_algs *TCRYPT_get_algs(const char *cipher, const char *mode) { int i; @@ -732,11 +732,12 @@ int TCRYPT_activate(struct crypt_device *cd, char *part_path; unsigned int i; int r; - uint32_t req_flags, dmc_flags; - struct tcrypt_algs *algs; + uint64_t req_flags, dmc_flags; + const struct tcrypt_algs *algs; enum devcheck device_check; - uint64_t offset = crypt_get_data_offset(cd); + uint64_t offset, iv_offset; struct volume_key *vk = NULL; + void *key = NULL; struct device *ptr_dev = crypt_data_device(cd), *device = NULL, *part_device = NULL; struct crypt_dm_active_device dmd = { .flags = flags @@ -779,24 +780,64 @@ int TCRYPT_activate(struct crypt_device *cd, else device_check = DEV_EXCL; - if ((params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) && - !crypt_dev_is_partition(device_path(crypt_data_device(cd)))) { - part_path = crypt_get_partition_device(device_path(crypt_data_device(cd)), - crypt_get_data_offset(cd), dmd.size); - if (part_path) { - if (!device_alloc(cd, &part_device, part_path)) { - log_verbose(cd, _("Activating TCRYPT system encryption for partition %s."), - part_path); - ptr_dev = part_device; + offset = crypt_get_data_offset(cd); + iv_offset = crypt_get_iv_offset(cd); + + /* + * System encryption is tricky, as the TCRYPT header is outside the partition area. + * It can be a system partition only (TCRYPT header offset contains MK offset to + * a particular partition) or the whole system (then MK offset starts on the header itself). + * IV offset is always partition offset, but device offset depends on whether the user + * copied the whole disk or just one encrypted partition. + * This code tries to guess the most common situations but can still fail and use wrong offsets. + * Recent UEFI systems never use whole system encryption. + */ + if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) { + if (crypt_dev_is_partition(device_path(crypt_data_device(cd)))) { + /* One partition */ + offset = 0; + iv_offset = crypt_dev_partition_offset(device_path(crypt_data_device(cd))); + } else if (crypt_dev_is_partition(device_path(crypt_metadata_device(cd)))) { + /* One partition image, header is the original partition */ + offset = 0; + iv_offset = crypt_dev_partition_offset(device_path(crypt_metadata_device(cd))); + } else { + /* No partition info, try partition-only mode searching for partition. */ + part_path = crypt_get_partition_device(device_path(crypt_data_device(cd)), + iv_offset, hdr->d.volume_size / SECTOR_SIZE); + if (!part_path) + part_path = crypt_get_partition_device(device_path(crypt_metadata_device(cd)), + iv_offset, hdr->d.volume_size / SECTOR_SIZE); + if (part_path) { + if (!device_alloc(cd, &part_device, part_path)) { + log_verbose(cd, _("Activating TCRYPT system encryption for partition %s."), + part_path); + ptr_dev = part_device; + offset = 0; + iv_offset = crypt_dev_partition_offset(part_path); + } + free(part_path); + } else if (device_is_identical(crypt_metadata_device(cd), crypt_data_device(cd))) { + /* + * We have no partition offset and TCRYPT system header is on the data device. + * Use the whole device mapping. + * There can be active partitions, do not use exclusive flag. + */ + device_check = DEV_OK; + dmd.size = hdr->d.volume_size / SECTOR_SIZE; + log_err(cd, _("Cannot determine TCRYPT system partition offset, activating whole encrypted area.")); + } else { + /* + * We have no partition offset and TCRYPT system header is on the metadata device + * (TCRYPT system header was NOT read from data device). + * Expect that data device is a copy of partition and not the whole device. + * This will not work for whole system encryption, though. + */ offset = 0; + log_err(cd, _("Cannot determine TCRYPT system partition offset, activating device as a system partition.")); } - free(part_path); - } else - /* - * System encryption use the whole device mapping, there can - * be active partitions. - */ - device_check = DEV_OK; + } + log_dbg(cd, "TCRYPT system encryption data_offset %" PRIu64 ", iv_offset %" PRIu64 ".", offset, iv_offset); } r = device_block_adjust(cd, ptr_dev, device_check, @@ -825,8 +866,16 @@ int TCRYPT_activate(struct crypt_device *cd, dmd.flags = flags | CRYPT_ACTIVATE_PRIVATE; } + key = crypt_safe_alloc(crypt_volume_key_length(vk)); + if (!key) { + r = -ENOMEM; + break; + } + TCRYPT_copy_key(&algs->cipher[i-1], algs->mode, - vk->key, hdr->d.keys); + key, hdr->d.keys); + + crypt_volume_key_pass_safe_alloc(vk, &key); if (algs->chain_count != i) { if (snprintf(dm_dev_name, sizeof(dm_dev_name), "%s/%s_%d", dm_get_dir(), name, i) < 0) { @@ -847,16 +896,13 @@ int TCRYPT_activate(struct crypt_device *cd, } r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, ptr_dev, vk, - cipher_spec, crypt_get_iv_offset(cd), offset, - crypt_get_integrity(cd), - crypt_get_integrity_tag_size(cd), - crypt_get_sector_size(cd)); + cipher_spec, iv_offset, offset, NULL, 0, 0, crypt_get_sector_size(cd)); if (r) break; log_dbg(cd, "Trying to activate TCRYPT device %s using cipher %s.", dm_name, dmd.segment.u.crypt.cipher); - r = dm_create_device(cd, dm_name, CRYPT_TCRYPT, &dmd); + r = dm_create_device(cd, dm_name, i == 1 ? CRYPT_TCRYPT : CRYPT_SUBDEV, &dmd); dm_targets_free(cd, &dmd); device_free(cd, device); @@ -873,12 +919,33 @@ int TCRYPT_activate(struct crypt_device *cd, } out: + crypt_safe_free(key); crypt_free_volume_key(vk); device_free(cd, device); device_free(cd, part_device); return r; } +static bool is_tcrypt_subdev(const char *dm_uuid, const char *base_uuid) +{ + const char *base_uuid_name; + + assert(base_uuid); + base_uuid_name = strchr(base_uuid, '-'); + + if (!dm_uuid || !base_uuid_name) + return false; + + if (!strncmp(dm_uuid, "SUBDEV-", 7)) + return !strncmp(dm_uuid + 6, base_uuid_name, strlen(base_uuid_name)); + + /* + * FIXME: Drop after shift to dependency based deactivation (CRYPT_SUBDEV) + * in later releases + */ + return !strncmp(dm_uuid, base_uuid, strlen(base_uuid)); +} + static int TCRYPT_remove_one(struct crypt_device *cd, const char *name, const char *base_uuid, int index, uint32_t flags) { @@ -894,7 +961,7 @@ static int TCRYPT_remove_one(struct crypt_device *cd, const char *name, return r; r = dm_query_device(cd, dm_name, DM_ACTIVE_UUID, &dmd); - if (!r && !strncmp(dmd.uuid, base_uuid, strlen(base_uuid))) + if (!r && is_tcrypt_subdev(dmd.uuid, base_uuid)) r = dm_remove_device(cd, dm_name, flags); free(CONST_CAST(void*)dmd.uuid); @@ -916,6 +983,7 @@ int TCRYPT_deactivate(struct crypt_device *cd, const char *name, uint32_t flags) if (r < 0) goto out; + /* FIXME: replace with dependency based deactivation (CRYPT_SUBDEV) in later releases */ r = TCRYPT_remove_one(cd, name, dmd.uuid, 1, flags); if (r < 0) goto out; @@ -934,8 +1002,10 @@ static int TCRYPT_status_one(struct crypt_device *cd, const char *name, { struct crypt_dm_active_device dmd; struct dm_target *tgt = &dmd.segment; - char dm_name[PATH_MAX], *c; + const char *c; + char dm_name[PATH_MAX]; int r; + size_t cipher_len = MAX_CIPHER_LEN; if (snprintf(dm_name, sizeof(dm_name), "%s_%d", name, index) < 0) return -ENOMEM; @@ -957,12 +1027,12 @@ static int TCRYPT_status_one(struct crypt_device *cd, const char *name, r = 0; - if (!strncmp(dmd.uuid, base_uuid, strlen(base_uuid))) { + if (is_tcrypt_subdev(dmd.uuid, base_uuid)) { if ((c = strchr(tgt->u.crypt.cipher, '-'))) - *c = '\0'; + cipher_len = c - tgt->u.crypt.cipher; strcat(cipher, "-"); - strncat(cipher, tgt->u.crypt.cipher, MAX_CIPHER_LEN); - *key_size += tgt->u.crypt.vk->keylength; + strncat(cipher, tgt->u.crypt.cipher, cipher_len); + *key_size += crypt_volume_key_length(tgt->u.crypt.vk); tcrypt_hdr->d.mk_offset = tgt->u.crypt.offset * SECTOR_SIZE; device_free(cd, *device); MOVE_REF(*device, tgt->data_device); @@ -981,7 +1051,7 @@ int TCRYPT_init_by_name(struct crypt_device *cd, const char *name, struct crypt_params_tcrypt *tcrypt_params, struct tcrypt_phdr *tcrypt_hdr) { - struct tcrypt_algs *algs; + const struct tcrypt_algs *algs; char cipher[MAX_CIPHER_LEN * 4], mode[MAX_CIPHER_LEN+1], *tmp; size_t key_size; int r; @@ -999,7 +1069,7 @@ int TCRYPT_init_by_name(struct crypt_device *cd, const char *name, mode[MAX_CIPHER_LEN] = '\0'; strncpy(mode, ++tmp, MAX_CIPHER_LEN); - key_size = tgt->u.crypt.vk->keylength; + key_size = crypt_volume_key_length(tgt->u.crypt.vk); r = TCRYPT_status_one(cd, name, uuid, 1, &key_size, cipher, tcrypt_hdr, device); if (!r) @@ -1028,9 +1098,7 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd, if (!hdr->d.version) { /* No real header loaded, initialized by active device, use default mk_offset */ } else if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) { - /* Mapping through whole device, not partition! */ - if (crypt_dev_is_partition(device_path(crypt_data_device(cd)))) - return 0; + /* Mapping through whole device or partition, return mk_offset */ } else if (params->mode && !strncmp(params->mode, "xts", 3)) { if (hdr->d.version < 3) return 1; @@ -1057,25 +1125,12 @@ uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd, struct tcrypt_phdr *hdr, struct crypt_params_tcrypt *params) { - uint64_t iv_offset, partition_offset; - if (params->mode && !strncmp(params->mode, "xts", 3)) - iv_offset = TCRYPT_get_data_offset(cd, hdr, params); + return TCRYPT_get_data_offset(cd, hdr, params); else if (params->mode && !strncmp(params->mode, "lrw", 3)) - iv_offset = 0; - else - iv_offset = hdr->d.mk_offset / SECTOR_SIZE; + return 0; - if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) { - partition_offset = crypt_dev_partition_offset(device_path(crypt_data_device(cd))); - /* FIXME: we need to deal with overflow sooner */ - if (iv_offset > (UINT64_MAX - partition_offset)) - iv_offset = UINT64_MAX; - else - iv_offset += partition_offset; - } - - return iv_offset; + return hdr->d.mk_offset / SECTOR_SIZE; } int TCRYPT_get_volume_key(struct crypt_device *cd, @@ -1083,8 +1138,9 @@ int TCRYPT_get_volume_key(struct crypt_device *cd, struct crypt_params_tcrypt *params, struct volume_key **vk) { - struct tcrypt_algs *algs; + const struct tcrypt_algs *algs; unsigned int i, key_index; + void *key = NULL; if (!hdr->d.version) { log_err(cd, _("This function is not supported without TCRYPT header load.")); @@ -1095,16 +1151,22 @@ int TCRYPT_get_volume_key(struct crypt_device *cd, if (!algs) return -EINVAL; - *vk = crypt_alloc_volume_key(params->key_size, NULL); - if (!*vk) + key = crypt_safe_alloc(params->key_size); + if (!key) return -ENOMEM; for (i = 0, key_index = 0; i < algs->chain_count; i++) { TCRYPT_copy_key(&algs->cipher[i], algs->mode, - &(*vk)->key[key_index], hdr->d.keys); + &((char *)key)[key_index], hdr->d.keys); key_index += algs->cipher[i].key_size; } + *vk = crypt_alloc_volume_key_by_safe_alloc(&key); + if (!*vk) { + crypt_safe_free(key); + return -ENOMEM; + } + return 0; } @@ -1119,9 +1181,14 @@ int TCRYPT_dump(struct crypt_device *cd, log_std(cd, "Version: \t%d\n", hdr->d.version); log_std(cd, "Driver req.:\t%x.%x\n", hdr->d.version_tc >> 8, hdr->d.version_tc & 0xFF); - - log_std(cd, "Sector size:\t%" PRIu32 "\n", hdr->d.sector_size); - log_std(cd, "MK offset:\t%" PRIu64 "\n", hdr->d.mk_offset); + log_std(cd, "Flags: \t0x%x\n", hdr->d.flags); + + log_std(cd, "Sector size:\t%" PRIu32 " [bytes]\n", hdr->d.sector_size); + log_std(cd, "MK offset:\t%" PRIu64 " [bytes]\n", hdr->d.mk_offset); + if (hdr->d.volume_size) + log_std(cd, "Volume size:\t%" PRIu64 " [bytes]\n", hdr->d.volume_size); + if (hdr->d.hidden_volume_size) + log_std(cd, "Hidden size:\t%" PRIu64 " [bytes]\n", hdr->d.hidden_volume_size); log_std(cd, "PBKDF2 hash:\t%s\n", params->hash_name); } log_std(cd, "Cipher chain:\t%s\n", params->cipher); diff --git a/lib/tcrypt/tcrypt.h b/lib/tcrypt/tcrypt.h index 8efccb8..db3b723 100644 --- a/lib/tcrypt/tcrypt.h +++ b/lib/tcrypt/tcrypt.h @@ -2,8 +2,8 @@ /* * TCRYPT (TrueCrypt-compatible) header definition * - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2024 Milan Broz + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Milan Broz */ #ifndef _CRYPTSETUP_TCRYPT_H diff --git a/lib/utils.c b/lib/utils.c index 7a6df4c..afde568 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include diff --git a/lib/utils_benchmark.c b/lib/utils_benchmark.c index 51f7e65..3694f27 100644 --- a/lib/utils_benchmark.c +++ b/lib/utils_benchmark.c @@ -2,8 +2,8 @@ /* * libcryptsetup - cryptsetup library, cipher benchmark * - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2024 Milan Broz + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Milan Broz */ #include diff --git a/lib/utils_blkid.c b/lib/utils_blkid.c index a5cf5ad..44e501b 100644 --- a/lib/utils_blkid.c +++ b/lib/utils_blkid.c @@ -2,7 +2,7 @@ /* * blkid probe utilities * - * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved. */ #include @@ -15,7 +15,7 @@ #include "utils_blkid.h" #include "utils_io.h" -#ifdef HAVE_BLKID +#if HAVE_BLKID #include /* make bad checksums flag optional */ @@ -26,7 +26,7 @@ struct blkid_handle { int fd; blkid_probe pr; }; -#ifndef HAVE_BLKID_WIPE +#if !HAVE_BLKID_WIPE static size_t crypt_getpagesize(void) { long r = sysconf(_SC_PAGESIZE); @@ -38,7 +38,7 @@ void blk_set_chains_for_wipes(struct blkid_handle *h) { blkid_probe_enable_partitions(h->pr, 1); blkid_probe_set_partitions_flags(h->pr, 0 -#ifdef HAVE_BLKID_WIPE +#if HAVE_BLKID_WIPE | BLKID_PARTS_MAGIC #endif ); @@ -198,10 +198,10 @@ void blk_free(struct blkid_handle *h) free(h); } -#ifndef HAVE_BLKID_WIPE +#if !HAVE_BLKID_WIPE static int blk_step_back(struct blkid_handle *h) { -#ifdef HAVE_BLKID_STEP_BACK +#if HAVE_BLKID_STEP_BACK return blkid_probe_step_back(h->pr); #else blkid_reset_probe(h->pr); @@ -213,7 +213,7 @@ static int blk_step_back(struct blkid_handle *h) int blk_do_wipe(struct blkid_handle *h) { -#ifdef HAVE_BLKID_WIPE +#if HAVE_BLKID_WIPE return blkid_do_wipe(h->pr, 0); #else const char *offset; diff --git a/lib/utils_blkid.h b/lib/utils_blkid.h index 6d7f70f..2112575 100644 --- a/lib/utils_blkid.h +++ b/lib/utils_blkid.h @@ -2,7 +2,7 @@ /* * blkid probe utilities * - * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved. */ #ifndef _UTILS_BLKID_H diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c index 31ac678..a5eca18 100644 --- a/lib/utils_crypt.c +++ b/lib/utils_crypt.c @@ -3,8 +3,8 @@ * utils_crypt - cipher utilities for cryptsetup * * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -95,7 +95,7 @@ int crypt_parse_hash_integrity_mode(const char *s, char *integrity) } int crypt_parse_integrity_mode(const char *s, char *integrity, - int *integrity_key_size) + int *integrity_key_size, int required_key_size) { int ks = 0, r = 0; @@ -108,18 +108,37 @@ int crypt_parse_integrity_mode(const char *s, char *integrity, !strcmp(s, "none")) { strncpy(integrity, s, MAX_CIPHER_LEN); ks = 0; + if (required_key_size != ks) + r = -EINVAL; } else if (!strcmp(s, "hmac-sha1")) { strncpy(integrity, "hmac(sha1)", MAX_CIPHER_LEN); - ks = 20; + ks = required_key_size ?: 20; } else if (!strcmp(s, "hmac-sha256")) { strncpy(integrity, "hmac(sha256)", MAX_CIPHER_LEN); - ks = 32; + ks = required_key_size ?: 32; } else if (!strcmp(s, "hmac-sha512")) { - ks = 64; strncpy(integrity, "hmac(sha512)", MAX_CIPHER_LEN); + ks = required_key_size ?: 64; + } else if (!strcmp(s, "phmac-sha1")) { + strncpy(integrity, "phmac(sha1)", MAX_CIPHER_LEN); + ks = required_key_size; + if (!required_key_size) + r = -EINVAL; + } else if (!strcmp(s, "phmac-sha256")) { + strncpy(integrity, "phmac(sha256)", MAX_CIPHER_LEN); + ks = required_key_size; + if (!required_key_size) + r = -EINVAL; + } else if (!strcmp(s, "phmac-sha512")) { + strncpy(integrity, "phmac(sha512)", MAX_CIPHER_LEN); + ks = required_key_size; + if (!required_key_size) + r = -EINVAL; } else if (!strcmp(s, "cmac-aes")) { - ks = 16; strncpy(integrity, "cmac(aes)", MAX_CIPHER_LEN); + ks = 16; + if (required_key_size && required_key_size != ks) + r = -EINVAL; } else r = -EINVAL; diff --git a/lib/utils_crypt.h b/lib/utils_crypt.h index 470cbeb..21cf4b5 100644 --- a/lib/utils_crypt.h +++ b/lib/utils_crypt.h @@ -3,8 +3,8 @@ * utils_crypt - cipher utilities for cryptsetup * * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #ifndef _UTILS_CRYPT_H @@ -28,7 +28,7 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums, char *cipher_mode); int crypt_parse_hash_integrity_mode(const char *s, char *integrity); int crypt_parse_integrity_mode(const char *s, char *integrity, - int *integrity_key_size); + int *integrity_key_size, int required_key_size); int crypt_parse_pbkdf(const char *s, const char **pbkdf); ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc); diff --git a/lib/utils_device.c b/lib/utils_device.c index 6b7af6e..1cdbcc6 100644 --- a/lib/utils_device.c +++ b/lib/utils_device.c @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -16,10 +16,10 @@ #include #include #include -#ifdef HAVE_SYS_SYSMACROS_H +#if HAVE_SYS_SYSMACROS_H # include /* for major, minor */ #endif -#ifdef HAVE_SYS_STATVFS_H +#if HAVE_SYS_STATVFS_H # include #endif #include "internal.h" @@ -48,19 +48,19 @@ struct device { static size_t device_fs_block_size_fd(int fd) { - size_t page_size = crypt_getpagesize(); + size_t max_size = MAX_SECTOR_SIZE; -#ifdef HAVE_SYS_STATVFS_H +#if HAVE_SYS_STATVFS_H struct statvfs buf; /* * NOTE: some filesystems (NFS) returns bogus blocksize (1MB). * Page-size io should always work and avoids increasing IO beyond aligned LUKS header. */ - if (!fstatvfs(fd, &buf) && buf.f_bsize && buf.f_bsize <= page_size) + if (!fstatvfs(fd, &buf) && buf.f_bsize && buf.f_bsize <= max_size) return (size_t)buf.f_bsize; #endif - return page_size; + return max_size; } static size_t device_block_size_fd(int fd, size_t *min_size) @@ -127,19 +127,19 @@ static size_t device_alignment_fd(int devfd) return (size_t)alignment; } -static int device_read_test(struct crypt_device *cd, int devfd, struct device *device) +static int device_read_test(struct crypt_device *cd, int devfd) { char buffer[512]; - int r = -EIO; + int r; size_t minsize = 0, blocksize, alignment; - const char *dm_name; + struct stat st; + + /* skip check for block devices, direct-io must work there */ + if (fstat(devfd, &st) < 0) + return -EINVAL; - /* skip check for suspended DM devices */ - dm_name = device_dm_name(device); - if (dm_name && dm_status_suspended(cd, dm_name) > 0) { - log_dbg(cd, "Device %s is suspended, assuming direct-io is supported.", dm_name); + if (S_ISBLK(st.st_mode)) return 0; - } blocksize = device_block_size_fd(devfd, &minsize); alignment = device_alignment_fd(devfd); @@ -153,10 +153,13 @@ static int device_read_test(struct crypt_device *cd, int devfd, struct device *d if (minsize > sizeof(buffer)) minsize = sizeof(buffer); - if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize) + if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize) { + log_dbg(cd, "Direct-io read works."); r = 0; - - log_dbg(cd, "Direct-io is supported and works."); + } else { + log_dbg(cd, "Direct-io read failed."); + r = -EIO; + } crypt_safe_memzero(buffer, sizeof(buffer)); return r; @@ -180,12 +183,12 @@ static int device_ready(struct crypt_device *cd, struct device *device) return -EINVAL; if (device->o_direct) { - log_dbg(cd, "Trying to open and read device %s with direct-io.", + log_dbg(cd, "Trying to open device %s with direct-io.", device_path(device)); device->o_direct = 0; devfd = open(device_path(device), O_RDONLY | O_DIRECT); if (devfd >= 0) { - if (device_read_test(cd, devfd, device) == 0) { + if (device_read_test(cd, devfd) == 0) { device->o_direct = 1; } else { close(devfd); @@ -473,21 +476,6 @@ const char *device_block_path(const struct device *device) return device->path; } -/* Get device-mapper name of device (if possible) */ -const char *device_dm_name(const struct device *device) -{ - const char *dmdir = dm_get_dir(); - size_t dmdir_len = strlen(dmdir); - - if (!device) - return NULL; - - if (strncmp(device->path, dmdir, dmdir_len)) - return NULL; - - return &device->path[dmdir_len+1]; -} - /* Get path to device / file */ const char *device_path(const struct device *device) { @@ -530,7 +518,7 @@ void device_topology_alignment(struct crypt_device *cd, /* minimum io size */ if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) { - log_dbg(cd, "Topology info for %s not supported, using default offset %lu bytes.", + log_dbg(cd, "Topology info for %s not supported, using default alignment %lu bytes.", device->path, default_alignment); goto out; } @@ -1014,6 +1002,36 @@ int device_is_zoned(struct device *device) return crypt_dev_is_zoned(major(st.st_rdev), minor(st.st_rdev)); } +int device_is_nop_dif(struct device *device, uint32_t *tag_size) +{ + char *base_device_path; + int r; + struct stat st; + + if (!device) + return -EINVAL; + + /* + * For partition devices, check integrity profile on the base device. + * Partition device nodes don't advertise integrity profile directly + * via sysfs attributes. + */ + base_device_path = crypt_get_base_device(device_path(device)); + if (base_device_path) { + r = stat(base_device_path, &st); + free(base_device_path); + } else + r = stat(device_path(device), &st); + + if (r < 0) + return -EINVAL; + + if (!S_ISBLK(st.st_mode)) + return 0; + + return crypt_dev_is_nop_dif(major(st.st_rdev), minor(st.st_rdev), tag_size); +} + size_t device_alignment(struct device *device) { int devfd; diff --git a/lib/utils_device_locking.c b/lib/utils_device_locking.c index 57a467d..8859223 100644 --- a/lib/utils_device_locking.c +++ b/lib/utils_device_locking.c @@ -2,8 +2,8 @@ /* * Metadata on-disk locking for processes serialization * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Ondrej Kozina + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Ondrej Kozina */ #include @@ -15,7 +15,7 @@ #include #include #include -#ifdef HAVE_SYS_SYSMACROS_H +#if HAVE_SYS_SYSMACROS_H # include /* for major, minor */ #endif #include diff --git a/lib/utils_device_locking.h b/lib/utils_device_locking.h index 4287dbf..9cc25ca 100644 --- a/lib/utils_device_locking.h +++ b/lib/utils_device_locking.h @@ -2,8 +2,8 @@ /* * Metadata on-disk locking for processes serialization * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Ondrej Kozina + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Ondrej Kozina */ #ifndef _CRYPTSETUP_UTILS_LOCKING_H diff --git a/lib/utils_devpath.c b/lib/utils_devpath.c index 2c94048..28039f0 100644 --- a/lib/utils_devpath.c +++ b/lib/utils_devpath.c @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -17,7 +17,7 @@ #include #include #include -#ifdef HAVE_SYS_SYSMACROS_H +#if HAVE_SYS_SYSMACROS_H # include /* for major, minor */ #endif #include "internal.h" @@ -262,6 +262,29 @@ int crypt_dev_is_zoned(int major, int minor) return strncmp(buf, "none", 4) ? 1 : 0; } +int crypt_dev_is_nop_dif(int major, int minor, uint32_t *tag_size) +{ + char buf[64] = {}; + uint64_t val = 0; + + if (!_sysfs_get_string(major, minor, buf, sizeof(buf), "integrity/format")) + return 0; + + if (strncmp(buf, "nop", 3)) + return 0; + + /* this field is currently supported only for NVMe */ + _sysfs_get_uint64(major, minor, &val, "metadata_bytes"); + + /* tag_size should be 0, but it is set by dm-integrity, try it as a fallback */ + if (val == 0) + _sysfs_get_uint64(major, minor, &val, "integrity/tag_size"); + + /* we can still return 0 and support metadata, caller must handle it */ + *tag_size = (uint32_t)val; + return 1; +} + int crypt_dev_is_partition(const char *dev_path) { uint64_t val; @@ -420,7 +443,7 @@ int lookup_by_disk_id(const char *dm_uuid) { struct dirent *entry; struct stat st; - int r = 0; /* not found */ + int dfd, r = 0; /* not found */ DIR *dir = opendir("/dev/disk/by-id"); if (!dir) @@ -432,7 +455,8 @@ int lookup_by_disk_id(const char *dm_uuid) !strncmp(entry->d_name, "..", 2)) continue; - if (fstatat(dirfd(dir), entry->d_name, &st, AT_SYMLINK_NOFOLLOW)) { + dfd = dirfd(dir); + if (dfd < 0 || fstatat(dfd, entry->d_name, &st, AT_SYMLINK_NOFOLLOW)) { r = -EINVAL; break; } @@ -457,7 +481,7 @@ int lookup_by_sysfs_uuid_field(const char *dm_uuid) char subpath[PATH_MAX], uuid[DM_UUID_LEN]; ssize_t s; struct stat st; - int fd, len, r = 0; /* not found */ + int fd, dfd, len, r = 0; /* not found */ DIR *dir = opendir("/sys/block/"); if (!dir) @@ -476,7 +500,10 @@ int lookup_by_sysfs_uuid_field(const char *dm_uuid) } /* looking for dm-X/dm/uuid file, symlinks are fine */ - fd = openat(dirfd(dir), subpath, O_RDONLY | O_CLOEXEC); + dfd = dirfd(dir); + if (dfd < 0) + continue; + fd = openat(dfd, subpath, O_RDONLY | O_CLOEXEC); if (fd < 0) continue; diff --git a/lib/utils_dm.h b/lib/utils_dm.h index 29ff777..4a55811 100644 --- a/lib/utils_dm.h +++ b/lib/utils_dm.h @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #ifndef _UTILS_DM_H @@ -22,72 +22,71 @@ struct device; struct crypt_params_integrity; /* Device mapper internal flags */ -#define DM_RESUME_PRIVATE (1 << 4) /* CRYPT_ACTIVATE_PRIVATE */ -#define DM_SUSPEND_SKIP_LOCKFS (1 << 5) -#define DM_SUSPEND_WIPE_KEY (1 << 6) -#define DM_SUSPEND_NOFLUSH (1 << 7) +#define DM_RESUME_PRIVATE (UINT64_C(1) << 4) /* CRYPT_ACTIVATE_PRIVATE */ +#define DM_SUSPEND_SKIP_LOCKFS (UINT64_C(1) << 5) +#define DM_SUSPEND_WIPE_KEY (UINT64_C(1) << 6) +#define DM_SUSPEND_NOFLUSH (UINT64_C(1) << 7) -static inline uint32_t act2dmflags(uint32_t act_flags) +static inline uint64_t act2dmflags(uint64_t act_flags) { return (act_flags & DM_RESUME_PRIVATE); } /* Device mapper backend - kernel support flags */ -#define DM_KEY_WIPE_SUPPORTED (1 << 0) /* key wipe message */ -#define DM_LMK_SUPPORTED (1 << 1) /* lmk mode */ -#define DM_SECURE_SUPPORTED (1 << 2) /* wipe (secure) buffer flag */ -#define DM_PLAIN64_SUPPORTED (1 << 3) /* plain64 IV */ -#define DM_DISCARDS_SUPPORTED (1 << 4) /* discards/TRIM option is supported */ -#define DM_VERITY_SUPPORTED (1 << 5) /* dm-verity target supported */ -#define DM_TCW_SUPPORTED (1 << 6) /* tcw (TCRYPT CBC with whitening) */ -#define DM_SAME_CPU_CRYPT_SUPPORTED (1 << 7) /* same_cpu_crypt */ -#define DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED (1 << 8) /* submit_from_crypt_cpus */ -#define DM_VERITY_ON_CORRUPTION_SUPPORTED (1 << 9) /* ignore/restart_on_corruption, ignore_zero_block */ -#define DM_VERITY_FEC_SUPPORTED (1 << 10) /* Forward Error Correction (FEC) */ -#define DM_KERNEL_KEYRING_SUPPORTED (1 << 11) /* dm-crypt allows loading kernel keyring keys */ -#define DM_INTEGRITY_SUPPORTED (1 << 12) /* dm-integrity target supported */ -#define DM_SECTOR_SIZE_SUPPORTED (1 << 13) /* support for sector size setting in dm-crypt/dm-integrity */ -#define DM_CAPI_STRING_SUPPORTED (1 << 14) /* support for cryptoapi format cipher definition */ -#define DM_DEFERRED_SUPPORTED (1 << 15) /* deferred removal of device */ -#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */ -#define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */ -#define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */ -#define DM_INTEGRITY_FIX_PADDING_SUPPORTED (1 << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */ -#define DM_BITLK_EBOIV_SUPPORTED (1 << 20) /* EBOIV for BITLK supported */ -#define DM_BITLK_ELEPHANT_SUPPORTED (1 << 21) /* Elephant diffuser for BITLK supported */ -#define DM_VERITY_SIGNATURE_SUPPORTED (1 << 22) /* Verity option root_hash_sig_key_desc supported */ -#define DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is supported */ -#define DM_INTEGRITY_RESIZE_SUPPORTED (1 << 23) /* dm-integrity resize of the integrity device supported (introduced in the same version as discards)*/ -#define DM_VERITY_PANIC_CORRUPTION_SUPPORTED (1 << 24) /* dm-verity panic on corruption */ -#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt support for bypassing workqueues */ -#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */ -#define DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */ -#define DM_VERITY_TASKLETS_SUPPORTED (1 << 28) /* dm-verity tasklets supported */ +#define DM_KEY_WIPE_SUPPORTED (UINT64_C(1) << 0) /* key wipe message */ +#define DM_LMK_SUPPORTED (UINT64_C(1) << 1) /* lmk mode */ +#define DM_SECURE_SUPPORTED (UINT64_C(1) << 2) /* wipe (secure) buffer flag */ +#define DM_PLAIN64_SUPPORTED (UINT64_C(1) << 3) /* plain64 IV */ +#define DM_DISCARDS_SUPPORTED (UINT64_C(1) << 4) /* discards/TRIM option is supported */ +#define DM_VERITY_SUPPORTED (UINT64_C(1) << 5) /* dm-verity target supported */ +#define DM_TCW_SUPPORTED (UINT64_C(1) << 6) /* tcw (TCRYPT CBC with whitening) */ +#define DM_SAME_CPU_CRYPT_SUPPORTED (UINT64_C(1) << 7) /* same_cpu_crypt */ +#define DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED (UINT64_C(1) << 8) /* submit_from_crypt_cpus */ +#define DM_VERITY_ON_CORRUPTION_SUPPORTED (UINT64_C(1) << 9) /* ignore/restart_on_corruption, ignore_zero_block */ +#define DM_VERITY_FEC_SUPPORTED (UINT64_C(1) << 10) /* Forward Error Correction (FEC) */ +#define DM_KERNEL_KEYRING_SUPPORTED (UINT64_C(1) << 11) /* dm-crypt allows loading kernel keyring keys */ +#define DM_INTEGRITY_SUPPORTED (UINT64_C(1) << 12) /* dm-integrity target supported */ +#define DM_SECTOR_SIZE_SUPPORTED (UINT64_C(1) << 13) /* support for sector size setting in dm-crypt/dm-integrity */ +#define DM_CAPI_STRING_SUPPORTED (UINT64_C(1) << 14) /* support for cryptoapi format cipher definition */ +#define DM_DEFERRED_SUPPORTED (UINT64_C(1) << 15) /* deferred removal of device */ +#define DM_INTEGRITY_RECALC_SUPPORTED (UINT64_C(1) << 16) /* dm-integrity automatic recalculation supported */ +#define DM_INTEGRITY_BITMAP_SUPPORTED (UINT64_C(1) << 17) /* dm-integrity bitmap mode supported */ +#define DM_GET_TARGET_VERSION_SUPPORTED (UINT64_C(1) << 18) /* dm DM_GET_TARGET version ioctl supported */ +#define DM_INTEGRITY_FIX_PADDING_SUPPORTED (UINT64_C(1) << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */ +#define DM_BITLK_EBOIV_SUPPORTED (UINT64_C(1) << 20) /* EBOIV for BITLK supported */ +#define DM_BITLK_ELEPHANT_SUPPORTED (UINT64_C(1) << 21) /* Elephant diffuser for BITLK supported */ +#define DM_VERITY_SIGNATURE_SUPPORTED (UINT64_C(1) << 22) /* Verity option root_hash_sig_key_desc supported */ +#define DM_INTEGRITY_DISCARDS_SUPPORTED (UINT64_C(1) << 23) /* dm-integrity discards/TRIM option is supported */ +#define DM_INTEGRITY_RESIZE_SUPPORTED (UINT64_C(1) << 23) /* dm-integrity resize of the integrity device supported (introduced in the same version as discards)*/ +#define DM_VERITY_PANIC_CORRUPTION_SUPPORTED (UINT64_C(1) << 24) /* dm-verity panic on corruption */ +#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (UINT64_C(1) << 25) /* dm-crypt support for bypassing workqueues */ +#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (UINT64_C(1) << 26) /* hmac covers also superblock */ +#define DM_INTEGRITY_RESET_RECALC_SUPPORTED (UINT64_C(1) << 27) /* dm-integrity automatic recalculation supported */ +#define DM_VERITY_TASKLETS_SUPPORTED (UINT64_C(1) << 28) /* dm-verity tasklets supported */ +#define DM_CRYPT_HIGH_PRIORITY_SUPPORTED (UINT64_C(1) << 29) /* dm-crypt high priority workqueue flag supported */ +#define DM_CRYPT_INTEGRITY_KEY_SIZE_OPT_SUPPORTED (UINT64_C(1) << 30) /* dm-crypt support for integrity_key_size option */ +#define DM_VERITY_ERROR_AS_CORRUPTION_SUPPORTED (UINT64_C(1) << 31) /* dm-verity restart/panic on corruption supported */ +#define DM_INTEGRITY_INLINE_MODE_SUPPORTED (UINT64_C(1) << 32) /* dm-integrity inline mode supported */ typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type; enum tdirection { TARGET_EMPTY = 0, TARGET_SET, TARGET_QUERY }; -int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags); - -#define DM_ACTIVE_DEVICE (1 << 0) -#define DM_ACTIVE_UUID (1 << 1) -#define DM_ACTIVE_HOLDERS (1 << 2) - -#define DM_ACTIVE_CRYPT_CIPHER (1 << 3) -#define DM_ACTIVE_CRYPT_KEYSIZE (1 << 4) -#define DM_ACTIVE_CRYPT_KEY (1 << 5) - -#define DM_ACTIVE_VERITY_ROOT_HASH (1 << 6) -#define DM_ACTIVE_VERITY_HASH_DEVICE (1 << 7) -#define DM_ACTIVE_VERITY_PARAMS (1 << 8) - -#define DM_ACTIVE_INTEGRITY_PARAMS (1 << 9) - -#define DM_ACTIVE_JOURNAL_CRYPT_KEY (1 << 10) -#define DM_ACTIVE_JOURNAL_CRYPT_KEYSIZE (1 << 11) - -#define DM_ACTIVE_JOURNAL_MAC_KEY (1 << 12) -#define DM_ACTIVE_JOURNAL_MAC_KEYSIZE (1 << 13) +int dm_flags(struct crypt_device *cd, dm_target_type target, uint64_t *flags); + +#define DM_ACTIVE_DEVICE (UINT64_C(1) << 0) +#define DM_ACTIVE_UUID (UINT64_C(1) << 1) +#define DM_ACTIVE_HOLDERS (UINT64_C(1) << 2) +#define DM_ACTIVE_CRYPT_CIPHER (UINT64_C(1) << 3) +#define DM_ACTIVE_CRYPT_KEYSIZE (UINT64_C(1) << 4) +#define DM_ACTIVE_CRYPT_KEY (UINT64_C(1) << 5) +#define DM_ACTIVE_VERITY_ROOT_HASH (UINT64_C(1) << 6) +#define DM_ACTIVE_VERITY_HASH_DEVICE (UINT64_C(1) << 7) +#define DM_ACTIVE_VERITY_PARAMS (UINT64_C(1) << 8) +#define DM_ACTIVE_INTEGRITY_PARAMS (UINT64_C(1) << 9) +#define DM_ACTIVE_JOURNAL_CRYPT_KEY (UINT64_C(1) << 10) +#define DM_ACTIVE_JOURNAL_CRYPT_KEYSIZE (UINT64_C(1) << 11) +#define DM_ACTIVE_JOURNAL_MAC_KEY (UINT64_C(1) << 12) +#define DM_ACTIVE_JOURNAL_MAC_KEYSIZE (UINT64_C(1) << 13) struct dm_target { dm_target_type type; @@ -108,6 +107,7 @@ struct dm_target { uint64_t iv_offset; /* IV initialisation sector */ uint32_t tag_size; /* additional on-disk tag size */ uint32_t sector_size; /* encryption sector size */ + uint32_t integrity_key_size; /* explicit integrity key size (HMAC), 0 for default */ } crypt; struct { struct device *hash_device; @@ -182,8 +182,9 @@ void dm_targets_free(struct crypt_device *cd, struct crypt_dm_active_device *dmd int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size, struct device *data_device, struct volume_key *vk, const char *cipher, - uint64_t iv_offset, uint64_t data_offset, const char *integrity, - uint32_t tag_size, uint32_t sector_size); + uint64_t iv_offset, uint64_t data_offset, + const char *integrity, uint32_t integrity_key_size, uint32_t tag_size, + uint32_t sector_size); int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size, struct device *data_device, struct device *hash_device, struct device *fec_device, const char *root_hash, uint32_t root_hash_size, const char* root_hash_sig_key_desc, @@ -205,15 +206,15 @@ int dm_status_suspended(struct crypt_device *cd, const char *name); int dm_status_verity_ok(struct crypt_device *cd, const char *name); int dm_status_integrity_failures(struct crypt_device *cd, const char *name, uint64_t *count); int dm_query_device(struct crypt_device *cd, const char *name, - uint32_t get_flags, struct crypt_dm_active_device *dmd); + uint64_t get_flags, struct crypt_dm_active_device *dmd); int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length); int dm_create_device(struct crypt_device *cd, const char *name, const char *type, struct crypt_dm_active_device *dmd); int dm_reload_device(struct crypt_device *cd, const char *name, - struct crypt_dm_active_device *dmd, uint32_t dmflags, unsigned resume); -int dm_suspend_device(struct crypt_device *cd, const char *name, uint32_t dmflags); -int dm_resume_device(struct crypt_device *cd, const char *name, uint32_t dmflags); + struct crypt_dm_active_device *dmd, uint64_t dmflags, unsigned resume); +int dm_suspend_device(struct crypt_device *cd, const char *name, uint64_t dmflags); +int dm_resume_device(struct crypt_device *cd, const char *name, uint64_t dmflags); int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name, const struct volume_key *vk); int dm_error_device(struct crypt_device *cd, const char *name); @@ -222,6 +223,11 @@ int dm_cancel_deferred_removal(const char *name); const char *dm_get_dir(void); int dm_get_iname(const char *name, char **iname, bool with_path); +char *dm_get_active_iname(struct crypt_device *cd, const char *name); + +int dm_uuid_cmp(const char *dm_uuid, const char *hdr_uuid); +int dm_uuid_type_cmp(const char *dm_uuid, const char *type); +int dm_uuid_integrity_cmp(const char *dm_uuid, const char *dmi_uuid); int lookup_dm_dev_by_uuid(struct crypt_device *cd, const char *uuid, const char *type); diff --git a/lib/utils_io.c b/lib/utils_io.c index 1e47673..801f6d6 100644 --- a/lib/utils_io.c +++ b/lib/utils_io.c @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -278,7 +278,7 @@ ssize_t read_lseek_blockwise(int fd, size_t bsize, size_t alignment, length -= innerCount; } - ret = read_blockwise(fd, bsize, alignment, buf, length); + ret = length ? read_blockwise(fd, bsize, alignment, buf, length) : 0; if (ret >= 0) ret += innerCount; out: diff --git a/lib/utils_io.h b/lib/utils_io.h index 404c0f5..f80cf17 100644 --- a/lib/utils_io.h +++ b/lib/utils_io.h @@ -4,8 +4,8 @@ * * Copyright (C) 2004 Jana Saout * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #ifndef _CRYPTSETUP_UTILS_IO_H diff --git a/lib/utils_keyring.c b/lib/utils_keyring.c index 4a0cc53..73df346 100644 --- a/lib/utils_keyring.c +++ b/lib/utils_keyring.c @@ -2,8 +2,8 @@ /* * kernel keyring utilities * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Ondrej Kozina + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Ondrej Kozina */ #include @@ -21,17 +21,17 @@ #include "libcryptsetup_macros.h" #include "utils_keyring.h" -#ifdef KERNEL_KEYRING +#if KERNEL_KEYRING static const struct { key_type_t type; const char *type_name; } key_types[] = { - { LOGON_KEY, "logon" }, - { USER_KEY, "user" }, - { BIG_KEY, "big_key" }, - { TRUSTED_KEY, "trusted" }, - { ENCRYPTED_KEY, "encrypted" }, + { LOGON_KEY, "logon" }, + { USER_KEY, "user" }, + { BIG_KEY, "big_key" }, + { TRUSTED_KEY, "trusted" }, + { ENCRYPTED_KEY, "encrypted" }, }; #include @@ -150,7 +150,11 @@ static key_serial_t find_key_by_type_and_desc(const char *type, const char *desc do { id = request_key(type, desc, NULL, 0); } while (id < 0 && errno == EINTR); - if (id >= 0 || errno == ENOMEM) + + if (id < 0 && errno == ENOMEM) + return 0; + + if (id >= 0) return id; f = open("/proc/keys", O_RDONLY); @@ -191,7 +195,7 @@ int keyring_check(void) return syscall(__NR_request_key, "logon", "dummy", NULL, 0) == -1l && errno != ENOSYS; } -static key_serial_t keyring_add_key_in_keyring(key_type_t ktype, +key_serial_t keyring_add_key_to_keyring(key_type_t ktype, const char *key_desc, const void *key, size_t key_size, @@ -207,7 +211,7 @@ static key_serial_t keyring_add_key_in_keyring(key_type_t ktype, key_serial_t keyring_add_key_in_thread_keyring(key_type_t ktype, const char *key_desc, const void *key, size_t key_size) { - return keyring_add_key_in_keyring(ktype, key_desc, key, key_size, KEY_SPEC_THREAD_KEYRING); + return keyring_add_key_to_keyring(ktype, key_desc, key, key_size, KEY_SPEC_THREAD_KEYRING); } key_serial_t keyring_request_key_id(key_type_t key_type, @@ -222,29 +226,45 @@ key_serial_t keyring_request_key_id(key_type_t key_type, return kid; } +int keyring_read_keysize(key_serial_t kid, + size_t *r_key_size) +{ + long r; + + assert(r_key_size); + + /* just get payload size */ + r = keyctl_read(kid, NULL, 0); + if (r > 0) { + *r_key_size = r; + return 0; + } + + return -EINVAL; +} + int keyring_read_key(key_serial_t kid, char **key, size_t *key_size) { - long r; + int r; + size_t len; char *buf = NULL; - size_t len = 0; assert(key); assert(key_size); /* just get payload size */ - r = keyctl_read(kid, NULL, 0); - if (r > 0) { - len = r; - buf = crypt_safe_alloc(len); - if (!buf) - return -ENOMEM; + r = keyring_read_keysize(kid, &len); + if (r < 0) + return r; - /* retrieve actual payload data */ - r = keyctl_read(kid, buf, len); - } + buf = crypt_safe_alloc(len); + if (!buf) + return -ENOMEM; + /* retrieve actual payload data */ + r = keyctl_read(kid, buf, len); if (r < 0) { crypt_safe_free(buf); return -EINVAL; @@ -277,6 +297,37 @@ const char *key_type_name(key_type_t type) return NULL; } +key_type_t keyring_type_and_name(const char *key_name, const char **name) +{ + const char *name_tmp; + char type[16]; + size_t type_len; + + if (!key_name || key_name[0] != '%') + return INVALID_KEY; + + key_name++; + if (!*key_name || *key_name == ':') + return INVALID_KEY; + + name_tmp = strchr(key_name, ':'); + if (!name_tmp) + return INVALID_KEY; + name_tmp++; + + type_len = name_tmp - key_name - 1; + if (type_len >= sizeof(type) - 1) + return INVALID_KEY; + + memcpy(type, key_name, type_len); + type[type_len] = '\0'; + + if (name) + *name = name_tmp; + + return key_type_by_name(type); +} + key_serial_t keyring_find_key_id_by_name(const char *key_name) { key_serial_t id = 0; @@ -333,8 +384,7 @@ key_serial_t keyring_find_key_id_by_name(const char *key_name) id = 0; out: - if (name_copy) - free(name_copy); + free(name_copy); return id; } @@ -375,20 +425,6 @@ key_type_t key_type_by_name(const char *name) return INVALID_KEY; } -key_serial_t keyring_add_key_to_custom_keyring(key_type_t ktype, - const char *key_desc, - const void *key, - size_t key_size, - key_serial_t keyring_to_link) -{ - const char *type_name = key_type_name(ktype); - - if (!type_name || !key_desc) - return -EINVAL; - - return add_key(type_name, key_desc, key, key_size, keyring_to_link); -} - #else /* KERNEL_KEYRING */ #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -408,6 +444,12 @@ key_serial_t keyring_request_key_id(key_type_t key_type, return -ENOTSUP; } +int keyring_read_keysize(key_serial_t kid, + size_t *r_key_size) +{ + return -ENOTSUP; +} + int keyring_read_key(key_serial_t kid, char **key, size_t *key_size) @@ -425,6 +467,11 @@ const char *key_type_name(key_type_t type) return NULL; } +key_type_t keyring_type_and_name(const char *key_name, const char **name) +{ + return INVALID_KEY; +} + key_serial_t keyring_find_key_id_by_name(const char *key_name) { return 0; @@ -440,11 +487,11 @@ key_type_t key_type_by_name(const char *name) return INVALID_KEY; } -key_serial_t keyring_add_key_to_custom_keyring(key_type_t ktype, - const char *key_desc, - const void *key, - size_t key_size, - key_serial_t keyring_to_link) +key_serial_t keyring_add_key_to_keyring(key_type_t ktype, + const char *key_desc, + const void *key, + size_t key_size, + key_serial_t keyring_to_link) { return -ENOTSUP; } diff --git a/lib/utils_keyring.h b/lib/utils_keyring.h index 33d8f22..67debf6 100644 --- a/lib/utils_keyring.h +++ b/lib/utils_keyring.h @@ -2,8 +2,8 @@ /* * kernel keyring syscall wrappers * - * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2024 Ondrej Kozina + * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2025 Ondrej Kozina */ #ifndef _UTILS_KEYRING @@ -21,6 +21,7 @@ typedef enum { LOGON_KEY = 0, USER_KEY, BIG_KEY, TRUSTED_KEY, ENCRYPTED_KEY, INV const char *key_type_name(key_type_t ktype); key_type_t key_type_by_name(const char *name); +key_type_t keyring_type_and_name(const char *key_name, const char **name); key_serial_t keyring_find_key_id_by_name(const char *key_name); key_serial_t keyring_find_keyring_id_by_name(const char *keyring_name); @@ -29,6 +30,9 @@ int keyring_check(void); key_serial_t keyring_request_key_id(key_type_t key_type, const char *key_description); +int keyring_read_keysize(key_serial_t kid, + size_t *r_key_size); + int keyring_read_key(key_serial_t kid, char **key, size_t *key_size); @@ -39,7 +43,7 @@ key_serial_t keyring_add_key_in_thread_keyring( const void *key, size_t key_size); -key_serial_t keyring_add_key_to_custom_keyring(key_type_t ktype, const char *key_desc, const void *key, +key_serial_t keyring_add_key_to_keyring(key_type_t ktype, const char *key_desc, const void *key, size_t key_size, key_serial_t keyring_to_link); int keyring_unlink_key_from_keyring(key_serial_t kid, key_serial_t keyring_id); int keyring_unlink_key_from_thread_keyring(key_serial_t kid); diff --git a/lib/utils_loop.c b/lib/utils_loop.c index 6af47f5..ec85678 100644 --- a/lib/utils_loop.c +++ b/lib/utils_loop.c @@ -2,8 +2,8 @@ /* * loopback block device utilities * - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -15,7 +15,7 @@ #include #include #include -#ifdef HAVE_SYS_SYSMACROS_H +#if HAVE_SYS_SYSMACROS_H # include /* for major, minor */ #endif #include diff --git a/lib/utils_loop.h b/lib/utils_loop.h index a0c7491..4edeff3 100644 --- a/lib/utils_loop.h +++ b/lib/utils_loop.h @@ -2,8 +2,8 @@ /* * loopback block device utilities * - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #ifndef _UTILS_LOOP_H diff --git a/lib/utils_pbkdf.c b/lib/utils_pbkdf.c index 56971f2..87e9419 100644 --- a/lib/utils_pbkdf.c +++ b/lib/utils_pbkdf.c @@ -2,8 +2,8 @@ /* * utils_pbkdf - PBKDF settings for libcryptsetup * - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -63,9 +63,11 @@ uint32_t pbkdf_adjusted_phys_memory_kb(void) memory_kb /= 2; /* - * Never use more that half of available free memory on system without swap. + * On systems with < 4GB RAM without swap + * never use more that half of available free memory. + * This is a temporary hack to avoid OOM on small systems. */ - if (!crypt_swapavailable()) { + if (memory_kb < (2 * 1024 * 1024) && !crypt_swapavailable()) { free_kb = crypt_getphysmemoryfree_kb(); /* @@ -159,10 +161,19 @@ int verify_pbkdf_params(struct crypt_device *cd, pbkdf_limits.max_memory); r = -EINVAL; } + if (1024ULL * pbkdf->max_memory_kb > SIZE_MAX) { + log_err(cd, _("Requested maximum PBKDF memory cost is too high (limited by the integer maximal size).")); + r = -EINVAL; + } if (!pbkdf->max_memory_kb) { log_err(cd, _("Requested maximum PBKDF memory cannot be zero.")); r = -EINVAL; } + if (pbkdf->parallel_threads > pbkdf_limits.max_parallel) { + log_err(cd, _("Requested maximum PBKDF parallel cost is too high (maximum is %d)."), + pbkdf_limits.max_parallel); + r = -EINVAL; + } if (!pbkdf->parallel_threads) { log_err(cd, _("Requested PBKDF parallel threads cannot be zero.")); r = -EINVAL; @@ -235,12 +246,6 @@ int init_pbkdf_type(struct crypt_device *cd, cd_pbkdf->max_memory_kb = pbkdf->max_memory_kb; cd_pbkdf->parallel_threads = pbkdf->parallel_threads; - if (cd_pbkdf->parallel_threads > pbkdf_limits.max_parallel) { - log_dbg(cd, "Maximum PBKDF threads is %d (requested %d).", - pbkdf_limits.max_parallel, cd_pbkdf->parallel_threads); - cd_pbkdf->parallel_threads = pbkdf_limits.max_parallel; - } - /* Do not limit threads by online CPUs if user forced values (no benchmark). */ if (cd_pbkdf->parallel_threads && !(cd_pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK)) { cpus = crypt_cpusonline(); diff --git a/lib/utils_safe_memory.c b/lib/utils_safe_memory.c index 0b1dc7e..5ee68d2 100644 --- a/lib/utils_safe_memory.c +++ b/lib/utils_safe_memory.c @@ -2,15 +2,13 @@ /* * utils_safe_memory - safe memory helpers * - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ -#include -#include #include #include -#include "libcryptsetup.h" +#include "internal.h" struct safe_allocation { size_t size; @@ -28,14 +26,16 @@ void crypt_safe_memzero(void *data, size_t size) if (!data) return; -#ifdef HAVE_EXPLICIT_BZERO - explicit_bzero(data, size); -#else - volatile uint8_t *p = (volatile uint8_t *)data; + return crypt_backend_memzero(data, size); +} + +/* Memcpy helper to avoid spilling sensitive data through additional registers */ +void *crypt_safe_memcpy(void *dst, const void *src, size_t size) +{ + if (!dst || !src) + return NULL; - while(size--) - *p++ = 0; -#endif + return crypt_backend_memcpy(dst, src, size); } /* safe allocations */ @@ -50,7 +50,7 @@ void *crypt_safe_alloc(size_t size) if (!alloc) return NULL; - crypt_safe_memzero(alloc, size + OVERHEAD); + crypt_backend_memzero(alloc, size + OVERHEAD); alloc->size = size; /* Ignore failure if it is over limit. */ @@ -73,7 +73,7 @@ void crypt_safe_free(void *data) p = (char *)data - OVERHEAD; alloc = (struct safe_allocation *)p; - crypt_safe_memzero(data, alloc->size); + crypt_backend_memzero(data, alloc->size); if (alloc->locked) { munlock(alloc, alloc->size + OVERHEAD); @@ -101,9 +101,21 @@ void *crypt_safe_realloc(void *data, size_t size) if (size > alloc->size) size = alloc->size; - memcpy(new_data, data, size); + crypt_backend_memcpy(new_data, data, size); } crypt_safe_free(data); return new_data; } + +size_t crypt_safe_alloc_size(const void *data) +{ + const void *p; + + if (!data) + return 0; + + p = (const char *)data - OVERHEAD; + + return ((const struct safe_allocation *)p)->size; +} diff --git a/lib/utils_storage_wrappers.c b/lib/utils_storage_wrappers.c index 52f065c..54492d0 100644 --- a/lib/utils_storage_wrappers.c +++ b/lib/utils_storage_wrappers.c @@ -3,7 +3,7 @@ * Generic wrapper for storage functions * (experimental only) * - * Copyright (C) 2018-2024 Ondrej Kozina + * Copyright (C) 2018-2025 Ondrej Kozina */ #include @@ -49,7 +49,9 @@ static int crypt_storage_backend_init(struct crypt_device *cd, struct crypt_storage *s; /* iv_start, sector_size */ - r = crypt_storage_init(&s, sector_size, cipher, cipher_mode, vk->key, vk->keylength, flags & LARGE_IV); + r = crypt_storage_init(&s, sector_size, cipher, cipher_mode, + crypt_volume_key_get_key(vk), + crypt_volume_key_length(vk), flags & LARGE_IV); if (r) return r; @@ -103,18 +105,11 @@ static int crypt_storage_dmcrypt_init( if (dmd.flags & CRYPT_ACTIVATE_READONLY) mode = (open_flags & ~O_ACCMODE) | O_RDONLY; - if (vk->key_description) + if (crypt_volume_key_description(vk)) dmd.flags |= CRYPT_ACTIVATE_KEYRING_KEY; - r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, - device, - vk, - cipher_spec, - iv_start, - device_offset, - NULL, - 0, - sector_size); + r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, device, vk, cipher_spec, iv_start, + device_offset, NULL, 0, 0, sector_size); if (r) return r; diff --git a/lib/utils_storage_wrappers.h b/lib/utils_storage_wrappers.h index ebc7ed3..c7a64b2 100644 --- a/lib/utils_storage_wrappers.h +++ b/lib/utils_storage_wrappers.h @@ -3,7 +3,7 @@ * Generic wrapper for storage functions * (experimental only) * - * Copyright (C) 2018-2024 Ondrej Kozina + * Copyright (C) 2018-2025 Ondrej Kozina */ #ifndef _UTILS_STORAGE_WRAPPERS_H diff --git a/lib/utils_wipe.c b/lib/utils_wipe.c index 2aa74e6..6a26ded 100644 --- a/lib/utils_wipe.c +++ b/lib/utils_wipe.c @@ -3,8 +3,8 @@ * utils_wipe - wipe a device * * Copyright (C) 2004-2007 Clemens Fruhwirth - * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2024 Milan Broz + * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2025 Milan Broz */ #include @@ -50,7 +50,7 @@ static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn) { unsigned int i; - unsigned char write_modes[][3] = { + const unsigned char write_modes[27][4] = { {"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"}, {"\x00\x00\x00"}, {"\x11\x11\x11"}, {"\x22\x22\x22"}, {"\x33\x33\x33"}, @@ -172,6 +172,10 @@ int crypt_wipe_device(struct crypt_device *cd, /* Note: LUKS1 calls it with wipe_block not aligned to multiple of bsize */ bsize = device_block_size(cd, device); alignment = device_alignment(device); + + log_dbg(cd, "Wipe device %s [%u], offset %" PRIu64 ", length %" PRIu64 ", block %zu, bsize %zu, align %zu.", + device_path(device), (unsigned)pattern, offset, length, wipe_block_size, bsize, alignment); + if (!bsize || !alignment || !wipe_block_size) return -EINVAL; @@ -287,9 +291,6 @@ int crypt_wipe(struct crypt_device *cd, if (!wipe_block_size) wipe_block_size = 1024*1024; - log_dbg(cd, "Wipe [%u] device %s, offset %" PRIu64 ", length %" PRIu64 ", block %zu.", - (unsigned)pattern, device_path(device), offset, length, wipe_block_size); - r = crypt_wipe_device(cd, device, pattern, offset, length, wipe_block_size, progress, usrptr); diff --git a/lib/verity/rs.h b/lib/verity/rs.h index 48f3a09..195e00c 100644 --- a/lib/verity/rs.h +++ b/lib/verity/rs.h @@ -4,7 +4,7 @@ * * Copyright (C) 2004 Phil Karn, KA9Q * libcryptsetup modifications - * Copyright (C) 2017-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2017-2025 Red Hat, Inc. All rights reserved. */ #ifndef _LIBFEC_RS_H diff --git a/lib/verity/rs_decode_char.c b/lib/verity/rs_decode_char.c index 0fcceae..f819dea 100644 --- a/lib/verity/rs_decode_char.c +++ b/lib/verity/rs_decode_char.c @@ -4,7 +4,7 @@ * * Copyright (C) 2002, Phil Karn, KA9Q * libcryptsetup modifications - * Copyright (C) 2017-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2017-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/lib/verity/rs_encode_char.c b/lib/verity/rs_encode_char.c index 259b29d..8d1b6c3 100644 --- a/lib/verity/rs_encode_char.c +++ b/lib/verity/rs_encode_char.c @@ -4,7 +4,7 @@ * * Copyright (C) 2002, Phil Karn, KA9Q * libcryptsetup modifications - * Copyright (C) 2017-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2017-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/lib/verity/verity.c b/lib/verity/verity.c index 5fe1cf7..65f5f4e 100644 --- a/lib/verity/verity.c +++ b/lib/verity/verity.c @@ -2,7 +2,7 @@ /* * dm-verity volume handling * - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. */ #include @@ -271,7 +271,8 @@ int VERITY_verify_params(struct crypt_device *cd, return 0; log_dbg(cd, "Verification of VERITY data in userspace required."); - r = VERITY_verify(cd, hdr, root_hash->key, root_hash->keylength); + r = VERITY_verify(cd, hdr, crypt_volume_key_get_key(root_hash), + crypt_volume_key_length(root_hash)); if ((r == -EPERM || r == -EFAULT) && fec_device) { v = r; @@ -300,9 +301,9 @@ int VERITY_activate(struct crypt_device *cd, struct crypt_params_verity *verity_hdr, uint32_t activation_flags) { - uint32_t dmv_flags; + uint64_t dmv_flags; int r; - key_serial_t kid; + key_serial_t kid = 0; char *description = NULL; struct crypt_dm_active_device dmd = { 0 }; @@ -324,7 +325,9 @@ int VERITY_activate(struct crypt_device *cd, return -EINVAL; log_dbg(cd, "Adding signature %s (type user) into thread keyring.", description); - kid = keyring_add_key_in_thread_keyring(USER_KEY, description, signature->key, signature->keylength); + kid = keyring_add_key_in_thread_keyring(USER_KEY, description, + crypt_volume_key_get_key(signature), + crypt_volume_key_length(signature)); if (kid < 0) { log_dbg(cd, "keyring_add_key_in_thread_keyring failed with errno %d.", errno); log_err(cd, _("Failed to load key in kernel keyring.")); @@ -352,8 +355,8 @@ int VERITY_activate(struct crypt_device *cd, } r = dm_verity_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd), - crypt_metadata_device(cd), fec_device, root_hash->key, - root_hash->keylength, description, + crypt_metadata_device(cd), fec_device, crypt_volume_key_get_key(root_hash), + crypt_volume_key_length(root_hash), description, VERITY_hash_offset_block(verity_hdr), VERITY_FEC_blocks(cd, fec_device, verity_hdr), verity_hdr); @@ -381,7 +384,12 @@ int VERITY_activate(struct crypt_device *cd, r = 0; out: - crypt_drop_keyring_key_by_description(cd, description, USER_KEY); + if (signature) { + log_dbg(cd, "Unlinking signature (id: %" PRIi32 ") from thread keyring.", kid); + + if (keyring_unlink_key_from_thread_keyring(kid)) + log_dbg(cd, "keyring_unlink_key_from_thread_keyring failed with errno %d.", errno); + } free(description); dm_targets_free(cd, &dmd); return r; @@ -411,13 +419,13 @@ int VERITY_dump(struct crypt_device *cd, verity_blocks += rs_blocks; } - log_std(cd, "VERITY header information for %s\n", device_path(crypt_metadata_device(cd))); + log_std(cd, "VERITY header information for %s.\n", device_path(crypt_metadata_device(cd))); log_std(cd, "UUID: \t%s\n", crypt_get_uuid(cd) ?: ""); log_std(cd, "Hash type: \t%u\n", verity_hdr->hash_type); log_std(cd, "Data blocks: \t%" PRIu64 "\n", verity_hdr->data_size); - log_std(cd, "Data block size: \t%u\n", verity_hdr->data_block_size); + log_std(cd, "Data block size: \t%u [bytes]\n", verity_hdr->data_block_size); log_std(cd, "Hash blocks: \t%" PRIu64 "\n", hash_blocks); - log_std(cd, "Hash block size: \t%u\n", verity_hdr->hash_block_size); + log_std(cd, "Hash block size: \t%u [bytes]\n", verity_hdr->hash_block_size); log_std(cd, "Hash algorithm: \t%s\n", verity_hdr->hash_name); if (fec_device && fec_blocks) { log_std(cd, "FEC RS roots: \t%" PRIu32 "\n", verity_hdr->fec_roots); diff --git a/lib/verity/verity.h b/lib/verity/verity.h index f0c43a7..7d79810 100644 --- a/lib/verity/verity.h +++ b/lib/verity/verity.h @@ -2,7 +2,7 @@ /* * dm-verity volume handling * - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. */ #ifndef _VERITY_H diff --git a/lib/verity/verity_fec.c b/lib/verity/verity_fec.c index ca60b2e..2dfb4ac 100644 --- a/lib/verity/verity_fec.c +++ b/lib/verity/verity_fec.c @@ -3,7 +3,7 @@ * dm-verity Forward Error Correction (FEC) support * * Copyright (C) 2015 Google, Inc. All rights reserved. - * Copyright (C) 2017-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2017-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/lib/verity/verity_hash.c b/lib/verity/verity_hash.c index 56b1569..02333de 100644 --- a/lib/verity/verity_hash.c +++ b/lib/verity/verity_hash.c @@ -2,7 +2,7 @@ /* * dm-verity volume handling * - * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved. */ #include @@ -302,6 +302,11 @@ static int VERITY_create_or_verify_hash(struct crypt_device *cd, bool verify, hash_device_offset_max - params->hash_area_offset); log_dbg(cd, "Using %d hash levels.", levels); + r = device_check_size(cd, crypt_metadata_device(cd), + hash_device_offset_max - params->hash_area_offset, 1); + if (r < 0) + return r; + data_file = fopen(device_path(crypt_data_device(cd)), "r"); if (!data_file) { log_err(cd, _("Cannot open device %s."), diff --git a/lib/volumekey.c b/lib/volumekey.c index 034e16e..afa0cb8 100644 --- a/lib/volumekey.c +++ b/lib/volumekey.c @@ -3,7 +3,7 @@ * cryptsetup volume key implementation * * Copyright (C) 2004-2006 Clemens Fruhwirth - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. */ #include @@ -13,6 +13,16 @@ #include "internal.h" +struct volume_key { + int id; + size_t keylength; /* length in bytes */ + const char *key_description; /* keyring key name/description */ + key_type_t keyring_key_type; /* kernel keyring key type */ + key_serial_t key_id; /* kernel key id of volume key representation linked in thread keyring */ + struct volume_key *next; + char *key; +}; + struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key) { struct volume_key *vk; @@ -20,39 +30,117 @@ struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key) if (keylength > (SIZE_MAX - sizeof(*vk))) return NULL; - vk = malloc(sizeof(*vk) + keylength); + vk = crypt_zalloc(sizeof(*vk)); if (!vk) return NULL; - vk->key_description = NULL; + vk->keyring_key_type = INVALID_KEY; + vk->key_id = -1; vk->keylength = keylength; vk->id = KEY_NOT_VERIFIED; - vk->next = NULL; /* keylength 0 is valid => no key */ - if (vk->keylength) { - if (key) - memcpy(&vk->key, key, keylength); - else - crypt_safe_memzero(&vk->key, keylength); + if (vk->keylength && key) { + vk->key = crypt_safe_alloc(keylength); + if (!vk->key) { + free(vk); + return NULL; + } + crypt_safe_memcpy(vk->key, key, keylength); } return vk; } -int crypt_volume_key_set_description(struct volume_key *vk, const char *key_description) +struct volume_key *crypt_alloc_volume_key_by_safe_alloc(void **safe_alloc) +{ + size_t keylength; + struct volume_key *vk; + + if (!safe_alloc) + return NULL; + + keylength = crypt_safe_alloc_size(*safe_alloc); + if (!keylength) + return NULL; + + vk = crypt_alloc_volume_key(keylength, NULL); + if (!vk) + return NULL; + + vk->key = *safe_alloc; + *safe_alloc = NULL; + + return vk; +} + +void crypt_volume_key_pass_safe_alloc(struct volume_key *vk, void **safe_alloc) +{ + assert(vk); + assert(vk->keylength); + assert(safe_alloc); + assert(crypt_safe_alloc_size(*safe_alloc) == vk->keylength); + + crypt_safe_free(vk->key); + vk->key = *safe_alloc; + *safe_alloc = NULL; +} + +const char *crypt_volume_key_get_key(const struct volume_key *vk) +{ + assert(vk && vk->key); + + return vk->key; +} + +size_t crypt_volume_key_length(const struct volume_key *vk) +{ + assert(vk); + + return vk->keylength; +} + +int crypt_volume_key_set_description(struct volume_key *vk, + const char *key_description, key_type_t keyring_key_type) { if (!vk) return -EINVAL; free(CONST_CAST(void*)vk->key_description); vk->key_description = NULL; + vk->keyring_key_type = keyring_key_type; if (key_description && !(vk->key_description = strdup(key_description))) return -ENOMEM; return 0; } +int crypt_volume_key_set_description_by_name(struct volume_key *vk, const char *key_name) +{ + const char *key_description = NULL; + key_type_t keyring_key_type = keyring_type_and_name(key_name, &key_description); + + if (keyring_key_type == INVALID_KEY) + return -EINVAL; + + return crypt_volume_key_set_description(vk, key_description, keyring_key_type); +} + +const char *crypt_volume_key_description(const struct volume_key *vk) +{ + assert(vk); + + return vk->key_description; +} + + +key_type_t crypt_volume_key_kernel_key_type(const struct volume_key *vk) +{ + assert(vk); + + return vk->keyring_key_type; +} + void crypt_volume_key_set_id(struct volume_key *vk, int id) { if (vk && id >= 0) @@ -107,28 +195,88 @@ void crypt_free_volume_key(struct volume_key *vk) struct volume_key *vk_next; while (vk) { - crypt_safe_memzero(vk->key, vk->keylength); - vk->keylength = 0; free(CONST_CAST(void*)vk->key_description); + crypt_safe_free(vk->key); vk_next = vk->next; free(vk); vk = vk_next; } } -struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength) +struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength, + key_quality_info quality) { int r; - struct volume_key *vk; + void *key; + struct volume_key *vk = NULL; - vk = crypt_alloc_volume_key(keylength, NULL); - if (!vk) + key = crypt_safe_alloc(keylength); + if (!key) return NULL; - r = crypt_random_get(cd, vk->key, keylength, CRYPT_RND_KEY); - if(r < 0) { - crypt_free_volume_key(vk); - return NULL; + switch (quality) { + case KEY_QUALITY_KEY: + r = crypt_random_get(cd, key, keylength, CRYPT_RND_KEY); + break; + case KEY_QUALITY_NORMAL: + r = crypt_random_get(cd, key, keylength, CRYPT_RND_NORMAL); + break; + case KEY_QUALITY_EMPTY: + r = 0; + break; + default: + abort(); } + + if (!r) + vk = crypt_alloc_volume_key(keylength, NULL); + if (vk) + vk->key = key; + else + crypt_safe_free(key); + return vk; } + +bool crypt_volume_key_is_set(const struct volume_key *vk) +{ + return vk && vk->key; +} + +bool crypt_volume_key_upload_kernel_key(struct volume_key *vk) +{ + key_serial_t kid; + + assert(vk && vk->key && vk->key_description && vk->keyring_key_type != INVALID_KEY); + + kid = keyring_add_key_in_thread_keyring(vk->keyring_key_type, vk->key_description, + vk->key, vk->keylength); + if (kid >= 0) { + vk->key_id = kid; + return true; + } + + return false; +} + +void crypt_volume_key_drop_kernel_key(struct crypt_device *cd, struct volume_key *vk) +{ + assert(vk); + assert(vk->key_description || vk->keyring_key_type == INVALID_KEY); + assert(!vk->key_description || vk->keyring_key_type != INVALID_KEY); + + crypt_unlink_key_by_description_from_thread_keyring(cd, + vk->key_description, + vk->keyring_key_type); +} + +void crypt_volume_key_drop_uploaded_kernel_key(struct crypt_device *cd, struct volume_key *vk) +{ + assert(vk); + + if (vk->key_id < 0) + return; + + crypt_unlink_key_from_thread_keyring(cd, vk->key_id); + vk->key_id = -1; +} diff --git a/man/common_footer.adoc b/man/common_footer.adoc index 21302eb..6747aee 100644 --- a/man/common_footer.adoc +++ b/man/common_footer.adoc @@ -1,17 +1,15 @@ - == REPORTING BUGS -Report bugs at mailto:cryptsetup@lists.linux.dev[*cryptsetup mailing list*] -or in https://gitlab.com/cryptsetup/cryptsetup/-/issues/new[*Issues project section*]. +Report bugs at mailto:cryptsetup@lists.linux.dev[cryptsetup mailing list] or in https://gitlab.com/cryptsetup/cryptsetup/-/issues/new[Issues project section]. -Please attach output of the failed command with --debug option added. +Please attach the output of the failed command with --debug option added. == SEE ALSO -https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions[*Cryptsetup FAQ*] +https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions[Cryptsetup FAQ] *cryptsetup*(8), *integritysetup*(8) and *veritysetup*(8) == CRYPTSETUP -Part of https://gitlab.com/cryptsetup/cryptsetup/[*cryptsetup project*]. +Part of https://gitlab.com/cryptsetup/cryptsetup/[cryptsetup project]. diff --git a/man/common_options.adoc b/man/common_options.adoc index 523b775..31ca962 100644 --- a/man/common_options.adoc +++ b/man/common_options.adoc @@ -1,48 +1,42 @@ == OPTIONS ifdef::ACTION_LUKSFORMAT,ACTION_REENCRYPT[] -*--align-payload *:: +*--align-payload* __ (DEPRECATED, use --offset):: Align payload at a boundary of _value_ 512-byte sectors. + -If not specified, cryptsetup tries to use the topology info provided by -the kernel for the underlying device to get the optimal alignment. If -not available (or the calculated value is a multiple of the default) -data is by default aligned to a 1MiB boundary (i.e. 2048 512-byte -sectors). +If not specified, cryptsetup tries to use the topology info provided by the kernel for the underlying device to get the optimal alignment. +If not available (or the calculated value is a multiple of the default), data is by default aligned to a 1MiB boundary (i.e., 2048 512-byte sectors). + -For a detached LUKS header, this option specifies the offset on the data -device. See also the --header option. +For a detached LUKS header, this option specifies the offset on the data device. +See also the --header option. + -*WARNING:* This option is DEPRECATED and has often unexpected impact to -the data offset and keyslot area size (for LUKS2) due to the complex -rounding. For fixed data device offset use _--offset_ option instead. +This option is DEPRECATED and has an unexpected impact on the data offset and keyslot area size (for LUKS2) due to the complex rounding. +For fixed data device offset, use --offset option instead. endif::[] ifdef::ACTION_OPEN,ACTION_REFRESH[] *--allow-discards*:: -Allow the use of discard (TRIM) requests for the device. This is also not -supported for LUKS2 devices with data integrity protection. +Allow the use of discard (TRIM) requests for the device. +This is also not supported for LUKS2 devices with data integrity protection. + -*WARNING:* This command can have a negative security impact because it -can make filesystem-level operations visible on the physical device. For -example, information leaking filesystem type, used space, etc. may be -extractable from the physical device if the discarded blocks can be -located later. If in doubt, do not use it. +*WARNING:* This command can have a negative security impact because it can make filesystem-level operations visible on the physical device. +For example, information leaking filesystem type, used space, etc., may be extractable from the physical device if the discarded blocks can be located later. +If in doubt, do not use it. + -A kernel version of 3.1 or later is needed. For earlier kernels, this -option is ignored. +A kernel version of 3.1 or later is needed. +For earlier kernels, this option is ignored. endif::[] ifdef::COMMON_OPTIONS[] -*--batch-mode, -q*:: -Suppresses all confirmation questions. Use with care! +*--batch-mode*, *-q*:: +Suppresses all confirmation questions. +Use with care! + -If the --verify-passphrase option is not specified, this option also -switches off the passphrase verification. +If the --verify-passphrase option is not specified, this option also switches off the passphrase verification. endif::[] ifdef::ACTION_REENCRYPT[] -*--block-size* _value_ *(LUKS1 only)*:: +*--block-size* _value_ (LUKS1 only):: Use re-encryption block size of _value_ in MiB. + Values can be between 1 and 64 MiB. @@ -50,50 +44,47 @@ endif::[] ifdef::ACTION_CLOSE[] *--cancel-deferred*:: -Removes a previously configured deferred device removal in _close_ -command. +Removes a previously configured deferred device removal in the _close_ command. endif::[] ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT,ACTION_TCRYPTDUMP,ACTION_BENCHMARK[] -*--cipher, -c* __:: +*--cipher*, *-c* __:: ifdef::ACTION_OPEN,ACTION_TCRYPTDUMP[] -Set the cipher specification string for _plain_ device type. +Set the cipher specification string for the _plain_ device type. + -For _tcrypt_ device type it restricts checked cipher chains when looking for header. +For the _tcrypt_ device type, it restricts checked cipher chains when looking for the header. endif::[] ifndef::ACTION_REENCRYPT,ACTION_OPEN,ACTION_TCRYPTDUMP[] Set the cipher specification string. endif::[] ifdef::ACTION_REENCRYPT[] *LUKS2*: -Set the cipher specification string for data segment only. +Set the cipher specification string for the data segment only. + *LUKS1*: -Set the cipher specification string for data segment and keyslots. +Set the cipher specification string for the data segment and keyslots. + -*NOTE*: In encrypt mode, if cipher specification is omitted the default cipher is applied. -In reencrypt mode, if no new cipher specification is requested, the existing cipher will remain -in use. Unless the existing cipher was "cipher_null". In that case default cipher would -be applied as in encrypt mode. +The default cipher is applied if the cipher specification is omitted in encrypt mode. ++ +In reencrypt mode, if no new cipher specification is requested, the existing cipher will remain. +The only exception is if the cipher is "cipher_null", then the default cipher is used. endif::[] ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT[] + _cryptsetup --help_ shows the compiled-in defaults. + -If a hash is part of the cipher specification, then it is used as part -of the IV generation. For example, ESSIV needs a hash function, while -"plain64" does not and hence none is specified. +If a hash is part of the cipher specification, then it is used as part of the IV generation. +For example, ESSIV needs a hash function, while "plain64" does not and hence none is specified. + -For XTS mode you can optionally set a key size of 512 bits with the -s -option. Key size for XTS mode is twice that for other modes for the same -security level. +For XTS mode, you can optionally set a key size of 512 bits with the -s option. +Key size for XTS mode is twice that for other modes for the same security level. endif::[] endif::[] ifdef::COMMON_OPTIONS[] -*--debug or --debug-json*:: -Run in debug mode with full diagnostic logs. Debug output lines are -always prefixed by *#*. +*--debug* or *--debug-json*:: +Run in debug mode with full diagnostic logs. +Debug output lines are always prefixed by *#*. + If --debug-json is used, additional LUKS2 JSON data structures are printed. endif::[] @@ -105,38 +96,41 @@ endif::[] ifdef::ACTION_CLOSE[] *--deferred*:: -Defers device removal in _close_ command until the last user closes -it. +Defers device removal in the _close_ command until the last user closes it. endif::[] ifdef::ACTION_OPEN,ACTION_REENCRYPT,ACTION_RESIZE[] *--device-size* _size[units]_:: ifndef::ACTION_RESIZE[] -Instead of real device size, use specified value. +Instead of the real device size, use the specified value. endif::[] ifdef::ACTION_RESIZE[] -Sets new size of the device. If unset real device size is used. +Sets the new size of the device. +If unset, the real device size is used. endif::[] ifdef::ACTION_OPEN[] Usable only with _plain_ device type. endif::[] ifdef::ACTION_REENCRYPT[] -It means that only specified area (from the start of the device -to the specified size) will be reencrypted. +It means that only the specified area (from the start of the device to the specified size) will be reencrypted. ++ +*LUKS2*: +When used together with --reduce-device-size, only the initial _size_ value (--device-size parameter) of data is shifted backwards while being encrypted. + -*WARNING:* This is destructive operation. Data beyond --device-size limit may -be lost after operation gets finished. +The sum of --device-size and --reduce-device-size values must not exceed the real device size. ++ +*WARNING:* This is a destructive operation. +Data beyond --device-size limit may be lost after the operation is finished. endif::[] + If no unit suffix is specified, the size is in bytes. + -Unit suffix can be S for 512 byte sectors, K/M/G/T (or KiB,MiB,GiB,TiB) -for units with 1024 base or KB/MB/GB/TB for 1000 base (SI scale). +Unit suffix can be S for 512 byte sectors, K/M/G/T (or KiB, MiB, GiB, TiB) for units with 1024 base or KB/MB/GB/TB for 1000 base (SI scale). endif::[] ifdef::ACTION_LUKSFORMAT,ACTION_REENCRYPT[] *--disable-blkid*:: -Disable use of blkid library for checking and wiping on-disk signatures. +Disable use of the blkid library for checking and wiping on-disk signatures. endif::[] ifdef::ACTION_OPEN,ACTION_LUKSRESUME,ACTION_RESIZE,ACTION_TOKEN[] @@ -146,102 +140,102 @@ endif::[] ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_REFRESH,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_TOKEN,ACTION_REENCRYPT[] *--disable-keyring*:: -Do not load volume key in kernel keyring and store it directly in the -dm-crypt target instead. This option is supported only for the LUKS2 type. +Do not load the volume key in the kernel keyring; store it directly in the dm-crypt target instead. +This option is supported only for the LUKS2 type. endif::[] ifndef::ACTION_BENCHMARK,ACTION_BITLKDUMP,ACTION_TCRYPTDUMP[] *--disable-locks*:: -Disable lock protection for metadata on disk. This option is valid -only for LUKS2 and ignored for other formats. +Disable lock protection for metadata on disk. +This option is valid only for LUKS2 and is ignored for other formats. + ifdef::ACTION_REENCRYPT[] -*NOTE:* With locking disabled LUKS2 images in files can be fully (re)encrypted -offline without need for super user privileges provided used block ciphers are -available in crypto backend. +With locking disabled, LUKS2 images in files can be fully (re)encrypted offline without the need for superuser privileges provided that the used block ciphers are available in the crypto backend. + endif::[] -*WARNING:* Do not use this option unless you run cryptsetup in a -restricted environment where locking is impossible to perform (where -/run directory cannot be used). +*WARNING:* Do not use this option unless you run cryptsetup in a restricted environment where locking is impossible to perform (where /run directory cannot be used). endif::[] ifdef::ACTION_OPEN,ACTION_TCRYPTDUMP[] *--disable-veracrypt*:: -This option can be used to disable VeraCrypt compatible mode (only -TrueCrypt devices are recognized). Only for TCRYPT extension. See -_TCRYPT_ section in *cryptsetup*(8) for more info. +This option can be used to disable VeraCrypt compatible mode (only TrueCrypt devices are recognized). +See the _TCRYPT_ section in *cryptsetup*(8) for more info. endif::[] ifdef::ACTION_LUKSDUMP[] *--dump-json-metadata*:: -For _luksDump_ (LUKS2 only) this option prints content of LUKS2 header -JSON metadata area. +For _luksDump_ (LUKS2 only), this option prints the content of the LUKS2 header JSON metadata area. endif::[] ifdef::ACTION_LUKSDUMP,ACTION_TCRYPTDUMP,ACTION_BITLKDUMP[] -*--dump-volume-key, --dump-master-key (OBSOLETE alias)*:: -Print the volume key in the displayed information. Use with care, -as the volume key can be used to bypass -the passphrases, see also option --volume-key-file. +*--dump-volume-key*:: +--dump-master-key (OBSOLETE alias):: +Print the volume key in the displayed information. +Use with care, as the volume key can be used to bypass the passphrases, see also option --volume-key-file. endif::[] ifdef::ACTION_REENCRYPT[] -*--encrypt, --new, -N*:: -Initialize (and run) device in-place encryption mode. +*--encrypt*, *--new*, *-N*:: +Initialize (and run) the device in-place encryption mode. endif::[] ifdef::ACTION_RESIZE,ACTION_OPEN,ACTION_LUKSADDKEY,ACTION_LUKSDUMP,ACTION_LUKSRESUME,ACTION_TOKEN[] -*--external-tokens-path* _absolute_path_:: -Override system directory path where cryptsetup searches for external token -handlers (or token plugins). It must be absolute path (starting with '/' character). +*--external-tokens-path* __:: +Override the system directory path where cryptsetup searches for external token handlers (or token plugins). +It must be an absolute path (starting with '/' character). +endif::[] + +ifdef::ACTION_REENCRYPT[] +*--force-no-keyslots* (LUKS2 only):: +Enforce initialization of reencryption operation with additional --volume-key-file, --new-volume-key-file, --volume-key-keyring or --new-volume-key-keyring parameters. +It would result in the deletion of all remaining LUKS2 keyslots containing the volume key. ++ +LUKS2 keyslot with the new volume key may be added after the reencryption operation is finished. +See *cryptsetup-luksAddKey*(8) command. ++ +*WARNING:* Use with extreme caution! +If you lose the volume key stored in a file or in a kernel keyring before adding the LUKS2 keyslot containing the new volume key, the device will become unusable, and all data will be lost. endif::[] ifdef::ACTION_REENCRYPT[] -*--force-offline-reencrypt (LUKS2 only)*:: +*--force-offline-reencrypt* (LUKS2 only):: Bypass active device auto-detection and enforce offline reencryption. + -This option is useful especially for reencryption of LUKS2 images put in -files (auto-detection is not reliable in this scenario). +This option is useful especially for reencryption of LUKS2 images put in files (auto-detection is not reliable in this scenario). + -It may also help in case active device auto-detection on particular -data device does not work or report errors. +It may also help in case active device auto-detection on a particular data device does not work or report errors. + -*WARNING:* Use with extreme caution! This may destroy data if the device -is activated and/or actively used. +*WARNING:* Use with extreme caution! This may destroy data if the device is activated and/or actively used. endif::[] ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT[] *--force-password*:: Do not use password quality checking for new LUKS passwords. + -This option is ignored if cryptsetup is built without password -quality checking support. +This option is ignored if cryptsetup is built without password quality checking support. + -For more info about password quality check, see the manual page for -*pwquality.conf(5)* and *passwdqc.conf(5)*. +For more info about password quality check, see the manual page for *pwquality.conf*(5) and *passwdqc.conf*(5). endif::[] ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_TCRYPTDUMP,ACTION_BENCHMARK,ACTION_REENCRYPT[] -*--hash, -h* __:: +*--hash*, *-h* __:: ifdef::ACTION_OPEN,ACTION_TCRYPTDUMP[] -Specifies the passphrase hash. Applies to _plain_ and _loopaes_ device types only. +Specifies the passphrase hash. +Applies to _plain_ and _loopaes_ device types only. + -For _tcrypt_ device type, it restricts checked PBKDF2 variants when looking for header. +For the _tcrypt_ device type, it restricts the checked PBKDF2 variants when looking for the header. endif::[] ifdef::ACTION_LUKSFORMAT[] -Specifies the hash used in the LUKS key setup scheme and volume key -digest. +Specifies the hash used in the LUKS key setup scheme and volume key digest. endif::[] ifndef::ACTION_REENCRYPT,ACTION_OPEN,ACTION_TCRYPTDUMP[] -The specified hash is used for PBKDF2 and AF splitter. +The specified hash is used for PBKDF2 and the AF splitter. endif::[] ifdef::ACTION_REENCRYPT[] *LUKS1:* Specifies the hash used in the LUKS1 key setup scheme and volume key digest. + -*NOTE*: if this parameter is not specified, default hash algorithm is always used -for new LUKS1 device header. +If this parameter is not specified, the default hash algorithm is always used for a new LUKS1 device header. + *LUKS2:* Ignored unless new keyslot pbkdf algorithm is set to PBKDF2 (see --pbkdf). endif::[] @@ -254,34 +248,28 @@ endif::[] endif::[] ifndef::ACTION_BENCHMARK,ACTION_BITLKDUMP[] -*--header *:: +*--header* __:: ifndef::ACTION_OPEN,ACTION_ERASE[] -Use a detached (separated) metadata device or file where the LUKS -header is stored. This option allows one to store ciphertext and LUKS -header on different devices. +Use a detached (separated) metadata device or file where the LUKS header is stored. +This option allows one to store the ciphertext and LUKS header on different devices. + endif::[] ifdef::ACTION_OPEN[] -Specify detached (separated) metadata device or file where the header is stored. +Specify a detached (separated) metadata device or file where the header is stored. + -*WARNING:* There is no check whether the ciphertext device specified -actually belongs to the header given. In fact, you can specify an -arbitrary device as the ciphertext device with the --header option. +*WARNING:* There is no check whether the ciphertext device specified actually belongs to the header given. +In fact, you can specify an arbitrary device as the ciphertext device with the --header option. Use with care. endif::[] ifndef::ACTION_REENCRYPT[] ifdef::ACTION_LUKSFORMAT[] -With a file name as the argument to --header, the file -will be automatically created if it does not exist. See the cryptsetup -FAQ for header size calculation. +With a file name as the argument to --header, the file will be automatically created if it does not exist. +See the cryptsetup FAQ for header size calculation. + -The --align-payload option is taken as absolute sector alignment on ciphertext -device and can be zero. +The --align-payload option is taken as absolute sector alignment on the ciphertext device and can be zero. endif::[] ifndef::ACTION_LUKSFORMAT,ACTION_OPEN,ACTION_ERASE[] -For commands that change the LUKS header (e.g. _luksAddKey_), -specify the device or file with the LUKS header directly as the LUKS -device. +For commands that change the LUKS header (e.g., _luksAddKey_), specify the device or file with the LUKS header directly as the LUKS device. endif::[] endif::[] ifdef::ACTION_REENCRYPT[] @@ -289,208 +277,202 @@ If used with --encrypt/--new option, the header file will be created (or overwri Use with care. + *LUKS2*: -For decryption mode the option may be used to export original LUKS2 header -to a detached file. The passed future file must not exist at the time -of initializing the decryption operation. This frees space in head of data -device so that data can be moved at original LUKS2 header location. Later on -decryption operation continues as if the ordinary detached header was passed. +For decryption mode, the option may be used to export the original LUKS2 header to a detached file. +The passed future file must not exist at the time of initializing the decryption operation. +This frees space in the head of the data device so that data can be moved at the original LUKS2 header location. +Later on, the decryption operation continues as if the ordinary detached header was passed. + -*WARNING:* Never put exported header file in a filesystem on top of device -you are about to decrypt! It would cause a deadlock. +*WARNING:* Never put an exported header file in a filesystem on top of the device you are about to decrypt! +It would cause a deadlock. endif::[] ifdef::ACTION_ERASE[] -Use to specify detached LUKS2 header when erasing HW OPAL enabled data device. +Use to specify a detached LUKS2 header when erasing OPAL self-encrypting drive. endif::[] endif::[] ifdef::ACTION_LUKSHEADERBACKUP,ACTION_LUKSHEADERRESTORE[] -*--header-backup-file *:: -Specify file with header backup file. +*--header-backup-file* _file_:: +Specify a file with the header backup file. endif::[] ifdef::COMMON_OPTIONS[] -*--help, -?*:: +*--help*, *-?*:: Show help text and default parameters. endif::[] ifdef::ACTION_REENCRYPT[] -*--hotzone-size* _size_ *(LUKS2 only)*:: -This option can be used to set an upper limit on the size of -reencryption area (hotzone). The _size_ can be specified with unit -suffix (for example 50M). Note that actual hotzone size may be less -than specified due to other limitations (free space in keyslots -area or available memory). +*--hotzone-size* _size_ (LUKS2 only):: +This option can be used to set an upper limit on the size of the reencryption area (hotzone). +The _size_ can be specified with a unit suffix (for example, 50M). +Note that the actual hotzone size may be less than specified due to other limitations (free space in keyslots area or available memory). + -With decryption mode for devices with LUKS2 header placed in head of data -device, the option specifies how large is the first data segment moved -from original data offset pointer. +With decryption mode for devices with LUKS2 header placed in the head of the data device, the option specifies how large is the first data segment moved from the original data offset pointer. endif::[] ifdef::ACTION_LUKSFORMAT[] *--hw-opal*:: -Format LUKS2 device with dm-crypt encryption stacked on top HW based encryption configured -on SED OPAL locking range. This option enables both SW and HW based data encryption. +Format LUKS2 device with dm-crypt encryption stacked on top of HW-based encryption configured on SED OPAL locking range. +This option enables both SW and HW based data encryption. endif::[] ifdef::ACTION_ERASE[] *--hw-opal-factory-reset*:: -Erase *ALL* data on the OPAL self-encrypted device, regardless of the partition it is ran on, if any, -and does not require a valid LUKS2 header to be present on the device to run. After providing -correct PSID via interactive prompt or via *--key-file* parameter the device is erased. -PSID is usually printed on the OPAL device label (either directly or as a QR code). +Erase *ALL* data on the OPAL self-encrypting drive. +The option does not require a valid LUKS2 header to be present on the device to run. +After providing the correct PSID via interactive prompt or via --key-file parameter the device is erased. ++ +PSID is usually printed on the OPAL drive label (either directly or as a QR code). +PSID must be entered without any dashes, spaces or underscores. ++ +PSID should be treated as sensitive information as it allows anyone with remote access to the OPAL drive to destroy data even if the device is locked. +Be sure you do not leak PSID through transparent packaging during transport or images of the drive posted online. endif::[] ifdef::ACTION_LUKSFORMAT[] *--hw-opal-only*:: -Format LUKS2 device with HW based encryption configured on SED OPAL locking range only. LUKS2 -format only manages locking range unlock key. This option enables HW based data encryption managed -by SED OPAL drive only. +Format LUKS2 device with HW based encryption configured on SED OPAL locking range only. +LUKS2 format only manages the locking range unlock key. +This option enables HW-based data encryption managed by the SED OPAL drive only. + -*NOTE*: Please note that with OPAL-only (--hw-opal-only) encryption, -the configured OPAL administrator PIN (passphrase) allows unlocking -all configured locking ranges without LUKS keyslot decryption -(without knowledge of LUKS passphrase). -Because of many observed problems with compatibility, cryptsetup -currently DOES NOT use OPAL single-user mode, which would allow such -decoupling of OPAL admin PIN access. +Please note that with OPAL-only (--hw-opal-only) encryption, the configured OPAL administrator PIN (passphrase) allows unlocking all configured locking ranges without LUKS keyslot decryption (without knowledge of LUKS passphrase). +Because of many observed problems with compatibility, cryptsetup currently DOES NOT use OPAL single-user mode, which would allow such decoupling of OPAL admin PIN access. endif::[] ifdef::ACTION_REENCRYPT[] -*--init-only (LUKS2 only)*:: -Initialize reencryption (any mode) operation in LUKS2 metadata only -and exit. If any reencrypt operation is already initialized in -metadata, the command with --init-only parameter fails. +*--init-only* (LUKS2 only):: +Initialize reencryption (any mode) operation in LUKS2 metadata only and exit. +If any reencrypt operation is already initialized in metadata, the command with --init-only parameter fails. endif::[] ifdef::ACTION_LUKSFORMAT[] -*--integrity *:: -Specify integrity algorithm to be used for authenticated disk -encryption in LUKS2. +*--integrity* __:: +Specify the integrity algorithm to be used for authenticated disk encryption in LUKS2. + -*WARNING: This extension is EXPERIMENTAL* and requires dm-integrity -kernel target (available since kernel version 4.12). For native AEAD -modes, also enable "User-space interface for AEAD cipher algorithms" in -"Cryptographic API" section (CONFIG_CRYPTO_USER_API_AEAD .config -option). +*WARNING: This extension is EXPERIMENTAL* and requires dm-integrity kernel target. +For native AEAD modes, also enable "User-space interface for AEAD cipher algorithms" in the "Cryptographic API" section (CONFIG_CRYPTO_USER_API_AEAD .config option). + -For more info, see _AUTHENTICATED DISK ENCRYPTION_ section in *cryptsetup*(8). +For more info, see the _AUTHENTICATED DISK ENCRYPTION_ section in *cryptsetup*(8). +endif::[] + +ifdef::ACTION_LUKSFORMAT[] +*--integrity-inline*:: +Store integrity tags in hardware sector integrity fields. +The device must support sectors with additional protection information (PI, also known as DIF - data integrity field) of the requested size. +Another storage subsystem must not use the additional field (the device must present a "nop" profile in the kernel). +Note that some devices must be reformatted at a low level to support this option; for NVMe devices, see nvme(1) id-ns LBA profiles. ++ +No journal or bitmap is used in this mode. +The device should operate with native speed (without any overhead). +This option is available since the Linux kernel version 6.11. +endif::[] + +ifdef::ACTION_LUKSFORMAT[] +*--integrity-key-size* _bits_:: +The size of the data integrity key. +The argument has to be a multiple of 8. +Configurable only for HMAC integrity. +The default integrity key size is set to the same as the hash output length. endif::[] ifdef::ACTION_LUKSFORMAT[] *--integrity-legacy-padding*:: Use inefficient legacy padding. + -*WARNING*: Do not use this option until you need compatibility with specific -old kernel. +Do not use this option until you need compatibility with a specific old kernel. endif::[] ifdef::ACTION_REFRESH[] *--integrity-no-journal*:: -Activate device with integrity protection without using data journal -(direct write of data and integrity tags). Note that without journal -power fail can cause non-atomic write and data corruption. Use only if -journalling is performed on a different storage layer. +Activate device with integrity protection without using data journal (direct write of data and integrity tags). +Note that without a journal, a power failure can cause non-atomic writes and data corruption. +Use only if journaling is performed on a different storage layer. endif::[] ifdef::ACTION_LUKSFORMAT[] *--integrity-no-wipe*:: -Skip wiping of device authentication (integrity) tags. If you skip -this step, sectors will report invalid integrity tag until an -application write to the sector. +Skip wiping of device authentication (integrity) tags. +If you skip this step, sectors will report an invalid integrity tag until an application writes to the sector. + -*NOTE:* Even some writes to the device can fail if the write is not -aligned to page size and page-cache initiates read of a sector with -invalid integrity tag. +Skipping this step could also cause write failures due to IO operation alignments. +For example, kernel page cache can request a read of a full page that fails due to an uninitialized integrity tag. +It is usually a bug in the application that tries to read data that was not written before. endif::[] ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT,ACTION_BENCHMARK[] -*--iter-time, -i *:: +*--iter-time*, *-i* __:: ifndef::ACTION_REENCRYPT[] The number of milliseconds to spend with PBKDF passphrase processing. -Specifying 0 as parameter selects the compiled-in default. +Specifying 0 as a parameter selects the compiled-in default. endif::[] ifdef::ACTION_REENCRYPT[] -The number of milliseconds to spend with PBKDF passphrase processing for the -new LUKS header. +The number of milliseconds to spend with PBKDF passphrase processing for the new LUKS header. endif::[] endif::[] ifdef::ACTION_OPEN[] *--iv-large-sectors*:: -Count Initialization Vector (IV) in larger sector size (if set) -instead of 512 bytes sectors. This option can be used only with _plain_ -device type. +Count Initialization Vector (IV) in larger sector size (if set) instead of 512-byte sectors. +This option can be used only with the _plain_ device type. + -*NOTE:* This option does not have any performance or security impact, -use it only for accessing incompatible existing disk images from other -systems that require this option. +This option does not have any performance or security impact; use it only for accessing incompatible existing disk images from other systems that require this option. endif::[] ifdef::ACTION_TOKEN[] *--json-file*:: -Read token JSON from a file or write token to it. --json-file=- reads JSON from -standard input or writes it to standard output respectively. +Read the token JSON from a file or write the token to it. +Option --json-file=- reads JSON from standard input or writes it to standard output, respectively. endif::[] ifdef::ACTION_REENCRYPT[] *--keep-key*:: *LUKS2*: -Do not change effective volume key and change other parameters provided -it is requested. +Do not change the effective volume key, and change other parameters if requested. + *LUKS1*: -Reencrypt only the LUKS1 header and keyslots. Skips data in-place reencryption. +Reencrypt only the LUKS1 header and keyslots. +Skips data in-place reencryption. endif::[] -ifdef::ACTION_TOKEN[] -*--key-description *:: -Set key description in keyring for use with _token_ command. +ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_LUKSDUMP,ACTION_RESIZE,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_TOKEN[] +*--key-description* _text_:: +Set the key description in the keyring that will be used for passphrase retrieval. endif::[] ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_TCRYPTDUMP,ACTION_REENCRYPT,ACTION_REPAIR,ACTION_BITLKDUMP[] -*--key-file, -d* _name_:: -Read the passphrase from file. +*--key-file*, *-d* _file_:: +Read the passphrase from the file. + If the name given is "-", then the passphrase will be read from stdin. In this case, reading will not stop at newline characters. + ifdef::ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY[] -The passphrase supplied via --key-file is always the passphrase for existing -keyslot requested by the command. +The passphrase supplied via --key-file is always the passphrase for the existing keyslot requested by the command. + ifdef::ACTION_LUKSADDKEY[] -If you want to set a new passphrase via key file, you have to use a -positional argument or parameter --new-keyfile. +If you want to set a new passphrase via key file, you have to use a positional argument or parameter --new-keyfile. endif::[] ifdef::ACTION_LUKSCHANGEKEY[] -If you want to set a new passphrase via key file, you have to use a -positional argument. +If you want to set a new passphrase via a key file, you have to use a positional argument. endif::[] + endif::[] ifdef::ACTION_OPEN[] -*NOTE:* With _plain_ device type, the passphrase obtained via --key-file option is -passed directly in dm-crypt. Unlike the interactive mode (stdin) -where digest (--hash option) of the passphrase is passed in dm-crypt instead. +With _plain_ device type, the passphrase obtained via --key-file option is passed directly in dm-crypt. +Unlike the interactive mode (stdin), where the digest of the passphrase is passed in dm-crypt instead. + endif::[] ifndef::ACTION_REENCRYPT[] See section _NOTES ON PASSPHRASE PROCESSING_ in *cryptsetup*(8) for more information. endif::[] ifdef::ACTION_REENCRYPT[] -*WARNING:* --key-file option can be used only if there is only one active keyslot, -or alternatively, also if --key-slot option is specified (then all other keyslots -will be disabled in new LUKS device). +The --key-file option can be used only if there is only one active keyslot, or alternatively, also if --key-slot option is specified (then all other keyslots will be disabled in the new LUKS device). + -If this option is not used, cryptsetup will ask for all active keyslot -passphrases. +If this option is not used, cryptsetup will ask for all active keyslot passphrases. endif::[] endif::[] ifdef::ACTION_ERASE[] -*--key-file, -d* _name_ *(LUKS2 with HW OPAL only)*:: - -Read the Admin PIN or PSID (with --hw-opal-factory-reset) from file -depending on options used. +*--key-file*, *-d* _file_ (LUKS2 with HW OPAL only):: +Read the Admin PIN or PSID (with --hw-opal-factory-reset) from the file, depending on options used. + If the name given is "-", then the secret will be read from stdin. In this case, reading will not stop at newline characters. @@ -503,190 +485,218 @@ Skip _value_ bytes at the beginning of the key file. endif::[] ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSRESUME,ACTION_LUKSADDKEY,ACTION_LUKSREMOVEKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSKILLSLOT,ACTION_LUKSDUMP,ACTION_REENCRYPT,ACTION_REPAIR,ACTION_BITLKDUMP[] -*--keyfile-size, -l* _value_:: -Read a maximum of _value_ bytes from the key file. The default is to -read the whole file up to the compiled-in maximum that can be queried -with --help. Supplying more data than the compiled-in maximum aborts -the operation. +*--keyfile-size*, *-l* _value_:: +Read a maximum of _value_ bytes from the key file. +The default is to read the whole file up to the compiled-in maximum that can be queried with --help. +Supplying more data than the compiled-in maximum aborts the operation. + -This option is useful to cut trailing newlines, for example. If ---keyfile-offset is also given, the size count starts after the offset. +This option is useful to cut trailing newlines, for example. +If --keyfile-offset is also given, the size count starts after the offset. endif::[] ifdef::ACTION_OPEN,ACTION_LUKSFORMAT,ACTION_REENCRYPT,ACTION_BENCHMARK,ACTION_LUKSADDKEY[] -*--key-size, -s* _bits_:: -ifndef::ACTION_LUKSADDKEY[] -Sets key size in _bits_. The argument has to be a multiple of 8. The -possible key-sizes are limited by the cipher and mode used. +*--key-size*, *-s* _bits_:: +ifndef::ACTION_LUKSADDKEY,ACTION_REENCRYPT[] +Sets key size in _bits_. +The argument has to be a multiple of 8. +The possible key sizes are limited by the cipher and mode used. + -See /proc/crypto for more information. Note that key-size in -/proc/crypto is stated in bytes. +See /proc/crypto for more information. +Note that the key size in /proc/crypto is stated in bytes. + endif::[] ifdef::ACTION_LUKSADDKEY[] -Provide volume key size in _bits_. The argument has to be a multiple of 8. +Provide volume key size in _bits_. +The argument has to be a multiple of 8. + -This option is required when parameter --volume-key-file is used to provide -current volume key. Also, it is used when new unbound keyslot is created by -specifying --unbound parameter. +This option is required when the parameter --volume-key-file is used to provide current volume key. +Also, it is used when a new unbound keyslot is created by specifying --unbound parameter. endif::[] ifdef::ACTION_OPEN[] -This option can be used for _plain_ device type only. +This option can be used for _plain_ and _luks_ devices. +For LUKS2 devices in reencryption, you may use the parameter twice to specify both old and new volume key sizes. +Each --key-size option corresponds to the respective --volume-key-file parameter (also allowed to be used up to two times). endif::[] ifndef::ACTION_REENCRYPT,ACTION_OPEN,ACTION_LUKSADDKEY[] -This option can be used for _open --type plain_ or _luksFormat_. All -other LUKS actions will use the key-size specified in the LUKS header. +This option can be used for _open --type plain_ or _luksFormat_. +All other LUKS actions will use the key size specified in the LUKS header. Use _cryptsetup --help_ to show the compiled-in defaults. endif::[] ifdef::ACTION_REENCRYPT[] -*LUKS1*: -If you are increasing key size, there must be enough space in the LUKS header -for enlarged keyslots (data offset must be large enough) or reencryption -cannot be performed. +*LUKS2*: +Provide current key size in _bits_. +The argument has to be a multiple of 8. +Useful when specifying the size of the current volume key when no keyslot is active. + -If there is not enough space for keyslots with new key size, -you can destructively shrink device with --reduce-device-size option. +*LUKS1*: +See --new-key-size. endif::[] endif::[] ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_LUKSDUMP,ACTION_LUKSRESUME,ACTION_TOKEN,ACTION_CONFIG,ACTION_TOKEN,ACTION_REPAIR,ACTION_REENCRYPT[] -*--key-slot, -S <0-N>*:: +*--key-slot*, *-S* _<0-N>_:: ifdef::ACTION_LUKSADDKEY[] -When used together with parameter --new-key-slot this option allows you to specify which -key slot is selected for unlocking volume key. +When used together with the parameter --new-key-slot, this option allows you to specify which keyslot is selected for unlocking the volume key. + -*NOTE:* This option is ignored if existing volume key gets unlocked -via LUKS2 token (--token-id, --token-type or --token-only parameters) or -when volume key is provided directly via --volume-key-file parameter. +This option is ignored if the existing volume key gets unlocked via LUKS2 token (--token-id, --token-type or --token-only parameters) or when volume key is provided directly via --volume-key-file parameter. + -*NOTE:* To maintain backward compatibility, without --new-key-slot parameter, -this option allows you to specify which key slot is selected for the new key. +To maintain backward compatibility, without --new-key-slot parameter, this option allows you to specify which keyslot is selected for the new key. endif::[] ifndef::ACTION_OPEN,ACTION_LUKSADDKEY[] -For LUKS operations that add key material, this option allows you to -specify which key slot is selected for the new key. +For LUKS operations that add key material, this option allows you to specify which keyslot is selected for the new key. endif::[] ifdef::ACTION_OPEN[] -This option selects a specific key-slot to -compare the passphrase against. If the given passphrase would only -match a different key-slot, the operation fails. +This option selects a specific keyslot to compare the passphrase against. +If the given passphrase would only matches a different keyslot, the operation fails. endif::[] + ifdef::ACTION_REENCRYPT[] -For reencryption mode it selects specific keyslot (and passphrase) that can be used to unlock new volume key. -If used all other keyslots get removed after reencryption operation is finished. +For reencryption mode, it selects a specific keyslot (and passphrase) that can be used to unlock the new volume key. +If used, all other keyslots get removed after the reencryption operation is finished. + endif::[] -The maximum number of key slots depends on the LUKS version. LUKS1 can have up -to 8 key slots. LUKS2 can have up to 32 key slots based on key slot area -size and key size, but a valid key slot ID can always be between 0 and -31 for LUKS2. +The maximum number of keyslots depends on the LUKS version. +LUKS1 can have up to 8 keyslots. +LUKS2 can have up to 32 keyslots based on keyslot area size and key size, but a valid keyslot ID can always be between 0 and 31 for LUKS2. endif::[] ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT[] -*--keyslot-cipher *:: -This option can be used to set specific cipher encryption for the -LUKS2 keyslot area. +*--keyslot-cipher* __:: +This option can be used to set specific cipher encryption for the LUKS2 keyslot area. endif::[] ifdef::ACTION_LUKSFORMAT,ACTION_LUKSADDKEY,ACTION_LUKSCHANGEKEY,ACTION_LUKSCONVERTKEY,ACTION_REENCRYPT[] -*--keyslot-key-size *:: -This option can be used to set specific key size for the LUKS2 keyslot -area. +*--keyslot-key-size* __:: +This option can be used to set a specific key size for the LUKS2 keyslot area. endif::[] ifdef::ACTION_LUKSFORMAT,ACTION_CONFIG,ACTION_REENCRYPT[] -*--label =A4Ei?EQXHm#sPtBC^qK%@#fowG*B0oAj4li{5xvnRi4#Uwt{r z#lDuU0-1tC3jkwVbwuzE7Qg4Q$hMIF>eaiUQjh-wyEw&f*Tt&hnIgMS?FrtK&}b~EgXMlekg zLm(aop!|~Em1QA{R!=ljQ#RuGMjoU8qWqLh=!tq-kI`D9RNEk3YwLl=M=0MmkNrt@ zO4&*E8Utm7eT$$X3RhV0`~nsN#qtmQ`Bn!?(qix$NDSRy_c`hf7~H zKw!E4AnK&z;<*!T;6z`K^X!ctV*wroo5deNEbk(|?hPIm{bu_wmm7`J(t8ognl^9Q z36H3Nr&6C-*>6?cFk94@fDszo1D?{=$FpSA z`2LtUfZ4A%x3ll$&F&&$UV|`z8uQEFwnL8U)ZdYY0;(6I3Ik;VBo@yPa$g)l5`6;p zPO5yA^q&hm(z5Jxu`Glv_e9y^uM(AiFqwr=f2M1JKd6oT*|)jWKaosTm*9EO)jT2- z^cy=WTY_%4rqYo9uj-Gr1okm`C>Ix8C9-#t6G>=*upd^^hYp9>GdoIKsJa zVC?G82gJluhI7Gi+d#cwGTsPGSraIlvFZOW)62`{LO3^Aei+#CA8>|&e-;pvk8-5F zhs}JUcyj}2v{?zh`)6K~&}2#k?Z;?n0@m2HSS)pbYgtp43UC?vH&LJ0zV#pzm%9E_ zXnwijWxf;MxLP`<_>VGT1o-Jq6gnEAYxCNqG7vE}b|~)%%c*5{f{@@UMS#5)&xd9{l+m^jxC%)`UV#m0;bM5)F6G;C*PiAL;n-D8eU>jlw53T7)SVx%Hz zpU4o|+=L;~{|a5wC&Xfrq@5iOsRK3e>lkrvq(TJwDjx%6ieFZRR$`6kgJg#n;Nk>h zY)AK9bxtOm1aR#XSmp-S6y4nJvUZq%aYM~Z7jC~4e2epl<-H6d2&hopBqEXtx ziap2yq@AXEn2fH6D0Q!{QiO8`Z6LD7u?sjZC1P`mey$M6m{4@B8UgqUo>&y0-}zwB z0m*`L6)7lV4bMP4LKD2av09BR6$t2>N(fL^PgFzAY|(z=m3^@(E;(kp-b>QSlK|}3 z()1yF$E>dXuwHao7CkUls?*x)*Cts2<3o z!R<9bN(|5Qhk@d?5x_JuwU-^mTD64|lKa$=v(6(6e7^olyak{fg&5E@Vw{aI*gZy* z$T=jgq0e{v?ePL^Ve8_%K4?a7CZD{kSV!+ttxwk9KsJZo)>vZ9>o;KyqnJ%}HSq*r zq4p~@T{D@lBH|@2sW>Yj_dBar8WAfBmeMV!+LS5AUr=dOPX(KeICB)IRCS+aw%$~*_T|hj5-f*L+2kz!6 zH<-~$q>V$!J186MSH07hQ`r4vec!!?FM8U>460E+e}cg}H_w7kNAS%0dU38vr8mnE&XP;9#Y89?`|Jy*+sYeg;it-0h>JcKRK z()aFLdrtNiUw1e;b_5XO?4J2qk0g;qUTvO|3XwT;4D_ z)lTkZTIlA6Calvau*Rv2&{&Wr3Vmfwsi$3D!hJ0+IYbAMLj%#^vLqH1^T>nlS8d6| z1{gk{t=<4I?es!|?}Txc5p0n=3sH38%;q9a&lkYle8*>)-^iW33vDy&JBO>(!=|{M;5``98L&V-tq9)LAmtGTwY5% ziS{5c!5&V6_gGL~zyB07!=1ivOIl~FA*W79Nyn*CuOIR4zN|&PTIz`{rT_fU!7v6A zDZAAJd%p{d7bvn;(J|`$eAGwQE{JU7vM#P2FMf9dfsJ z^+3^e6;$?FCnaR`)glXYk)hS=esPT~0h{s1qlCS$M1a3U${Y=-@GrYEVMBzt-}YvA zTS>9Vu5|X<4VaE}1OM8>R9^cq_bWpxcW0_tU^hP%pk|8Fp|Q?Z*zZ3w8)A@}gk^jO zQ-8eV<(kzx1<#}pGcehx&>6!O87ToKGFDUZ(je!z)&&kUa5%l zmHF69u)?%FP*I+%9hiJgg5_;_)a(=B&<5o{3j#u=OehH;U&C0OD)zhrqAf0$vI@C zj(Vn#x2lzy(tG~OjMIDYL9+dD0e9qyg+W}~o}Jp?l1y;RB~EnX;$aWms;r@r?B2Sb zoov~wdR6&7X1iTJ()nuM4azAHG2ynP>@8I<9jXSaXjJd+rsrDH<)6>vLoCx4gWkHX z!ST}%-uG<{WUfPC(H8c4u>V%-&CguUNw|pA?d)6MK-Vu}l3M|N)?uf@QmhjRDnR_C z!&+x0Dx^YVqsas*QQdPR7mxi?@R2_a3E{w-`IT1ocOtzJO#wsBFvJkw1yj|R{C$nNV%22lH z>oFQ3L?+2AX2=JBaMnB^^~E}KG#LQR1;oVC_s+C9C_$M|bj7Iy@8k)0>q6x2lZG8y zeN#vM8%zKJothkes#O|=O<8k4x4`>eFuJ6l7B{Fn^==JapLMMuPMT5UU;JU~+m+vE z*q2&@MTvFJKV74b%~P_;3>A}6zN3Q|<8Q-P*o7{3&fc_Raz}vxe&~?u$YpNH`J>MA z*!S#!dYVRVBNSZ&To%R52F$^#8(legH+}1iVeaHZUg?FCclonee3#0erHCKO8yko4HL- zPKjNmu|;N$8GLwI~#~t z2yzLIlSkDjG`26L^5`lJpXR<~zpY_9Tjg-n;#yx=vbQD*t(BqmSRrstcC9rZku8c&c6=At)Fx&JvuOK#v)cH%N} z8qEA=C$A=a0i!dkl}0&DrS~@V4)^N~rT6NVj9|!;anvKz)Hkah_}zcy+U>VCX5KZ; zDWW&UVn+!P=AK7K0>5LJtUY#J{gA%R&78 za+)Ar@o-of40vBXGFX?Od7EQIMI{u6xMPj=TwZ0`Ud`c9Mf#3Pp3Uv(gF1!ZNO&^Kt`ST|hf;6$R zV050)p|!i8xzTPWFK>^ulEZNsP1sCe_^52S-l9jgmrF$7PvPjKJN#IigXgVmbM7B5 zfeSpD1W8sVx~(lE2T{nlhf!Xqbv3^jsg&&Egj|oY74hVpr^ZMo(_xkWlOiaDmtm;KaIaiogw{xGXXX|m)vWD-WE=O| zyrTm6`?#SEMkRmt-rh^B(!Jhw)Cbtn%!k5`DrmK1QU}yf#3@Z;u!Ksj%BtwN`7Ls% zoVoYp>+OowCI<{kY6b8v6<}U47YG6h4$$-|y?CWch#oL&@m|q9JMhBpAepB65Z!m? zFo6P0H$|=}9`IA!dvq#ILby}toK~2;84dG-crK1z3*3-6lT)%}unb*Xv?QWXFbDUS z3r&K%XQno8*AhEg59^%3ba}XMJp%EGQn}$81f6QxyEhpF(M26h(`;Coe-Mfv4YPD# zom7$ryBgOGd+AxBVO9K?X=?sw*qJNX%HA-ifcJOpMpmt>4Vh%0u9VFPK(T#weCwz} zjEwaFo4Y{mcf%M+5QT6XQB#~KFOhhoioo9@Yr`1(%ih9;pfdf`R8@ED8>F7nDhk^< zE`z$kA+_)JLGPSJwC%qG#pNMcak_qS45Io=;Wg$Bmyn!DV@6R=`|%&~qD8vH-X$%G z+W(h`hvQ_iY>@7bI_y~wb8@m=0bx*sAtx1B@29c~R0v$r9EIK8J7GDcI)&qghdk^u zFOO`Tfii%%+HxIE_E7>nxI54PWKN05>2|I$k%fEMnH_^izGx# zgx>JXf3k4W5-nK_c4!%#lL||74@OiK3G!grkCH5*#9eAo3nO59cy7EPg6k_-Ic=xM zn^_clq|Wapjt{l&6>f9E6bzMc1Rx07+H zVeH2CMDvL==*|5T!z1ksY^5q-0#XY9*B9%>P5>+7r8v+!Z|zdN}hUeK!~+mKy4kEqV~+=n-`-JNtaISo4{(1 zHt|lTG{7^|L*Kg8znZmS9%-IC^-31KSx;1Qz)2F(tAt%1SMy^6tD8x6rTy6~DV_ld zJS;jCC}h30V=pimba~P)mCIl?bSR?YHyni&mf?2s^MiB1)TS-Y9w95LK;3p-FQ`TP&bUj zjbH|oic`O zY48X$M_qmOPO_xqBkXUO(5rsK8Jk1Ej{FS5HiHV(GJGQbKs}6dF&xR`$#l9Wum_lfRhB^AA|H z%v23uc=TGuS)6t8zii~ZET*B)`@h&4Ks&2(J9$9!&9=A(`wqcj$vpk3EIShS?)8Xk zxzmH7CDk`hrQ9oS!k$Np`)0VO2YS>A{-}=&IW9%nhY;RzBnYF4SwS4-!Sa4WtM0^7 zo_JHIi8sImte{!!0?_U?Ora|0-vaK*)A-X*tWyF-og_*ETW-kkG+u6yBPx<;JhcBg zb}W#l=4ucX+K5Hz{X!8XOfebuD9_tj%l1=ebs#>uAo@gdpU4WBW?&XEb~im21J51Di*BGOx`C-2|1+j%t=d-WzJ3lNxjUgRCy znE#PbqHtkO=)qY7CPLe9M)CR6TrVs4n9Xmj5Id8p68|H|mK{XbznJX&zbx)bvqj-a zXYRD!K_}TFmDn>=a!2CHFV!mWb?F^cJZC&T@gWK5q&@XiE<*1b_8MK6<6V%6_dc#p--2?Cn4oMt)v1}* zjtk#pYinpFP>xb&cDV!lZ;g5 z=PkU|;ReyPD}RSjZpq2{+}VJI*h2=EkR^?^jJqUfnLE``3LlAUaqFtl*|zg`J|xKL|)hkNK|2UYi@^^hd@$c+p<@7FPti7 z9-o(<3{!;dO^T?UIO$ZH;w+zDq5SH;RBR;0RcP-}H|eKe z1h_a`Zi`YC;NvuCQzD?gq04(_TDzp*x^$WtHAPQ%plA^BMJpQF@oEW!Q04!e{{}bW zw5o>;82+Ew(FoO;$Ym+qBuBDX40)|E1X%obk0k(5gc10;*>Ck8AXn$hmpq79m7(}< z0k^Nq(60XYvx;=;fy|_~dc{Pj7!d^}9r0F6@&L18$S)1H{=eVMcLtHyTT2U<-RDU; zlMGyJ{PUEwvB2}yy7TXi8_*}TlxbE4HG|p__~oeQd2EVQ#p%kNYnt=0lubxg=^})I z;+>)zf^Ae+-QGt}pm>rjwrWKZXptFwu-r{Eq)C>btAvJw>kJZ&CBIB`y3m~bM`cWa zaehyk?z&==Pe-L{!^(;wRtDl3nRY0So*x@qj6zhK){>%M;>T=)7C5Bz?Y_ncA7@8$ zC$Cne@^3&9Z8d?(Cf)0l1Ffa&#@BS)>z2LaFx>^1Go+7%8oysly9qf0Vjo~@(P zKBP}^7*J3sjoZ;L#F_VCNi^jd22%KLvGI9Z7k~x)1C!+H5jC5`g~`hC_-9)S$h>Cz z=O6%%rjv44XCU>lnNndW9Up8URBIqy1`Bu2l`vChJKerN*9>X>!&;#saMfUnUx@=r z+$DLAUZm0_R47>i_O4Th6_MGH)@D2QVRX2g|% z4yQSLsfl#ikmsShNn^2O*wTGF*dPS|5g#}*HtLT!3oeaUHGV_{a!t!5?oUNkOpJ8B8P@saeAJm z!1=-~c9^VrnvtfJT1~uo$Zz-Hu%icuZpNCi_cAf0+*Ql;>zQ%H-TJ=Q8{_P6JuE^TbU?7ftv>hHrB~)~W3-M&6_|7rQHE8d z?NP~Y=XIQau-DlRm@paT`()bzo`G(yF$ciZ5+_in4o&l2uEV#hKlI=d#t53{>M63C zCVyR>?nak*r8cD<)CWUU9Q!&~7(cKrK;^wA|8UTj%!ob9KH+A;=nr4C^o!fdq-S{1 zGV#bPIa+`!92;`tMOH7$|KD_W}vznYvydA`;Z?ve>K+CF0T@EB`kz z?6u?jC``7T$6z@vIS93`vVZeQ7bTzne841%wO_%CfnkWq>=G&c|2{&CmMV~4>av3> zAuvzQ|5x=8km(XQ^kxIk-K>roDZ!u5tjEbgyY`x&zU;ReA|Wx^|Hd z7CuS;4WPR-bJ!jYyT9J@{dkUv-Fff^Eo3iMJq2fV9AHo=*&`*gCx<$VW-7HH+<+T2 z4>^M4UZ7r1OsjD)h_|L3S8C0x3jt!lEglj-SYeQ0-#`VC*klsF_nZy@h=LxC18@?8 zDre=e3K^2lE7;kc!r%7bBLIKi^V#t8z_d+%ZY-+Y69C3#ulq?YP)k=-Inf&45XJ5M-QT_ zyVMr&tauKRt>GYw7fK?>!9v{ot;EGwKI2#(Huw&43!PE`N~8X{?a@NpiuGClb;E zeOAiXK91GDZHkZP)K$sYmX*hV6cY7TTaLJD#YZhFDvSZh;BH~~@~6v|Jb-=fr}QBL z&8I4##d%SVz6C*Nj34>SoB<2}TjI8}iw0}e5iO?`X?vDg124Tu% zL@=xpyG?6wLnpCNt?M|%w9nqW4GuROk#xY7XZb`ZMV^*BQ!*uKd)wl`aiei=nrz}? zoL1qucThaK2l!1+(jZ!1_nOcm7N=B6> zKq7>`qaAD~12fT>28h(`q&ZUmUolmr{Totnfg?ny?Ws>bUoiLujHOIhwDV}oCNQi9 zY6O|o7$riI2zNv=hL1-9v#^c{<1xagl4+Y1C*z3&7EteY3LDYGLtavRZ^>XBsWkGF zCFmJoxavsZ@w;t&q!#Wt9#9xvdr9Wp$E>ErpWU+l&5S4$U*VsN3;+Xhx{%5V(kn-S zVk+*LNkf!G80|xA3F6)mGInm{l5`U0s_#=4E?!EC?&h-95Ok~!L*@s7r!J=~Dq8n)DU%kDggI|M$ z9)PDpnbuJj(uv~0NG8AEBNzQ6PAC_ahIwZLXf{$3sxjKyqm@SxJ2bBKevYaajUFDK! z>o$&(Ko6Noz)V+l2Hb_qa9wR;EbAPFUXCABTUkuchoA>TH9#5^$z>AA?<$)z79Y@~ z`2UZ(@*ANhhIVI0tI8J+2Gz2G%S^=|0cmQI=BbJ z>Si-?L98AbN;k4snP6z$)>&oyJ#D+&#*t$xZF6Jrv1Q9fkSMWOj_Xq7Ed!hUUntIfSD*^lswy0 z2AOy5T0ibCII?^PhyOhk`7Jb`0!402$E?9q%a3Hp#v<=*7Fng7@Rl_3yKkhu_|?%r z0a05ysc3Tm%VOBRM}I2UZ-RKA`;3o1U-_&=$XYPNyFJ-esiD$J|F%kqzR${4Wln;? zg{w$ZJU_;O2@}jq&Jc%)?l3sZXmf7ZTQK{72-jxdHe^CKIa+fn4?O*NuS0u;J4N z3VE4!Hid;NSk|8pJ4S?9m4>oRQ{ICtM_VbObrJO9+~HZsEd)&4xl}X(Ou6SzJJL@E zA3?HaUnZ;ee9lFxlG^>2{uM)Z^6BTgEXZWakf=Q;n!F5+%pItuK?rp@@gpJYoR#}+ z*JI+VR18L7n1azHfsGB3<>z;7JUe-)y#4j<523l$X>Up_f$gGOG`2rI^@d!r6gqZ2 zwK)m*8Uk=hbk?Amikge@H2zyly2z*8jvBSq_E38iNx)8A=M(Y8XEsBDnFQ&dr>hpb z1oXlPK02Osrf*z6 z%UM!I1z6ac{tH}+;*Hpr)zvH+XfTaDR7;>X(>fRgamE|IMAw!pZ7YVjH|!95`Q+x( zK7L*?WP1FP6Kyi647<#4TeGVG5b%`^q6uxW2zzU^?f;U+C(6=+q|icglk@6l+>u+x zGHZeZXf=oCK5awrYnghNo+#0&#vhg*?%yK{1WmAtMDo?0@827pjd|i%OJgyxcMJA` zG6%S?;OmuCa`}OAQcWm6g0Ju)^jfqx*L>iCoLh?xjI(4%sN6DKDi3#mmPUDw7Dw&a zpDerm8-Pw<7C)E2&IeqQLktSR$_;jo7Y$kd5Sp_~;hC#f>e4)zddilxIej=&=Gav0 zoW~cKg!fW?FE0AXP0C$Ncnd^+JUgQw$#MuR{iBll4K@9W3hfpf?^HHMNoh1{^1hb= zz3fIHOalew$!_PlF6w1fPOJVlaa(!|4ehA-f3P7l=sxd{mPfW2YTTjTcC&D!djzoy zZwLML;C$0g;G<)K^q$gF_dXqNzCwZ5fL>>^;D*EsH8&A(NHi zoPHGd&Gh|_vu3CeVw}eYbJ(6dthx#B3Z*iIQ+b%`pwcmblkydM?CCFF=U~pE`py5?>)9RgRUE4|eNM8X5%M?{%)kyQBkE{M9jP#M zG6Q((Z=JJaR5{u=eu?BRo;ic8)>kTn09;Rw`CPV5Kt}P{BK9|Px$>0Z2uX5L+g0(r z)u@4DQbpYpFl1Tuv`ia{`(#e#Kv<>XVc`JwILSl0{1XuQ)1mAZ{zr7R8M7 z8={k^eT1R3gA4Tui#AWq_joP~zli3F-!F0W5~k{%qcKvkYUMR6)~cBn%nj!7aq*_! zD3j8)(LgI|s=d&`SD}0n)-b#oFA%SVW(BhvwB}wbAe`Dd^?3jA68ix52Q$PL{Ff~O5(9)hHQl{bOZo*lCD~J|Yl>8-As^() zvnt-_vAPMPFYtfEWQcDPBYV@IAm5m4cC0^D*JoV9u2DvfrdBP>V_vZN_sfS1m|WFc zk?zRgDj{o+vu6qADEz7uSZR8tZkSk<{v$on)C&lf9*TB+$H%2A z<<_S;ty(ex7>lLc77{J1@{cb#=B3@`7HPRb3hFSso7>9N>)X|4&$0r7(GI^@euVP_ zGWA*$lW!BwS^BC-QaOdBlvPp~pikQuS*B&qGrbv^b5pzS)s&*ZDlL~GubfJ~(ul6k zW@vkAsBTKp_Jmsb6O6NWGsQ@gNzGztG9IRXw9^Uc|Q8HmRPY@#~ z+<%kxp?)K(v{cHfR*hxtHFOTgha8sv;M9v>b*U+-jHL01QApa56r@(RfwQ)+?a-nK zjSFU>bUS8fqz1*^v|k!*7!|g4<8R=!TCM*R;j6rQYdZ z*~Ckr8#yPkzqP9sf9|bXw`ypvx(sGCw{_tW1E_s{_CKNB#yzXl9bg$Hy%{udkc3fG zm7cPzFKlr^J8iG(x!5B>Ca~27$KHpqN`rO;fJ57$G}?jS1JKd6UN>MQL`5QfPo&c= z<aKk z=!~Q{$(FCXnUxGSIntU5gPDd zL1Mqw#gcNvI|7Emfk7zlwcInPP9mtCl(UqGS^Xs`3?C=sJ7Mg6G66^CAkgVnO!sg& zu4GG;35W`8^mQ9u+qV~=G<&_VwSwFiX7k5|$=&zPApLn=l-Lv~XlWVN^~@q94L7fq zmv(O==NYz=bPNJt)+~ZrG)LpCG5WnRaRbisxwJP+eY#fsLEVc-3L~ZBQu^LCXf@0q z%>aIu>7?m{zYr|em^3p5-!S!h)nVPP61k3GO0T}4Q4C~r8z>&q>0jyB?Z&xPtLh4N zbK`3-p;h*^V4rp&xs|v}C2T~#+?sLDh7=>^bQ5GC``}`{qt_M&=taz_DrQ(TFB^QfGww5=*(n^Wc zp`sy)R@0hP&NaINsblukR-zE6%khC5(qy;idj1$_)10}!4mJL=5F)@Sj~EHoPi)hFyaWa77 zhj-9U3(4+W7Q_9!1WEd7$s>3%L53mGimQnSu*v613jFq*lJEu+Nj^MD5}P{X~~Dwt^iI|1{6m zPtbNjXfwx*uK1-7{rQ1KJksJPbps_oo_4>Hb@Bv5JPL5$DV)*rdFZMFHP+oy#rINj zY4%kUn@TiD0URJqr#b`~2z*$>SFtp9j!GG*vmpfeA!tdEY8}$OZiDPy!zYoS4q{zk zq=xM7xS}n(XD&!h&EIz+S4t1a4!Mf)aAXlkqzb0>Vh`sb3P*`b>TDD8b@V=+{mWC0 zfH41+KPKGq(c1=7dYWv6w~BcLDjw=7h2Ml|A))r*QPTA_Hpebz>+_s`gc8~_`AlDD z=A>Ht@QV>eFWa7F@3cgAfW*>u1BIty|BMHpv-lBr_Lk-*lA+jL|Z9RMap_C&-S--&PPR=ie&u%#P~0MN9$XXU@Airo@GYzM^M7_rxS(4EJ5m#n6Zd>?8p8ueI3e-#|fJB%?<{C`_s z&a^jJVIEX}1=jh{XwMb45zX84Y=u&_vGBRAziZT9VKg{9K^%w^jFVkml39`1&L?`C*oVHC{Vnl7!fj&i`CAHVQb91sgpYw<{Cd=K zP7}|WE0ZD}AVy6u*%50%nX5VKSlSl$nHa@Kn_+@y$u&iP~{ zbb=W=%rJ$gsZ7s6iRX{F)uKOWX+h3plPR@11t-fStKw`Fnz5sPXLAFKa{wcm-#Cc+ zvdD}`Av7*jqE@&YN{tkpw0(3hj*cx)ze9d$y{t(Fk}3lR@wLR;+nE=#@afb-46xT+ zr!4zcc~m4$9OV~c6m^sCAeJ|;q(Ens7}g2gpuE%eSnW$aO6Q`GqQ}*jcohmvx_9#T z>%1>ka<6YG$&Yzbl^}KSRQQz`l%VYT?xe9looqD>Y+Bk(q`fcfKZP~?KbfOB2WD0@ zNLViNGc^i0qk3|sfD30+3Jovqh6I(wvP9vqW;RXjCiL!p_`XJK;Q72aZp{epbCw%rodl_;!ikP5% zA$VPXlJNM_qR7M4snxd;FUkI>f-R^^o|&WT1dbr8-IW(X)0ZF8^fv*OcN8wp0)WIk z`VvqD9^_sU^G989{dg6-(#>$lL){9^x6cKjtr1JB=vhlniY}Lxsx!E{$~?5W?mgb^ zyfN+qoWSBrl2`4b@pHq?+hfkc^_ma?OLH>O(%?=jT*YWhy&KIF%RRZCZWjMxMfEy> zEAe;SA-kvW2bWAT{lYQK6J@M7Gy2F!?(fN5&~<4tlm0wvH%v_9iAXoi^SFL@EDBgM zFk~Gvq6%nlI0c^#();aoxG4<#EdZGg#Jzwu`lTq^Fjj57&pT(aJP4~A$?mB$i%QOI zkvbpJW9D~SexJ9x3*Gm3GyAAxNKzUP3@D~MhWrNK^5LMp6olVixU&0CiZYV<4%y4=pwm~n(DaDJ?uhVSf33URy^eHv3*U=!;q7u$(k$kNbDM@tS zVs=%7Xyd84Q?_TG-1674eBu`$$6`$i$T7?eW=CmW-B>dcr@uDjaB#PWY@VGjGDS^v z*9tj~hda5@OLjU#$GIC!n^SE2wZE!&0}No}6YI9T?<1EOjykUf33cSg0{*=O|3hfPx;*$)XS#GB zUkz^!V~ApkTS5X%9)A7Z6UJgWhIdv7?QtN}5W-MEdSET-ClJGX&xEKy;P_d=)iwjV$n9oHc_m(ecX=Gw{ z%=dVsJJGaiFF$Cj0*BIY#drWn1+yPMvV?qyIwp*qqvxavn}v%~Dz59^{T0=ATdR3G z)26baN$%~#6_9JXb>;#AjsE2zfvs0cuQDU<$^m14MYw?$W~0tzffq7Xs&5HTXCft{ z)RaiHJ>d7b`MtCsU8J32to{en($nLohsIn?6hC4_p?hZ;afo!yv4bgarKCs}{?JM- zfwn{tmkAK^A*;blL2F_q^=!Xm9p1=EM?B*9E{G$|P&wsRxP^3CwW?_$x~m)_X84a{ zM&+OoZwVG6VIr`N2G$jQ5$YNKcAyVY2C%~gzOqkt%>6Cz_W)+>EhKrLP)e$}9}*fQ zCx|rG6MP&;VP?KS8p6CcrD7F=3Ju5@&Bg>BXWV}93~)6*Z}cwewD0Y)qQ3%WcQ!n$TTzvlbnDRK>y67fqPEOHL5Bb z@wfbJGa}+rvD+m}DKxx?s#y9;|LB3n5TGhPiKFK^m{qYfDNOVsTgJY7u2@eqw3VyN z=chjknuT0kwbt7Ar-qJs0uQ|U^TA3}W z_F;}uOx{FDhZ>O*`1hFnAILUfx$OHoXA+!t!N+Bs^;x;&6}4>wJra$bS(rK&B{=@7 z@a=2BAd`UyqwO1~f?ar?*XD#!xlbd3$i!)?%ZN+PDCgXgHC~RRyj5iF)Z;#p2Rt$V zsCwks#&a4Slkn8);GK66Ic3*+1%N`TXzOLkPD6d%;1Z%3;@$8tbJzPa5RF{S#Q$jn zxMpC@gk99*iMmI0I0@XBUL`*ZM1xZQs?e(|n!*Doh}V*o?D-f6I<=WbMqeZo?5x6> z@Asn_6oBxd^V*KxIrr)M872#fg3Fny7KHwSU`=7Y}!`7(#k&abjf1CBaVZ84rZ+ zH4*Q4a|aLQu$F6?wGpml1PASP-M)p{s+UNJxK8AZuAM9_DO%VJ$9^#grJiXFI``Q2 zpAE!&FGz~Kw0y1_h^f4g-FbanG}KupZFO!_rpXQSPEoqDck_t+P!5LlQp2jh)=3oF z40Vi+3|41bN!i=fy_|5e5Y3>Dop-uG3ax)Tlq<=pQc$JO?%258em?lrHJP52r ziEr6v7gQs1*fyn^JOy6RK9%O&d6NCN2A$=J(4^h;u}K>7;{F%;kqalxLd`XeInSqB zu1^3?Nq`traQePk+{)QS{Rz2oz~83=vqpz16cgHLU{F>D4IX1YGbU503pEQ_R<0Dh zP7dCMG^JdYtlibg+}Y;5w7t|4H*wnh3^6WvJ}C2wfoV6oo@d5ugz)Aw}GJjX`G@?7xeAX6;HG3QPKrm-XMd8D5Qk z8LGYETFcm{w@z_K*=pIiTiMa<{64``UX>P>gc?NUc2^$ZlvArE*3?OmR6|JO8QZ-T zNQPOJOGrXtjGAGnauk!1>c7?lX{PFh>wPSQwjj5TscS77FK^3LVuqb? zOO41A)uc6C2ebz~M&usBBi%H|2FVyRe=6|_fxk}&IsRbrjPDv|Pb1j17$*C~5iO=u zICu&w&cw>%1^>~#&J`HIRs0Tiu%D%FC?SQqn_!c?^_hWt>$qp}$KI(xt59MV!8bhE z;2NEp^_=9ewf)E|ClzpGVsHO>R#8+Z{j?uU{ULmWCM{{9?XfhBQXNOPT_a=zw!A`( z;@YvjwL<*%JzkR^?x{wMC_Yd|z-em?mZKWO1sAUkObkN937L%&(RrfEs?cHpOs%Tg zhSJ?S57!MBP{kc8CmK4@0v@ThNFVQb{NH1NOjhG$^Mn1Ib^%t4>>4-=Q%HdG zYmQUCI}XwMVWxq&7dOXYL6$hs=zWQRrzcBJY`Ocbgk1CLa_6j$n?!!UfV^s<`6b%r z9O5nx>``U7?34f<~|7N$i<&oA|Ibtk9C2x&FWTL<}Dwrmp za`BNvm=(U9@?DSgF$HV!yZ5T`12NYF$-YstfhoSR=&~PxkEy&Ak6p_NuzT4siTRnE zBBw1vISjbQX}r-;hj%3Hy|1+tdUWIUXGIf!7=pzLmm-IVF!t{R)FCn$T;xxIbrye| zH0_wi!)lN{L7s$}Mo1tv+gF?3Cj+`{*s?&tzB9OoVZ>rTN;1Pe;Hfu}Pn~hfh)M+L zWLk@JE5*GQv@8ZTFWaZ#lKv6DA@8YSag085yoWxr`~7jS}#NO3>_Gi6m}@@=Jr%|M>KSVTPJ$wza0%OnMur-S!(qz|j$yh_b&=DxlXmAr@*F zpl&NMD^~rm^j{DOj*Wj#X_dZy_=w8p9 z$G8j6084R6p!QGKpM2Jf(_o439+|_!7;ta*lh6CxS1iiBg|0Pwequ7RAv2SZ$`zLC z;VB5(_Hi*HgjcC18*?+HxHD_e8Jnal5hl;bQpT_}QQamDqN*wG4RX0GAoYi!ib+5y z^BZ)ES|vxE@P))sXTOkIv+ya`%js;y-H@>d97{~+&@^{7j|SNXJl(I z4&z%C;AXK(l~H-ZgTwbsAA-s|u~6PUCWE6P-i~FUBOwiLf`1j(SKC;UAxmJjCvQ&L z{(`no`%0ujJ7~hUUCPVfl|l{&PQ>NpK!12)^%Hqu{!Qu(H7tJ0G0oOzOAHm8dhLon zni#)o-llQZUz%T1n(iW1<2y#BZtQJ4yziSL+2POWCglfb$0I4sLU)(@M2~w7eT&k^{g_Zc}SO$~J3cOhJkMS|3Ohfn4NOpvm zWO*TD(=>X9+X+pBU2qIBINXn;-%4FbCZtw8sjDP?Uc=Qft20dFHSB zPY(R&KFTgmW&B~81nTwpY1s6(lrVXZ3lc%=KL#ZHK&_t^T6RtcmQ+Mk*t}TmImQTe zuwJ!2w;eKV+1S5Hh^H{N-LPgwmWi2e0A_e;QRE|6?G_~LzuB|v`b!1?W?|u16 z1Dn1e_5wHj`BkfKR{HM?xh0hU$Yo6!*RTwM!=CT{0FV@-<_wHDQ&V7HNiruoR9bu8 ze)8G__njZM;2PvCiN!AcaYAqXMeNP)A!SPUJ5|C^Y!Akw)<2+D8fIH{;DjQ@nV4v~ zU=nXl57ET*DG;~D-cLLX1-kqdoG))^1kVL33(B6(ut|3mKp3K4w!$%Q1y9kR%f*IE ziNLWSN(t~=m%i-# z5m3KCUyXuDsHUEA<}O$&pI$o_8Wj4fd^ExMJe^-YPahKk1c{E|8~jc6nKY3+F-iU^BbMqiHShuJyy6F5KynEUfLZ2PKi zzc)w+mpzDY`5AE2Ye6PMdk|u?I|jJ?G(C?kr;KD?#&)sy(@a5Jv8IOaV&oad%=|Mx zlJNSesn*nEzqLqp8Ep3dW9t!c!+XQ?oBlJw#;vz_@x!fA5n&}C&t&%$k=2gmS`k4r z0dvC%Hb6)@rD5fF8*y5&NpFqsnVSv;b+(;R1Qc*3z;UppC!V7cQh4Bns4pBMUzg=* zfTKIge97zZ{lBx1?jbg{AQ*!X(CzSE^NYXzKg?mQW5_fAEQuWFy%Nw4gQ{l`5Tue5oX(`_cZ!%M^WgYJq?G~m@N)xQ5u1CZHH znak@!r7HQzvLlQ4CY9z3kU2FPy}%v*3QJFSFd_Dr>J(nQ0tE^}ueXA&<20?a44diC z+8_bb|4B?BO$(;O*<);8ig8pRs7(a5DCJ7yN1m>^( zKRRBHYhf7wK!pFSpJ^L*5IXvK}vnFs1TDsOOoA$t0ZZ9G$G?AI!$UuC>Ye2o-BtR2LIcB z#(H9Gs&G`SI6dMUe$Rd-Fcx93{lcJr?BwLfOL3;FX_;Y0rf}8Xd6kFut7+3gik+X9Duo~&eWn&GrR{_h2px)Ep#b@J;g%MeuAQ@1B@@Y%=k|m z%vXm>ayy!Q^6fo@%3&Vhb26BT7MOjxsJ%#x{B(3qt3lOZOoYYL&%%0;|6+y#R0r|= zh9kWk78WrYFG04O+;WRsn>kdlSyegVR_g1#V8YH**AKDxHtp_C6^A)-atej3eCmGp z?=5dCSp!|3)Mx=}airjeGz_S=ttGF1V9?Bvn}@}nL7@GK-}ZrrnHL*gW(U?7J%Zvz z-etIMXh(R8h@QAUrvwr+E*hAg_!CepHzwJ?P|Pi~tAAA|g41H5r^UgwAE;9NQgYV; zGDYB7Hnk%O@i|qM^^Hpl>Wbc33RBI!6xi}SE|RAiQX_Uv(GkS7v$wQ_lzD3IzOCL349$A~P=@Ce z9Jw9CwFZ*|#Ni&xR?1Y7Jwdm@t_A`6k9|5!K0Pu@$<)y4)3cqGL0;lgAhMEGYNz&Y zFf)f{t>WSV39>jr{Zl>7PnK1YBs`)??pMK2@_tJWmJN-oji0RwF+(v5qu5p8N z+hY-#k@j1P*@Lo%hb31OCXZE`6q2C9E3PoGi^~s91 z9^0bTqt_J%lS;WqZTreCxVMx|sTE+ZzLySr2_WrNdw7y8Kg}9gKB{&AxIR`qh4!#l zr%!N}ZhcDoR0Ivo8B ztm#T)<(R*s`xxL06x8|C9*~h(!UJO*GG83o_#&;-22=SSsVc_qf{>Gvs5SqigUp}s zM;Lyhhb;XPZW89+eL~igyv5KD!5|KdaU-@yA0ET0wNboUX@EC-JK*Jf;mU_T^d)(J z=#0{Av-#7jjwe#UTe4qVNGw&y{Qo?8%scT`ZS`Dz#D2Hu>Pbcd&c0JLR+JhFc?5g+|Un6=%a7kfpX}c!g z%k66xf@F^mVP6AmZeRnO%@PFbAk~6>n!OkYJ7M#`kgkkx!{Nu{;Y^Dz=ND#l()mAwFDzo1Xpf6|nEJM8$@JlY1# zebgxh497|Y6-)OacCYyoXchg~ls5$v$tx@HC35klc-S|H-11~71qb505Odk^y=Hv9 z)0+83u(Omrplo+{qJDs54hdJG6!V)vo-M~6+i=VY)H!NzTjsBJycMF*Wt z(PA3TBU$FF^}33Z^=RVdI3%7TljCQ64ohESCx+*$4bQN>)jRVe_+BOjvNT}x80Pp; zLo7tck)ONrh#G~-Y-0LeVm}4dxeR=I>JauxOqqa9Q@#=Do^mZU=FdCt^_(;ovQ$Ya zN?C$%TJcE&$pAEr+!}UP!7<23!NeTKRoQ$d|K}((mP~t81|UOq4H!_PJU4WxtNn2P z-@5S()VUeph$YO1MJMt|-rD+eZW}fV4EWjK=|J&j`KZ+hvb_Vz{WA@-2Md_vbmh>08*Pf z74WjL4yKaoRMP((+vd>%!n{K&N5oLhz72+%aZ(f#_Agi_MqZDq9wQzc&Ug#Ga^ek9 zOT4eDLQi>=_%T{w=x6u&7Q0;Ta!~CqmwqrtFMRTOV+y!!9~OHvGEE3GuqIGN`)2_G zPJURB_R)wAK59eNf;52*mAq-`FJo-DWT+7XzSxb+bKz@w^F4AQ>g@FEZ?JiB44Hhq zO2G&K1uwjoeJO;l#95c)8F#tf3^r0%d=4m$?r9ZR=6d$g0s->$-F=#L3gt+T-qm}< zaJvU6`f2(LCme$Kz(`9UfKjs1$Z*1gp&8EDcXeV2G8JIeG85!@AR8MbX8M3!Z&zY!>kCDjo)7MAOYO21-7jf#JuXjg zu*K|$9dwB=^^agi6W8tKCL@u&Fzu`zC~KAq3nEvw?xf)FGN;LTN}*8vtGf@}zdLZL zb)*B?k^?9(p}(L2{}R*OD@d>CKI9Lg6lziRwYaz#QJe#bJPSpC1B7-}QcMrPT6JGb zGp2^>s-H@X@u{$jKjj@z=}@N5E!7oUu;@!Zrl0T+$_r5jLQevt1x2j?({CsK3JWIu zDfiEyJqKEBdP-pOF>hrzVehq}l&OgMB4XVz+m*9-dk(fq*(!7%T*o^MIs{zUu*6^2 zh+a7$4(xhJs63*Q$hLSK!!^)8tQEAzhZnXrI}{7b#wv3{y$)$?J3F9n3sZ6y0%*b{ z@w+pB6-rt^MEE|7WY;uW8LJ8Tt{V5gK9%1?*-<HfyKLR` zm|#t3+$p%kx1wKu*R$8Gje#L9!Li){9`N!q-EWBJk02RA8bi^0u7HB zaC$tD@H`|=Q)!KbAt;)O7L6?|3od1nf7rn5gp%;c08XsU6 zTI2z)J4Q0KCz89kfSQ&m$w~hF_eflwu}Qm)!;SpgV!xYTViPi9p?QcQ)<|gp!oep8 zEV0w`lqZ;;PC<}LcncaVmvm{kR1hRNy&#^;_%JTV`oOE7#I*k+FdmdM#svhR-9Hb( z6S~gd`!oDxkudEDbgwHG8AdeoNgd^1d)L6^Y@Gw8y2KJNBMha^X8#H6`&GE*D zqNf&EJhM3eqYKfU-4D8)H6dqQR#@)Hmwmd}Wey4l61NxQn)5!GiSL$2G@=>+JwU?0 zfS{`!7vZWr3(wJ-x_#FGp$sb}i~}Jl6|Qhuoisb1-sIY96Il!yT2b=nGr>p!PQ{wD zE4sxz;ZR2F8)-! zhU)3qVgKN=@voFhbe>9#d9xs_n{_dUuLh>&AR<+fu(kLtcVS1rytK0?YnYFu$_3*o zigvQ(Kh;Dn~bN3O3;9*|G=0ezcI!2A2bPb(AE6p1EVUv);zIQ1ddIg;haPTL|AP2aCeIm4u+?RBgG4%ynil=lV1Acq2?05bt~PO{ zJzX8<{WxlUw|c&T-P}6J?M_(RJF)^0vU^8E9n5q=3#Hz$GNVSmNWD>Pc21$&%IT7s zlLGNfvih&ZMQJBG)n|=6iwKS7)qqtg7a8xQmu&pV4feSVLO_e9$~w#|e$e)?u%XMG z^RRpfAbBkPQ^TW2`j@j}v<%F2QQ)@FUd>EBKK&qXQ6rsb=nT;CO_1{Ev{C%OVsb@t zuT8~>p@G%RmF3sl3ZHN(GJc_aFNKoAKjMrvgSc4^jjUF6RRHnqQyNy$1$yakMd(GJ zelf4!7tSLUmAFZ9;KjFHv*O=3@@c&V(kA zMk3@cv_4|g@Pb4&!QFXFKkexesIibqWP*{+mjc})Z+iU{U<6lxUVH=u^B?4964DrczmpQ8<#`ld?88@aznQQEinN}2gAALf0M6O zfp&F!zLS?$*|3lL~-87>?=!I5hK_w1#+I-d0T); zDM2z_1F7zI7`BJl44Yhp?3#t?cVQWr^)9N9DvikLi{7Ni>gg(W$8e)+i$^4}w6~W( z5@oQqP}*Rfbtbq~)(o*@-|i)Lsep7MzVyE(aI`KzA&O$8E7e9qiTR)iZ02(d!sXDJ zq*?`e?eFMJG;rT7;%G%L8@N+2Y_yW>iA$9uQF}n~dizB;A{a;$X|KFS1i4ovm_(qn z(6;AgfydO5cZ~&n^=Kkxu{~kk85#g$u~78boF${SkT>~8PlZCu5rExOo)|4Y;EL$6 z{2Q-;H$f`M4>l@$*;?ulxPjn#_v{_<5_%CuLa(CNk|KVHZaP|n8pTxKE1EI?2~HIK z_OZ)eG<>k3&i7zwCo7~aiBpV5XmoYeX3Mu9{ARj9(S_hxE4;ybOO&@a-nT{~I3S;M z%Yf!D%9SI|%CE-SPcu3zK(t{+b~OR!L|BI{_|s3~&9>jUw<%A8)<2n}3nQP*d2jl` zqYJ8(Vvhi0C(GJukj*{Djr*hO3dpNT zn2)U~M#C;@59{sOMIPW9`*^F*B_z~ReWPnb$5k4G1-39cH$G-^q8Z-y<2a5 z#uKsZ0TjRcNT2m8YF_?ew$E4mK42<<>5+-Zcn)fg_6@KH$3+=E=o3e0L0BQ>+wuA^ zrE{a?xL}ub!mrr~h$We1!D4j1?aM@KBtd11BVYCe&VZ?9czL_X$gyKcy%_FEYVJto%Qqfnlw`BvG8awy zw)0?OUt*n|0z!op>ITutg3Pxz!kM8Lq?Z1a=(SD8V#08bM@RyFl1{RiBWlyeaYSXWk$?U_qC@#cWb+@S^_$6*{+ID*cOA;a83*m#t zbU)gc>hvE$;$}_2MMcb(MZ^&EX>gdBZutqF{QHV+di{v2Zs55Icxn^_p1T-`#H)Pd zwLDh4vfS&?qx@1Iv@$RokehzUU6`~>oSNGIom5!~W0+mwS_aetH?ZcqmgTbLYcE6b z7PAaI+#yxmu6%4Tc*@PnTVByOF3ZO@{cqg22~e)^;NL9L$g+Zz@vEOzr`gMwJC?aS z@*^gTC?*vDH1uznD@eXT?fI5b7C7RkutStkV-5K9ExHQ|bp)`CxRS07T`jvcHWquO zHy+Sf$S+TO35Hlpayh~U!u8mGh-6l959isq1t$sd7XCGBLku+v1^|+#RG&;`&SKOA zcYJ#Yob1?GV`m;NLC`QnkC;eD9%2rrkOob-AJAM0Hw9A!N(;WEG zTyUohGr8Mfs<-H3BA)PB%}{~~hogv?WF~a`G&>D*Xqb9&1)1mUV~lw0+(v9eh@|p% z{>CD`8)e@pq&AA5;pB~=O`*doRS5U^16MqqPRrIY$VnZw`BWbw0>48*Q%vjNxN#|I zBEspwK_w^p?D++IP^h*8yrje3?Cg{T41b+!m8IT^WRs80aol@-o?!)K(n3tCT~x8F zHBe|jY-oVquYX6 zZPPmffs){4#SuPaXmODIYtNQ$|ko&XVY8ORy1l(~V zU4xzeafkLik-3QJpo|`EyYBf$AW?PWX}I~CGFqCT*AWv7TTcvywgJEEx-HrK5=f#; z9G-7R)rwM_mt!yJSl5xsxrO1m$>Bl`VH32JqJnw8UKRg*Cv&DN+G%D<#W7-fL+&r zJ~96SsHZ`f3aytACIT;YGa5bp3o6-NC`ZCa+2HjZG$oNE z|Cm1K@Ai6o`JBBt44X({W1bLjV@2RRTuRGK&`EH4Hhg#I$X_|ACndw9ye z=2gR0LT{;3sTQCiRCheD5s`FC$43mb zqLQ%<$BNjU?dOM1t|Qg@Rqr~#KHeZ)EP_?~4S1#bru4l}dO||dbK(>p3%s2i%p+CW zk+N_J<2!(g(!XKkb+3nS%*-|vT%;QY2WC6rYNze=804`p{@Xg7Nhs##`A^+{O-vkY z^|H^x=>$E3w7Cdo$2B~v_=H_Wiw9+jp7gloP2uqv~jNhVCI< z&ySpy)Tek@(LH837u6s~*k0~;SBSKIq6HpEn{BOY{efmIokaijLxe;koDLbz}!|vaGSZ?hqzs(HuV@(DC3Az zWw3aL5`CZB_bkz-uB=kMdX|nSrRM@}AST&YaopC|MNu7tHr;YJBzv`+u>fDSR^uif zdPXMH0rlN*>6er@)#7KS&*ILB-OS($t8KS} z5tU^{kqf$M;u>sT3!m&=ua2JB@CLUbR6>belij!ed2!g;-p^zVQuQfBRC8EzBk+O{ zU%+K2Ynstwo3G^IXMt7(-{_h;rE+EIL**|Z6EXCxpsNv7C4~ZsRxGl%VD;vTLsEQEtEz1=*Yptg5J||Y9#udeZ2iJ-bA9G zNU(2U*iEagWViwZXHmGRZBNxv*wD2v+tXqhr>!-jd8Qe0o2nqZR?Qv(JiCb%@O*SW zcMp7;u(^225O=gF)|?dYK8hZ-m^zk;_LZ2OR6cQ+znEwD=1F~*+nOPYf<@xF+PCkc z{eqQ|{g(up%2<9#x1O7Yd@fLWpolk;ve*BuB0N|v zxS|z5Zo#24ce-e9G<$6bE+~!r4+=)CMov_3wzh;!`@`_{Bv#FUJf-2*5Oa>eoziy4 zKNlJfnt@*A%vpfQ+aPbhjyMWhG*<3TZ@eZ=lrFgUgso482_cKmaeOEJCftjzqKu~< zw*b(7uu7^BmcUF)bc6UNqYX)-_O1GLYuzxn8ZKxrX6;yS@K|JWMUYf zIJ96456@<-PJfDCFYA#*Rh{{l1j>K!lA2Cx+w+Mw0nEli4y2d>G}dSbAEH^uyE*C~ zXtn6fD|fg1KdP~nwQITdO7SkYxvzT{WRxrM>4x(_AYdT2%(Z%=ZKU8Ugh@siO!emq zckD39SNebe$)2T&Oh2v zL0V0!h<;B>1E}r|cC3itxX)JZW2!saCFDt)Y{?=ct%Lf*j5p-rtkqwk@TL1y-1TPD z1Ng%Cj#7fdi9y?3PM?n@Yx?Lnc3>*RRCxR=;gM-O?@rcI!TLBObQNLLj6a{XFO8mk zxp#>iJ?rZl(@{{6GKl<=a+rj9&1JR-vzXq=*l8=dqKWcM)0DMcR(4t2{<3b}p1R_t zOJfZVbDDS2aUI}oTB(wa3$q+RH&V+XeoOn{YT3fQY#y-zR3QT|dFpk8LZZK;J40&j z9#4{uGefiAa*_Oz1o7wG!;{nv;}|tTJ|8alPw&C1I`SWpOtvonI{6x}Ahr&lnH=?d zcZ*Zn#prX|dC}Seyu_ZQc)706&aS^&@u9e-QF2-c_P*34)2#Sq*H0k2|MunnWMqb zjXMOJsMoLshXsUkiYy@{Gn`z9Dkbv!3k$2~7s`ip>0=?CX7V?#>-YbfP#n5>N37-+T`S$=ssvp$L8||2n?Wpi z5rkZha3t!!ed|I*z%9MJJ@RYor&q6SWzh|6txjcjxh{$ixqbgu9j9M#CQuhX1gxdr zSZcUZ$3}&#W819K*J-ZRD>r%B22fI930hD2rjI}ZLl}o0FsOvNH+}rVNbjk@{gyKm z6<*6js86|IKKkty_jlf26l`kk2_~_J(E(E;`u$QlMKQm68{M0Nrz`=0pk!O$EfS z{WMN8Pl^RXq{n;WUPbbGkiQjNg@gXtBJvDP_mnW@GH32;*6>o~#c&+OHuZ&wv!0@D zgmf&}`D2AiZCb81C=cBv8$XpkI)DLyfF=>KbAdi^>VYk-f^&7*6ng;)h?6RminpDh z$@}0qhA~SdJ{@jW|Is*Kfl!5I!1ieHzq)C(bUN^s2#nb`AdMf zh%tGv=+rg%JfES?k2i~4dI>y{%iSaF1tiPWC6q0~$4ATXLLxG78yT&y32Em@`=kBs zE4gBy&ilo&uxM*wVd!Y}OQKx+|FF_vpfVL`^~=5tjcFLXAm8-|=78M~Vk^T<=zBXx zn!N0fn#Pk7PG764nF^0Y^#WgTYcK5>Q)&ShM=7zcM@;e3x$B#=B)QtHdvB46YM`N4 zIFbWIv7MpZRoCODG9*|a4Bft0mV`p2@oaFv}j^9nPTRrL- zN>R@W(5(eaw27RIg&$lTn?6ToY+0Xi{Uc+8 z{0EYvQ_yT=w&kRv@(d*Xw*l`H+9=pa9{^FvAICOIGsKu%IE0JJa^(mLD=vPn{LZ_S zy4}4%Jif+>m@A8Pl0u-$ za{@FyA&_58VGwHdewh@;;4#=`{LWkInmiH)M0Vu8Sr+=KCH9xAy8QnjwclG0pnTS_ z(U92T*}!f=zGJU8CE*`wQ53MU;g4FS#BX?r{>G-$QCWJQ!A6!%&8;Vp#hGt#6sd;= zNL`}=9;8lKDFZ*5>Yr3gi(M0l$EcXPGP*aA+d?pEatkz@6$R8CpvgGTIYrQCoQeJW z7{|$d6Vq)gd?+fGoi}*`?-h3joCo)GfBZ&x3z}{`-kyO`k^*)--8EP`M`h6z0S-#e zvUs!p;0n*Iv> z>cN(#mn`m_!gh(TAeN1>Lp@typXTDkCI&tD0W(OfI*u`lfXd02(CK#6Ka@XhOT#tr z{05BUJOcfzBaI}#c7p-rIY((noro#1F8ai<2Br%;F6QBz(b{748vSd~%``{9Abv_h zWC|MlSjQc!Q51mQvacJI{lRA!GVhtK1AylTu#mlu_GRr96kl&4y-3o$9+g0kc zI~iQsLBGjo4wnvZne6|aq&SgR2OS8RF3E)@M9m2lM;Js73zxo&yMBt&$lY$hx>aFq zIQ((hB3oXfH+5QjEONnp*eh~!`#wKIi1$-fJ6g*kiXCR){$PsER&fA0({{kM7Atx< z${HvrT~;cz#~r*la13?ut_37u73=KTutx7NpF%+i%#yIo|0U(&$gPogIL54X1zZYb zwC}NLpUr*-?|uyCAdB8drxy}3n(wXWy$qbdWPlr}h{~h&F5zZ%e54g6dY5z>eG*36Fl4+ma zxh@Sbu%2%N?xae&Mui;3gZ+1JAy&9cufVn9n9=-$%`_~|DG@M<>-EQW+5A`ktfhJq z@B_g)36L%&YT}J58sr0h^Rv-3sos~!?nE6X4$`+p(tIt8xoYuCYgHDIiq)Vbzj3=j zwrh4PF+r&4159*8dX7%JasvfcxdA>Z>Uy(CcD-4Onfe{T3pi>CNXcGp_Ck8s5Dgk2 zUMIpjwh?hk$##b=*bKRXu?z`8GDVXlW&L~??5((1PXdKMq}tFMK!z^JO$WdjJcR%-(F zxaR`f;YFy@M|qyy$=!Q@lmM8karTtt#pLd8TU?W3%6jMBP>71hQ^&Oj(7KijSz(25 z{cr(nsFeCxA99;arvlo+XWJ|_vvh>VJUDHJ2mo*1+VW$A@xlq+_6RwQO(yATGhM?5 z=Dny~?LghuCu-@pjmR|)N$Jh%vDE60zgyaCQO6w-POm5Ob*nyrl8p@lzKO3GSU~0C zNLZ3+^M{lA^v0_so0|Rt8i&OpFZ5g?G3&`5B!`@*z{c@46im2|Fc)Ks3C>!tgQ`Qs zHFTwFsjx8v=Mhp3{&~~wy=Zs~dT!VW?pxyX7F&6+T*f5-kY)mdB~GeNCpT{kq0Syo zpzRgey@o@|JZJvy_BWJFbpRhmnM!DmTuyg-CT5B1&U=p#o~5fC@_ zG#17%1HPCyR2XY)I*P%;15;d(tPwxemO6kGJ-@%mz%#uIQqwG?iUa;*8qdOSvD|%M zowH<1CG2i{Y{a>yU(wX1*QPLTkJ?H;X}i6_>(}j?%$8{D?ElljlY~xFYC(U)370Ku^?H7ng<^P?RHF8aFr0A2&Gy> zATWIbp^(u*9yUJpB#E36AJX7?2Lp`Cu-hN`R$_>PrXoJ1V=%9%@Q;72Osf4iUaxry zc>5&jtpx%#E4dMiahr@CN7N3T6J|V>m~w-n7QmS}h^M*c1f}DEHWjT5nj0S#QWMl! z67?nn50A$z>;nlWAw}F_tkDlgQ&-_wc~Cn(Tdj&;Z!Lq=n^eBVQVu8sO0Hjl58Q;A z=^d&0s4MO+zUJo_s7s$#xb`dL3ixNc& z{X34B{YmYK?por>R>uuuneOt)PngPZQcEI+ASN(cNYZLJl+@@Hndde{gmaQngLa$Z znHoRAfR2k6z3(v_nfi!(STin9e&e00`R}yGZ(~`eIH52n^sp(M{c*|dY7cZY0G!!G z;QYv-ybraDp+x?yqv@RBL7FodO@SShJC2o%8ODzWgGTG}KBz7Pr`3S8`QQqkF?&~S zMV@Pvm8w+?MgFQF^8B2&fwnt*HUwP2Q)ko!rP_`^$&|AxtI-7g0}pG_59TX|eH-1ax?#A+8Dq!`TvoUp(`WMU zL?O>EB_dw;KaLWPaV!rB{}`bPqn@Irnf9gR9kIo-tp;EkbS-97^fv^gQEMO`;XB28 z;NeOzvLdJ|HCv0#qWHBimt}LH7llM`g#B_LBiMiuexiX}IkdxK+yA#m4mLe-EPMnk z5G`Gu)rySPK}D-tldiDa<{BV=GpL|EiX%ex$ID4){yMc4ik3V|O4K@$KYQ^&9S=Kej0;KH zR$3tdh>cT1Y7cfok?rSmZKGSQgocuRW|7_RG_r?T81tD;W18Jv+ggVy5))fA+Vwr* zE!y$;uH38id4$3`luIB9CLKc&Qf4D>e{u{p!*OI5;x)p#wPFwGfQb_*>st?kGAwVW zE+);X{`dsHVsQd8ocO$@B%AYF4^cbR3>)EVi1Z`CqX6yp^KG2|hrff`Ok zbv`5PA2OuKv7QSs=7Ah=Q%9HOwJGDoG$l(!dszlKprvh+fCd@hK=m4b>q{-OuS_*m z&yl6uW=o0-bDQaB}y@X?J9VRCgVEP3h{dgtLIH-CAq8n*T z(9ffW)<{2})*H|iR^(R1{r!|^j3NjQuXl6w*zs;GG}AKjN(jzU+vdUKWTxg2#t{tt zfkK+4#z}PxcG#Y1!1-hT5QxVy;3T3kT{+4jtjdzaU795^lRiW=DqCuiv*N?9#n2gm z0~n0+B%xo8$KWlBs3{F|dOh%}U+}8&_Vm$WR|KL{Q|aMRiNj9M?Rdn>PB69~+KrY5 z$fmClKRG?6=cq)MjYFWFkwR zqYcnL?~*teEtmBvOf9w4-50c~*F4tNAhui>fDYgk2HCXq5uzcQr0pwO0HxlZXKe-rCA#}g^ZpUl` zZa55p_DFShIu?-vC9aJ=_$RE7(F?bai+J~aW0KQ5UcT;u$Hmb|+LCKsoeO6&^UaMp z9}C6yrol}?U`}O0qswb7p)vd=3u2vIPH=q-#Lr}!>H`rc7J-!!$QKrCD!?w*Gzhe0 zNA0uRj9d)v*;UO^rsyS=v~-?{{HviGqqxSG;*YwFsQ@%qUkf*(`tX0obtCof z<>pk?tQr8j%n{a*olG6`eNX48TDqcJVEnpI-`$q|@A;{-1R_cd$a;J*>1vo@F(H8t zOQp;pMeZsa71epBJGAV)?LmFCu6|L3`N_U`#D{P)WrB7T`k)0s!pN2})-;U#@&$S| zTQbEKP6gzLJQK`yaA&Mn(S-CwdrIUnFKPheWTNykjqw$i`E+P%BDR$)NI*(qo?xF$ z#o%XH{zidPk-Trh(ec5mAQQ262r!pR((+@Uz?Sp*RbqP7<1-}}MS#k`-bnm--}pRC z9np6yB40Jh$XC2)3Y729ToKnQpxv}Jx!2myXZHnBsQn9lm0YAFmfo@}G2p*&G0cK- ziwffMvf2jnXvb?~1!-Vq_mXW*u8}=GOGJ>9V1Vo(t*-%;Wkmdl-4uoVM!sAX1H!e;N zaNqF6C66bpNWu~1w^$M6*89s@Zi+LR;`^iG-G5yOcU6Pktm2MJLO8E;zH2{U3_0}hF;GrMMe}4dB~RIDJ(+?L zXc>4qT6Q`);BLqDMA0%L#NJ6!bZ!4a2v(j|D$hxmi>$F^^Jgo(FM!*BM{(e9W%?yiCa!*|F z&|eg=PGs5`{k%GWGKR6*bJQrvSPdaqqYjSYyDdvV(_^!?&yR|DW4ioW z_!W$T{*6R^E2Lz*wbumPRm{0cPPOZYfTZ0xKjYK#>XFgeiPxk9lZ#_h?2*dv?E&!v zPF2oOum;i3E}~xGF2^<`bnAQoKO~Rpxl}IYyD1e>Ed5Oy!)+NHY?PnpI38suPxsMl z*C=bgyXZi%SpsWD4P^q&c~b4XB8pmX5Q;_Qf~q{dEhPe0^!$(>4!ZmWt@o0#)vv#J zjAafCa8ci|9hjPr5GwcY^@M=80{JXv*Pi56dWQB0c6FPAd-2qigKBvZAKSbSK1@p^ z4}cuDem3%y%vxyv#nj~uf#xiw&oFC2>xj`f$N=ix+7klOKbgXB-M+}mV02*4l{NG! zlhzXAJ1Q2~cZCSS^aUPb4U#wtbfD@AFA6uh;dmm6v(#7kBL2XKnH^0Oor>)n@p)p7Y`R0c+F-a zXMvY@?Fu5ahNL~~i$crg!$&K%>oRu#JG!HdAU#c}d!f$%c4I9ll0rurdlRH4K`;KW z2`cy36we8y6lz6t%eObfbj<3fV`RAs!-cR+%-_|eb;tg`KG5F&@;ML} zio9(={&H3lcR&o02In(Q2Xr`p;Lt<4zwC0jU{hxlU_&J@SW-3pK5F`Oo|v|eQpPgZ zcBFbIl?W;9@e8Zg@bWzZj_~ z2Sr{BspyF!s7B4Qq5Q(=%lIYsn7&W|l1jy$Qh0jR`(xTaQGEK_X<;qj>>0(Wbvl$( z_Ysfi89rGedIug+aJ$IqGaeze8F9Ty9^L9B7el_Cts-8Tx{1AP2dbFBZiCW&Bs+Ow( z3`vJr^h9W;!cosj9^Qh!?O>y6Q7#DprCQD(k0qL|&!*?wNN!`Me&Qn|c2*l=a_)D0wtYKSL2l~gJ^C~;Q^8NG(s*}edLtO7(ePMWn#UnYtj>?)K+p7?T}`wSWvq9w<(mW){ZBq6xhaN6G-gxTs#6!-E^un-ik)Cs3~86ap{&M7 zsDXDz&DI^j>GgW4oIUMQ%q(1tt-TA#oB7z(4=kjr1jS_2(Z`^>DCO!;^#hDCWPL0` zP5`*PA@~o!8_6ETvb*aKu(TFoDf_i(LZoGxBIj8)u>lX99112+Y+)z9GA%QCG;jNC z5%QVglJxt*qsf{m8`n*P82tM~pJV*qh1bhsZZ$bhY6>zX{sA^MCk*IEoY3$4MC9pQ z_9WF>HWsg9=M0e!&^*bKC~QAz(_ULUKzla}Te#FH%bJh!fxzzx^l$Msnc?_ZE0BaV zw&P_&x1aJx~1JAnI5pOh1&!8gtSq-!l)hGqQh;zH8 zY*U+q0#$edio=OYJaoX}x(V>(Y=%2Zf5O0c;5Zb2kj<%G#Ke?-$#{;{)F#6B5-=xl z2#aElh^szIjunk{+sBzf4CVVj)e69$u+Kbpucnd83R|h6#ro^ zKz27b9CTgh$mYy+g>TF%)3=nBBqSTJ7yvx9C^rHc{TlaVy$1pzwIi^x?T`+48g)12 z`RC?drsoA>UgD@TjeJm$D)D7tBNPYDz$O}}?a0-H%z}YR2$9sI*&!HkQP@dUUrl*? zaIccJy)&1A)f(B$*irfEC3^E1eOhUD*2hYu#hRecg*sl(>k-;gk`jJz* zul&wL47_SljUZza31R+4@o@o=jsvhs7hNU7iDf#bP{(dUx|z)>Yh}eOXP|XFB#aV6 zQN)H@94Q+jXvE}tT(dj) z8)d;ZG5&BosLiCK<{14=C|iCEqu|V<-gS8=X5B{Y#rbfVeJt8*D{O(}tSq$=Ccp=S zY}V(&60KNGC2m;bMV3Uio6!l8+bpqu?ZbO1ekIzCB;V}G^7uW^U#7{63@VAy`|I7b zxPBbCy*ff5^Nt5?%&T@DqVWQ;wcwiP1Qdk(qYisOE8TNThP|wYiZ6)rzUaF}HyNOf zFpOPFj?|ztudmow%yLweFrtu@b%OFKXX_P+BOM;jvM;S(Yw0SrtD|N7HS#7PbEmNY zf}~fWa``2i0}}u5v!{RaJOI~U%PJyqG8wOdJNH$IiLG`4tq-6gcJN$T4U!A@XY}*Y z!R+cR;{|J82Y)~wUjpX5aSX8%$)sUb;d26-{^zg3PrjF|5MY-iSU zjG{FyWX_##sk}ef?Q`sJnDT}V87B_k`LU`qMTmh+P=aEj5Pu99L^RJ3EWcnLz0MY# zj1%no;{FEb5I*G!*!5LKXxtgG>{>h>rfEJM_UGRc4M+;-yw_&GnYHCY_*L*G+ld(H zz#y%9tT=~a%{XbjY;yDiJ~lpk5)YtI6?kbZ2wid}5yMG^a5gw81d~B8TWhtVhMPv3 zSe~3T=%h#hA3c!Km@PzSUSw=|`LQ+e1Q(FS@o%eYNOiO#JN;gudO;j_?=s6eo(4>B zWLp&OXab$LA-z`f(Z8JpLH)A6lOfpwxd#;n`dOH;|6G?ODJ2m4g6X4d8-2V%o(vjVw6$PxlGhi2W~>VQMDRg} zVJnlb$ZwMxP!q3aE`bPjn9EnWkWuZT#bJuUZMHy~lrs*n$jyV0GWem!A~Brv1#7W1 zPEx~u*mc@@{7j`p)>bp88cYXyWd4S4KI{gJo@cs>Mug))_`OV?BZr3XQ+X5CB+?an zPBs46W)ZZ?H_}n~>Fa_x`MKSfa|AExUGLkBcUcJYf4Vh|;{K;)QHw1HOr8N$|4TF9Sp_aRQvgmK%RW*jr$^@bPk4fiEK^U-&?GrFUui(0y@oe7Z+ZGkrIE5@`?nwkF*H`pcMg*w6n}(xcI-|~S&6p4%GB3+pZ+KRfwVT4x44xU} zxX!d|srn5CUp1mD~CCEBcDPP+P} zqAg~hgLK9b+r+e&bN17Xujw3&78$tF1o{H8kD2)wF!GssKI3g-W*^#u_yL}5Sf_e8 zkcY?D#j0kC!T$EAjd$x#EsDxNPK6CuaD7|W4>6<79iDDYrv;5zm;$Cs1G^$Ce@7h6 z8Ev1OC~YJQ!m6(cyqb%B#JOT=8JBimwwvMpPf?B#kZ&rw%k z2pCH%Vt@eQT<_ni=Cp^0A#o2{rK>vyy38crEk1AQOxY+#w&NTXI*=kcXp*aGU{ATn z@dKC%CSPsjijzHpDmxfv6QZ>{RG`H*8+*wGK|4oTjS@3X|5cj%k`mlBBL9x;aU>SR zTROTpk^c(2Vz*t6m8RJ-gEqj$w#2||CT3rsK+%$dqfmXDm^P&1jgbCkVgpz4|dPZbl@MkuKOGXs}4|ym1xs6tr=0m#p1&TdC{g5|Xx%nxn>6CP0}9-}@wHBhv~I3*8RP6@2pLrKSVZJ?NfE zIUS71H^oBNx3M0pX$2?4F|8-NK+Z&|c@9Bw+Sigg$@jIDWntZX+}Io91~jGdnz0A! z2Cee?Nayc;70r;)I^o|=p7I9HXWQNpt*_q<))+eM;Z-IN;$zc5Hp7O& zE%-N<4Ni^t&(k(oEjBGQbfd6rdnt7vI+ai@jo)EDM8V;+WVBd`vQ7|h+|0ENozXz} zD~#V^kF9r5ngeg`EFIbwUh9crl(ogv?_CoY72;|xgob&kkXW(Bi@|XT4k>-0GBi-j zGM7BE6r#uI$0vhJS#JDQALFYTLf4qCWyZ$;+Hg3W&C<6i(!~mf$xv%ixU62L)&vRc zh7-%IDuX9-J~hgQ0-4nean#`nTNdSIi)G_Psa4=egvG8r!$P9lYBJlXw5R-gQto-A zW`~_g@FO!?cO`b9PirH$e&{Q;haxA`EUkN;{mGac0B@t<)?}ewBve*D-H`ub>y05S zx!eKj-F=F>LCRvG414^9BU*-f-b5dxeY?AG-Rt&_?~_)onX9SvU+EaEpws=mzf$g5 ze&K|FhML=a=FZoUNM_mEqKoSJFKDtLk)>`YJS?fYJV8f}lByQg28iP3g1v@1?PN>_ zNMaQP9xgWomD|UFu?n38h4q%e)$(g*`Drw*xTy67Ju<;^BqqDJ#;ffL0PIvno(-e3 ztc(%NwO*b}1;_wE=uyMUuN7rII7Yx_%plo!BPGUoUmsG~h5$`XnUfn1(%YWCSF?*D zZgaEmUmssRQHZnRsDCN~bio#$O#){3R(X-T1p{e%147L;(gk-ZXdNw?EjnR%GlDN; z{9@)#)ViyT+11Emrk*PcGNfD=?yV>y1eFyR{tOd4eU#x3iVYU2%IgIMc;m?bOS=y; zpmkSqzb;sPIA+I20sJ|Sr%G82lHP#4+kT1%0bF^imP{@Xu>h<-cmYQS^trn2<*C0d z?C^^(O@Pws#i+HY3wO){KXyMamr26{ z#L6HiqtQ8tG*&T6J=@DF&ap06jR6u?h}2O1f06?R5?o!f63JV4`2gTmz3oNG`Nm3V z5T(t9#ho=+eOhuhetvj1J*f`tXjYF{;ouK%51u?k?I4Ad6CLM0!Lq}eabtC&-7-NJ zc->NWq55zNGEDP%XnhoAIT_sVRQo)<_dN72@)OOKAQadZhwQn9zMrTtN zi8>?2g*gTUteg*^cPa!q3W1sNj(0Hd;8JwAI6i2Ao&8cr-sj=k=3|@<^%uwD4FfmC zL1xK4xrM}=hrasH0VTtNWI7Tvsi-t)WUEiz0qN(;hlih>W zTc?&UqOC&b8glGAK~L?^Tdkj}&jltO;7O}e;hrsQhadjTX^-^#V8_KJQcm{kV$8`> zD;aq%$QS)RgbF^%2VL?_n+ZAIeA4ic^H>QL=$a-y@H1TmxXA7qeK`MZ?c~?_0S;s! zH*Lspz8?e=noSkn2?HL;==Y0+Z=i&1mu?@OLgk8a&aiSDSj!q9`rJbdAWOCFaduoJ zPVOOI8xP>C7zxkui1L4DZ_vAV$(a#V3}gH+-Y_J6Uts{7-=CDQ98KV>a!$cKG@Fim z-S32I8w^cQnw=e4zpE-(#bc5n;rt5%5g|^QC@@)pNKOe<3QFK@hORw%CMwN%?o6VE zJ+`x^$hn7PgTVDBm21zVgO0S?pgjX|++%Y9AEhG1VPv!ceDDQ|E`eph>RNtQW)NT^ zKs;%OO3y$^CwEm0xD`k39XNWIus!_?Gxfxx)sSURr#v>{3=VlJ>@;0-E3G^v z&TlLf>6K~zW=v(4K*_7if$Y%gmZBPZ5ZQ3*TMa*WfEAGIsJW3Pp_`nY=AC?r3<6cb1yM>})#m|WCn^g-gCY;(IwX%D9lMNJqwvqL%lxq5=3!{vY! zh!2rL($1{?V%Z5dp(4g#OJp7l4?Eh)>TyK2gxIe+TQ`9EX?Xs?T+&if&avwzX#j`>>Ca&9(hgEKE9yI~E&|XdKHwqej#T16M4t&CC zNi~i@vL@~K@Z{t=^t@Ag%KiBr8g3|@#`Pe4u_V8o8=B0Y4virkfJxR#ML|+~WVUz8 z`}iqYtliXKCXHu)lFQ^z_aYTXv#)Wcv{V`2Khyw|ICfd7!NGR#&PyfU`gmkU(vFqdjo2UB8DcjzB-pu_=>PahTl59Mo-inz$L`JvMlDQ0`C^Ce+#(p|H zRE4)i_INL6Vp7JE!&!*Mi$O1BS%q8M19SPsz7nEeC>nI0*qHKFUqpnHx}}}g7V1YEbV!t z>LD@1O1l0}!W$Aoqg$1mm(9ybio-%anQPApbi0;|X=74Fq0KYROuxa*A(f-;O+gp7 zP)wVKt@{q*$g3Dvt-r?zn*Y?5Wl0Hc-1c`5{O1nc@Xkg$|91tN1 zfr^5%%;b5??rovjUuvY}#^GG3%lPwTk_lU78V+8Y-;cF0+SVTL=t%7;xszQ;4+k|T z6fX^HO#m%$^@>?R@O#Eh{U)Ic$KXV9%&6fxN*O6+Ew_U@EOgs`t#UXxkBZ33hN?60 zv~E-mmV4py6zRQJ#Q-%x%D+?1j~nZa(;U_s=HBc##cU%ddb6x)%q>I-g`{JR|2E*Q zG>?KVQB`FzPj|AsVL-I#>%okEt;-0KX zewmNRN8G7E_zfx0xQZ$iMf-V12raLO(ptFSL1i!)vfxp+PVsN8l8QVqw09eR9^(!@LFgI4q>Nq=-j4e44zVM=(8B=rHMt|p58okF^aM8cCCRf%2fc$r zR8R(9vE18b%J^BgX=h+!c7B)p1OzG%>Saqo_L7_y-YZLudoB zUX$P3hnOK*DJi&1hFn@7X>%<+`1A@ekg5P;=*w8@404gm5wjv)7^}dyYiKdh5xweC z9)QJfp+NXvYNVyf((u#F9M!!R3?BTBn^Q)*|K1Xw^`M)q@&%VRv&MX48>HPE{y*zP zbdxHsT4`NWYq6SH*S+5D*d8TwaNk*s9sLCoNARY$=FbDq^sgfjcV$jxEow2M6O?C4 z972-xIHyA`8n45xsN$nb3-;mI8?H~e%G~w#K>+R){0D@f|U4WlN=jXK6m5Mo(o-u z)8IhbSlKlWom02GyE%_+Ihhe+?4rEe$)WGvmc;nc@hkD{myA3!g_BQn&1Yz^A7g{@ zA9D_SKX!GXiW`KI1Zj=XTOla(;ap3!!=a3<3$Pv2`e!SvP{*46vhDUfl}1g2 zh-(?hiTV?CH$>(EEgfemC7olK-b%)jkhefX$c^X+3g!^NL8g;KO?2qy-nAe4HisxB ztQds{h}8u(@eR{c`jfP>5v|Z)(j^RS0)J0tkvgg8$UZncf&4`s{kGYyLZdp$e$6%8 z_2US9jwb$^m%w8iyK1_#13H2ZM%l1atKWJCZRYGbYV@7yb#^n7?H4(@mum;&no~}x%v9p-IwhKxXXnC!}<5}8|f-hMfMP_|keYX(3tDkrsn`OX5dmPR6 z@J(Rck6%R0e_L+Zefbe@0g>j3}$bGAVdZ(U?9T&)}+8k76GaAKkKgGI8 z+1z#;ruX^hIui?&-6M+^$G{#jO6wKVYIbxBK!4?~nba)tV@EgWe}4D8qq&IZ!**>; zMXQ6cc7q@_TO3MgjYM0e9HKNBVp@)7t>9N``p=3~Y)GkQ@TBb*?RBy|o1-~Q(WkXS zR@znT#ID)mFkfr{;aTKj$}Nv#xzm9C{~4}1Tb3NPR_c`@v3g(=Uey*6F-1Rnh&Y)N zXq=_N*U2R0)kck=auYF;*w&XIHhM7JKS<7*4NK0zlPOoSrUL*t?QE8GB6Fnn$qVgK z9yIS1vs3<0+R~qgsP&Y!K~a1r`>kq= zio|2#a!`Ht=*MmADfve*YCb1uq(J~%wa)$aYCr=uCBvWPG}XaWdbuZ=WW;y1i4BZ_ z^U~qV&_l^3RvL4hT3A%5y#>FuyK(Nojsw-U{7zx}24yKTBQ@pvV4zmi`{*~MXSc~B zxaCpyP4VaG5u+FD_8Vb1j}P#kBUY$3m7U7tWFlH$0u!u5n=bp(4ctnI;_ievOsK>w(qK>d7aKNYr_kEAMd{^vRqLC*KYGSQyrZURN_zzqd#uff<-rA zTWlYFX)PY!j~;i9-RlaX@*@WO(I8Eib5y9gY*7na6}s;I)eTQH(8&42>seaQqzwrP zB-T~}Xad@;D0!+m32W4Jd~$?fZ!hN$^R{+ zbEFw*-!cjTp$Eh9mqQZzN1Plk$tIpnzu2WMjshRGMTSZdw1~tmQ-aZr&Kvy-OENQ` zQ0kjPr^^l{rRH?-3io#h#{SQm)aj-X~eductlmz;AZImVG^v7t4OtH`ZT28NH4z#D|>|97kB z@T}yCDWVhShGnT$Y=uDm?QR9Byb5=BtNu$V?LFGcH<+UsQ+92oZ{t>YuQn5R3G@z7 ze(n#BP<(^?(_CXic`QBTe2u&W9ECB?a_zy521IrMVUtl{ z6iJ08F_k+PbmjOtmL8b;lhq(CVjBh%D6hdXw8duw*Ej^l)ZSIp20n6 zsHvbk-ZRnMNdW7O2&Ih!j9NHUwnvhrPnu@1R%#?pAMgd1fOT#f2(wyOsCO5NsY1*> zgVY@jni!Exfwg%G14wSLPZ|Mho@VR44ZcHM-fh2$|3&QrF@%2G$OV`t55(NZs_y%~ zbBlVi|0Xthk)ikTZ0I>;YTUJ~zdoX0=_eaq#3=SByOUpY^<4e(uxt304Ww8HnHIUF z5RgD(`Hus$)WHg+9~t~-+)0LNH0Y^(nowyP3oB4jc5eI|8ag_F`-#<`iA+KHv1y zEPQ)$Ao!I`0Z4DK=)zlZd@mCr!*(0wGJe4@Qc01A5ug{b_a@qZO+Wn+BstM3jOuC$ zHiXBmdYrl$`i8O%R4FDTG^p9{I7>q~o8wDxP~6D1HTo^}u}41`MuNju*5>iOL$+q> z=aWwVhO^i(mYtijLr(lKkE_`;PxwD0uR4)JaJ+oG$Tb$YURM!I2@jM*lk!PV}HrLN!U#@Qe-{xO>cA*&#lh7FnnIpi)xgUYR!Yo zBKU*0lB_E>Ch2ECO$WWmIoEk*3SUhG&#|)Oz~ZuQ{UFyR)>5?}TWramm!)Sdd!Sct z6GMWgFu(4DpHhaXe2})*VkwhPPAkR7q6*q(NOoHVzR{Nc@CB#^!{eLQL&nDh9O4 zNf!#LO1+s6`&QL51Pl`{?UCuat|NnV&o_Cc(U))7mZZe*MPL0Xq_RFULo<{lD!8r; zKoNiaJ21xB{uM$iT6|5CPb$$31T;PfY8qcO8nxihrnqo&uXm+JrnUS;L)P$sBPsDW z9=2&1q}qFKGdY^b`%utsMH*Dnm=bRL71xpc*voS$EYTCzBbjZIhowWnY?ggSaEH;x z#DhX;TNilG=hhyH&`rTw5A}&8^Ch`WaDcZZzI+6?9|U+BvNc=(9da~`>6w?_iP$Vx z+MV0r)h=@ZN&uUtT?KC8 z43kR_u-G50_b%WfYAS~@l(Fjg!{aM+t`2PhPF!uPqq#b1F{s0aMLkODu*;2$0weMy z{&O-^HRY)CeT`>H`zPb$0Vq)M<8(BHx`vmKKz*qDz|pe(5-lVc=DQ)|x`YY}QmIfo zcNAh<$~X{qK#~w5zF^G!rLAJkb;ILF{EVK2!QzxBk9&}qTqJ!OA-e%oIwhN+-;-r- z>sYbUY?h81wYS<9XoXRoSO3YY{M;+Px$s%Uy_g4-X+bh&eCc1JuolaVUPXhkg+~?* zUWFr|GCv;m<5HqDJTO5vHh6 zV7TnWVB>v}cUvsa5h#)c4({`Ukte%2>T9W}) zq!$5qV{`kGB5Z)6e^DW#9u{Yia7EdVL2IcYZepvVvLBdJ-zT!oUQ{>aJ{Rhb2p8i8 zJ2{keL(w)Rn*@(Aj>|}u>k?%R9}N(e{qL=Tz(Twn)%&01%1F4<5yrSKbWm`NmEG2u z>;uhd3KPqP*SGNjX(Ha+u2tMsKmlCU7AWN8fq2>M<`tj_!<L8W!2tRmw+7 zAfsxU*Iq6rH!_3ftLSG2!6->%K_|0UvTa-;^NWy|cUiWeG%+6nnrim%jd7DR0BEoY zPV-LTliggQOM99zi3@-q*@3e1Ms9VXtu92e_&P?#DJ^{>Js#6XbHT)-e2vK*@%W^u zX`HIuofVd?6e$t>GHv*Rns`8|>O0^%{Mt4|P7R*sx-hLW0ormB^fN`HXgUWlHVzd# zsjq2@#5P)81NDLI+&~x6xn#exeF}X^iL-iLCdzofm$sx=pkPA~I+VSPlx=fkKGuc2`&&nl7+g-Z za8Az}1BsW|g?^4Nd7bthX&02?Nk-U?F^^On!^SpYCe=Lc9XMu4>v>id#E>}mgb`bh z|LHEF6JvfG^t@{vABR)U`>*D^%erCV_TU#OBSm#+qcecs0ER-JFhn~i$2`X7$Uvt{ zMUGd-%1&V}y3VA%e&=J%(U@5~3^E#QCp#PlbCP*$2ln4bjt;Id@{-r_(aS*?L;kKA zIOU!{sl9%d*E#mj3CfG9#rh((f~<}ZLCFCkdNf!_<|KDptF1DUny#Q*Z&EaDKQA|u zXP*m?Be}qW+l76>%LoZPxZIFQgK8dS3fO?s<6C8+y#VX!x?^&viOT^~5QEvWkBl%q zr4Y~FCWIYsz?4+~=%{V)Q|w3~iD!mrmx}#($k!^0CyMTO9+GC}U_s`lmG=a9dV@Tr z3u9|#Itx8kljgJ58XC(?s1i6flUQS{%2AqA&BWJVZZY!^8!od)=v0Gu@~k}SKf;`) zV2c5U=5e_fw|;z8ix`<72S;GxA-Ug8{`fXBA90NQyp~b1HYof!zR=&ktS-Y zS{M=Go?6hd&0|~d@&c)-FJN*7@)Z5yHE;~WL)Nd{xnEBUaRhR=h%i(Pvrd&{PZNqP#M1b%&xg#$^c^JU-M*A+L3Msl8+4lKeQ z^=Z_6|LUl`{0Ev{NrTkhrb@DQNt7{~52Uf|NfTGz+}QEMkvPib*!ltFylLW`@liGF z2JR~$cX=lIPV*N=uSmevKR{UdT_4GC)36{t(LOV8x9`}Cb2ei!oGocPEw5SQBO9Aq zE3ga)M_SrouLTrlqkfLO&Iu<7jQ7T|bYgOepF1{=Ko#^cfh-!p%bH2wy};v%_U5U(AQEXC(@N2?m;9bq`ju-YJ<&>|CmLs|@{`BZ>pfN_^0*6? zC~{0R%3-Vg)=tSq_N$IHO_-Nc{f;(Tx(c4A@f`+}*_uS)NS1XAdx}Z#4Ngs;qw1DN zH(~#0om4bl>9i9$^kRLXR;b_?@0{H$$X!4d`ESPlVGv!o_qm2v;Tzw$H#5Db`EQ9; zywh+OS`qpQQIVz&`ZfmsogvignS6Zi85I9P0F4tp_DjT2`tdZ9Cj7dA{{vQBPUM4f zU#70JE=bU#s*-!B<9O)*=qD&ADbW@hXsz}>CiY);>aR1nVUn(e6kBKyRZ0r9s;pKE zGj{!$;@&cmCB82VL)dIQ%h6D>Vw*xX94yqzpZ~{5l;QvY7L&N+G=O=3;OfVW2^KT# z>;iHe5v04WrTo}@~B0v|FMW|!ZdmOFL%p`?;*lAi8`S(9^iV)CZk&Vwk-B`mE+m!SOF48 z#o-Ei5o$P>Xkco+dzz51@0@1M5D~#N>F>JvS6pqPkX-l&tLG-6KFt+(EIqx^$L(7^ zWYi$RoFf=V4$tlG!*?6qLsG#Jp;&bY9ZOvEMxDay*J$b!-xIBr4)6g@Q1jpN+e7S}1h=%(0Z4Aac z(@bV97l%4W20Bg@eRhsSO~U7yMsvIjpiwb|+(PKas$rMHH00 z?bp>=XKNKBy@F8-BR#Gk3Lc{{lS(?Uc?hOmZY4QUW{5DRw7O*QnWPVsW9zg_YG@_u z1k#OTdtz_JpLtYGmE^cDc0iEN*maDwap$g6&$;dHftH;lbTq)m8u{}2l)B~M(b<{U zT_yfRDxA#>r_4EXD%OL!9mzvT{21jAdoIVExVnmb|HAU8p#UJ9BaI){NKDNO zUMZSDs0=!OzS=Cht5FZ#%ck$*;)cFyu48fB=KU9zGUILNJO5yJ#Cr0Ev5OAQsPr~1 zb3eM~?&}=w7tPC+cloaBthXt{IU!hUf?<`)_T)>P1h~nM4FhBoZ>X*%aCpFgf{dJa z7p(~+@gaagoG2)vOk9FA#2eyFzWJ}CktF%%Uu zL+(JTW=D?-w7xrcLZ?TshQWTkeU4mNR3@@D?zdO0*v0`Puw|J22lS|X{|#B@LwrA>vt~ z7rMM$*bb+kz^$l^~+>+D8SBMgrT6JkWn$NGH;4r;2557Mx=Wh=~f^d88 zJg{GBA&vRxzHTtTl9OQ*KhPA&J#YX%=YViJ#|Q{-45Oy(Z_R6mx}sX&LHeu@JopdP z%P4>gDUB8<-TVod9Hi<>ntQL{$J~EAGfWZzTs=iHp(eUVXzsk2vG>@9*s(SHqmjNy2-wk5+&U2aq!$Chm#Qfv?2v z9ZbsGKP<@G+h@LgYHcMxHlD{ZDt%F5d# z+;np`_ex=bbHu|{3B<>c`)wgTyxMZ66onTc>_%*_>6V*hek=}nV zGVu%mkPcmH@p>8^HqP$50uU^eIpB3AbR|*Vy61hkHj*aHaOqUl`!BRB78I8I5Wh(UDQug5BcJj8iPIl%prmP6bd)6`ln7FuNzfDkwhbEgYa zoA`0fGB~kEk(ti!x!N0DpKX&~M0D~8NM}9%#U_L!l}JG#H$GR5xHh3Lug)Oa!$VSb z%*g`>eORXMn$uhF-09I7WRumu2e2x9Tod-m^%GCpxL`sDLhe!Yikn;c9jqz))r&88 zY0U}ZgIWBe2&o1@Xwy(jDrP5Xep#e_BvqujQLhjG^S2IQ$r2K54}1$@kCIXDOAQea^sRfBkhS5xkIXwXZTU2c?6CeLdV zaU#zQ1xYKAe=Hbj54LV{kxd7yJA{i~UL!pNG|cf-aq3f#%TIJRxEHhOko7m9y@u6W8w{|h%6Ua)gIZ``X~`tdOJvMxZ&>G5(OM_WvBW)98;wt{69L4 z<;S58Ss}nuW#+FbhzcOINcMR0lBVt9g3&DBwcwoedOYaKg1-gcHv%}B~ovnxXoiMl4>5fMTCPAqlC^X1{-*^qwnmfMrdF=qY9qz+0_5PpaIG#bNmgCn(a>n zhm{dRmCm@(B8hGs`+QZkr9tl{7gB3!wu74hBavJTB&-6pSdJ1RcX{_W00J=Y@*K-Inxs4j+gKah>p2^Z!$Li+o3FCbW#rXHKTE=qE*21{=j@+do#h7wdwGL z)q_r$jnJ+w3tB3P%4$EsYjZyDaaomKi%_9;rtniw(pb)MWZT*UYTf`VlC^7&c&(R;P2ZD zw$?s}k(k#t;Upvbt_)NSle3ls+d|!skv`$st`>nu+z?S>im+)lB&h>fujD%uc>PvDFRF^-ze$ z`tohNHwMC@Wxzyjo|PFJpcOVtu~l7@_L55L`SDFzC%y>Vo|=gjtII$aXA3?mfFEn| zG>z=ss|w6wrdNUqU`uuBK;JZU(am_yDu*w2xX5YVo1}c&{)eJ(umFMwy!Ag%)wu3` zx8V}M8UJc2%~qC~$m%UE1egMj1mPB4*uTAeat$swi9XZoUqZ)|yk?5ef%+GX@kyr# zfg?Si$t_D@R(GynH472C*vkcUY-XUyT04+m+KTxXzy1!)(DFTQ!Ospj1De4J9RC?9 z8GbHv_l>1JztBl{UGt8nZfNZJQNSaxFx{%kI#}0BDER-+^xQjzO&~>3CprN!9jbgk=3 zruZ7d&}%7iGP4O7Ye_34E|JFYGgz+>-%ZOh)nz)%G3kz3Crg|Tsd%QK$(Mnj*6zHI zrASfyg_x&1xaYkOw>SA=0(8a}rI0SW3aeWXin?L5Y09{{biY{>QY4- z%EIb9Uo0}tX0_Aebs-PiVdBFhJ}krS&opt3k=>mwjQc34e#UnDK7LddTz61}LuRt3 z7hq$M2;)b+exVU{(t5k}&$*CEI-O||W+Xq*Q_xl>giFd^#!E{Ef+sjz>g^?nj7*=K zz3qJK#^0=2WkFFZcj)NvQjS>SYm>SbD_ofYmd>gtwxtYb5)7XjjitW%e#9s&BDnQm zaFVcR?48honQl3ml4l!q3H2TA%Z$M#U+g8wb6^xykJUuNS@ zsdmIu_(|+Yp_J}UF3Sx*$$V(6?#m&Z`b81ueX5tjeTVLARKp5(C1k-6+^zzYgS-?V zI6^LML@z!qUifA4wXJnTfXL8LdQ*_0cXv6aYgE-R-r~F%%GGNNLO(wKPNnQ8_NQ?Q zob&4a4}e&~RkPr@=$DUGWf^8=Lc$$2)y@^plSlIpo=hh2k{HlG>iD^CAsbBI)VP4a zFm^$9sxozSop6L`_oeBe8g(`lkVKq0ElRQauwxepyuKx0GKOuA6oe{|(jN3sm@4&Z zF{gEwbmaBD2 z(RfrUQChlmRN8|(Hr%DJL-h1iFTHvHpl-!686Svjv#hk0vpf_cNNJc5?8j5JX@P;C zoL#VguG2wqzP>LW6icDMixDyNO79O1a$Pe7qKZ);V8G*p7{^zw^MJ-5$KYb))=gg$859@sB6&_+#G4;g#TDWd8wwl@{nUE{bjzOvzg1vp3g>+X|ccZsN#};_jJB0#d}7%Kj!!fF!UoWhT7Ip}vUThkNlM z*)?4`NtbMBLp&XSg6nXJ@ZpS&A*3v(^*0~!VH<6&E#w%`0tG(8zWq;HhF^BdS2RZe z3{^+LDAvt&*Fri{i_k655b@w5f{*YILUfus9$b0bhtwndH;7qKS2FSNVgT`z1eW|1 zHa)@>u%lr(BX1mRp6zuB;dEoj+TRoA9@IJLBO2SGzT)J0YpU%|Jhi*-YKKx9+Cyh2 zCq{q5ICM5#kea9yc=V0BmJ=2iLbk8j)ev-E2Gc}_ok2+x|JX2f0hZPyaTz;ylsW^u zcsrH_5tm}jdyo`&E_7;XhP2nH1#EO~9*07^RfVeC=aOhxeAxD+oGP*F&LOGn<$Ph5 zsu|l9&GS8yu$Nq4ui?e18`?+)m(#6%P(|ZWXiTkW=~p(5fA{h8p&u4&3TA}65gs+E9xgCBL^mD^ z0o>ocMIf3CVSMx}IT*ZItL*A@Gco2IBeERxr>oXd+p7bMT|{%yWjO4t4t`6A7+FFA z^Dv|09-H7IA$zkeLW`tmyB)oI|6g|EpQW0gwf`ApEOVHu3a5?Q+|dD-xPQcAd~r4( z)0Z>Y{6*m&=e)`3>xe@%f8GBHZwzn@Ed^5k{`q~QmsYS%wU0ijcn}0J7-vh`IFc#P z++h2r1TTils=+Vj9;B9HjAG2?i4?b}cEtps*9BzY1C2Q#(XMcA10dQ#)JuC?qCTmQSH1(~>PO7p zxTtOwn{s;O|9h9A*;a)Ui1zYNiBh1P9xqU2iEF37BJN(5x#cFl_=uZ}4fT}n?)LtW z7oyAfLFn6X5hHsq!FX-}m^cy2z|}j?%Gsa^R-&VT?8ia0?dFQR#TGE4w zl(w_gE_@KWCe0mYo#ssj+Fw9^4RZ%!v_KQI3C~E`S_OVy#)hQg_M4j!Rbh}{CK`+p zM=DO%$=v2FF8Y3&(D(U_x&1r1+@+c0Ui=ZtrlGj3$$w=1p#oQJrGOI@ePDjj&7M!N z(z~v-X%~?Yy^L{tE~kn1)LnxAU<7*+I7{cy&JGDEF;E33I>7TNY+SA;JYU_g2_?WO zV)jp!;Y7V65x2{R9wQRHQYfznIkHt^mULL{EGR(vF6CW^&o`4EqV!wWZxQW9uWx5z zaq;o@4y9%60L4Ypi-J{;{Sdo~>`HXufhC4Np72EzrQM^Zsc@*?e5(B_rEcYpCT5|8 zR&l>u)ySvn3iE?_af=vo&V76dSdgupCk;T}y zmKllTVi@c*IIo3WS*W6@qX9a;k*Z4&%@a&-|Ks<-Ypoq|2}lNA@>d2yDqPC6w)A_2 z9?Ncx4-gq+;J4uUX>hb$q?tWvPjAnZb+O(~Pl8>5L+(Zq|C;PDh(-28xLNGV&|o+?fSJdCSnGo|;^9AR z_92-M>!xW)(F8`3-o;kl(KY@6=k2zu%xlLi`}F)Vh}UYaN?WcZvUE1Dd;kEk{1<<4 zN``ncH`62;JTcg0Yg<7ujY@aCgpip+6zA%yK z=^AV`2#3sxgHmN<)ayN(O7pK59*e7}g*(Vv2L}ah1-o6(%-R({ZIU#fl%jfEu$?SC z;UA4-SKPLwj(-fL%+F72{vjh77Xo3ZT}#TD`*CbaTO21jZleZj*rQCu@C-E^?93U5 zV$cyvOg0aJJVbcaX4xzi&(>kbHNPo}bCgQ*K_xuI7GcY(F)r%>u2pzMLo=ToCRM1T zr4C7ejL~n1107=fWg5nXywNJ#k#*RCeezF|qF!MyKVusZ`jBpwiZ1r3iQB=SBAYMU zzUf!ihPjhd9e3rt22C8$FB{5GhhA8iIl%~J``b)D!XolHw2s%AjZMy`9?q9ZThOuL zl2Urm2BVhTwK#1e{@N*xxB-#pxxyU3x9w^D;9`c&z>~ce+Vo%*5FX-@CpBdp`@;^W zkj6m0`uqUs6dh=95$O?K(6_1AMewCd>i)ZOs} zZfuaVZ^)J{*XW$y1{+dhdwk{JaR6aP;gAhTcYI%nmfn2S&g#{eJ1|;SjVt;_zmjhC zWl}9RC{0h+dkGz2STw?9zrQ@HGWb5u8e329Rfi_$0XU2c(}R8wf!Ym+#`FE%r50;z zqF6hsMwc`8vsUQW#CeRdv|MzHi|X6id$)zzvii$mXptCaewte`09&f}M|>q9HAZXx zMi1oJGcJ}$I0!3#pH3$CtWVj*hTC%1ii#91OATLJO~Hszc5QVU!}91QJ`93`zhfyU zSGD!Ozgn96`TBm;u_5;FwP%HB4BJ7SMUYe)nE~ulENee+@x(7w17?W&-&IdIqXBa3so8QGGTLOy%EE=@BIP~qw`$$hr*oz;)q(Bz&3S9 zMCWbqC+BBxSpZb?s$A zFn$`s=mKB#T{Y#`HKb3IZPgZaVQL9j@QI@o^d+CPWeK9zIH}vyT=%Wo#LvPt|Gpnm zq6tT?Tatx>hMO zW)O=|pXXrD)|m*v*t*z?a!baJ10RBh67wE|I{a-7LSNWyopLcTK>6h1Dh_Olt)V4s ze|3bLNfs`=2taCSo-1woNKjvQpG=)H9Iuj%Em@$1=nurdEXpw!K)ivY^H0!Ey_U-R zlv{}B1pJQhZrB(>sjUZ*qT7zx^y9l9T<>D4+~d=?R-aQ}fITXI#J#g^rnV>{O&MpG zEF;1lZ#8Ek3&=vnkKkr^R2$&VTj@--U$DCz?}Z{k&8AXOsj@ z4c!nhw8C;W5qZ!3OA)6i1}&v!LY}g`*s-1v4DO++jHTwl7DcL!rvBZ^>v^&?I@|E8 z(Mp*Uv3LZnf19}61RGe%GFoD2MG7Az4I977gzmYAefQ8AUBAG~A93951!0PZ-WR0z zhUNuUv3~w^L3BaStDevI>6`^wzu3IF-;CbRo1Ia>wHKd z7XFQk6^dxLWBLLImdML>u?eYGfb$JyfT#~gdjrwSI~ot{3Q%6vT0!A`a>KC@#t66* zCsN^PY}{0qpTV#bKaM4($grhc{iG8q+&mS2i>=k>+mn~MMlzD zTj50y%bYmvpj7A1ZVb!!^j~-Thf?ziUQBk6GYq~@335J(#wsrxGcts;>%{nqcBKqP zGFbQ5#5Pd?qj8Akq`(#N?rr5hSQ7)d>8sP*_S0ap*!8|l{ED(WNxf&x(> z>sBsAp6$9%dFfEB&CdU6YsBv%L)vJWqm3014vDqoi!v{J&hC_9tu#_dqKbXIA*`;A z{Zp^f{e0(6l&fEB4%91=x_e05dojQ!2tcrfT??3wa~(aYfm`J}FCl$rKqy2Bk@zAc zExE-l^9r=Q$3y+Xwt8ee>off1l8-JY09&DV6&pGOAHJ`3Dsw92NtB;(&+a&t-be5p zp|&SE`dFzKTS=|Qv5`8fl|UF?b0s%Ed0!9ue9#M!W)t7p)xYrX2%(rEqGvkZZJ;Tz zwm#=I#WMRn#Q!F4yV}!LFv%srJ!)IeJx(}(e?ZK59De#LK0SBgHVim}w0X8_A1{&t zJ({y?`;$Pyp*Q{ws*Q(GCF+y*o>{^NL=ayG*KedT9{dohmP(OsOi<1YjtXr+T-(&8 za#gV!VMvbGZG9zt#8N_f7Z>n!WO^Yl07BO9A!NBbMZM{KC#eq#n6w-EO>_oA?di<0 znKMvJ+`{LvAAzUe=tIhQf)w#zSiXe#COC8f`wx;#vRr=A!D;N;fVXm4hh z73hO8t;5vjwwAY;x{u&%Bb1AJM0b;MOZ}UowR`CryN6g}4l2rwz2AL*+o)geFYhrj zYR0d&Xn@^9C}(J~_+K10W#3G?ue)Dz;SO ztBNcUlcKnb{?U*5^b3_F%X~%(iQTmR!8O^DwpQ)p@`S9+K0=h4DJ|7IZQL(ci)gP9 zp#%qW>VF($1|d6rKf8jXp%CjnaGyhuc&F{W-jhtrF(@l1&jH7F3K!Ji`7P|czCKU}{@G`SwZH%o!z7Tgy{kE#bD{g2}a z7?h*d!Z=*gVAdGJcZ6zVX3=n~|MpY>mHNU)La-QaSXW05aO0FB`;9T{H6#`^yXL2K z<*HhnKh=8}P4VYQ*DLjQBy7!}I-lVGSmnkVESMK{+f z7a`EQw%+9G#nA)F&M`fz+%{@%J_sud-%VZU#j%T-)^LqL>2}Eh3dOV&0PpQriP{&= zLUBM)?>Wz=$d%YDqiy+Xqw_C{v{vS&q3?Aa_(bzk;_BR~MZqF<)LMszn17&2EfZxg)$#V;GX%N7fE*hIT@^yhpy^+H93_oAwbuMZYAqRaipq0 zV4?oa^ZF3zY1j$p&v5=3`V`ue!J#@+eQ9puA!yGhB8^tS2FjsgLRM{E?VQHr^$p0< zM}&5TSt}8?#)Z003^xjD4}sv%aI%2#RB!-i*v~)bK_uo^yOJ^PA{N0Gbb41Vn!TS{ zDOARzti5aMA@auG4wXJv7%qQpEU#QX!LeYo(WL4q%k{!{E8 zK$7qAQY%E47&k7YE`43V%6UnDZDr!oPTXE> zs&|(eMlo_9DB%U5Zg}`r8d7{XGN8Rdpk_rn$IcPCj3i`1Zj55e48g1|vVkfois?t@ z8==JH|6XVyIppom{gmeO4331zu+mkR`za`neS{vm>u`%W{=vU)^SftHV>9 z+7`#I1*ZdEp9UDVfQSVeWOXCd6E1#qB+Ci{OgU^(=puKYyD*#&k(pl zReJY7yYF+55*D}U)v{vrdGSqcew1z82Rp`!Gi~_g1{|G23O++V@GVnjCg20+=SSSr zg>Dd*iGM+n{q?F*+uM4_!^BM`JAlK6?6u5B zKB?C-k6t(4rLA&bA?!tq%3PwamHV+t+_a*Pmcroo#X+G)@>q>o z;-MTk`NzK?*-PZytN&T^Xro9<5~h4&1?z!l2RA@!LR6C~G{r9pDyvq8D{vip5%61F z1ZPxJ=2*<0Eyt*PMQJ^6;rgM@oxEReEc5^YqNH34fiAgJ-j~A~+Do5Qz@#xqq0Gik z+bP#{3s6=~FQxNTqxN$J<0O`1hnl@AG58q$L(bmHff4(A*`foOUfuv+k?WnoR-DpS z@xpZ$FE-Hh#dLmvs-m<77@?)JvTLwL=#$+$nXvV`@XL*2@qc-yWJcVrtas1J_G2h8 z!Pf!igf=^k!wP_PK4+tJ`#PLTsI6(~!U&-w{*>>is%Q(sTFFH7$YEwySmHrzG#hDg za5D)enhziax%*X_l@4vcIiX{AW`cn`&g;A|IfWp{rSSY%w(EIFO7LZ@rFUl@hprKk z;K6kPDvygkNYB7({e=phEJ7IhGaHy#+)?{}@QO;Eu!U=5*wJO?4w!rS!i|nu8Tb|; z(2YnSDgWo6ysw*r3`o3eF^+`|3J!AQBQJ3+sLY!*_`c#){CExGN#Ro4T}qDG{fqu} z#36W#o_%W{whdHk?f-S?*-s`HU*8K{&3Y(sViitc1Uf*Zf_9LJZPkwrjn5%^mITs_ z{b_BP5VD_#fry{Ty#8bcppi65c8j@o)A((P2QQ0fKsQES5IjwZ3OyyS8%Nd!EYkT2 z7>J+ZFCddv2qDhgSo#mvrN4kef~yhxbkHW{geQ+%%JG=%KoJ{p={SPsez@U|vl6!tESt@SUM(a0Q}Q_~#Cc@v1Sp z+L|u!ZdHLhwGS|NwO!eD&*){MzycJQ0iz`G)zQrK3+MS+vg4)$jc~Q8mNmKEis(cL z+3eRr7UffNDA%A!D@Wslpxht?V~33!c42Ga(Ydaul`Ci#O-2;{;y)V8J#i2h{u|Hj=xPbPkSe=eRJ>?(XWrIqhTwqFlgrE|qJlG)Ir6gpsDWzt^@b%f5&a9SKKs3?JAc&as#VM2x zNSz1Xt;B27QL5pt?6^)pQonk>%9Jyf|0rV>tT)}}*l&N>0aDYzXCuP0-uQpNN@g8ct8UEf7RL3A(CU1fTEK>ha5QFCQ54B+pSc)$`eb z^AI_c6J31|5Av3|m!^-Wn9E#mDXQlHDL~f0ns*@MOVWIvyp%V>FrbV$i{$nLWpUD$ z0O@#B$|)N+LJ@u>>E56)uwj&5>2eMLw3H>ZT^rsuZ2SKMwj=5{~2@gvi$FgN>anGUKxFuGX8H^%e8w7f6yU z4-dJSB1S{&HDbvDRQ|LXpK;(#+!E&I0etpXSRj@O#gi^yzzw%20m>5Brt(;?;-+cG z52xM!lb5>_Zp_b^z9M7-*j(8Z+lc1rrv-TugU(X=5b`mglr5z!D$@mAmCJ?_yvq$L z-fb`3%JbzPr%X)5|J)<+P%&{@hjrAF=s~Vu&s+DVYcOtSzPaw$181e-o;hZC#4qQ( z%Q(9rv{7NW(JY_B0!PUXl$2n{{>IuvJ5xFjDu{+eR> z?TI3p#kfW6x@_Q?6m@(>;I4v7(!885%T;_>;pdKCHy>1+3su;rHr4Pq%-(2?t73AJ ztURCPo_o&OvL4#CNK*rRaxhr5lL5slc{IeM|Va4ZSw2-@teNd){4q`+|GoWm9ni14F z&%XS4OslbSwM!1c(t*$T8KOw0mS@^5STix_H_%HU=h?0i5m~7J_znst5KMB6`%6d? z{c>}PK;&K~Tbm-=64b#RA^>Yq>S6ji4wu>kjXnI;D;9RtJDujbYssxCr=toc}|C#?4tHJ*P7$L4LV@&f1j&Egh z4|CyGwjCY2C`feFtYiePf9{vRgP-Xoj5C}|FFo8-u38HA z&b-$jf~odSZ1rnihQ|`xr4uf6A*KwD2X)MvK|iTu@yARJ&1ovGY1yGBb`{nCd_b@b z0k-Bz|CCwUJOlr8PK`bM9I!Y~0^sZHJiy0$rD0yBdG&Nz3g=UM=F-NW2$+6Bh0ybV zJ+LQ$vb)z@=ctsli3J2-biV=MV^luormbeO^oR;Ls064Mj*~|{ag)5kJpA@gU}I$% z*QMxUD@}ZGi^!`kN^zxmIRkbRpEm*ajvP^R z^om5CB&Wnp*v<`KJg;O}`<5jQ2e%sorLN73Vgz^uik0#Q4a-+^$d@pL&}maoa)F{a z9GTu^w~hu=;rvP+d)<_OC0kI;WXqldsEDMKXe$N?eTJ^cQamF$E!&ANTC!%UHyW)AJwHkJ{ur|xEhE{c+t)&;=foyut!=y!`UYA%J{JT4XZ)K({8@}LY)xDbmt z-Hu;wlRsDosi zxqL*osk{(Sh4+%|gz7G^{p!t|6x^&gQgN#L?I}jGY(~wBnn+fu3L;(5)w)ktSnZF! zYX_LRh>dwkQO*w_9U1mN5<{5qyBr*xjxsNOF3}5}9cVS84q*P;+$!*25rdzk`?8MN zkoSZo0XTwlMUrkrv)6!PUW6KQ{BC*kjonOvJ_(2_jmi1VsS8e!tZoTX?|LbyP)jK1FRm8_@$-9 zM{n3!?Jgd8eutmRSN@jxilTqq;WcK;lG6)w5i_+(6Ilhnz8s+nE<+a|s2(rBou7>H z+ebC@V!v_^W)&QYx_?wG&`Lt4{mUn6N)}$#W7B!wF>!+H8tfS;O*GI0D{A0qX|5p# zT@c9-y~%qyx0e&H_xZqgv=48`B&%@S14xaHG5Uk8Kx!59$d@Rc?|6E>F)p+wAr#dw zu5iNrgzYprfWY|!;+MS7YB{QQDg=Ecd$}c2`4G@oy zl(vJN%vAPQFFlrOF+(z>SqC(08$eM&+Unv6DU#8;#LQ(lRE*kQ1mOb=L+&o0}OO<5*wSkl}Bve zf82HtIs!tlR9KVNDL?JqvHMp?;{|-H1kQHL z7!_|Rl`D99Di$G+8!MYLOiWNAvy%jph*Q1?cA}&9hkRcz`8Z{B$!H{3;CY(g#Vg;p zF@1l(4WN4{C<*d}$wfX+JX2N7&_@n5>cVzQSUw zy+Rdwue>!x7&>qg#9)RY8ZC5*E;uOm#lCUK9U7U2rXXkisxZ2Yrxp9re0o{gb*t8H zwHU-Bb%!O4Mj1q?bkysj8Q07;^wLQ{*8i*kh>ehA*V-@3*>raOwc1Pb$hHnV(y`=6 zL4jL;uQQmz)%PoX>Rxnvm$9Ddw}Jcv=sH`+NxB|6ar+gk1L{`ZPc6cL%yY{vdvm)9 zom;f1vrgKN8)h98g-CTQIN!Os*nbfPsL$dk`m$gS`)E8m( zOn8?EU^G)tWz~?$$kN!plHE|t=RRE--2%LoiI-DVR(gWTh=^}yj`5;=L!sZ4Ad~@m zxLmJrMF~81Fe^MCv~*b&?@F-gX}^9eBPr*S-eQ^F4&xysp_?caPfAiUMJ2kth`D|j0}@*DxVf4VwZb7A9#rHY)h?5Px~<0tXVl9 zCzf}wetM#S<7F->F7H~%GxpZiC2Z~tQF$Egr(Cn5;&@&_MI)_{F$9@ChyGk5qSW8B z6u9Y8c^+L49j~?$)PDEJ4u%jOc8e z=_Td+64YPGF_Yn!hNR09)14LQUeA%j8HFQ8T;DL9oi7OINgcax64B@#NdkQQheV>l?jqF@u_#JFV(*(JU z?xD4Vg(hUwyGh_uga;NHpRF@A1&%xzc*4D)D2^&!QS^-4MOjY)#Ubt4s1bpb#xs|9 zT<~wgZ3ky>Tr1z&;6Ycx7X>2+)!9TKFWwOpkyZxyNmIZX&t@vJK=GtRLgS{0Z^m## z!HR{eEGePIR=W%Y`5zkfxA|CZvP_AgL}BF|Mm8 zEj7a1H844wnG3R|oR7)nPmx(m?HA588!aXi$`$_84Bo|7ig`0*+IIGZ;N z3q>%`f~T8GB16xU#j|%#_*5f>s5CWccE*CBVarX-?v>c!C!PMbV+cTpFyH~AG$^9a zm{NS$F#dVHB3JZvqApyz5wC}%V{HpXgOQxO-#?Vj5TjHifN znXvBeruO|bZCR&#h3&d+fXcSHlAbay!!2t1oKILJ|a6T?aD;4X_k z!z|+EeOPJ=*>TWV97~(CP(ISdx@(A-;q5)QdWGOK(w_D;pRp3C#=pt)f=->Ly4}tF zC^9UO(JhySmlPf+Ai@I%7?L0^q`P;9Td&QtlEZeSp#on9Wo8U9uEnVcFE%E8qgu$X z&gqel-FN{!P@8&p7pDJ)XWdKWJ&A&L)sFT0^a)61Qw}L+aw$D8Mo%o1Z#Ui~pk=4= z>;5psFz8(|@0OA3wQ%DCfw!6M$-xiUp8~1pLX`hTcVjW=amMp>-x2>b;oTEpDK+{m zwPYGz#?+H-T^~$`07VJth}@1RW!%#t(lAn{h^L}8_+ZD?Y@9NO;|BBktu^<`IRZJK zd*id9qVhiQ8}p(0NjWx5;s}3I=9$bJP+9$t^2(*Muj2`R*V!zy$O}`iI!P~sEKDG7 zH@y~Jb?)KOawSA`5EB67o#J%{d)lhZJZ^4oafXya6Q}M5(=2318}H8gGks-dmc{pW zR3f@?#TaB@aaEp%({{kd%(t!FIu1GSoB7OL?e9xOLlNSK$q{e15zZa*36w;xn0apOmcs4N=!2x0N{fgl zRR|c5uV3zfM-Zy0;7v=JAx&dAH1Z}$sgLvY*y{UThh;AkijyoakfJAf0+SO93*Jzm zB*GbP4%evQIouk82+`!&ex3II!lbr)uA9XX*;&!kBzp}8Fa|bEkAP;*0fGury5nGc zO-E>cD*_kuv;_<>&VitNNm3p2Jh*@3X-4WcCdAFvObCIpEVKiCj%SvOSnxCc7333g zdaeWG&CMzsgW50@arIo!t{o{c%acU7KBjQtd`;?v37Xzdp))^rBlprV!bo2Lqp?b` zcXC$Ts+}W0UxtS>bS5&gq&HL7NB30HbeUty#u!%vj)|+$56|bQTZY~?bJ!0=TiD4Q zw*he$P3D*SX08pnD#%A;R9sq49Rq9`R4Z3`XIrUWUe0s(D@vxe6j{Gbs|~Ai(B^(b zT86D3h6CGY4CWXyQCyy;`U-Cxg-w%s!upw>cuMj;$2B_3kvzmFtPGcm1a$ne#AS&) zY6_j@N!nu#j}mp%3trK7e{z1`C>@b!yo0-P16@)_(Q^JXqJW)R_YD7pWc(>_&BBNr z0Q&s{IhF$893#`%IxJv;sVKTpA;%66$!2o#@`Vtf839#Waw3A<@Uhj~{Xc>73oKaS^9B z4h6a?hYz>M+{fj{3aNqBr_E{oxwm`kzr|s2cktD<-}fp4OVDUjKqi+%<{+IXbv3!c z)wvZgrBfB}6WL9A2y~{bZ$u3mfYimL&NbS~zdUilg~d#^Vx)4C``N#l4At|uH~>FY zipzTbm}ri|3O@{?$6%>1T(vXl7B?XA73jp5w?}uV&TNd)d_Be!Bz6qj6C(iD%QZ#rbN3^6uutu*6JSm0hg%;(XM(LjY@Z4#WR1R~N?^c8 z>f|fhM7wBh=F*C)nAawT{wTU!1HO&QrHLGV^dKTh&pZ{x#@>=C;1%7C#LAIvlM3m) zizK{`uV&IKOxNzX=Cd+jHcCc8!L};wk3L4){RDkbJCUO$MHA9@ABmD%Fg?Ht<(c+i zJi1;FFA?><&Q}Zqb~Dx0M+u%Vv^x&pCHp;GJ-Uu8n2$GN<4lfzx7^gK$x;flV9myI zf|GO~@-AMZb+8&&$N{`j$)K&NJ(BbbX@<}Ou;p7x>se~+>YTuWk5XGNH6>zV4g1>8 zKFb;o+VgnosZQnC zG?yyRO#LAe6)^Rc-4mlZzmd0AQoNfzawaL@!_zj%Fgg`G3fNKsx@CW z%sy8pybbU@$(O~(JID#MgDw!pF{(@k%Yt#C_f8+tXV8jrBWTw*2~C!jjjz1ol8%I0 zs$UohSU0+0XhX>SMZT@gn|ab))VY;W#MvbTRlQ67C-cUWi}zH6!{tCLrbewdG~^D=7ILRe`yr) zr}M-YWV2{!`50VDS)PaE2)uKO$pk^4jrXpn&|eF6ZhtxQZM>xwz!LXi8s`2{abZjg z^*Bu7J(GcP`;Br5Zv8l0ZsqT!u{P%kck98P*dU@S(;TQ+n}*k1-mjv_V)zIB7DEVI zSm!+*t!MWDgQmxx(`7lv?jErDWPVy2VDh?6SWFZq$K0tj{o>T7qc&=lpi>#14k(x- zPD!hNWU(x>5Y4^=>@ey64EXqVsYnFT;X+1b?Fjbigh_q(mnGCas%~zVfLAsJ2=G#B zfx$S@nixGP2>S2rsz1T+ux>;?8=qD#v_5T@v@P|s zlu2HShPD?{RUJDVadidK7CY1f_lfkF!g7F+FqoBtiULrYL3BV)o~s{3QjRK?ibSSu z3b^DSY{``T2^sTf<)2CjcS))HFD){=*T?!vLq^=R9G}UfDBOU=v6TX-`nC@wv2%0- zrMPa}PhF8bduNQ`WCv@;Epxrc$r3>9mV*$2=G5^IH6o7}`)p!FZf1CQ4Gfo-M#^V$ zZ(#up*DL)u>zJErlWL0+rFWGfu9a@5)i%Kmd$>&rA8)oQ?efu*mtG5Sjgsdbq|VpS z^AO+Wzn#bAL;{GkltsJRW$kDIJ@+_4D1K9bz#NWIIM)ea5(} z*U37PyfQK0xY@Vo;?}XLfgU8wb(3s;Vv1-XutTj+h;iuOAhOD>b!cx_k3Tc!SfAlF*)idVIE^l^O=V zvcifg-2Qb|H!1*=lhKXe?*U^d!=#%PXgD|{N#AOn6)ot{*4eBV*JEl&=fVht4A7|u zDML=@Wo53$#&rY*i~lOteS~^TEm!EAPxrkdi*4AZR#0|E&>zPTnmdWF*|3ONf5Jc@ zjlzSR^R5vl!S*Nm(k__Xmf-iImwk)tkVqzuH2 z;BmO!sG%fkhxmG&1NGIJA6k>5??*L-!2wzU%P0P*%+*-RpSYmeGti?*9a23u6jJHL z+$V1u_n4gr$9ygRzF(hVXarOkdzp7#Jo^VBfF&J~1p4@p&Mf-g#ooNj1`6FKa^qvB z)XidIg^zW@>Zw;nC0c|OH=BC+FZ@S3uR2Ar=VQq6I$kj66LK@`(2>ecgQvq|J56Zm zB1e|Yj9{pYi|jCZ=-4ZcMdX3f9FEeQQQ<160KgNRsNw}2IE5{NoRFS&@A1b4?wvzvbXMOg z{WIv{GOSW}=KJ+`P4%*zX9{$yssS?Iae~Zs-79yr9I9jjEl$q__RnrAecE#Z-eWB) zC!$nM;)=MnPE5-s=gblZO1qHlnkwQm(ptu9jS$ZQX%I*soAg^`y<){A*4ei*$JF}8 z%35C%rq18sfgUFXFewBA7~SL#ZI4g_hDP+VULcuxO?vGGhhO7X^a%+>92=7`Nu)5X zL=|t$f@i1L+WN!fvZ#nOz>{O+h_GhJK7Xi&L*zenvy_Ve=qNNzmA^Sgvv1)m)A4-E z8toMhqp!p<$*(SK$pNrjbmEn}a(nA!#!d0+u+KflZg{yd-q_!UBnNytLcv=L9`dYg z(cV0198|FPX4P_>Z%!z**ZN8*ER=|4FlM+ysr=$;J(GuH(@xX@C&)GApL-lzV4_>#y${VX0w#GW`S;D^E&H}z*#6kS$6LxNA zBhs&u?`X5mLZS%m{|4cQeFF+bSPdi#b7l%CB2g-K8;F|$S3L!NoZ)wPta{2nh;G4D zwW%kkg^ZSWqD@(+KnM>)B-y5V>@|g7sd*ph^k;MKJ(^;%GcXP(xG!lYI64RW&WCI) z3HFBC4v8B9Hn&PkhbkR5kpT(wW(F9PnTYMGD9)lk>65LM7J< zR`SXq9pvhc>n`x^jXVVlPM!?^0;L_g5hkMA>JYZ&*MLqfgO4f>t_zF|@H0U5+iww+ z^*^lnDefq5%P0M+l7*QNd^Yb4ix&>xYdd6};w!HLw1DK1g4L$heB*Q~Rm6P5=ihL` z{E%X-_S5PRwZU}r@NftiUtL5rAN->oj~u4H6L2RUVcX_45pSBA7rKe(cpU^vVtOi! z)9`n|wo{)}QovE3iZTv-l0wii5BSk+TA-6ofnGWB?7$(V5MwAwwA15t^>$KU564sx_ z&^c*3Cf{>)X!1$%rSt)nKx$$M438q*wvD@FviS!KQ$MG||3Sg0;r_dCQg&D2^shy* z|Hxew55Yhq$RAif@nE?46A%NBr;wj0(tqQQ-zr}d zHbyuS)H|EpoJWKc zhIaQ5p*SqH=lIqh&K+Os(*JY&h{f3__Eu(qwDdP@mf*;N`kxr?%%O{QC?aTU6&4j9 zCFqQ#9I41cSPti7!`Pmi>v)Aj@)CwP(jOGTm$sT3`3cy} zMy}0A&=hI8F5(mLjX_cQT1?SU%10ZQs61CkV z@a-R7y#XgcK7C$c|DNiV%CUFg|MiWEplLLzC-{SczzCO5k&;ysBn@`}^t3$@`YW;4 z;Qu95av#beS!P6z9oE{SD%>w7XmnZB{q^r4heRQ;AV;AMSWxjMpK8DsyYdqOEqMQ( zngs&s5N$qQaTMGZkh0(p?%aO%it|pw zX&fd?VQ2gr+jL#S`uVYu+3H{#XKBmNR!V|aeXxBa`PPv{4uIl2{l9amm^t-_fA`by zDZ(`CZ6*TSm;;?of}8iS)h0OF@fsA3Db=PHSD)TrXIm#o`2bkoPyiZIeAZwSvgntK zOCw=RmEgk{WYn`lgmoOZ^``qgcre~mEgGCxq~9aHT%PFbOekSLI9qIDvBCihQJ&GG zZkdV)huNAjBi`W1?j>1>FH0hf=?nKS^Tj{n{`6@jotzsN*F%IdFz7$!0#OiKX&)5s zESOORr%|z$dNaZQBg;ci@FP;)l37j80vDfZ|NU*7mm&X)m@g`_C&F5&{E}c_p4^YRH$SV&{Y z7Obt#{1UY_X#Nv*tsDh~r@g%`xn~~auO=i~`T-}^O(n%P2A`>U0=b;BiG+%JP^EIb zu8IkM#F+p+k%+(T!nO^5c`_DqVpxzba|A8xuVY8Hg9z}!2o0rGY|MjHnsECOMGZ>l z?X_~(T0%J10PtsDh1d2+jStjb-=aJPMJzj$4|wwMZR!gF3Xn(fa4Eib&k)2<_JZ_KCfZma~?LYo#U zx1GBk@ScRQ3ay0yGTWDok8AJX*tD0>OP1=?tXwro6mGyx%$Hr|{GozBKFMiWy(+{a z-Ml#q>p`?GNI+#1^l~}Z5B?YZ!>Nu z%xm%~LXPX_PL}B0+Yk~8msj3fK5y^!?Vi0Frm1HnyhSSl_1rm^*?#m0A& z+^c<#-<92JJ%Hyl*Ocqjde5r7|?ZzQl}n(C}=mZ;}=zhcoSbr>1g zw{E!=IHEmXrQDcq1Y&G5tro(53Sl4D$c-s~mp!K0WC3rqm^54U;&E> zU&v~Sko~tK;MtQN#H90)>t>Eye$IEH<>;I<8N$Ekl}-TpnYvIM} zZ>df}*91L4#kKaX`ipWH;|j7b`6tjQUN=R?=Ms11BH8ywN0Rf0zyp z3jizd*`MWfP0BkcvM?F(gcbq)AG&nEl8KXG_)W7Jqw|gh|1=)8*5+}yZ>4$SLeIVQ z7Y-wupYoe$>V%o8qwrjP4&2?F8_SrE(G$t;olQei7Hlr^LX72|;-Ilt7cxTCJtR-y z$3ut*sRBg1%=eyU+Zs2~IfOn)+&trdD7n}_QuDd9b$yuQpp>|k->~8z5YamUuqHF_ zSBU}k5=1f*d0hzzLTfwJ)Hq6_y3GjunG3_3zZ=C+4iqH5Oc9slbBP}DI>|!q_s1iW z(%>#6n@B0T;g{X#qxXMMY04VvRUThrC~7|u!f7}Fkwcnab|@%A4^>TKo5 z$O|J4oeZjUwQW#FL-Xls5AgnvX|Z2 zq&BbC9+$}p%1!#@gx4fva-V1S@Yg94a2qsSBTZ3X;v8f-VhU@ugNs|lOBN6$b>Ev* z4_=ugDwHiOMfaINOUT?h5xvv{RjkwG6Z+*gBp!Ny05A#EyH%_`sCR3Pp*p4S=1%Bf z5r2^)R~|%_@)Hinhy)0i^nHo9TuUbC0XBXv40KeYI^NRYq$V zoQFu*WXu0Hc8$W~;($U3H+!m;6URh1y_|J;wY8Bl(PW-(^?T>g46PF!@3E;ppKM@4 z2g8Jki}MdaaVG^o>vML+o`Jc#4K3M_EXtzB+{=~{ht`x#(S8$Vcv zfr2ec&zWjM+TsiNc2Los3pcb8<(Y6sa7nx+k9yl*Kwn^@OU!?9CH23S=E__oWr1OF z_}o}of#pwo-R&urNQLIJ+yvx;byk4a@7TVIl*gufJ-BvH%#0i9C?%8G{Z*SH%^X z`(C0xvi-cr5=c(*p8n3t*Z;h-Dfi6}#s~+H_w}GzpAe?yL;i&v=iBZ18sEoLB8z$m zverCoF^UL>2$A9w2>CF)qrEBhy^tn*l*Wu*kUAM}qFV*uJF<-I-P3AvJqQ6TJCvBF zxLZgZq#eI?RqovvTTbQ-D|tPg$qT=zL0GFRb{#bw!y!;Yq7hx&nHc;QrgF5(!+2X2 zg6f${4d8G~9TW^~7e9eN$!Cs=W@fj|MM$cAYhUq=el`Zue3sy5={ljWta#OB7>QO` z@fr7l5)TH8psJ)RU?8Xpp0^Y{{+q9PTE>DLF#adi8G_f3E{-0FAv%l|K3C5JyIQSd zEP^HrbW^AtPXGHab^p&yF5fHXf;S$V2XT^*_-C(xu^|C}^+}&fq#)pHxi9bl)YiQ} ziL)5c2ExsLs^KaYP8k9S||JHB2zW7 zXB9NlA>nwm8=1M@Y2(Vvv!#5nCI?6C-Holh=cFPC2Pk?~Tqx~TE7-O-R&_iBZ%kq< zNXr*;FGO#DqJLASFgn}w$E{pa`bcTat(@NV2O==EyHtbQdzN)B$ABP?*X$yJIFloZ zBlw6z_SvIZus~DjsF2SIb0!O<}1 zqZ4^Vx8vUx|BL5->dT_Ro(RUuBd|zgJRE7e76LNagn8O^b&NbJ%7=A)Dk3xJ&7(FiPrAA);9w5w}970I*^8DZZ1i;Pv5f`wRlAK=f z36_!T4Ca#F3j^l}$a*q3%T?;p4*3cxGk z;J1&PUh0%v#kEArPCb-o{AX_gVa+9JhHIFfszi|;PdmhwP-DUi}Gh>BUy1}pZ1t;%KNib(4i3UBi z6swzL<%?E}Bd7C>qnD^)%=pWga&o^VNrz%{W$RW3pvHY?W*_swYB2kVUj_cdn3yKp zG#!P2R?y)7Um<;l7-7s}ztDZrjEe?#ykA0xz}M&>Ke)E%eh)6 z-hwCP@)dZ^!PQ}_$+K0`JmN~*P;ebE2vOXA)OA^?lja}`j#?FgkXhaUgst~1!^q$e zm3P|mYmu^gm&(=4ns~+Vp*qRo4dVD+W7t3u)&1(F6b*RI5A; z)c&VRu6Ge(ZcQSLwI#mkXtVNt>ha!qUeur~9F#aT<77JYiO72TBDl2yz&bt79gE2C zK6{v`9IaAcCO?1;)d7oe+*~G^X~A`&XD<0QPQ-TsZ`uPjW&d)3ky$~gq8XjI?BX{CB!U25l*sf(qIGqa^dOZe@{V#p} z38W4GA{Yi@n@?lP*}~bMDvLwdG4K3wMjp3@4dLZV-dlj4iiTg5fXruM{f%~_64c7TO^s3%9pvV$#*U5H)9A^H9+IyUA>h8w?~w3NF6DTG`&8OzI} z>_e$Byqe<|zHc1YClc|s4-cu2@5;j4`31tjO|)fP6}oXvMPS2i(1tkuP7+b$!GFeFy>Wsc;7`J5< zW>RzXA}8P;e}%H;WAHRTzr+%Z_v;p5b5-<5Bv~WSklddO&oLSnV&Sv3275(4qO5N_2ER{Lyzutn-zG@VX zhP@{t{iT%^18Fp7$UW0~m4*vn8w2cTvsm8-_+X%~YV|i$i(t_>4QtGuzcVn`obu>j zFkTn$HO$nL_hPDj|7EW=`13&NVDL~-Pvb8r$UF*kRY~9Fko-oq2asBKHNOqO&^ucY zDoUnqQ8o>?6~I;tBEkP&J+0-?H0T~4A`V~gH%jWSt&TN$7uJ+g4bG^z!x}UstXZoT z#Uyw&wP>Zf$8W=PZXzyDIjte8Hn=R-5zaFy9ZU}*Wfpr{{>Wvh59SB-F#RWtXS{C) zEeX&z4fZ_PUF7f-5)o|!7-Qr>$D(t`1{%86CWC!h~*Up!iJy)L@sK6{qshueS{MhswK- z%Y%&HHe0t9#BqU}!D+>ebpN+&1a|4H&kKdU??^-5-3I~IMz#Ni8|8Aif1_Azjj zooh-0d|zh>FT&;?5l$YT4X1CdkC;$`ppf?M`1x6b&4>K@2j8yJNtYve%6^8w>C;ZwvpLxQQ za)RYFNClx2W!}&+c()^c;t8$*z=(Q2at#Q)R|3emeFV+{}~NoI%mazWGW!pW&eH z7RhIB+|Wa(30AI1Fy4-<>fCeZAFHI0o(l;KHWXljR>SeaS7CSF)Lgac+RRj=Cj5(3S-W-m%hJ%;7*4TZtD zxkIMCUH;@RW1arP^SFnhGrka;C3zpuvHrQrzsdal5ZF>pp#GgRKbdr@@XkFUIA2vS_7Pi}LsmJs1=|Cpb^m-=nUvUK zY)FCQ8aWLei{X1oK726E#)_*!eZ9Eqk&HiY!Gjufjfwlug2+zA;CKc|WR%pVPbydPF%n+GB~ck?^3 zjc!UQiT&4h8idE0dF?F#51w+h?`AZwTdGyPQ)&8NZ6;^A@F;dsp%>e7N9nS{p!KXX z`e`U+55uxfnKd1WAO)syi_cw($YTQhJ6jBxi&5fT0uDs>Vd@X3V zA4Wb;-SW}k>8@D`5P?2LV>+zkEuyL6=TE-C6b8*8{6sO9V_R+2#=2L?F=iayvbRsX za=O_oFwBd`UVp)Rei(#W9(KD9)mIHSsCs!0YZfEavd~>XJtszmvoS95le7Xr(0<#O^BWR(o2YhNlxfSYWpY}Nrv^7VQ z_24#@p2x;lF%+>KIQ*4>jtqUQ+2oh$=_d+QnGT|yCP-t>Z%phS!VZ;=&9E>h}EM3x_+Hz;LH@X4@|1~ zBHLsXw}x}MRAY?UmlpWniBL_uJ}eOt1zRiL@`#^+tN9sGP}Z&C>myyW*B`m2tmN}q zZmiw>PuBf>(+8%g>RoY_OlRpHJf14zZEIhKHGMB3^xr^OeV~|`pPKAch2*y7-A-A! zR9@_9d;nfQ^Z9e`|A0y_#3hlJ$@XgzC|PXdvgyEka7b?<&nr5=eDSvngI|_MXCGEV5&-5CD~TJP+NYEN7#vGHj-X(Me$bxzQmAH0Px5ihT4rHXzD0y%#|H z7_TVz$DuQc%@!cX=~~bT(Z>?8;4q?s_6?660OtAp+ZhdiPr(MyU6mk)reR#aQokU` zIAmW`3C~0R?bL{hZTk8Il#Uf*ZSX`}gDr&EDvZo<>cJjqUE1m$ENBC5EKT<L6JRp`Nw1aO8DI^4# z+1j&H2p4@PmGhqm(n1&wzEAls zJG-NqI|F;d0~DVQ*W0P*>exq@mM%?X%%%KRJT<$^59EB^q4YY;lLTB8b0GFWeOge| z@&bDyVCFe>>89M*yS(yc=nkrUdA~QF0_3-;i@lm;ta1j}kEL)kR{%FKq2T&+ady{o zlwVQ}1&rHU|&iE;1!1&H!@(a_cKMeB{ zbr9P~xL2_JQ-4xiy5~hx>GIzWy)D@0$;Pdr`=fuoyQM(BDi=xY&BeIRfoj7|#~bh+ z+5XHYnnXuDe=FM(siE^IXz7jcgQ#*&_7*uHq8inZZWJ_vr~FMPCI^xuq)+9`0<<*_TtRW=044eDYMpx9i=0*LrqH zEL6^m2IY=o$B`p_sI?yigld>yf@zc_g+}xX+}4yCF8@PARkMB3qG9PFWVAuNJ5%6^ zT~<&)s^Z?)iG8B3csn3kn#ilncJ?t3AM4T}zi*49iH)UiTGr}y6X3+}2lBb>Lg>n3 z4Bctjre!f^OC9-9nMjB%fqZr6fz%t*K%m9Pg=9w!%Ip4`@C2s{f|}lzaUf7+nvFLU z_OV1DV>NSsEArD|StaoB9!h+)TeSQ|iREJ?k;caf3yGoP$1(@a`9P4XC4r&@UPpv#I-Ni8G$< z^NOkM_x}4_@qVQ70>ey4@ZTG}NeJ|%lpS+S-kt8Bz!02s@fIR;g*JsIotvl+VK=;n zsG4a!o?#L=wRjO1icvxnpu!fCSFHJGX_83>`s@xK=+PwO-80P#>X+5 zPVlfZ>Pr{Un*5S@9!PQMsmv44ubvks6WJa zjao__6>z^$;fgA>u*To5vWa~+D3r+eVM>GB+}w3ce+~=RH2iEfbWsHu%X@(Vlpg!r zO!eM(_~|W7#`52PN;bMnEnQl6oswXchoXq;(8Jm}R#Cp2fhm7`QV0xEAN+qI!k%j!7A|SUEN*foGQ)f5dsQceOn8Tdb&uawiD1__w>V9P~Q=6hn3R8{G1SG zUqj2;nk2z%f+Z$FZw^(|s@ZaLs)^~t`QB6x?V6m_9ss4MA1@ILvQqJ=P00LT5=~q9 zc=!>Zm`4Io2-04h!#^u6g~d9E(rA>gjgPg+5?;Od1%$i7BW-xplosY8)y1%zrqCDh z?L#C{A}1vd!>Br~y}7YPRFR|-uWk+251y_y*WZI|tBEw`^_9rNtzma7&54$ zM1+_tWz|4}Sl7K0S5e_DgbHaQZOR!c`1q{XBthqIg2B1u^iRtq8!K@KO8=FD6Q0M= ze7G}+orV@#&^;y=V6I^qfvfv~_iL#mB7-SwXI47Cuxh)I87Ec=dtbWYBQV0-9s>Hq z9_RPJ+FE{oe1r-C%|H*UEqmqP6Oh4Zk+a#)@o4jdyl@&Gm-Pchm}n&- z>oOP3l!do(0K83}GQ0_0oq=l96KoWpP8tn;Px#eH#V1|siwBw*V%rS9hx=MsU#em5 zdi6DL`vLthI72gCmnbN4VgI$}zK(>7aLQCXIjBXHSbg#ojFq#^f|^INPtZB_bXIlB zVTz!zAU<4s=1i^#h*lQQ@Fc=4bm?*6a~l3$2l&@RA57|>`y>yDFp^gHNz@A_c&l@V zqPo$tQFDyF^9?opQe?-xi2I0@XJzv0eD+^;iBJ|QWkG_Hl#^VAd@XOHC>)~>4M>Cr z$`pp2#kf8`jyyuEpYX1*7GSUK7B;22(#o3gIrI*rR*|%cot0F8B+KF)wr-YYWv4% zSEP^IX`U^A-JTRhX#(M{?>A=s8hVrXVMA+TaF3?foT5LOuUy!~s;p!5mU2+0#yWzGI z3)Cv6Rk3hpl_Vp%+$+;*V-`Ak0Q^A@1U&_&7ic<o#fR+cl{=cv8MgpVYS zHOQ#_ih2MXrq!M70+8*kdNquEZt3xQ8Dnil`{g-*P9Rsh^ML-ihV>Y@e;uItMjW^!uzQ8C$UTR`=XGfmtIy7D{~KKwdIdJBDyO*$AQ#*F7xsD z%>&m8u!5@57<&3^^p=f#0^IWxW&4){cPX}{_e~EV!IGH^bc-L2bh?}^vnm(o-ZM(7 zIa^z&DxU2s)2Y?O1m%AovYvrb(7gQ(G(G@V=!+hI1TV^*>~1%c%I^Pi{Yb%#+}Pjd ztrK>;pf<1W=fG!mAefMiAf*NMh-tPcV~O*GrC#L)nxWsklp_58@c{q@Q&X6i$t|N` zRgmT5`Xn5Y$1}Wy^H?*x&7?mXm%7Q)`U`AB0Rhi~_YO0=R!pg(SR~EwKs~LUc9$sKQ_`s_qw2)AgKp9E>n9h|eDt=IxLJ$jV z$BT-vexR3m!VSc=k8Rf-_sj>paab1YW>l~*d?G$@19?RX8iPOU0gKK zs|X7GYS#@7I=TdzNd{@|>g|&p2=swKv6^89ZLCx{Pn1%Yp3{TIS`04FlsdWo;8FqL&kr>9zT2F3=reZ>9mzM%#C(llE*kYaq*7>hUzsZY7_h)JDDxXOQM zCJhn{h)1wcjxXo1xGf=xXf2+05*bg-N%z6ZH@$xJD5i$jUob>WUBJhNDt>cuRuW5?3@mEtt`d28VeGRg{lpq-Tw6LXtTP0^bb_BISh^IDK!H6M>?NMc^Q)VG|4cLQ%;+(gyLv)1`M zUaZPiuV#hd7S*{<@bGo9PV~~}o&vbm#c@{8oP{aQc5unXlN0&@9%B=>i;@9k$V`5( znCz*(9hOE`6W_zn4)Q=d)zNw+N-EEph<0Y};ljJn`?nrQ~2x&?2YSW5+kWw!BSTBzsMl#SD%O9H=?s`Uaiix;R*fo}rc; z&qBF*#a#DwASHH%UFsOW5W;A1s^{}2$$#$aswGN#f~*SVSf>P{0mI-j8f8F;U7Jzu zwqQlK;_MU{z;vHGR?C;Q=cu0-_p<=&xvr9@m}FOhg+{LpU}g`2&?$jF-1UJUoBb#K zk`aG;#_l*SG%f-Z)1fYoc^n>)ol|Xl4v5%}h8%Dm0??7zep{@XQBOH*(TND_Nx_(9I zD+k%}Ig980IQ>Wg7Nb?G!7I*gbNMnCnyCW7b%tVEoVCYbF=ye( zV=}*4hLW|iu4>f>f@{P>e{}64qbew(^_0=&v>IqK%2I7#p3ul zrr~W{#uUm7Zqbm8QkR!nsw(4~6K{nB9fj4pL8c6ajRThc6*nU6XFmJ|yY4ZYaFg*J z#nR|@{EDm6-7>_FGiT|!iFU}%CSxnUuG^L*ek60Ho!hhNzKgW10YT-oksOacSTug2 zMpQ*|vJR&qi0i!Zulf3+<`R#SJW`I9JHFgDLC2+7ah?CAIG;I~TPxkAj?4Ot@JCZ; z3k|i)%D@hO#-bv-E#~iK^fE_dLh0338UCFLAUlh0y?kk}{M>t}G;Gq_+y-QAis;=w9GCl{W( zC*Hw;K%H8ccKNEyf#-T{%K=;;tlq}pSVkH=OV(jU9u}LQAW@h3=c?8DegDjny0tp3GITwOmK8OLEd>68HA zzuw@&V{v}w?Kg_&2P-)s*$csEM&dgx(3#R$h@|Ifp#O<-`Lp6Lfy<82K9^NrRa5M)ZX?Fgr-D!8yUs zmPJ0uMI#YmAB@jKiM)}A^3tQ(h>*J8wZF_M`$y<)s`rg5>TvuJlso{wG|`v4mb4xL z@vIMP+7;QFdoc7|-gbqa4+(oDxT3LvbaPGUWphVY$`WyUw6X~X?b2q||0uu90`n0Y z;b#*!xB)hS>(8~G=|_hV{api>=I&<4w&COs=Q!RZ(K^TRG%u|QqpM^}eo|=k-Avuk z1MNqXZ!xsrW?0D@SS#n|8!hfK&P@dut&AO7CSbpe{q2(@23IrjgcS;wJk6Y~{O{&# zt6TkyGP^p`NT*1-)PMw`;ywCpvtnWlvb@R!&d?VEe*b%x#Wseoun=!amE3TDY$8E9 zelq^u(aQJGyCMgh3+P%i;dSyK9Z}ScnG@1_pozPIJb8*>q|)y14Z;Q@l_8@D!Ml%H}kVK ze!6s&Ej_w_Ah~@MaKQ|ee+rhD?H25#U=7Vk#x_Sf-3D>OubG^tu}g`vKOL$)s0?R3GguoM_{d4nZ@w+I*g%B;*Ka$l%p9`}Yk~f-pwElW`~Io?0q! zv}GnsKW#9_O!;7aGwtp;p_UMgG3EaxS|+)xTK$RcrNO}<%R0AmXQ%8A4{iz}=f=b4;pM+AoqC#4 zqey{J@tiLAH1`1#>ag>xLI?m0Gud~kLuux9Bm*z+a?N#?2oD6@N>wQ2eDwtYLvM$Wij zZaw^UMPnh;$o%R_t_Ip(jleSs+tm*cP3#=iDnT9O@t#X!=)WWq8a+DW+YFlsHw!8* z5@jA!?J&2q`#_l)5p`NTGjm1u8#EE^GDjnNL@C3EZc&#}7*8T7uA~CPeYos^<>f!X zJDyo0&P;(JJj%Rv6J+auoYPL~DumJDv+FQ_tm@=<7k7q;+W?UVCepNKY z>4v^-2qDb?o}S10JQx~7XA=nT>1!)@j%;DKxnw#@V%SkqMwVu? zc%*bu>K+ey7p{%VcA$7iz_emZTlCElVaKarY?sXh6FaR{uL{h~QOiAIT51tKP`4NR zDx${-T|U)*KuIb9_8&hkGD?81Im{-+jlVT=;e(J3S3Z2!~lFwKl+)~ zR9nj!jn1w;m<0y<+2?as%M;X{u1pU?j;&XYplgUG|6z4{w{=L7lmBF6LaZ@rOpFL1 zRF7uKVYXB{*f*Tg@NJnhY`9In=EQ|`Ez6-$h7Ew75|U-SmNFc7r-;3VI9 zY>XroR9)GuV*Gc^0_e8sEEgeg zrAopE+)kph%p2hz>a-0N`C6)J-LY@-mp}3~g`YTk;Rx|Ags@c^ry#sgcx-x)v;F#b z&1#vv-9{2j8cU*9I5Ue@^&_lg!JYPF##s3NUDgRVuz240ltw9cu`!O)U|y^)g#BWD zzSM&iqq;Kd-n#pS7yRl3S^myTW_0%@%lC$Ctk~GVtsL#BJVe~@;I)+82NzJF{y^?L zEa6SPDjj5A0FtjhlXWcLPd^smzZ}$Igq7k3a;g{?mhcuUBWWVPpjj6C#<8mP1i2XzFOd;B8 zbgA#~r;ayMRxe31H~a`$?{|rqDDrFqB7{(<&xq-;d;5(lndhGMG*Ht|%-!t=Z#yUv zg6nxY0>YRzaLVY2swhWGv^v%_*PB%zzw<3?^PP*>@>W`L3tr=DdYrD}rb$%$nLBI# z1aZ1N(z9^#&Od$FffV5N&J`}B-r28wnUmeJo%Nue$kDp5UN&BHZ>1M8^(F0LFFE1* zB0r%#zKs)@-;}ZMMNnSEMe+Lmu#w%zyHy98ct?z%X?N?P;z7l}djrr8A2g;1N!z*b zItMprVb{w^>^pZ$K&!~J*j*n4L|oVJ|902CZ6pO3eA474p17yG43;#Qb8yG2; zd5?d5bULETQLiT)_J2#uDlIG@o+vNIsRB63LtWF{H$!w4Xe0MD9y+{M(7)V5IiaU( z_J;|D+ETeXxCU)+2q=|SqTobz_X#zDI_>3pv3m&^AT7zgD~9jkIb+&0d7lmNi?ypZ zYA&l3I^KC34CuZKm+$GATZQ?@^&?yBNUmUS>kjH>I0_sYep9K0h9iA!!>hTI^0mDv*Q0k} zKTA_WjnqyW4!t^LYUQj|DCs9f4EolStLu)jYAE+qGvpY-W$mq&f`=1IEH_Bwbf|KVIbo-dqW`p zY=nzUJkG&4I-aCr5)pt@%|V$bO@;`G9Qh~XSfj}sa;i8&O%8@kh4&2g_bi1_n8hhv zih1~r&J^SLzR6xSqKhc2;Bk?|$U~7#1OCcL&%J0wcBcLx8}+%eJG~$xDx9RZemnZy z`iQv{&f*{KoU*l?IW+S(A?vPITeV#pXwHhC*nXW|~8v4k`^U};lm|80 zoR?F?CN}amOUGJC8ioGnFf`#}X$MXK-aoX5`L4$XSpZkJkvF6GHQ7hhe|Mw!D>%R|azM&6@=44mdl_fZR6Jg*2D-9BKAPATI ziR{d)#R-PiC4AO5gsqZv26%bQ4JLg*+i^xNCywTkkB+*|A}z? zcLc-`0dTew%g<;o6e2(Mz_=Q&SpL5rI^M7kMe}leOHUl$v5gW@SnYPX^wpMw+_#nt zx=SZ%V(0x$Bmev-%)rSu3Cr`RH)ePt_rY$R{Xf)&3%hK-If`Xh45k5t(j~r?Hm2AO z7QAf5hd3GLC+>iPb63`pVe5LPhurW6iqVP%jNeo4g6E3xsEGXpwSE@>$hHizqbDt{ z2KQ2`U{VJ@j?UAUufT&LZGV3$6_4x?_U&$<2TQRf?_THUEGUPatsTH_Z9L&lI9=kF z-f$%OV!IQvf+|2&e))9_9Deu1hs1Su;H^F{!h#`kwhTJWo{CW^<6s+!I6p^GFDC`P zkiDJ#4mae#B-`z^R@~ttn1GwCkqVs0Yu$b2o+s9BQ$lPR?e^v2wM@p8+TuVY9D+)b zCV~qECYfA7HJLLcsvV}qyB!$S^(HpoJHp51E?7nK5iAYuP2fCs$sykVWfaJr*JH4i z52=rFTAJ{fxY3Ueq+q53RdRyd6{`}0k?(b^6>!d&3+Hf?wg(@l96qeTqCzILCVL&8|bJVQ)M?a6U3!sss+uurB9SOK@7fM20ykO zJ$A8_O2^l#kvo8;Aj4wn@Fsu%UK$)@E-EFgarCPH(CPxV6o0CGCZ7C%W zy|A|yjvM@FCz)l_JPJmrv%}Z4O(dO`zO;6MrDpH`0C>E2s-4^pJ0&Dh%>^Rf<}M|M zlp3Mg^;h(`PP}s&y)hn%`Tz`Cps%C) zJ-0ki>;~ZSnb`($!V}@qYe^5gq(_@v_BOxpPoXz9-Xsibrt12;%!cj^702UK5GmjF zIvk$Ct8@rc)!a5NPQf&@LYOd+y^I!q7jI!AhDC6vnDtYT`8#1?uR(t;;0knsQw%g@u_J$O-> zTwXb@z2HxSc@Kc6XOi7T$@z~*c>?d8iHNWN2H=`J7Zy@%$>T`ywpFn{yM3A=kpC2J ztdbAeR-TSGjt?XIbg_U_P;83G+0|wJvcI`uQQ#v{8{=E(3+{Es%S0w(DQxFMgN2{L zi5Elz>AfJs9F#!-yEmd;vK`%GdB`&x-Gtqa$32ruxg^u#b-;Bb^J(Ouuy%t|iZA&j7@a?W4#K(qK<_k> zN7IHbX;|l8(E&+FnW4qZGf5V}bSlDCz+b?wNJO-qj!nU250>DnVNK?hSn5yUym)~y?{3>Og2M@hy;do7^Baq|q(z#n}IXm;UDT~iS`h&RI~mRU$YaHd_$a%X zSJ9fdAhgK+e!0j)GFc^A1mzop2>=(%UK&12)y^8nNFpw4>hCkGeg$VgW9uoPT0WvFpHyOWfs&uN?C=tvk0@ zZtIOt#2Y?jD%SIGaix}n=6PDf5>IP@SOT+ZgPE_G!p<3p`(MZ~j<0Z2z%y)BP2W79 zL5QQ&%Qc=F{n?5w7vI971SsRb)=kNlz>Fc#d%m7&v+lP*hl$Cj6dc^OV6VlZpE&l& zmN+oFD$Fw6(J}zdU@syTZ;k>VDa15PWE)ebMY&0;)7K=bx>4as`*Wz}%U z#+6)-(|p`!3xX+$T@jTAuZuM(s%!MN!IH%vXFF`py|m`ZLPaUMbbH*2^kmoQc=v~v zXC_8iTLn^)K)LV=M`?8HPPZv2Ctlcy=5m~mpOjw7j0v8`M$ z=HolDy13KLCuBl94u5N;81aqNpz;nwg|d^erb(`Lfk@dGxT0A@SwTy|gE7}sAP@-`BCCwwC&Az$nJ`$si`(mxz0slwbDCKdKY3^k~taa&hemw&{7$hxy^mYMr_*W@*s^o&u>N%LD6a$iO=`sOktsfc)x zrZ1~A(V%X!if1klTIw`lN9oG}%bac@KO!OyYD2!>L0Us2=H;v@xP9tf18G$+nPd24 zThGuq`VD6PK~Pl5fnpc@BDj!?=ogBNi!ytsKo4jqre;kxJ(qW~_P4<#jXRg?)J=1( z&7vEi2J-NJgmR@@&{qg^3%{CwYxXU-2;Xk;j-|Fz|_`chQxa5L`#~4G0H1 z(RwM&F6T{ZQ#7H93Wb-0`~v^kZ*$FSE#|4bC>of|sCpf8^|k_PBfGQgu`-v`4z#$r z?*a(yoVSptFqCth=N5G)Nxl)yPN!Is{Op+w08{ z(-lqW%|RjUR8F)=Q#R1s(*^zYdL|xEV|ka(Vd2z;vTkMn77tDUv%k%xwTtEs_l7?Z z=bBM{CE)526}IgOjyCO)J;$cq!TJ>5;uVL7H}Oj)O1KIL!;tMLeGCgbc9;A3RIAaE zA(e{0gz~zy;X^i?n-7AR0rrY6nbNyyQW@g<9bjici|LLSJNfq@zSZHA6}+ojT0(@? z{DE%YMO<9-N-OVorV}e^BaU6|vjx7eKI48m^Shal4w3HyN6vo+^Y3BuVdJjVcrh*u zts*cfDCPqymRVjB>O3+dWY#Rf@`6)wfkSJLAg&WS++evc{FI|M7+tuA zyEBMOtImlzMW{G>2S{3i?BU`{I(?*gH`#7!*9>x0Bob31=+!h0aj-d4A!><|(%Wp! zwF(cXBxz|@QiHfnhv73um>iX@z$|U|JHCHs_w?$LSYD8JTHD~}lb%aHq@8rP3|efE zSmTY^La?9YR_uxJ*L$E+Z(*jzGRWSFOP?ir;5O_X6;nh774cwm4q=c%UdB$YhyUk1 z`6i#PFL`{=-m+iC+?zIUkrBn*w|2EN(P%W*Kx?gCrEfARLU4=-TFui^;yF@L12sC>&#y~gO6ChPqQQlO9Vw3%azf<- zsN-~xWj^u73-0}!!tn>eOb8nn-Wb^fjwj_}6Ut2mBOZA~e*cq4>kXOjaiwta6VG=V zaLqTV4#uW+BgK@_1mU7nDiUTJD5QmxLXVEL!B zQp5H_hpz!D%?Zop3J^bfLGgAvt)&Kh>Tl`yTY}3-50RGdEsSS?`O(s7ea4dU&dgR1 z>AazP!aH@$1|jJIF(DJ+fY(DBZjMbek#{M<$pmGzTNf6Lwc1{jVJUPJP_im?3k!H< zj0PEmxLN?q;D$uqTcn`Rg@N{*TRHv@vyl@?HiLnX@qSKka_X+s8l#l{Oi^NrACu-E zpTZnp4AVi@(3oEK&nSgKWe6%atl9{A(uH4o*q~|U8$VFMW?J=GHndFYh#z)Vk@&%> zhG>ZDcK3&nf`?_DJ+UNsP2Grf0|CVAkBcx}b5#{qkjsnRGFlY0ktiD{X|%Ito>tF+ zsRvt?u(|t;(l?*u4^#0OVUM|S_|gcwxGdwUQS7w})Wow+)$isI?1pf5f~qn-u9;tlhk&ZqY+_<_<5U!~?@_O+P{Fp5EjFXIx33(mqt!n1b{o~avTOvZ&@It(hsW*+j z>Km@$iTNE;vcgp1h{6DF zH7ixw#$-s`67DRaWtLVH#a1AfaYdF;1*(lqk+n5^0U*Bwb=ntV1x?%pT;TWw3r6Nl zhJ5^<<|mx=y(Th!zvW$JF3D_SQLFx;aO|KPhY5&k?kOm<*K7^Ss6=V+QVR1|&Gc+a zL}!&W@_;=H?&k@CeV%VA)L>|{ME?Biyp#552*3*^8BfZ-G#^V&7Gb7RaSf==x&>W= z8Zm~bciJD~0D);?+X-3c5FnK$!U~uLpZv%*z^ahk%_M67YDPEz)?pcbrN@}2Cp10_ zTHGEaa&Ov?^5*<^8A>c>f(5$!0wFe4-#}r0#`pDH9m6DtXHu|Ixk$FY5Rdw222>(m zC;#xW(c+PQB8(drgLBd_=isJehlmU7{GDnO{Z>K5XHy%3Tz0KchYCNd9##<>uofQT z$pmTaM?@s0Y0yEMtkGckm$YqIR^?Y|9!Bp5q7qb!U;vJC^c(!d=SyJO!x2?-zb!U1 zDXsF{m7e~KqM5V`;mJJ{S`l_X6#Z$aQ6{PP=r61O?BJYVjJBMrV%uoqeL2MIor*^U zMubldnckrBh#!#1W}-6miHdgClo=!IVKXJxUw(a$dd^iXJFj+MLXgqOcF-eSVXSxH zi@Hd9U#r>BhV1nUu#)0d;q0h_CL8AG(vi#L`p_Y};4ezK2|+M6W4_8;`$dy8 zprv&oO5MeW`(P;;rwwg`P=7id{)U*iRHPTVi1isJT?Ckx!-(XvU z@+Uh&szdEj?70K6#1F-TrkX(>nCyArZnl@j4%w_>-D<^}B^mkTM|01s=b0A_rH#w( z|2q#Mv|0rYohB^SF+j!ehB!gq=mLG6@|`wzlRSxVd6<;~4Tjzv5_oG$u;G)FqYw4_ zUHfkY{_$VGaVZZzl_Bm8ae0BGx5>WzmBgiL=+c{?O|YoXN`sM*z*f7zEZXSN3xG5Y z73OE)WF=w5m}7-x^948={{w*7yEI8_v-@{4G0ZQMaUjBXM9r;(*$wyeSt9!rt8jw# zle{WQUgV&Je6MPS`$XtQ{sTQrVsLe+NqmRMJyHBcgv507aY{qebMD`wET#xL#EL{J*y zh;<%zZFjp`d-8nP<-}(BQbb}Eq0Y;=T@zKDey3W%dv&<}?nq@}8-Wri6FCO~{19Vy zjb%V4e>d~L;ht+0$nojsB#Ja9(uOBvO7fi*yIFV z|BP$8F85J0acR=rU!gX+q8yFrVNG>M&y$?i2-tSaPT2+Pj;{(#H3k2pV9#KaN>!i7 z7fcSNxS@5Ue{I5~J5&h_k%fxox{=-lXrq~p;Vr%5r8q&{?Id9#Uz%siI0lUr4j#y9 z_=^rVy$`0DC9BHQj1=T)pZ^vnThW5ysHl&HpU!sl$Kdg}onWz2$f z)2I~s3J|AQ7O$$Qm7K33yxt3He3Qi>-=a4S@U&v+*anUr}^Ebi6#& z_qP5z;AFCr3hn>9O*s%+Q(d3|f=T`4qjf`ITzY(f?3DfV&(ju6UbHCp!DtsLvUeVd z_^aFJj^0bb!%6 zx!QPcRLNBaJ?Zmr6NogD@Qepa%iBDIuk+5WnKUjHorz-*EFPE%mK3Rmht(9*RCy9q z;+U^NV)e^E(h4so7RYHPwMGP;N3vrsSh?570@1;|BX-8%1T(e=_K3^F((861+C znWQR|Z%0i>4x?SNSE~7mOay9BlK}E!(M94OaW%JIa4Wl!uGnNC72v%3o2~GGSFIK* z*3aoJ03&NOea(F4!ZxZN^A^ICyBMi21=n&}2@(u)>*a&jQN`^u?7&}F?5yK6ThP2p zkKhyYEmAjLDN*#IDBCI_FN{ zk(dY{(eDQ?<^BH2(Z1>CF{}K@4f(Om58^H_-NXIrcxu4%t;rD~=T<~5B-72$5YA+V zkS(ixy_lq_w>qSp7sYCPd=BAPCEfz*1(B3$=+_er??rmN95z3DDOol&CtWX!1AzdZ z1@(_Zx=974RVbj$Qk#%*LQz^QN5$q3=>#tZ^g>SNa3&h_Y#kgN;O!xO3dAf=18RN? zmDm*U?^>VaC@0hF&Iv^#%eJlLlHn}y>=Xh$Lf83PXJ*mO*at~2O+5xTI6@H9E;yse zZXi?jDe}=pj6YsD#_(z~Pb0bfNGVCwh2USH8fMhSsq3f8|CHot39SJfXX%^DGCt=M z8rBkDm9hohjQTQAK5O}1r+y>?xks(3;&;h6twPIt+W}_384<@?`sa(i;tZUIYe3xs4O-IGu&Idn z3T!+3b&xUjrXH1p2<9dR>`JvZf16~ev3#6`28#QMV!W~KKP6uMo3#ytz?n_JLA~d^ znn*4O3|XhHQeEaM(?vk`L3*%y-{_kR@75;$TSn&`5g!zVts!QYrW%MT92Z4pF|E*d zY}x3zd64gaIZ~u}_k0OZ^igs>uTu<_{Z8~G7sBM|)5H8OKXiW2-q)9|K_6!}>LkTR z7YNgk3Pe_9+ghhPj(~#0s4%Df|B0>ZWiZ_oxA$-q!FcI3i^1x`o74b3h?bce9Ae*9 zBsg9HTEHj0n}KX&-n6u<`ySA0k`(oDklC|J5_i@oJ&JoI-inH%6U*uPg0ouh9p^Pk z@pDNpyF_WOa&fpuB=JYht<>c$h>Jzfnt*L0Mvi*S&x8pNf$*=H24*x&ZV|^vPJTUD zSGHRKg4LN#+L|9r4tT2m7uZEg3o@6-EB3E@u0};jd?h+tIwJ`BB5G`{?U@61*VHvqBD-!6&&uA4hy(| zuY8M1P|Bx>+~4j+l^Dg&*eHUnCEpenM|%d_$bySRRg8N%gfUsOX<(;jr$!OjS)+L~ z@?S*GQW|zczc|>jj(x!gG-)XKJw87bWc3x^RhN{WPjMzkOeK+3MXP77!0lrbWcT&~ zAa~7Z%>J?v5Uam5Oln;dhEVN7?jvR)NaOM_0+C+NPt1HskvL(!Pwt5v!*{?a?N--N zpZZse9UFMnpLqk0x00EOID8@VpSbtQlEuSX6b``SLOB^nb<{Zg6oAAx@SsDLz-_x7 z!>dHIT7ENHu}hN&utd@$Ix9iuI3Q+V{cr|8MsxZsMw!~Z3kTcd2JGl++a(6b2$A5F z--9(X>z%0JP?@BBcG<+U+MYkF9okrNbRY0=>lH50DT$|qebX56b?|Nx~da@1Os%0XMt#~;l^{-e+ekELZ zSo(QVB7T$Aqz+j*lB6EDVpy+lZz!5(hGLQs-GeF65C-#;bM}Cf3^rUVmf-6$Z5Csk znS*wyp>%`_4DE@(|K-z97^VYM@(JCs;i4t$4^EBl$`;<5Lb7jd0c@!fDdiH5(UP60 zP!xPGpFiRuKRZi#TT~kJbre(ie&b7CvuPw%h{Nv_9e~W)~^*&~4&xc)6caEEInyrUG?uP|a z)Hc&lO_Ith9FpLVBrxmuW*lknS^j#yNPwysO(Ne?~Mk6o+y9%sjb)i#z zfQ|X55~<=ZO*ny#RUr)X{3X-JXfJLCLQTIoU}OxK+b6jaNbkH+wNggKm=?j{M$BN~ zxY2BLSn<+!qywKl!afceG&1B_u-=~`6WDQrS$f(V?xfVC0B9zp{^fl6hp#&Hv$t~0 zzOE49PV1bHhFxVcf`wU4&h(A&@hWow>+J447g?ol#v9}OGT-Zl; z6D~H@0mQ&{o*4<_Yx0ELs9`>**DV8Yl^nDn-Ov3l)#kCNZe(7&JMPu~57oXs%b;gN zx>aT4BkpdKIBKm++$V}d^*QL46?`8@mxcF(sMi- z?7mh2+@=c^RfMwsb8&8$ul&iI2l5DKf{VNC2xYouj+3y7M)l-uc<{*Bm`h*;ovw9k zdV=}t^gq}%k3U;bOJe5WurJ>V#XpZx>AW^ITX04;-i|piKPtQs^wgAOmYO&!b38!k zi8q>9pft1KYAJ`)Xl575?tXmBO)XOAAtl-+m3j#%lJk7ONwS6Uln{NH%x(y6=kRWB zQ=dKBRc9-HM$QZ&!@VJD26;?6&S%}{OB;pvrO~&f$Z&1I!ym5g&g0*&$s`r-SZ4?0 z_U6J3#7v=QF+CPW4Zci*!Cg8QxUThgLze=bY;favRHLF$eNMMko(QJ^XWi2 zd2!JGS-2u7o+Oco7zX96EF43+aT_C>UmC*R~CkordeeJJpd&5Vxk=;6|#^foa2J5ISu_> zCaN^C*hXjZu2QO&?tc5{{D4@}ZDRY=>tWn3WypdyT7Q?1ZhJMyD|CLQk_*z2|Cx#F zy#G`(-oFn~lp`=^?U}kQ(HET<`e&$uRw?PwvFLJubGQx07~<_&-lI5Sol0Z09WO9J zQlYMUnZ}9L(6h~Y_SY>*3K>lWEd%K1GbAElflDI;i?>_w<;KVjkg|(bR@A)K?gCK> z^Yn^2(ZVNB$v~KX(trIfj4*|u>^mR6MqlUJ7GdjfL!}Ow9**p&*BX4j6T{5#pB%@? zLqSbkfSv@{c6dF&eDy+;Xake&VA9X_EV-Cf848IDG3Zosz=7Hf9gB=2yram3-Rzx& zpxQsb<~#|F|NY<@C$opLhTRzHpz@&*=3=SCqhjaX23N8m4qLM^>}wLNPZPm2bzjks z9+=jimO%M5Ea02ml-!@p+fd5|^pS~oyhx-m!sD;CrTwNNpFg6+coLKkM{Gccu8K&0 z3fZ7GK}odpeqBy_LMlz$Ef&_?dT_$Nwt}COV_Z_6Oh`{3ta%0#h(MEK*?N#acpn=M z9s?B?sCHs}J!oQsHmYiqVJ~mfx zO9!iC6Xd47>m!7<6`Yv&cvUq){;WR)jst*9A>f^McU*pbowixz2}JD$axDXxcfJB% z9%GPPClA6)L67*EDYouj@f$(~Ad`_u{ADAqyTO7mOoBJ-=5O7e20GRw6xboP^!}Nm zPW%Xctm}Z-NsHzy+=j8D&>?S!)?g2>HBe3p7`EmCooV8neG<5RN+@vkkWLTNaM4N| zCnJx2^^TNR@gx8^qkr`KS=vzDc-0)ti^PctPE0h!PU9zLWgx_*PfYtc!SFW|$Y#jm zBi!ESwR#TwOGxo(do;t6nL6X%*JZ}4eINsbd5H}WqM_XlwJcVb3`pvC2DYjQNuC)Z z;M0uF?|;=VtGHG}Z!Ef!3Z|toOjgqB7K=rdm&J5+_T=lJw{$NK-H;Q1$2k%wmEE~* znBRq6JMMN9zzxarg9~xJ(lu;d zjzp-d3*zgxgQryboL?KKn`gs*X3DBJ{Ty^ucti{`RAwBNd%E;u4>FE5+bPhQ@@ud7 zoeZRtJ!MD_Hh3@w2N@0J8jur**euRn52BhysuBx5r=Ds>W?i}L*Ev=w$KY@fdz|Ur26a*G8=xbkGjOmhYeDJJ?~ z&&op+>x?~Pv;C28{YklNN=B~}^96zdpoNmT{-cm1#6M7ex1nzGwbOUhLki1n5+Fa) zPa$Ua5BVNSKH9X9CqW zc(Ka*C-Q07k*X!!&wB=aj~VHrgk)>=*!$(eqHVD)5Fjl?B|$R`4ZZycZQXnyoMIB* z#_5HI_S*K^@ZoHRZFO9AKKgkPC3(pmpr39|@Djq7yVM)7mjT3$a+kC8o*@kYls2_ zA|V1Y$jpr8BnqPB8LXMIzFV%k>+}HRGMZx?Lp;}k&2rv$4guU4Qs{E*G(CgTUWJ#5w&|*@UJ`Lyyi!*aUeJPBvY0*AI4So9 z`50w-^g!iRvw%u|Z!Hlj*@vB5=tOvsBPJOM73UlZ0OR&vrB%JZjR%#fBHXGu1I2-3JGbKeY5YnRk2= z8kvl;+`eo!2`C_nw&SB<7Ys*lfWV7OWaRm&VI%;muPECCHylv=Dy278(DEHiWp^A8 zEKli$Tg8M$?8k~nly9AsZWSp6N{?p3y}Lke!ee%RyK;RwJMN`J&7#<~YI-CE%AY|v z2)!mAG#O532R_HG2l3g~Xh9ex#ez+ZlylM2E1DjkqnGL1+|COLSS&ll@AK~4Us5H5 z*?oBjZ>e5XM7GnmaB$a#jF2*MHC0=&=cHd3+y^mhva)}(B!~vlFAJ6bsq2*e?>!d$ znVBF4-C%0i^lK^aCQ9Yu0+AAY2+tJ*>Io>c9YJ}Q49gJLlkb?E!#~or|2W$n9>>-Q z;@YgtnSPi$ATv$0=t5w@LuGP<#TCh()s5gb_~s~Vj}K6Ia+KdbmZpfAIoDy`;)JeU z7a?@%*cwbx7Jk6VOr7HXw(oC#$s|bWo%nw$7s$M@uA&BZ_8Q<+O2H&7$d3FI=;hd? zmcW!p#CC4*w9Ews8R6`EjDI1pL}4HclUZOA2+Y@S3 zCTKi7*Wetd8O>t891G5NNc_q|y4bvUwm_qqONmi2aR|&v;mnP6eaL3mGABWQ$x&OFU~AkMQd&5kJ7nEje|MOWjP zl|J=asK0QmIafL?8DXtx(#g)EZG5^^XwkTjI^B?zWA#K<;q@KGStB$WLPQ>GJgVor8?V4|Sbi!akv0`W3gpBc>mcq-K<$={1qd5znZ!H$?rvj2y z;hxi9j?5u?)i{`0<(a^3waRH8oRKtW;xB>;X#{-k*U?_**3#T8rqdbjvBq^J7V`Bs zxcHF$_V7N}NuXaS@0)%y&)$!l=>%Ko*_^2Hs7}_kFqo9W)ts}RaM3$CIlY|r-!&}e z0-ghO52(;nc~u(0Zq78tv-S{Gp}4EIB9YlKjIbwo?88laPjgvOCGLP^K9jxNI3NGZ z_DSR?uhLSEQU$kE{8hIqH657oU>(pt(J0aRi6HGG`yw=}g$tbiRji z>7qvHD=88>9r}InL4R_7b18L?tbTdL&5)UeW6*^9eq1XxznfgrEbmOeVgUfC-vdtw^chk)-?=5h|*EpM)^+C4)bMugTYhX@UbwPmogErS2G zUGZ1QeX?;rW2W&#dqFhBDFO$Dv*LkAks(OOf}K;-v)GmA<<{h5maq>rt)UWb)H!)u z`ouL-Z$Ij1QV7f}HtYr|LRlBqs{>J;f?cBHQJQ<5L6M}CQxsAx;q#=E zMW+vQkSMHi|4@Jwkqn=U_JNA9sVqnr#Q+v1_QZxS51O8L##?~V2{syznbHVO8`;y^ zgt*z5y@5mb8>f-a|3EhWuI9y2g=S^E6+Y!X?BD3(B^aC!&@l17VGiJv$s!Fd@?;Ss zth?-2?J5zsR@SxBWr#ji`}<$g^};r11D2E8zD1j|#7p_5220aVWmx8Kmia4i3H8tE zrUE=nF6o@Psg*VR&cRL<)9j;=^$QK4LhKOm+_CeJWV8-nG$9%=;*bU3wqk(Jy=3=p z1~Nme(u`1gv>9X&h{RO~5At;7Jh)*&*CC&2j6+A-6@RIQR8{}9hMlZ+zH`hgdVRW# zo+nAfy+~$(-t0a4sf2JdNS*dAf{tm3NKYdi$Z$55a-pRLSngraeVC@_uGP-)c$SX> zr!rQAVD&dJ;GMg!H;FLUuAnR-S(~nuc};}i1|beZ3{w5;-0XYCkec4$hYoDPlrTNp z`$5<6m9#t4qd7D}7>c}bX*XPIfYe^_eECT(jU-eGk1ZV#z&3#Esmu$ODb1XNQRna~ zo_GCPIs_@x>AhTU3Hh)Z_O*{Ay<%^JQa36|SHZY3k7JkC>D~-6R({7QK<{pmn#~xT zmszr3h#ux!YDdyP1|w7cfAID;iuy#*7F;+nU#m~!Z|+m^GTv4!dFYZ-i>Bjp(>KGw zV`1WISw(@4rQR(5->qC?60`tp9n8Z{WLg+?TrS$D_7uheoDKNI6+4bB9jb($D5J?U zonK=`9Nb#7ib7pDIugKy%AAi_KIFm);jl!EO_l3iy?Hq@0{uwyViR8<2Z%eayH`BviIR)u#Adnn@zD!$ac&GJ5_w(%;1Pb>6E54Q6w@AOR?LF-cwZvQcpt!D}OgY>7jLbwhWl3=0x^vSU7${pMem>1SB1lj5wvlkdj%9!#_ zu1#YzKLB$MY|?!Y3Tuem%~^u}Wb%CLp=+Pjprwxrp(V6~72;(YbvG}7c;NlLOTXv~ zwzz1`woCEmJ0@~T4?e1SnM@O={**Mf00(klJl83lS?Vuq+4};M4;~3Lvx9ZWjBkH`i9!CCz3bMeDLa4uoVOjp8Gght zQ#UF{p_v9zYGdsb1;?8imO?XnMmUYVtZ;FJ;ql_oI7@*#hX@{NlAF(J(wVjufq-<@ zq&&Q+=IY;RCwsir_r{a51X;wiv_x}VwZ@Q5MjApHNEpUJax-SM?4S9@bQ=#;&;)+M zqzbI!C@vlC(&yh$evq>M5rNV|5>&2bq(?~H-2M}zq_Mu2igu+AExJ#`#6z0oNru6W z!tbJXt(8~wa;UcLqc-nQF=Y?X3M#`et*xAQwh0!6oKCSFbGciJAaP1d-~4 zA?G>mur6Y8G9_#wzx+^KUhqIQLm<*C$PlvMFIO?>PI%l}9u;qZhIhGcbvRmwbw={H zg+3;oJm+7)3to>b4;H%3HCb~^?~s*$aJF^)^Mcf5cp&(9(g?4|@HgOpbb9nFDuv;^ z-Q_e)eI0-9Q6=!vg4S3n;cvj!3d93Z9wu+v&Qs;-%4qee9@-j+^78kg$vzlzZr>Uj zOzQ+K{=h}yug;@o-}82ar$6(Pkn0$3X&4c7NBJu>qG?t}+16BGSoORA@;1Hu&DR*Fsfz7wwnHbVw=s=m3N) zI_opYoi?SCN6hc>wx~fLaQ~+@r&=(4y)m`p6EJ0%8|UoHcnbjvmPV@bj$lAAA3a?< zk)?S8^;?Z#MQ#f~e9R*xZy}7d!JPKcWBjTz@6si-%U*N7Ew~0hjPe8_MLY~U#Mb4= zg+8-ChVv}c6d?D5CEm(5fI+DE!#vA}7lRUj5*D32HX~JVW14FfV859o0cs{g`A^4O zf3nC+r>m2%Qi@W+`clX&W^M1LDm5=d6Vc%clGuV_o zT0Kj=X)ocltj&GGxvg%lj$PWAo0t+`R0q)AR=HcEok=gF+NFHvKTg_ZvtRtJ1T9EZ ze?5RxK@J2}*g{AVzJ6$I<}Wy%)@Z}Dx97rct1d{pNpiy7@_PDxkgSN&8f+TXQwKA= zO~?PtZ%Z&_wTKdPx?y30OMB?~V_*(;eBe!BiQoQb_0y`=RV=>MFhJ>3*0}_6RA;x? zm=YNB18Gj`cgCMmU){~Pf4O-Q`?MMy2i{>&z!m=*iuQx~F|0LPp`c&)aEy3niS)@2 zC6IVT*-y#+_OvUo5;|QsnO0LoU}mWTfM;sN-i0iTB`?5q^;?f$1b8xi>{ zDkukXKjOmTSsE28{bDlY9y1Aun08vVIpABcp|sQj1qLROKDpwu!fNHat>`dqu=vcP zK7M*xoV8_V`P--<-tI}db{L)U2LnImDU%IwuMGvABq5{Zxf>l!G!`8-p9c0<%Yy7m zR><}yJi2y2#F(FZxjhqu_$+=PHa__XpcHS3gyW{xn7uRD$x)=PZkLwbnrG)?h(fCP zk4>WR_6{2xKZsbF1w_!$9dGjx4TMk5l|T4*W4HD0bu->9?(VYp>C)+fjddXa$lSmO zwV6dG=@7x}5tIxYN2SjJXEPTDoR!!ptDtih6yIl;5|3PL)FySImD=?Yv2}ywH<>Hl ztr4L>zQ5e2>rTz&HPE%U@Z7Mj#^HzG33%J7!rGoMGa;4o_OMNQdY~wJSAl44j}p8Q ze82xf{AoPmtQ<#$zG{w(TB@T|%v;q?js5t)ZV|{jYm4QgNkcaiLKMSXzLHx*@K2nbjPXpXf=NtXHmtZBewSzwgtBEGm? zQxRGr8fIgib^+?i*_(b2(0wBzB%{We93CybOe6e*=y~=b*1B1ETEA6DER+{q;W)bf zp88$+atv_g3yeb<+E1Emq8Ksi*{5aekZS~Ff3+rczz5yuRMrkF0 zBxy*SwAavQI+Zu}^J3+N-_GJbD%@bO!+ZIMd!PHQZGf7?5gDG*quBu&T|c``N1A{x z@WTrB*Wvm=+iWWcnCGVK&*gm>wnVZ-v|xWoZCAxdA-8e4p5Gw^ zB+(R_7?KgdG)i8}I=;NDu_&D_Nbo+d(GMYqTL~|72zqUR4>AiMEVvyowTo6(tfe4= zeB=r3h&#A)y7%=2A&1IZ_DHm%pAX_y-}>xI2lVK|00Nt-jD30G$6=Y2wMbVb%${A%dP1==sv3QNG<$<>}u|XnEvfj&a!_|#(g|nlmPh=eVxQjx% zr@y3avv7iP%Lyj{Gu%|z;~MNRkSTs%+{oikKO%kgfGqilG~@*MI-_FeZO>|)vtZ^P z4^H-fZP*%LYOPd&NNQR8MCA+29sD(>YuXLSt{mRUN4gp}LXRx@JrV~18#l*w`#$)R z$3L+LdO?Q45L|Tb-#lgq1ap797bso{Ve<^%lG{mielOsAjfap=xHd0|%$_cvDR-fI zKd+??%>uMbIa{Pa@LFdN|lrWA)udYE*Zm_@L(Tl}6JJvOT5?gb zV3XE2H4e?eL27G;$}Q2WMM`@{;wo1#IPVj~&8|g4pB~U(H3*P94il zP2_04D3y$tRN_$*0CAl~>JtIS?-S7V(yp#Os~m$)3Co4DZhj7@1xJWhP(i~%H1=f3 zKh(!>X82+1D2m-mX`Z(CWJ0<^mw<6Mv5D=iWKIU>Ab`;N!$R|0WGcko-z00wS2llFmGqMn);7ilfl!oX!P@J{{U34X&5 zaRk$cwG6F) z9twIO3gcp=r(}C8<*yUZRbkuTg&bWr_401Zq&oZw*IFHeW>Cj{k|U*%1cWtB3cOq; zFq)8MD7orZLmmdnhX{WdZB!U_H`7L!bfcd_5R}srQGG_!P+MpqLEfOrzjPzoPKw4+XDn~8I2rM~0Cyl--a6?0rV zvg)3q=e19ckyY~zXFK?573s>BbG|_6PTaVEn66Ep{W{a6B)W?6`i@*l69Z4jshs~u zhT#8_X3o#Uj1_?J2+kfS28gNsl_;SA1v!Sjy`9aTOLU2hR$foSX}2_UoaAz@w`6=< z!iHuLn0O}VK-LK?;mdgS4QYbR66OL4a;vC5qWa!Gdk(}7NFG^1xAi5}v}~6j86(aJ z(kEVcS_b6F8XXgJ6l0;`VFWtN3=PXIM}mu=&$;F^oKwc@2i=YdPsHY32j1g7Z-LL` zty}s!VC9=?&EDujl1dmnc~N1(8IBBY#qTuWi%sNPT<5WO%u)?I_`l4u2UC{BExj2` zk(u8#C%=4F_IJ&yy|BsUa1?q$r#h~b8hbhE8j4&yGw}f7rR) zxz6E#f*jc6XiC`hkS5iKq?DfL7oZ<8MLebNz;W_S>Zh+m;^Y&;4cY*v6i#Z|s?fh} zr#8>U5x4gB^BQT4E-!J{H5Wfzg8{fI7dbjrAG2OGW_P4<AHjxFZHhCSus#{H@}J)h`+{Y`p+7OA?dfub1sgiC-2)zx9^}im6zbmNJD(;O@7t4v@1jDFoV349V(`^Pu=c zade5FxN&I3?2|<25`SPjtfxos*Z^`9TKjX{cd2>-AYiP(MzIda?k=V@zLe z`HH*vctUW0@BESe96D$N+OHmEp60a;8EkgQqc(3b3r*ESxs{WHb$umV<$AV6De8Q? z>R3UC%PLZjf}Otj4=g8Yj-*X!o`Z`UI)$6JK@`|Xcy?!e5i-0wa2BCfRBx1ZqzWX9 z#;RtV;y5K7q!HraKeAKC0b1RQhmdNOMai;=Siae^`;zO0z@EITQ5E+@eD5Tt)zT_J zS+&|RJ+PHA$ll-ZEzN3c%3*)d?(;fy7l$1feflQY>x1CDB&RNxqEA42uMW7tzU4GheA&4s2li#y&K$G1!#k zsP~@lOS5|U<5*U9H!EB2)EQnIpm&raJf~)vtgv0tB-2~#rA`;M^5sl4<|r)QWKBAua^-T{Hhztx}wrm4f)M0$q(3D1vCna z{#!|Klj@;ZuXsRMBtKL;WshVS1DwYARvFyc1uU0D8Adx@v1s4_rXyRpF0Iv~aWCb-GdeqNUFa<2|1kql{{jE_TWd`zj9K1hEQ-E6MWVK*6Q4Vz|kC3@o`McS=I z(KHT~ZkYzOMFHUV`bxeAhX{w6g1I3G1`%R)vtuAHSH61oX0kI&a`u;}wRhXC26Y7J z+>$3|8NINm8R%ECn_9B>j-Iy~Qdw4)(BcYgLi!e4tzXYg7FU*@esP75?U=_DKz)kpDugYUcApS3_>BYsCLnq;*B_v**7``dGQLo%fF5qCFl?5F_I}S1Mfv=H2 zluIB=3(<`-bwke!<&l^#fk@4kr$iZALtq@-_Z{;_d~Y?hz;-j1$98#+#&Nbm!S($f@EPewBp7!HW*Ns~SG zJ{z3TK=zPg6(&HMtMb3j|8sXmP}4#vsBa+$jwnSRxOkhF7Jy1jZ=ncM#^+0I|AF5L z?kT1wJs3Ri+ECL|F<0Mzrd*79p?%>jv^zZd(S%8qBu`{DDA+&p#!7DZBe=ij-_*PS z1%)<3Fh0Dxm`^eArbUl9yL~fl@!c`D|EtKA5LCqrB>H8#Ukog!_VVHt3srL5Q`~YT z3p%ZL<>n>Xk$o1lJD}H=D?nc9tcbQ;cp)n6HKUU)HwmiR*NQ-2Md5ZNe}z}!NdwHw zPs+%+2R&+*Y?19MQm6xTej*;!EgrMx!PofmDdTL_Y36io^)@t&mW~th;Xgz%f$&}pnfti8CcovIH8=cMr`uk)@0;v(3J+#1#25rf8(Bv8t z0V@jyrrxjS;UD_87_D}#!aHwH$=VjuK-3r97&)GvCLYjh0y;t+Vz50Rxn&FkzLOMY znahK0BVUy;LPAa;xN}f$nEEC_V0Y_8iXQ9LTio-%clm%d6k_#-#APW0os+WzMAd)a z_tm~=C=LBxIzOZvBM&)^k~EKC1vMyqeMfp5W0@o(7RX$+^UtCA$l7#U>oTQqtO1jL z!!|Zz*x|T6J-=PZ zDWurvEoQH|Dn)rvxO%nu{?~`*&|*K4nnye;Q#3DfHZV|j;cPfkQSi;CGKXQ_ycf>8 z2|d^967E>-AyHWbN*MyD90XKbh+8{(YKy_ZY708bk1N`g%uGqF^#?lzOj1PXmj+&1 zp^6jt8DKqli|~D-;EOQ$a(B@LaEK#&J1hEK+nIG0tHBaKi|gwk4%w(#Uv$#|wejIc zhO{1l?|KYN1d@j)*#t@6MpX^SuV+)DvEDJ1{mzLweH#=ZNHX^=e=Pu^dT%&%2*{Z% zzn2t*JI!5XQs<6Jep~fVZrg>x{m>m)uzV zij`&3<8EfwEOvdxzxhu{mUE&NTluP^NF~o!W)S>RTu(M%#3-e0fK42M;fsQzWsv_p zN!e~72P(lF`c~cSwcy<`y(Ps^x$1vV?Av{OLCAZ zI|0Q-G?1hq>Mk=XLU86Xs^p%s*4)Qc*Z8~uuOem4eI#FBTJS({bql4>cAvT?8!VuC z;6cF#R^R=tnR(U8AP@4o0~^0@T`Ajp5gsBX{4OXi7t2V(Z`G-I?@uc%(?_9@`~E~b z0a-Oii9A|Yk^(7#mc`DRP8|qxAhXj|(_LfOso4vfb8gDQMZ!cW<=u}^DlG4;6*wWB z;{p&Whz3)M+6p7{9%J1GDaJ+u-UD&zLwc8E067(z@rgHYr<`+)U_QS zTCKyIiVJR^^5(U^PI*Lp%pGo-11MC?L;9^j<^vfg-)&AE^Vr5pU={vVf#zj;aTPGK zw5|1TEFBJ|QQdq(?Smb}-00|! zh5Nw~B`1Q;L`qr6eaT}6D>E|@K!5>9UyY?-Z|MV?3^-t@i%j5Vnb}@}bsoSN4g#7a z)-c)Vsy(-N)I!OizKr#`U-TItyP%7%u`o5y4DHOePjcT25&e>*vV8UpaMoU~663<= zxx(NsLdHMhouAMUsMJQ)yq&M0uv2yJDfXjZd{uV>Jv#RIuUCJx@V;q5f>}oDD4p9m zYtF1CS1A&@TU-@sIYQ$i-d zn!8f&I)77n(4=_4G6K}Ks}Lcw4oQL3W$yB~9wUSt4e!z>ZM^0`^g4Y=cqTgV+_!bj zet-XGw(3@Lh&Bd5M@FB?J09cfOR`B|b6YtWic9|*&ui>ZnntC#rc+CN6~B+;d|Tym zxuyr!83JiO=0H+lV5(s67npwX_&xXpwJGIHCEj&e26T$?gUMxaO73fO7+LNH$@10@ssxC{wBE)T0^hsGim{f% zCM+x!Ictv4tff^JVhpV5S8%n(!^fn?!kf}#-#(5$zDo8qILNbsXUYul$=agL3=ML? zt2K*oVa7q&F22K|N%G!%6}%-tExIqnezq>Qa?|XBV%RTWaWPod^DmmPh@%uY;YCG( z@ON~23Xpj_95OZ6aF$xyEi6lS4P~jHPD_T(!^u#)jsV>SM;9RF$VmQwb|Bl-I53sp z7l~}I_CvF4{YXE{5_Jj{CFxVA{dHVAhS5Gy{sQ4MYHe?y*DvC=NONR1%$IGy9c(Gx zzoZ?DiYrF1ZzbyBxGuQQ3vv6!+!b7~lvmsckE}2ZiW;4!JW%vX2xpDDeKH=PV^!H5 zXst5*Xq3slA%O-h1}saf8cJlf2`w;bm*01x(+R7B{oK)Au1e>?HO&>l;F6BSLMd!d z$hjF)9SNr~ZmedO0-7g(Otk{jNLo+NFmlFdDc^MfG5nh&{D^FQ+c!(}OB@l3kmVW; z>jd{fw2fk~)atn7opR_AcP?%qcw+O4()0u)T5sFu&6`rE2Rv00=ryf$t=?6s-6cmU zf9AX9%;X;<Vth!YMDmp5yFfY$lcgRC{}>;8!QNxW^oPr z4)?FWMZmTx6d-ikH%o4^q?|*wdA^qySIP`1w~6_rFfLwaskf(my=zze;EOPM1FeDn zJ;r@_mwR;Z5dqQF1!S&?V<_h?a94Pe9RU>8kT#;Fi(7~%HEuW{4a`{7QSLtRyXs;S zW2xw!u@Ba>`k@B+wXb3aA~FujbmMy(eVLAkI@C^gT%aLZl43g@-y3NbHMoT18{~S3 z1A`!~@Y z;J<>GJ#l2Y-B?WmNU7fym;M}`w*ODcr3(n#YM*{9kOaHgD;Vk`S8yUvsm%5@liML!_oT&kL|< zR(r)>hR9=@`i$<=pmPYXhxhJ~;J%%{J#x)nfmrTI7Z#aRaj*4eqZ1=t4bxhsJXObB z;v6FwX6VzfrMdjy6x@qwW5n(g(LxjAM&boJ?j^=j)YE8y7VG)Ot z4dyC=2$Q$M$AHB@uKRcChl}ZPT$ol5l1X>=ENpF4*c$@E)&bthMgmM=Ink@9yMv*z0re zU2kNlTIb#Nmj+iQB!5R(YTb&8N?qxpdOT253;Zdi8|~TO|4|HN@}jAlD62g&urhV! z0Vv>7CmL>3sR=Js-iBwvHXY*(h+ZZKDtV2~nE;T?TG{UQ(DzZ%#yjiDNhWbUfdG(s zh`Em}XK*GzGa4Jv;J5hT=+SMH%1v)%p#56!NlAv6eE_NC1f~f4)z0T)FSE|m8S0&Q&-CA7rqN~u{%PE5J;VA143iZzw@fEr}?=&+uTRD%| zV%&GOBKi65ylDf{`Y1P}f=j06WxkpKXVVvW=9Vz+UVBk5r4q-fe z{p5WhN?HO4)NjhkZEhms(BRGFof=Fs&N3B2oy^ePM2krVK6=2&a&=*rYWU*peQX&w zF#ke$S8Wy*8@=N6+2!K!JsFPt^29c9C-AGN4u0DbTNInmW%KspIYtAaT~h~#9-{

tC%Y^Cv<1i##+`^!3?qqPPr5t{gbUtB-t3Xq9QO-4i<28O|GB4N(at4HxQYt08cH zVr=|~h!8__Jd8mzVyksbER{QKD414p+XCOlri9cz^Rb>24YcGZZR5&_S{ z--EG0Geu4Yz*R2EK+lqF5_ffnEhI*{mvt)nQ(xo8H~p-34xC0&17pa}PZ0x23}z`0 z-0lqlk#SEE!aW^3)5km_vU*AiaM$yw{ZhVtU4FQivc>}t zu`mjId2v_atbx&#K5=$r`Vur@J#_p3_KPXjG^3#2HW)};z}UL4I;(HKNZON8|4|S+ zu;9dTK>E#V0`MnN7x1$<+#o+}r)Ry1H^ ztUvv$HIzW)%X$Hm5R$~pSZCZ?2TVHj6zr!@)XA#0QDr|>{ezW!QvBu=27)7S=7D`Y zokpl>Hm9+=Sh+$A06L_UY)ZwE)gqVJ39Jk%0I3ka{Ci0>As~^9UtUA<5OJZA=m@cj zEz~c9p32L#ArO5gzCUhveBCSI08jN>koJqcG}3|;1!?blvS2Wo`Np!4uUULwi!u;} z3-|>W7u9b;FPZ1RG<-d?nAH*a#`(o{8z$fezP!x5*UKE1PlVPm3a94|Kf5A&TDi+- zq9H_0IH64#RXvBkg8jozaH}_B7xqSt$8ASS?Kj5fq%IZk`&7EgxWc?#>m@p)ieZc3)i{-yLns?@BgV+I`u{C`U`M!}EP zGjKhp2?Y6qKBjWn>|uyLD`B%qqyMpY7nEiV0o%LXr=A6JP4DB`O?W5N>*kRn^MYmq zN%WKiqOD z2fy)UyTP6P>LU$HM{Lu@v>eEZ#&&TwxE5VG-Q$4Q-19ZDf%w`Z!c~7jj_BMby_HX; z9T-r?(~*6Ht99M=R0qXw_Xf%uK{+98G4f7tL3frTV6OWDmy6KDLwzq06xj7-?TtYP znyC1E#RB?3<)66r`9Ju-JTk(1k1e(FmX;8^sM-ZIuZ!mAc|5~HFiky72ftoXG1njyA3y-8sc%w*-d8jtuH!&=IPS0 zK)FJKcS5?cPmTW|9aSe4JbbFa6X)#J7`7Dc3TBPsz`86_u_qrXHTeX3h!)kz(pJ~H zK0`*(F{{Q?*1dL8DDBUksEqV#awqC=OCsblbcE%qJ|SIVxkvLc<@4c*1(Ujj^;4kP zh5Q)Bh9`Tr$TtP=pYL+p6&CqK7;auCnCy48wk0BMta{yU8<){c&3u$Z094j9^z&uO zZ%{Iy`!a&@wBMA6^u`h`E{+B|GP2$S{nl<6W2!=WC$eiU+Qvz!VH51@84Ezr;K=NoHc%J)U*CF_h zLvO1=r%6@J&#S6?plE$GlfJWa-O|o?FqBTEmXF$odAUgp<@jhoq76&C?~w4lZeBjy zlxP%s=Hvsg6#5l_Sh(ho$G)8@5cAt7PxKi80$}sb8s(Ukx`_9Z_zfTiie;_ymYRw& zxUQ)~>^;dk{965wJo8yEq=e%B_8L0LJYM*EPshQw7{#pQj+a%%p2oqy+XDfa*hagB z-DufYT|O1CTDU&6U_w8vzkIbza#cb38Fa&{&TzcvaaC8$=3^3c(?${a zcsJL2c`;b#d6{c=-IY4J)_(LlpfQh~+msUTa!*Zi4|U)V1i4_yaq0fI@N3{&z^M;h z)CWmTl4(q_P;w;Vn|w`6KwDg$tv-E|l%J|LjGL~Y$QT6pYh z%r%F1pS82q$gd+rcmz!GEj`%5%gtssHYcZ`Q1xH)A8yF5n(%I$> zgv4!KTPGNB-d4%9AdnM72ix}0mG;BE)0(#dD8lcY^xuKbhu%@g#fP$&Vu;OYo^NCf zzRt=O8n-~qbLz4I351AsWk!LyVMT=bG+8S*cb3t2JTH~xx$h+vAB8V^2YW(132YOp zzj&W2N>{Qcbk4ZT_f2EiJv2X6h}rgjG&)@15bZ;dIN{D@^^9DTg|k@oW#CE}ndwyEi58*^1`L=*xdo>;O3_$M@0bOpG`c6KMrg_+pC9Nc9ci3{apYQ_sy-Xc!4mPY=y>a(FH7=fH!D*#=@OAmZ@=ziAE5 zd)r=EkD)|XS8@mq|L8&6LkdcDqw}dmiYI$V@g$(;76qnK=Stzh9Yb@HE_ZW(RfA^g z_(b0iIub$cudAG-Y%bq9NMqp8O2s$tD3SrQ zQ-d}<;4 zEF=PUqJvKa%`JuHYW$Gay!xfnQ?3kuLJJP^?o4zh6PcFK#@&_fpntBeyB(%b<#@Eo z37kSS8WJgXO9YOOL@ch^!r>) zq*@UGJ3z$0V%;hLX}er@&Y?;+tCsIB8lc9SikQqJ$s$J@c>F1^qVnd1E}e7i_+{pZ z!}rt{35B~BrqU}-w-N@LSq=T~#3a`wZY zudiB%LKw^uIn~o$qtwnPDkonr6U@NmrYL?BD0?@P>Ka2#>aja)#H5q^{Ai!+Z7K_E z$tH{C6ys+a`_&yYiNyK(kf(iJR0K7nq)-N|-UoRw>*r%b34dQ|T)FD zpU5uURrD6zhRVeY5OyB9HTBE7a}=pfS*;-u5un<|xe&dx8oXis&iI8xdn22Y)hDq; zN8L+s%+T^#k%@)mqkb)v5Hkdi83&|O=~f{22VOMfdS6eSjpNJKfC^;Eq z3{_t|~T3zD{&Np)Sql%(&8W6qBpYGCzICwahV58`(4|2yrSj=KyS1?3nEhFpdfi z6Z@2^q@>+4sOyl(;SgM#lUBk&ob@SL z0)x!iq5@+{tQQFsxf5OK(IYUQ)dXJ3{WPRe1aUTT!~wESl{b4 znh|9BCl>NHNb5hrwX(z*PRrnp0HSEncp#S}HML-(_4Jk9V{^`Ng`8}bbm0BS1@YsA z#d{o7i}CREbRjPj31|rONk>ucBKf9jJHZ^48vk}J-z`!K52@BQvIjSvjBiqpLK*w^$b-xFzO!)5RE_CT#t1gfdCN^pAeJLiX8% zK+ZbWVxwTGD~72cg^e70pZebD+EbSule8tIwAFT?G^>`@Tr+3Y!#>mgf@1`iqUr`u z39-x?1A*3y9R`8(+9@~MSr?j4Z)R};1564(eP;NrKm3~CGQQ5wuvhKU9c=jUV@E_WtoCH9sx7K3A+mxzVxvgazxn=_*+lM(9j;X?C;9Y z=Yp#@bf0ygCoAj#^~uLjWvQ3eQ@fh2n3edq0{tD#CRAAE>rPLm7B#(L+hN^Ni?IaC zFd^h__jWT_v6Z|y?E7hM{=-~|F``wupj~JkUBmVRmF*{bQB|;b&FFthx!|lo0v(LV z+O3PujZR?|^VjPohO0G~%5fVsGSxNU9 zE3ap;eUtFb=$g${(;xqh&VF9+Gb|$m^?P3HTTCi3SX85(=mv-O@*OUuVf;Md)fs+s zzkfgqGIlZ_&M^BTp{_%B&orL4tnhRg)e)%lx)FD0uRHs&uuz9fVFPV^{xw%+qHZ=t z=Mj@y59zw$3{iuu;{C77kwdY8a?_*(&x01$5uls((mwb0Y&LrNEd{FZ(Ed=%GNk8& zr9p`Yt{g}|vU^!yUc=qvpP6Bl7q?-BX~T&DymQt&VobhK@q^fZLqw=tvivK*GV8sy zPbu}>Hv(PSh0KZ9!P()ohDZ^aq>lUGmj*JbzTsL)G>&sQ(>9{!%tlv=FQFz=5p*aw zoP0z{XyJ^5F#9}+hCXr5;`-kj))J(bYAef-6AS4RGJm-bGw;#_4Z2>@B*CpW>iK7D zt)4nSP={9DzV8OJVTALTA8+z;w+Sif}k8_Q&B

dPaV*hvkqA#FBuT{}L{TP$%u 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

HBg@>i$tRT%-cc5kWqlNHQKy;hE2 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

aQBn)3c~+I~P=S-FGz>LR{m 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 literal 293068 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 onW`hs^uuTI3wUYV{G{UTAB5|LfkwNIuJX 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

S2%Fd*x#y7 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%0AcZ+@W9+?m-D{ziMUHs#8txX`4%seyc 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 /dev/null } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo "FAILED backtrace:" @@ -29,7 +29,10 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" echo "Test skipped." @@ -37,7 +40,7 @@ function skip() exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -47,12 +50,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function xxx() +xxx() { $CRYPTSETUP --test-args $@ > $TFILE 2>&1 local ret=$? @@ -65,13 +68,13 @@ function xxx() test $ret -ne 0 || fail } -function exp_fail() +exp_fail() { # xxx $@ $CRYPTSETUP --test-args $@ 2>/dev/null && fail } -function exp_pass() +exp_pass() { $CRYPTSETUP --test-args $@ >/dev/null || fail } @@ -282,7 +285,6 @@ exp_fail reencrypt DEV --reduce-device-size 2G # max 1g exp_fail reencrypt DEV --reduce-device-size $((64*1024*1024+1)) exp_fail reencrypt DEV --reduce-device-size -64m exp_pass reencrypt DEV --reduce-device-size 64m -exp_fail reencrypt DEV --reduce-device-size 64m --device-size 100g # bugs # exp_fail open DEV --decrypt --header H # exp_fail open DEV --encrypt diff --git a/tests/compat-test b/tests/compat-test index 909b0a5..1a956b5 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -52,7 +52,7 @@ TEST_UUID="12345678-1234-1234-1234-123456789abc" LOOPDEV=$(losetup -f 2>/dev/null) FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME3 ] && dmsetup remove --retry $DEV_NAME3 >/dev/null 2>&1 [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 >/dev/null 2>&1 @@ -63,13 +63,13 @@ function remove_mapping() scsi_debug_teardown $DEV } -function force_uevent() +force_uevent() { DNAME=$(echo $LOOPDEV | cut -f3 -d /) echo "change" >/sys/block/$DNAME/uevent } -function fail() +fail() { [ -n "$1" ] && echo "$1" remove_mapping @@ -78,18 +78,21 @@ function fail() exit 2 } -function fips_mode() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +fips_mode() { [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] } -function can_fail_fips() +can_fail_fips() { # Ignore this fail if running in FIPS mode fips_mode || fail $1 } -function skip() +skip() { [ -n "$1" ] && echo "$1" remove_mapping @@ -97,7 +100,7 @@ function skip() exit 77 } -function prepare() +prepare() { [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1 @@ -153,14 +156,14 @@ function prepare() [ -n "$1" ] && echo "CASE: $1" } -function check() +check() { sync [ -z "$1" ] && return $DIFFER $ORIG_IMG $IMG $1 || fail } -function check_exists() +check_exists() { [ -b /dev/mapper/$DEV_NAME ] || fail check $1 @@ -181,7 +184,7 @@ scsi_debug_teardown() { test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 } -function add_scsi_device() { +add_scsi_device() { scsi_debug_teardown $DEV if [ -d /sys/module/scsi_debug ] ; then echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." @@ -198,7 +201,7 @@ function add_scsi_device() { [ -b $DEV ] || fail "Cannot find $DEV." } -function valgrind_setup() +valgrind_setup() { [ -n "$VALG" ] || return command -v valgrind >/dev/null || fail "Cannot find valgrind." @@ -211,13 +214,13 @@ function valgrind_setup() CRYPTSETUP_RAW="./valg.sh ${CRYPTSETUP_VALGRIND}" } -function valgrind_run() +valgrind_run() { export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" $CRYPTSETUP_RAW "$@" } -function expect_run() +expect_run() { export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" expect "$@" @@ -236,7 +239,9 @@ fi prepare "Image in file tests (root capabilities not required)" file echo "[1] format" -echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $IMG $FAST_PBKDF_OPT || fail +echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 -c 'capi:xts(aes)-plain64' $IMG $FAST_PBKDF_OPT || fail +echo $PWD0 | $CRYPTSETUP luksOpen $IMG --test-passphrase 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $IMG $FAST_PBKDF_OPT --disable-blkid || fail echo "[2] open" echo $PWD0 | $CRYPTSETUP luksOpen $IMG --test-passphrase 2>/dev/null && fail [ $? -ne 2 ] && fail "luksOpen should return EPERM exit code" @@ -250,7 +255,7 @@ echo $PWD1 | $CRYPTSETUP luksAddKey $IMG $FAST_PBKDF_OPT 2>/dev/null && fail echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $IMG $FAST_PBKDF_OPT || fail echo -e "$PWD0\n$PWD1" | $CRYPTSETUP luksAddKey $IMG $FAST_PBKDF_OPT 2>/dev/null && fail echo "[4] change key" -echo -e "$PWD1\n$PWD0\n" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT $IMG || fail +echo -e "$PWD1\n$PWD0\n" | $CRYPTSETUP luksChangeKey --force-password $FAST_PBKDF_OPT $IMG || fail echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT $IMG 2>/dev/null && fail [ $? -ne 2 ] && fail "luksChangeKey should return EPERM exit code" echo "[5] remove key" @@ -555,23 +560,23 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: DISABLED" || fail prepare "[19] create & status & resize" wipe echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash xxx --cipher aes-cbc-essiv:sha256 --key-size 256 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV $PLAIN_OPT --offset 3 --skip 4 --readonly || fail -$CRYPTSETUP -q status $DEV_NAME | grep "offset:" | grep -q "3 sectors" || fail -$CRYPTSETUP -q status $DEV_NAME | grep "skipped:" | grep -q "4 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "offset:" | grep -q "3 \[512-byte units\]" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "skipped:" | grep -q "4 \[512-byte units\]" || fail $CRYPTSETUP -q status $DEV_NAME | grep "mode:" | grep -q "readonly" || fail $CRYPTSETUP -q resize $DEV_NAME --size 100 || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" || fail $CRYPTSETUP -q resize $DEV_NAME || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "19997 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "19997 \[512-byte units\]" || fail $CRYPTSETUP -q resize $DEV_NAME --device-size 1M || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail $CRYPTSETUP -q resize $DEV_NAME --device-size 512k --size 1023 >/dev/null 2>&1 && fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail $CRYPTSETUP -q resize $DEV_NAME --device-size 513 >/dev/null 2>&1 && fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail # Resize underlying loop device as well truncate -s 16M $IMG || fail $CRYPTSETUP -q resize $DEV_NAME || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "32765 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "32765 \[512-byte units\]" || fail $CRYPTSETUP -q remove $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME >/dev/null && fail echo $PWD1 | $CRYPTSETUP create $DEV_NAME $PLAIN_OPT $LOOPDEV || fail @@ -579,18 +584,18 @@ $CRYPTSETUP -q remove $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME $PLAIN_OPT $LOOPDEV || fail $CRYPTSETUP -q remove $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME $PLAIN_OPT --size 100 $LOOPDEV || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" || fail $CRYPTSETUP -q remove $DEV_NAME || fail # 4k sector resize (if kernel supports it) echo $PWD1 | $CRYPTSETUP -q open --type plain $PLAIN_OPT $LOOPDEV $DEV_NAME --sector-size 4096 --size 8 >/dev/null 2>&1 if [ $? -eq 0 ] ; then - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "8 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "8 \[512-byte units\]" || fail $CRYPTSETUP -q resize $DEV_NAME --size 16 || fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "16 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "16 \[512-byte units\]" || fail $CRYPTSETUP -q resize $DEV_NAME --size 9 2>/dev/null && fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "16 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "16 \[512-byte units\]" || fail $CRYPTSETUP -q resize $DEV_NAME --device-size 4608 2>/dev/null && fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "16 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "16 \[512-byte units\]" || fail $CRYPTSETUP -q remove $DEV_NAME || fail fi # Resize not aligned to logical block size @@ -798,7 +803,7 @@ echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --head echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 8192 || fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 0 || fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 8192 --offset 8192 >/dev/null 2>&1 && fail -truncate -s 4096 $HEADER_IMG +truncate -s 4096 $HEADER_IMG || fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG -S7 >/dev/null 2>&1 || fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --offset 80000 >/dev/null 2>&1 || fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --offset 8192 || fail @@ -806,9 +811,9 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --h echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV-missing --header $HEADER_IMG $DEV_NAME 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail $CRYPTSETUP -q resize $DEV_NAME --size 100 --header $HEADER_IMG || fail -$CRYPTSETUP -q status $DEV_NAME --header $HEADER_IMG | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME --header $HEADER_IMG | grep "size:" | grep -q "100 \[512-byte units\]" || fail $CRYPTSETUP -q status $DEV_NAME | grep "type:" | grep -q "n/a" || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" || fail $CRYPTSETUP luksSuspend $DEV_NAME --header $HEADER_IMG || fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail $CRYPTSETUP luksSuspend $DEV_NAME || fail @@ -868,6 +873,9 @@ else $CRYPTSETUP close $DEV_NAME2 >/dev/null 2>&1 $CRYPTSETUP close $DEV_NAME >/dev/null 2>&1 fi +# Deferred remove of device without DM-UUID +dmsetup create $DEV_NAME --table "0 8 crypt aes-xts-plain64 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 $LOOPDEV 0" || fail +$CRYPTSETUP close --deferred $DEV_NAME || fail # Interactive tests # Do not remove sleep 0.1 below, the password query flushes TTY buffer (so the code is racy). @@ -938,7 +946,7 @@ prepare "[35] Interactive format of device." wipe expect_run - >/dev/null <$KEYE expect_run - >/dev/null </dev/null && fail +echo $PWD1 | $CRYPTSETUP open --type plain $LOOPDEV $DM_LONG_NAME --hash sha256 --cipher aes-cbc-essiv:sha256 --key-size 256 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DM_BAD_NAME 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DM_LONG_NAME 2>/dev/null && fail + remove_mapping exit 0 diff --git a/tests/compat-test-opal b/tests/compat-test-opal index 8ba164a..2422cc7 100755 --- a/tests/compat-test-opal +++ b/tests/compat-test-opal @@ -44,7 +44,7 @@ TEST_UUID="12345678-1234-1234-1234-123456789abc" FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME @@ -58,7 +58,7 @@ function remove_mapping() unset TEST_KEYRING } -function fail() +fail() { [ -n "$1" ] && echo "$1" remove_mapping @@ -68,36 +68,39 @@ function fail() exit 2 } -function fips_mode() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +fips_mode() { [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] } -function can_fail_fips() +can_fail_fips() { # Ignore this fail if running in FIPS mode fips_mode || fail $1 } -function skip() +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function reset_device_psid() +reset_device_psid() { $CRYPTSETUP_RAW luksErase --hw-opal-factory-reset --key-file $OPAL2_PSID_FILE $OPAL2_DEV -q || \ fail "PSID reset fail, wrong device used?" } -function reset_device_psid_nofail() +reset_device_psid_nofail() { $CRYPTSETUP_RAW luksErase --hw-opal-factory-reset --key-file $OPAL2_PSID_FILE $OPAL2_DEV -q 2>/dev/null } -function prepare() +prepare() { [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME @@ -146,12 +149,12 @@ function prepare() [ -n "$1" ] && echo "CASE: $1" } -function check_exists() +check_exists() { [ -b /dev/mapper/$DEV_NAME ] || fail } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -161,12 +164,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function dm_crypt_keyring_support() +dm_crypt_keyring_support() { VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -183,7 +186,7 @@ function dm_crypt_keyring_support() return 1 } -function dm_crypt_keyring_new_kernel() +dm_crypt_keyring_new_kernel() { KER_STR=$(uname -r) [ -z "$KER_STR" ] && fail "Failed to parse kernel version." @@ -195,7 +198,7 @@ function dm_crypt_keyring_new_kernel() return 1 } -function test_and_prepare_keyring() { +test_and_prepare_keyring() { command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped" keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped" TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null) @@ -208,12 +211,12 @@ function test_and_prepare_keyring() { # $2 description # $3 payload # $4 keyring -function load_key() +load_key() { keyctl add $@ >/dev/null } -function setup_luks2_env() { +setup_luks2_env() { echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $OPAL2_DEV || fail $CRYPTSETUP luksDump $OPAL2_DEV >/dev/null || fail echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME || fail @@ -310,7 +313,7 @@ test_vk_link_and_reactivate() { keyctl unlink $KEYCTL_KEY_NAME "$2" || fail } -function test_reencryption_does_not_init() +test_reencryption_does_not_init() { local _hdr="" local _hdrdev=$NO_HEADER_IMG @@ -382,7 +385,7 @@ function test_reencryption_does_not_init() $CRYPTSETUP close $DEV_NAME || fail } -function test_device() #opal_mode, #format_params, #--integrity-no-wipe +test_device() #opal_mode, #format_params, #--integrity-no-wipe { echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat --type luks2 $1 $2 $3 -q $FAST_PBKDF_OPT $OPAL2_DEV || fail echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME || fail @@ -391,12 +394,14 @@ function test_device() #opal_mode, #format_params, #--integrity-no-wipe dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail + $CRYPTSETUP close --cancel-deferred $DEV_NAME 2>/dev/null && fail + $CRYPTSETUP close --deferred $DEV_NAME 2>/dev/null && fail $CRYPTSETUP close $DEV_NAME || fail dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail } -function test_device_detached_header() #hdr, #opal_mode, #format_params, #--integrity-no-wipe +test_device_detached_header() #hdr, #opal_mode, #format_params, #--integrity-no-wipe { echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat --type luks2 --header $1 $2 $3 $4 -q $FAST_PBKDF_OPT $OPAL2_DEV || fail echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --header $1 || fail @@ -406,9 +411,13 @@ function test_device_detached_header() #hdr, #opal_mode, #format_params, #--inte echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $1 || fail dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail + $CRYPTSETUP close --cancel-deferred $DEV_NAME 2>/dev/null && fail + $CRYPTSETUP close --deferred $DEV_NAME 2>/dev/null && fail $CRYPTSETUP close $DEV_NAME || fail dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --header $1 || fail + $CRYPTSETUP close $DEV_NAME --header $1 --cancel-deferred 2>/dev/null && fail + $CRYPTSETUP close $DEV_NAME --header $1 --deferred 2>/dev/null && fail $CRYPTSETUP close $DEV_NAME --header $1 || fail dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q --header $1 || fail @@ -416,7 +425,7 @@ function test_device_detached_header() #hdr, #opal_mode, #format_params, #--inte rm -f $1 } -function run_token_tests() { +run_token_tests() { $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN0 --token-id 3 || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep -q -e "3: luks2-keyring" || fail # keyslot 5 is inactive @@ -498,8 +507,7 @@ echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --typ prepare "[3] format" wipe echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 --hw-opal $OPAL2_DEV || fail -# FIXME: BUG (--hw-opal-only should reject --cipher, --key-size & co) -#echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q $FAST_PBKDF_OPT --hw-opal-only -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 $OPAL2_DEV 2> /dev/null && fail + prepare "[4] format using hash sha512" wipe echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP $FAST_PBKDF_OPT -h sha512 -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 --hw-opal $OPAL2_DEV || fail $CRYPTSETUP -q luksDump $OPAL2_DEV | grep "0: pbkdf2" -A2 | grep "Hash:" | grep -qe sha512 || fail @@ -600,7 +608,7 @@ fi # format hw-opal-only echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom --type luks2 --hw-opal-only $OPAL2_DEV || fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom -s 512 --uuid $TEST_UUID --type luks2 --hw-opal-only $OPAL2_DEV || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom --uuid $TEST_UUID --type luks2 --hw-opal-only $OPAL2_DEV || fail $CRYPTSETUP luksOpen -d $KEY_PWD1 $OPAL2_DEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail # open by UUID @@ -939,7 +947,7 @@ prepare "[26] LUKS convert" wipe echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 512 -s256 --hw-opal $OPAL2_DEV || fail $CRYPTSETUP -q convert --type luks1 $OPAL2_DEV >/dev/null 2>&1 && fail $CRYPTSETUP isLuks --type luks2 $OPAL2_DEV || fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 512 -s256 --hw-opal-only $OPAL2_DEV || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 512 --hw-opal-only $OPAL2_DEV || fail $CRYPTSETUP -q convert --type luks1 $OPAL2_DEV >/dev/null 2>&1 && fail $CRYPTSETUP isLuks --type luks2 $OPAL2_DEV || fail @@ -1109,10 +1117,10 @@ $CRYPTSETUP luksDump $OPAL2_DEV | grep -q "3: luks2 (unbound)" && fail prepare "[34] LUKS2 metadata areas" wipe echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV 2> /dev/null || fail DEFAULT_OFFSET=$($CRYPTSETUP luksDump $OPAL2_DEV | grep "offset: " | cut -f 2 -d ' ') -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=127k 2> /dev/null && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=127k --luks2-keyslots-size=128k 2> /dev/null && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=128M >/dev/null 2>&1 && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=128k >/dev/null || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --luks2-metadata-size=128k --luks2-keyslots-size=127k 2> /dev/null && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --luks2-metadata-size=127k --luks2-keyslots-size=128k 2> /dev/null && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --luks2-metadata-size=128k --luks2-keyslots-size=129M >/dev/null 2>&1 && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --luks2-metadata-size=128k --luks2-keyslots-size=128k >/dev/null || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail @@ -1120,18 +1128,18 @@ echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT -- $CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "$((DEFAULT_OFFSET-2*131072)) \[bytes\]" || fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-keyslots-size=128k >/dev/null || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --luks2-keyslots-size=128k >/dev/null || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "16384 \[bytes\]" || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset 16384 || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --offset 16384 || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "16384 \[bytes\]" || fail $CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "8355840 \[bytes\]" || fail echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail # data offset vs area size -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset 64 --luks2-keyslots-size=8192 >/dev/null 2>&1 && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset $((256+56)) >/dev/null 2>&1 && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset $((256+64)) >/dev/null || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --offset 64 --luks2-keyslots-size=8192 >/dev/null 2>&1 && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --offset $((256+56)) >/dev/null 2>&1 && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --offset $((256+64)) >/dev/null || fail prepare "[35] Per-keyslot encryption parameters" wipe KEYSLOT_CIPHER="aes-cbc-plain64" @@ -1308,7 +1316,7 @@ prepare "[39] LUKS2 reencryption/decryption blocked" wipe echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal $OPAL2_DEV || fail test_reencryption_does_not_init -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV || fail test_reencryption_does_not_init prepare "[40] LUKS2 reencryption/decryption blocked (detached header)" wipe @@ -1316,7 +1324,7 @@ prepare "[40] LUKS2 reencryption/decryption blocked (detached header)" wipe echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --header $HEADER_IMG --type luks2 -s256 --hw-opal $OPAL2_DEV || fail test_reencryption_does_not_init $HEADER_IMG -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --header $HEADER_IMG --type luks2 -s256 --hw-opal-only $OPAL2_DEV || fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --header $HEADER_IMG --type luks2 --hw-opal-only $OPAL2_DEV || fail test_reencryption_does_not_init $HEADER_IMG prepare "[41] LUKS2 encryption blocked" wipe @@ -1328,12 +1336,12 @@ $CRYPTSETUP isLuks $OPAL2_DEV && fail test -b $DEV_NAME && fail echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal $OPAL2_DEV 2>/dev/null && fail $CRYPTSETUP isLuks $OPAL2_DEV && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV 2>/dev/null && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV 2>/dev/null && fail $CRYPTSETUP isLuks $OPAL2_DEV && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV $DEV_NAME 2>/dev/null && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV $DEV_NAME 2>/dev/null && fail $CRYPTSETUP isLuks $OPAL2_DEV && fail test -b $DEV_NAME && fail -echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV 2>/dev/null && fail +echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV 2>/dev/null && fail $CRYPTSETUP isLuks $OPAL2_DEV && fail fi diff --git a/tests/compat-test2 b/tests/compat-test2 index d21fe04..77f075a 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -45,12 +45,20 @@ KEY_FILE1=test-key-file1 FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" +# 32 MiB + 1KiB to bypass minimal memory check (hardocoded) +FAST_PBKDF_ARGON_OPT="--pbkdf argon2id --pbkdf-force-iterations 4 --pbkdf-memory 32769 --pbkdf-parallel 1" + +# TODO: this is configurable +LUKS2_LOCKING_DIR=/run/cryptsetup +# hardcoded value +MEMORY_HARD_LOCK_FILE=LN_memory-hard-access + TEST_UUID="12345678-1234-1234-1234-123456789abc" LOOPDEV=$(losetup -f 2>/dev/null) FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME3 ] && dmsetup remove --retry $DEV_NAME3 [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 @@ -68,13 +76,13 @@ function remove_mapping() scsi_debug_teardown $DEV } -function force_uevent() +force_uevent() { DNAME=$(echo $LOOPDEV | cut -f3 -d /) echo "change" >/sys/block/$DNAME/uevent } -function fail() +fail() { [ -n "$1" ] && echo "$1" remove_mapping @@ -83,25 +91,28 @@ function fail() exit 2 } -function fips_mode() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +fips_mode() { [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] } -function can_fail_fips() +can_fail_fips() { # Ignore this fail if running in FIPS mode fips_mode || fail $1 } -function skip() +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function prepare() +prepare() { [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME @@ -153,12 +164,12 @@ function prepare() [ -n "$1" ] && echo "CASE: $1" } -function check_exists() +check_exists() { [ -b /dev/mapper/$DEV_NAME ] || fail } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -168,12 +179,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function dm_crypt_capi_support() +dm_crypt_capi_support() { VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -181,13 +192,14 @@ function dm_crypt_capi_support() VER_MAJ=$(echo $VER_STR | cut -f 1 -d.) VER_MIN=$(echo $VER_STR | cut -f 2 -d.) + [ $VER_MAJ -gt 1 ] && return 0 if [ $VER_MIN -ge 16 ]; then return 0 fi return 1 } -function dm_crypt_keyring_support() +dm_crypt_keyring_support() { $CRYPTSETUP --version | grep -q KEYRING || return 1 @@ -206,7 +218,7 @@ function dm_crypt_keyring_support() return 1 } -function dm_crypt_keyring_flawed() +dm_crypt_keyring_flawed() { dm_crypt_keyring_support && return 1; @@ -215,7 +227,7 @@ function dm_crypt_keyring_flawed() return 1 } -function dm_crypt_keyring_new_kernel() +dm_crypt_keyring_new_kernel() { KER_STR=$(uname -r) [ -z "$KER_STR" ] && fail "Failed to parse kernel version." @@ -227,7 +239,7 @@ function dm_crypt_keyring_new_kernel() return 1 } -function dm_crypt_sector_size_support() +dm_crypt_sector_size_support() { VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -236,6 +248,7 @@ function dm_crypt_sector_size_support() VER_MIN=$(echo $VER_STR | cut -f 2 -d.) VER_PTC=$(echo $VER_STR | cut -f 3 -d.) + [ $VER_MAJ -gt 1 ] && return 0 if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then return 0 fi @@ -243,7 +256,7 @@ function dm_crypt_sector_size_support() return 1 } -function test_and_prepare_keyring() { +test_and_prepare_keyring() { command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped" keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped" TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null) @@ -256,12 +269,13 @@ function test_and_prepare_keyring() { # $2 description # $3 payload # $4 keyring -function load_key() +load_key() { + [ -z "$4" ] && fail "Keyring not defined!" keyctl add $@ >/dev/null } -function setup_luks2_env() { +setup_luks2_env() { echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $LOOPDEV || fail $CRYPTSETUP luksDump $LOOPDEV >/dev/null || fail echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail @@ -294,7 +308,7 @@ scsi_debug_teardown() { test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 } -function add_scsi_device() { +add_scsi_device() { scsi_debug_teardown $DEV if [ -d /sys/module/scsi_debug ] ; then echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." @@ -471,7 +485,7 @@ test_reencrypt_vk_link_and_reactivate() { echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring "$KEY_DESC" --volume-key-keyring "$KEY_DESC2" > /dev/null 2>&1 && fail } -function expect_run() +expect_run() { export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" expect "$@" @@ -479,7 +493,7 @@ function expect_run() # expected unlocked keyslot id # command arguments -function expect_unlocked_keyslot() +expect_unlocked_keyslot() { command -v expect >/dev/null || { echo "WARNING: expect tool missing, interactive test will be skipped." @@ -504,7 +518,7 @@ EOF # expected unlocked keyslot id # password # command arguments -function expect_retried_unlocked_keyslot() +expect_retried_unlocked_keyslot() { command -v expect >/dev/null || { echo "WARNING: expect tool missing, interactive test will be skipped." @@ -552,7 +566,7 @@ echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --o $CRYPTSETUP -q luksDump $LOOPDEV | grep -q "offset: $((512 * 16384)) \[bytes\]" || fail echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 1024 --offset 16384 >/dev/null || fail $CRYPTSETUP -q luksDump $LOOPDEV | grep -q "offset: $((512 * 16384)) \[bytes\]" || fail -truncate -s 4096 $HEADER_IMG +truncate -s 4096 $HEADER_IMG || fail echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG -q --offset 80000 >/dev/null 2>&1 || fail prepare "[2] Sector size and old payload alignment" wipe @@ -768,27 +782,31 @@ if dm_crypt_keyring_support; then load_key user $TEST_KEY_DESC2 $PWD1 "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped." $CRYPTSETUP token add $LOOPDEV --key-description $TEST_KEY_DESC2 --token-id 1 || fail $CRYPTSETUP -q resize --size 99 $DEV_NAME <&- || fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "99 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "99 \[512-byte units\]" || fail #replace kernel key with wrong pass load_key user $TEST_KEY_DESC2 $PWD2 "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped." # must fail due to --token-only echo $PWD1 | $CRYPTSETUP -q resize --token-only --size 100 $DEV_NAME && fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" && fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" && fail + # resize with keyring description + load_key user $TEST_KEY_DESC1 $PWD1 "$TEST_KEYRING" || fail + $CRYPTSETUP -q resize --size 99 $DEV_NAME --key-description $TEST_KEY_DESC1 || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "99 \[512-byte units\]" || fail fi fi echo $PWD1 | $CRYPTSETUP -q resize --size 100 $DEV_NAME || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" || fail echo $PWD1 | $CRYPTSETUP -q resize --device-size 51200 $DEV_NAME || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" || fail echo $PWD1 | $CRYPTSETUP -q resize --device-size 1M $DEV_NAME || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail echo $PWD1 | $CRYPTSETUP -q resize --device-size 512k --size 1024 $DEV_NAME > /dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP -q resize --device-size 4097 $DEV_NAME > /dev/null 2>&1 && fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail $CRYPTSETUP close $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP luksOpen --disable-keyring $LOOPDEV $DEV_NAME || fail echo | $CRYPTSETUP -q resize --size 100 $DEV_NAME || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" || fail $CRYPTSETUP close $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail if dm_crypt_keyring_support; then @@ -799,10 +817,10 @@ if dm_crypt_sector_size_support; then echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 4096 $LOOPDEV > /dev/null || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP -q resize --device-size 1M $DEV_NAME || fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail echo $PWD1 | $CRYPTSETUP -q resize --device-size 2049s $DEV_NAME > /dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP -q resize --size 2049 $DEV_NAME > /dev/null 2>&1 && fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "2048 \[512-byte units\]" || fail fi $CRYPTSETUP close $DEV_NAME || fail # Resize not aligned to logical block size @@ -1007,9 +1025,9 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --h echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV-missing --header $HEADER_IMG $DEV_NAME 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP -q resize $DEV_NAME --size 100 --header $HEADER_IMG || fail -$CRYPTSETUP -q status $DEV_NAME --header $HEADER_IMG | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME --header $HEADER_IMG | grep "size:" | grep -q "100 \[512-byte units\]" || fail $CRYPTSETUP -q status $DEV_NAME | grep "type:" | grep -q "n/a" || fail -$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail +$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 \[512-byte units\]" || fail $CRYPTSETUP luksSuspend $DEV_NAME --header $HEADER_IMG || fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail $CRYPTSETUP luksSuspend $DEV_NAME || fail @@ -1036,7 +1054,7 @@ if [ "$HAVE_BLKID" -gt 0 ]; then $CRYPTSETUP isLuks --disable-locks --type luks2 $HEADER_LUKS2_PV && fail $CRYPTSETUP isLuks --type luks2 $HEADER_LUKS2_PV && fail fi -$CRYPTSETUP -q repair $HEADER_LUKS2_PV || fail +$CRYPTSETUP -q repair $HEADER_LUKS2_PV >/dev/null || fail $CRYPTSETUP isLuks $HEADER_LUKS2_PV || fail $CRYPTSETUP isLuks --type luks2 $HEADER_LUKS2_PV || fail $CRYPTSETUP isLuks --type luks1 $HEADER_LUKS2_PV && fail @@ -1268,6 +1286,8 @@ $CRYPTSETUP luksDump $LOOPDEV | grep "Label:" | grep -q "(no label)" || fail $CRYPTSETUP config $LOOPDEV --subsystem SatelliteThree --label TheLabel $CRYPTSETUP luksDump $LOOPDEV | grep "Subsystem:" | grep -q "SatelliteThree" || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Label:" | grep -q "TheLabel" || fail +$CRYPTSETUP config $LOOPDEV --label 0123456789abcdef0123456789abcdef0123456789abcdef 2>/dev/null && fail +$CRYPTSETUP config $LOOPDEV --subsystem 0123456789abcdef0123456789abcdef0123456789abcdef 2>/dev/null && fail prepare "[36] LUKS PBKDF setting" wipe echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --pbkdf bla $LOOPDEV >/dev/null 2>&1 && fail @@ -1276,6 +1296,7 @@ echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force- echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force-iterations 1234 $LOOPDEV || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Iterations:" | grep -q "1234" || fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 3 $LOOPDEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-parallel 99 $LOOPDEV 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 4 --pbkdf-memory 100000 $LOOPDEV || can_fail_fips $CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "argon2id" || can_fail_fips echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2i --pbkdf-force-iterations 4 \ @@ -1373,7 +1394,7 @@ DEFAULT_OFFSET=$($CRYPTSETUP luksDump $LOOPDEV | grep "offset: " | cut -f 2 -d ' echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks1 $LOOPDEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=128k 2> /dev/null && fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=127k 2> /dev/null && fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --luks2-metadata-size=127k --luks2-keyslots-size=128k 2> /dev/null && fail -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=128M >/dev/null 2>&1 && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=129M >/dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=128k >/dev/null || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail @@ -1649,11 +1670,51 @@ if [ $? -eq 0 ] ; then $CRYPTSETUP close $DEV_NAME || fail fi -prepare "[49] Interactive retry keyslot test" wipe +if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then + prepare "[49] Keyring description use" wipe + test_and_prepare_keyring + load_key user $TEST_KEY_DESC1 $PWD1 "$TEST_KEYRING" || fail + load_key user $TEST_KEY_DESC2 $PWD2 "$TEST_KEYRING" || fail + $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --disable-keyring --key-description $TEST_KEY_DESC1 2>/dev/null && fail + $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-description $TEST_KEY_DESC1 || fail + $CRYPTSETUP -q luksDump $LOOPDEV --dump-volume-key --key-description $TEST_KEY_DESC1 >/dev/null || fail + $CRYPTSETUP -q open $LOOPDEV $DEV_NAME --key-description $TEST_KEY_DESC1 || fail + $CRYPTSETUP luksSuspend $DEV_NAME || fail + $CRYPTSETUP luksResume $DEV_NAME --key-description $TEST_KEY_DESC1 || fail + $CRYPTSETUP -q close $DEV_NAME || fail + echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --new-key-description $TEST_KEY_DESC2 $LOOPDEV --disable-keyring 2>/dev/null && fail + echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --new-key-description $TEST_KEY_DESC2 $LOOPDEV --new-key-slot 1 || fail + $CRYPTSETUP -q open $LOOPDEV --test-passphrase --key-description $TEST_KEY_DESC2 || fail + $CRYPTSETUP -q luksKillSlot $LOOPDEV 1 || fail + echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --key-description $TEST_KEY_DESC1 $LOOPDEV --new-key-slot 1 || fail + $CRYPTSETUP -q open $LOOPDEV --test-passphrase --key-description $TEST_KEY_DESC2 || fail + $CRYPTSETUP -q luksKillSlot $LOOPDEV 1 || fail + $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --key-description $TEST_KEY_DESC1 --new-key-description $TEST_KEY_DESC2 $LOOPDEV --new-key-slot 1 || fail + $CRYPTSETUP -q open $LOOPDEV --test-passphrase --key-description $TEST_KEY_DESC2 || fail + $CRYPTSETUP -q luksKillSlot $LOOPDEV 1 || fail +fi + +prepare "[50] Interactive retry keyslot test" wipe echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail echo $PWD2 | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_OPT --unbound --key-size 256 $LOOPDEV || fail expect_retried_unlocked_keyslot 0 $PWD1 "open -v --test-passphrase --tries 2 $LOOPDEV" || fail expect_retried_unlocked_keyslot 1 $PWD2 "open -v --test-passphrase --tries 2 -S1 $LOOPDEV" || fail +prepare "[51] Early check for active name." wipe +DM_BAD_NAME=x/x +DM_LONG_NAME=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef +echo $PWD1 | $CRYPTSETUP luksFormat -q $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DM_BAD_NAME 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DM_LONG_NAME 2>/dev/null && fail + +if ! fips_mode -a -d $LUKS2_LOCKING_DIR; then + touch $LUKS2_LOCKING_DIR/$MEMORY_HARD_LOCK_FILE + prepare "[52] Test pbkdf serialization flag." wipe + echo $PWD1 | $CRYPTSETUP luksFormat -q $FAST_PBKDF_ARGON_OPT --type luks2 $LOOPDEV || fail + test -f $LUKS2_LOCKING_DIR/$MEMORY_HARD_LOCK_FILE || fail "The locking file disappeared unexpectedly" + echo $PWD1 | $CRYPTSETUP open --serialize-memory-hard-pbkdf --test-passphrase $LOOPDEV || fail + test -f $LUKS2_LOCKING_DIR/$MEMORY_HARD_LOCK_FILE && fail "The --serialize-memory-hard-pbkdf option did not remove the locking file (did not use the file)." +fi + remove_mapping exit 0 diff --git a/tests/crypto-check.c b/tests/crypto-check.c new file mode 100644 index 0000000..43be252 --- /dev/null +++ b/tests/crypto-check.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * Test utility checking availability of crypto primitive in crypto backend. + * + * Copyright (C) 2024-2025 Milan Broz + */ + +#include +#include +#include +#include + +#include "crypto_backend/crypto_backend.h" + +static bool fips_mode(void) +{ + int fd; + char buf = 0; + + fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY); + + if (fd < 0) + return false; + + if (read(fd, &buf, 1) != 1) + buf = '0'; + + close(fd); + + return (buf == '1'); +} + +static int check_cipher(const char *alg, const char *mode, unsigned long key_bits) +{ + struct crypt_cipher *cipher; + char key[256]; + + if (key_bits % 8 || (key_bits / 8) > sizeof(key)) + return EXIT_FAILURE; + + /* Userspace crypto */ + crypt_backend_rng(key, sizeof(key), CRYPT_RND_NORMAL, 0); + if (crypt_cipher_init(&cipher, alg, mode, key, key_bits / 8)) + return EXIT_FAILURE; + crypt_cipher_destroy(cipher); + + /* Kernel crypto */ + if (crypt_cipher_check_kernel(alg, mode, NULL, key_bits / 8)) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +static int check_hash(const char *hash) +{ + struct crypt_hash *h; + + if (crypt_hash_size(hash) < 0) + return EXIT_FAILURE; + + if (crypt_hash_init(&h, hash)) + return EXIT_FAILURE; + + crypt_hash_destroy(h); + return EXIT_SUCCESS; +} + +static void __attribute__((noreturn)) exit_help(bool destroy_backend) +{ + printf("Use: crypto_check version | hash | cipher [key_bits]\n"); + if (destroy_backend) + crypt_backend_destroy(); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) +{ + int r = EXIT_SUCCESS; + + if (argc < 2) + exit_help(false); + + if (crypt_backend_init(fips_mode())) { + printf("Crypto backend init error."); + return EXIT_FAILURE; + } + + if (!strcmp(argv[1], "version")) { + printf("%s%s\n", crypt_backend_version(), fips_mode() ? " (FIPS mode)" : "" ); + } else if (!strcmp(argv[1], "hash")) { + if (argc != 3) + exit_help(true); + r = check_hash(argv[2]); + } else if (!strcmp(argv[1], "cipher")) { + unsigned long ul = 256; + char *ptr; + if (argc < 4 || argc > 5) + exit_help(true); + if (argc == 5) { + ul = strtoul(argv[4], &ptr, 10); + if (*ptr) + exit_help(true); + } + r = check_cipher(argv[2], argv[3], ul); + } + + crypt_backend_destroy(); + return r; +} diff --git a/tests/crypto-vectors.c b/tests/crypto-vectors.c index 754653e..43ea688 100644 --- a/tests/crypto-vectors.c +++ b/tests/crypto-vectors.c @@ -2,7 +2,7 @@ /* * cryptsetup crypto backend test vectors * - * Copyright (C) 2018-2024 Milan Broz + * Copyright (C) 2018-2025 Milan Broz */ #include @@ -18,6 +18,8 @@ # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #endif +static bool fips_active = false; + static void printhex(const char *s, const char *buf, size_t len) { size_t i; @@ -731,11 +733,11 @@ struct cipher_iv_test_vector { const char *iv_name; uint64_t iv_offset; unsigned int data_length; - const char in_sha256[32]; + const char *in_sha256; struct { size_t sector_size; bool large_iv; - const char out_sha256[32]; + const char *out_sha256; } out[7]; }; @@ -1508,6 +1510,57 @@ static int memcmp_test(void) return EXIT_SUCCESS; } +#if ENABLE_AF_ALG +struct capi_test_vector { + const char *name; + const char *mode; + const char *integrity; + size_t key_length; + bool fips; +}; + +static struct capi_test_vector capi_test_vectors[] = { + { "aes", "xts", NULL, 64, true }, + { "aes", "xts-plain64", NULL, 32, true }, + { "aes", "xts-plain64", NULL, 64, true }, + { "aes", "xts-plain64", "none", 64, true }, + { "aes", "gcm-random", "aead", 16, true }, + { "aes", "gcm-random", "aead", 32, true }, + { "aes", "ccm-random", "aead", 19, false }, + { "aes", "ccm-random", "aead", 35, false }, + { "chacha20", "random", "poly1305", 32, false }, + { "aegis128", "random", "aead", 16, false }, +}; +#endif + +static int kernel_capi_check_test(void) +{ +#if ENABLE_AF_ALG + unsigned int i; + int r; + + for (i = 0; i < ARRAY_SIZE(capi_test_vectors); i++) { + printf("CAPI %s/%s/%s/%zu ", capi_test_vectors[i].name, + capi_test_vectors[i].mode, + capi_test_vectors[i].integrity ?: "NULL", + capi_test_vectors[i].key_length); + + r = crypt_cipher_check_kernel(capi_test_vectors[i].name, + capi_test_vectors[i].mode, + capi_test_vectors[i].integrity, + capi_test_vectors[i].key_length); + if (!r) + printf("[OK]\n"); + else if (r == -ENOENT || r == -ENOTSUP || + (fips_active && !capi_test_vectors[i].fips)) + printf("[N/A]\n"); + else + return EXIT_FAILURE; + } +#endif + return EXIT_SUCCESS; +} + static void __attribute__((noreturn)) exit_test(const char *msg, int r) { if (msg) @@ -1527,7 +1580,9 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[] } #endif - if (crypt_backend_init(fips_mode())) + fips_active = fips_mode(); + + if (crypt_backend_init(fips_active)) exit_test("Crypto backend init error.", EXIT_FAILURE); printf("Test vectors using %s crypto backend.\n", crypt_backend_version()); @@ -1556,6 +1611,9 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[] if (utf8_16_test()) exit_test("UTF8/16 test failed.", EXIT_FAILURE); + if (kernel_capi_check_test()) + exit_test("Kernel CAPI test failed.", EXIT_FAILURE); + if (default_alg_test()) { if (fips_mode()) printf("\nDefault compiled-in algorithms test ignored (FIPS mode on).\n"); diff --git a/tests/device-test b/tests/device-test index 9aaf03c..c6e745d 100755 --- a/tests/device-test +++ b/tests/device-test @@ -37,6 +37,9 @@ fail() exit 100 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + skip() { echo "TEST SKIPPED: $1" @@ -44,7 +47,7 @@ skip() exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -54,7 +57,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } @@ -77,7 +80,7 @@ add_image() dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1 } -function dm_crypt_features() +dm_crypt_features() { modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load" VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) @@ -106,6 +109,9 @@ function dm_crypt_features() [ $VER_MIN -lt 22 ] && return DM_PERF_NO_WORKQUEUE=1 + + [ $VER_MIN -lt 26 ] && return + DM_PERF_HIGH_PRIORITY=1 } format() # format @@ -183,12 +189,18 @@ else $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT $DEV $DEV_NAME2 2>/dev/null && fail if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then - echo -n "no_read_workqueue no_write_workqueue" + echo -n "no_read_workqueue no_write_workqueue " echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT -q $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue || fail $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail check_io fi + if [ -n "$DM_PERF_HIGH_PRIORITY" ]; then + echo -n "high_priority " + echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT -q $DEV_NAME --perf-high_priority || fail + $CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail + check_io + fi $CRYPTSETUP close $DEV_NAME || fail echo @@ -215,11 +227,16 @@ else $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME2 2>/dev/null && fail if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then - echo -n "no_read_workqueue no_write_workqueue" + echo -n "no_read_workqueue no_write_workqueue " echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue || fail $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail fi + if [ -n "$DM_PERF_HIGH_PRIORITY" ]; then + echo -n "high_priority " + echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME --perf-high_priority || fail + $CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail + fi $CRYPTSETUP close $DEV_NAME || fail echo @@ -280,7 +297,7 @@ else fi fi if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then - echo -n "no_read_workqueue no_write_workqueue" + echo -n "no_read_workqueue no_write_workqueue " echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue --persistent || fail $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail @@ -289,6 +306,14 @@ else $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail fi + if [ -n "$DM_PERF_HIGH_PRIORITY" ]; then + echo -n "high_priority " + echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-high_priority --persistent || fail + $CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail + $CRYPTSETUP close $DEV_NAME || fail + echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail + $CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail + fi echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME2 2>/dev/null && fail $CRYPTSETUP close $DEV_NAME || fail echo diff --git a/tests/differ.c b/tests/differ.c index 5d19745..a713893 100644 --- a/tests/differ.c +++ b/tests/differ.c @@ -2,7 +2,7 @@ /* * cryptsetup file differ check (rewritten Clemens' fileDiffer in Python) * - * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/tests/discards-test b/tests/discards-test index 27e5a5b..59c5922 100755 --- a/tests/discards-test +++ b/tests/discards-test @@ -28,13 +28,16 @@ fail() exit 100 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + skip() { [ -n "$1" ] && echo "$1" exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -44,7 +47,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } @@ -68,7 +71,7 @@ add_device() { [ -b $DEV ] || fail "Cannot find $DEV." } -function check_version() +check_version() { VER_STR=$(dmsetup targets | grep crypt | cut -f 2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." diff --git a/tests/fuzz/LUKS2.proto b/tests/fuzz/LUKS2.proto index 7ec017f..3e4c564 100644 --- a/tests/fuzz/LUKS2.proto +++ b/tests/fuzz/LUKS2.proto @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ syntax = "proto2"; diff --git a/tests/fuzz/LUKS2_plain_JSON.proto b/tests/fuzz/LUKS2_plain_JSON.proto index dc2bced..d825f74 100644 --- a/tests/fuzz/LUKS2_plain_JSON.proto +++ b/tests/fuzz/LUKS2_plain_JSON.proto @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ syntax = "proto2"; diff --git a/tests/fuzz/crypt2_load_fuzz.cc b/tests/fuzz/crypt2_load_fuzz.cc index 4e53c42..db365b6 100644 --- a/tests/fuzz/crypt2_load_fuzz.cc +++ b/tests/fuzz/crypt2_load_fuzz.cc @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 fuzz target * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ extern "C" { diff --git a/tests/fuzz/crypt2_load_proto_fuzz.cc b/tests/fuzz/crypt2_load_proto_fuzz.cc index e076938..def3cf0 100644 --- a/tests/fuzz/crypt2_load_proto_fuzz.cc +++ b/tests/fuzz/crypt2_load_proto_fuzz.cc @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator fuzz target * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #include "LUKS2.pb.h" diff --git a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc index deb15e3..c1f0f43 100644 --- a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc +++ b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator fuzz target * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #include "LUKS2_plain_JSON.pb.h" diff --git a/tests/fuzz/oss-fuzz-build.sh b/tests/fuzz/oss-fuzz-build.sh index e883edd..b3c6e04 100755 --- a/tests/fuzz/oss-fuzz-build.sh +++ b/tests/fuzz/oss-fuzz-build.sh @@ -1,19 +1,24 @@ #!/usr/bin/env bash -function in_oss_fuzz() +in_oss_fuzz() { test -n "$FUZZING_ENGINE" } -echo "Running cryptsetup OSS-Fuzz build script." -env -set -ex -PWD=$(pwd) +last_commit() +{ + echo "$(git -C "$1" log --format="%h %s" -n 1) ($1)" +} + +echo "Running cryptsetup OSS-Fuzz build script for ${SANITIZER:-address} sanitizer." +#env ; set -x +set -e +XPWD="$(pwd)" export LC_CTYPE=C.UTF-8 -export SRC=${SRC:-$PWD/build} -export OUT="${OUT:-$PWD/out}" +export SRC="${SRC:-$XPWD/build}" +export OUT="${OUT:-$XPWD/out}" export DEPS_PATH=$SRC/static_lib_deps export PKG_CONFIG_PATH="$DEPS_PATH"/lib/pkgconfig @@ -36,28 +41,49 @@ mkdir -p $OUT mkdir -p $DEPS_PATH cd $SRC -LIBFUZZER_PATCH="$PWD/unpoison-mutated-buffers-from-libfuzzer.patch" -in_oss_fuzz && LIBFUZZER_PATCH="$PWD/cryptsetup/tests/fuzz/unpoison-mutated-buffers-from-libfuzzer.patch" +echo "Installing dependencies" +LIBFUZZER_PATCH="$XPWD/unpoison-mutated-buffers-from-libfuzzer.patch" +in_oss_fuzz && LIBFUZZER_PATCH="$XPWD/cryptsetup/tests/fuzz/unpoison-mutated-buffers-from-libfuzzer.patch" in_oss_fuzz && apt-get update && apt-get install -y \ make autoconf automake autopoint libtool pkg-config \ sharutils gettext expect keyutils ninja-build \ bison flex -[ ! -d zlib ] && git clone --depth 1 https://github.com/madler/zlib.git +echo "Cloning git repositories" +# FIXME: temporary use branch master instead of develop +[ ! -d zlib ] && git clone -q --depth 1 --branch master https://github.com/madler/zlib.git +last_commit zlib + # Upstream repo has disabled cloning https://git.tukaani.org/xz.git -[ ! -d xz ] && git clone --depth 1 https://github.com/tukaani-project/xz -[ ! -d json-c ] && git clone --depth 1 https://github.com/json-c/json-c.git -[ ! -d lvm2 ] && git clone --depth 1 https://gitlab.com/lvmteam/lvm2 -[ ! -d popt ] && git clone --depth 1 https://github.com/rpm-software-management/popt.git +[ ! -d xz ] && git clone -q --depth 1 https://github.com/tukaani-project/xz +last_commit xz + +[ ! -d json-c ] && git clone -q --depth 1 https://github.com/json-c/json-c.git +last_commit json-c + +[ ! -d lvm2 ] && git clone -q --depth 1 https://gitlab.com/lvmteam/lvm2 +last_commit lvm2 + +[ ! -d popt ] && git clone -q --depth 1 https://github.com/rpm-software-management/popt.git +last_commit popt + # FIXME: temporary fix until libprotobuf stops shuffling C++ requirements # [ ! -d libprotobuf-mutator ] && git clone --depth 1 https://github.com/google/libprotobuf-mutator.git \ -[ ! -d libprotobuf-mutator ] && git clone --depth 1 --branch v1.1 https://github.com/google/libprotobuf-mutator.git \ - && [ "$SANITIZER" == "memory" ] && ( cd libprotobuf-mutator; patch -p1 < $LIBFUZZER_PATCH ) -[ ! -d openssl ] && git clone --depth 1 https://github.com/openssl/openssl -[ ! -d util-linux ] && git clone --depth 1 https://github.com/util-linux/util-linux -[ ! -d cryptsetup_fuzzing ] && git clone --depth 1 https://gitlab.com/cryptsetup/cryptsetup_fuzzing.git +[ ! -d libprotobuf-mutator ] && git clone -q --depth 1 --branch v1.1 -c advice.detachedHead=false \ + https://github.com/google/libprotobuf-mutator.git && + [ "$SANITIZER" == "memory" ] && ( cd libprotobuf-mutator; patch -p1 < $LIBFUZZER_PATCH ) +last_commit libprotobuf-mutator + +[ ! -d openssl ] && git clone -q --depth 1 https://github.com/openssl/openssl +last_commit openssl + +[ ! -d util-linux ] && git clone -q --depth 1 https://github.com/util-linux/util-linux +last_commit util-linux + +[ ! -d cryptsetup_fuzzing ] && git clone -q --depth 1 https://gitlab.com/cryptsetup/cryptsetup_fuzzing.git +echo "Building libraries from git" cd openssl ./Configure --prefix="$DEPS_PATH" --libdir=lib no-shared no-module no-asm make build_generated @@ -128,6 +154,7 @@ cd external.protobuf; cp -Rf bin lib include "$DEPS_PATH"; cd ../../.. +echo "Building cryptsetup fuzzers" if in_oss_fuzz; then mkdir -p cryptsetup/tests/fuzz/build ln -s ../../../../static_lib_deps cryptsetup/tests/fuzz/build/static_lib_deps @@ -140,6 +167,7 @@ fi make clean make -j fuzz-targets +echo "Installing fuzzers" for fuzzer in $ENABLED_FUZZERS; do cp tests/fuzz/$fuzzer $OUT cp $SRC/cryptsetup_fuzzing/${fuzzer}_seed_corpus.zip $OUT @@ -150,4 +178,4 @@ for fuzzer in $ENABLED_FUZZERS; do fi done -cd $PWD +cd $XPWD diff --git a/tests/fuzz/plain_json_proto_to_luks2.cc b/tests/fuzz/plain_json_proto_to_luks2.cc index f3a52c7..04d33f8 100644 --- a/tests/fuzz/plain_json_proto_to_luks2.cc +++ b/tests/fuzz/plain_json_proto_to_luks2.cc @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 protobuf to image converter * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/tests/fuzz/plain_json_proto_to_luks2_converter.cc b/tests/fuzz/plain_json_proto_to_luks2_converter.cc index d130461..60d2e1d 100644 --- a/tests/fuzz/plain_json_proto_to_luks2_converter.cc +++ b/tests/fuzz/plain_json_proto_to_luks2_converter.cc @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator fuzz target * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #include "plain_json_proto_to_luks2_converter.h" diff --git a/tests/fuzz/plain_json_proto_to_luks2_converter.h b/tests/fuzz/plain_json_proto_to_luks2_converter.h index bba0df8..74aced5 100644 --- a/tests/fuzz/plain_json_proto_to_luks2_converter.h +++ b/tests/fuzz/plain_json_proto_to_luks2_converter.h @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator fuzz target * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #ifndef LUKS2_PROTO_CONVERTER_H_ diff --git a/tests/fuzz/proto_to_luks2.cc b/tests/fuzz/proto_to_luks2.cc index d6af21f..bd5ff79 100644 --- a/tests/fuzz/proto_to_luks2.cc +++ b/tests/fuzz/proto_to_luks2.cc @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 protobuf to image converter * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/tests/fuzz/proto_to_luks2_converter.cc b/tests/fuzz/proto_to_luks2_converter.cc index 1ae32c6..17a2cb4 100644 --- a/tests/fuzz/proto_to_luks2_converter.cc +++ b/tests/fuzz/proto_to_luks2_converter.cc @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator fuzz target * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #include "proto_to_luks2_converter.h" diff --git a/tests/fuzz/proto_to_luks2_converter.h b/tests/fuzz/proto_to_luks2_converter.h index 56156ba..873a28a 100644 --- a/tests/fuzz/proto_to_luks2_converter.h +++ b/tests/fuzz/proto_to_luks2_converter.h @@ -2,8 +2,8 @@ /* * cryptsetup LUKS2 custom mutator fuzz target * - * Copyright (C) 2022-2024 Daniel Zatovic - * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2022-2025 Daniel Zatovic + * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. */ #ifndef LUKS2_PROTO_CONVERTER_H_ diff --git a/tests/fvault2-compat-test b/tests/fvault2-compat-test index 047798a..418009c 100755 --- a/tests/fvault2-compat-test +++ b/tests/fvault2-compat-test @@ -14,7 +14,7 @@ fi [ -z "$srcdir" ] && srcdir="." -function create_mapping() +create_mapping() { local image=$1 local passphrase=$2 @@ -22,13 +22,13 @@ function create_mapping() "$image" "$MAP" } -function remove_mapping() +remove_mapping() { [ -b "/dev/mapper/$MAP" ] && dmsetup remove --retry "$MAP" rm -rf $TST_DIR } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo " [FAILED]" @@ -38,7 +38,10 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" echo "Test skipped." @@ -46,17 +49,17 @@ function skip() exit 77 } -function produce_dump() +produce_dump() { "$CRYPTSETUP" fvault2Dump "$1" || fail } -function produce_dump_key() +produce_dump_key() { echo "$2" | "$CRYPTSETUP" fvault2Dump "$1" --dump-volume-key || fail } -function check_dump() +check_dump() { local dump=$1 local key=$2 @@ -67,7 +70,7 @@ function check_dump() "$key check failed: expected \"$exp_value\", got \"$value\"" } -function check_uuid() +check_uuid() { local exp_uuid=$1 local uuid=$(blkid -po value -s UUID "/dev/mapper/$MAP") @@ -75,7 +78,7 @@ function check_uuid() "UUID check failed: expected \"$exp_uuid\", got \"$uuid\"" } -function check_sha256() +check_sha256() { local exp_sum=$1 local sum=$(sha256sum /dev/mapper/$MAP | head -c 64) @@ -83,7 +86,7 @@ function check_sha256() "SHA256 sum check failed: expected \"$exp_sum\", got \"$sum\"" } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -93,7 +96,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } diff --git a/tests/generate-symbols-list b/tests/generate-symbols-list index 33a2e23..8e88af5 100755 --- a/tests/generate-symbols-list +++ b/tests/generate-symbols-list @@ -1,12 +1,12 @@ #!/bin/bash -function fail() +fail() { [ -n "$1" ] && echo "$1" exit 2 } -function generate() { +generate() { local ver= while IFS= read -r line; do diff --git a/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh b/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh index a7d3147..b1f85a9 100755 --- a/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh +++ b/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # make area 7 access the luks2 header space OFFS=$((2*LUKS2_HDR_SIZE*512-1)) @@ -28,7 +28,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-argon2-leftover-params.img.sh b/tests/generators/generate-luks2-argon2-leftover-params.img.sh index f0b74d7..a0d920c 100755 --- a/tests/generators/generate-luks2-argon2-leftover-params.img.sh +++ b/tests/generators/generate-luks2-argon2-leftover-params.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # add keyslot 1 to second digest obj_len=$(jq -c -M '.keyslots."1".kdf | length' $TMPDIR/json0) @@ -26,7 +26,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-correct-full-json0.img.sh b/tests/generators/generate-luks2-correct-full-json0.img.sh index 5cba271..c7ea781 100755 --- a/tests/generators/generate-luks2-correct-full-json0.img.sh +++ b/tests/generators/generate-luks2-correct-full-json0.img.sh @@ -15,7 +15,7 @@ PATTERN="\"config\":{" KEY="\"config_key\":\"" -function generate() +generate() { read -r json_str < $TMPDIR/json0 json_len=${#json_str} @@ -41,7 +41,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh b/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh index 1365e0c..6141433 100755 --- a/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh +++ b/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh @@ -11,7 +11,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str < $TMPDIR/json0 json_len=${#json_str} @@ -27,7 +27,7 @@ function generate() lib_mangle_json_hdr0 } -function check() +check() { lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh b/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh index fcbbb1e..25132b9 100755 --- a/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh +++ b/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh @@ -11,7 +11,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str < $TMPDIR/json1 json_len=${#json_str} @@ -27,7 +27,7 @@ function generate() lib_mangle_json_hdr1 } -function check() +check() { lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh b/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh index 925763e..752142d 100755 --- a/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh +++ b/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh @@ -11,7 +11,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { CHKS0=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) CHKS1=$(echo "D'oh!: arbitrary chosen string" | calc_sha256_checksum_stdin) @@ -20,7 +20,7 @@ function generate() write_luks2_bin_hdr1 $TMPDIR/hdr1 $TGT_IMG } -function check() +check() { lib_hdr0_checksum || exit 2 lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh b/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh index ae8c595..e87fbde 100755 --- a/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh +++ b/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh @@ -11,13 +11,13 @@ # 1 full target dir # 2 full source luks2 image -function generate() +generate() { CHKS0=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) write_checksum $CHKS0 $TGT_IMG } -function check() +check() { lib_hdr0_checksum || exit 2 } diff --git a/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh b/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh index a56695d..67778e1 100755 --- a/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh +++ b/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh @@ -11,14 +11,14 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { CHKS1=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) write_checksum $CHKS1 $TMPDIR/hdr1 write_luks2_bin_hdr1 $TMPDIR/hdr1 $TGT_IMG } -function check() +check() { lib_hdr1_checksum || exit 2 } diff --git a/tests/generators/generate-luks2-invalid-json-size-c0.img.sh b/tests/generators/generate-luks2-invalid-json-size-c0.img.sh index 13dea92..2991d87 100755 --- a/tests/generators/generate-luks2-invalid-json-size-c0.img.sh +++ b/tests/generators/generate-luks2-invalid-json-size-c0.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512+4096)) json_str=$(jq -c --arg js $JS '.config.json_size = ($js | tostring)' $TMPDIR/json0) @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-invalid-json-size-c1.img.sh b/tests/generators/generate-luks2-invalid-json-size-c1.img.sh index 5cdc7ce..dddf99a 100755 --- a/tests/generators/generate-luks2-invalid-json-size-c1.img.sh +++ b/tests/generators/generate-luks2-invalid-json-size-c1.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512-4096)) json_str=$(jq -c --arg js $JS '.config.json_size = ($js | tostring)' $TMPDIR/json0) @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-invalid-json-size-c2.img.sh b/tests/generators/generate-luks2-invalid-json-size-c2.img.sh index 4122338..4760618 100755 --- a/tests/generators/generate-luks2-invalid-json-size-c2.img.sh +++ b/tests/generators/generate-luks2-invalid-json-size-c2.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512)) TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K @@ -34,7 +34,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 local str_res1=$(head -c 4 $TMPDIR/hdr_res0) diff --git a/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh b/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh index 8187b72..8d509db 100755 --- a/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh +++ b/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # make area 7 being included in area 6 OFFS=$((2*LUKS2_HDR_SIZE*512)) @@ -28,7 +28,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh b/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh index 2ba1a9b..c66ffcf 100755 --- a/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh +++ b/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c '.config.keyslots_size = (.config.keyslots_size | tonumber - 1 | tostring)' $TMPDIR/json0) test -n "$json_str" || exit 2 @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh b/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh index f983438..4f96ef8 100755 --- a/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh +++ b/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq '.config.keyslots_size = ([.keyslots[].area.size] | map(tonumber) | add - 4096 | tostring )' $TMPDIR/json0) test -n "$json_str" || exit 2 @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-invalid-object-type-json0.img.sh b/tests/generators/generate-luks2-invalid-object-type-json0.img.sh index 616120b..3a99356 100755 --- a/tests/generators/generate-luks2-invalid-object-type-json0.img.sh +++ b/tests/generators/generate-luks2-invalid-object-type-json0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str < $TMPDIR/json0 json_str="[$json_str]" # make top level value an array @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh b/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh index 3f34692..9974227 100755 --- a/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh +++ b/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str < $TMPDIR/json0 json_str=" $json_str" # add useless opening whitespace @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-invalid-tokens.img.sh b/tests/generators/generate-luks2-invalid-tokens.img.sh index 9719cf7..6475bd4 100755 --- a/tests/generators/generate-luks2-invalid-tokens.img.sh +++ b/tests/generators/generate-luks2-invalid-tokens.img.sh @@ -12,7 +12,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c 'del(.tokens) | .tokens = 42' $TMPDIR/json0) test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr1 } -function check() +check() { lib_hdr0_checksum || exit 2 lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-invalid-top-objects.img.sh b/tests/generators/generate-luks2-invalid-top-objects.img.sh index 174dc2c..cbb51f4 100755 --- a/tests/generators/generate-luks2-invalid-top-objects.img.sh +++ b/tests/generators/generate-luks2-invalid-top-objects.img.sh @@ -12,7 +12,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c 'del(.tokens) | .tokens = 42 | del(.digests) | .digests = 42 | @@ -27,7 +27,7 @@ function generate() lib_mangle_json_hdr1 } -function check() +check() { lib_hdr0_checksum || exit 2 lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-keyslot-invalid-af.img.sh b/tests/generators/generate-luks2-keyslot-invalid-af.img.sh index 99f7679..1825780 100755 --- a/tests/generators/generate-luks2-keyslot-invalid-af.img.sh +++ b/tests/generators/generate-luks2-keyslot-invalid-af.img.sh @@ -12,7 +12,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c 'del(.keyslots."0".af.type) | .keyslots."0".af.type = 42' $TMPDIR/json0) test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr1 } -function check() +check() { lib_hdr0_checksum || exit 2 lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-keyslot-invalid-area-size.img.sh b/tests/generators/generate-luks2-keyslot-invalid-area-size.img.sh index 723d58a..59bfd1e 100755 --- a/tests/generators/generate-luks2-keyslot-invalid-area-size.img.sh +++ b/tests/generators/generate-luks2-keyslot-invalid-area-size.img.sh @@ -12,7 +12,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c '.keyslots."0"."area".size = "18446744073709551615"' $TMPDIR/json0) test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr1 } -function check() +check() { lib_hdr0_checksum || exit 2 lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-keyslot-invalid-area.img.sh b/tests/generators/generate-luks2-keyslot-invalid-area.img.sh index c41037e..5d14439 100755 --- a/tests/generators/generate-luks2-keyslot-invalid-area.img.sh +++ b/tests/generators/generate-luks2-keyslot-invalid-area.img.sh @@ -12,7 +12,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c 'del(.keyslots."0".area) | .keyslots."0".area = 42' $TMPDIR/json0) test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr1 } -function check() +check() { lib_hdr0_checksum || exit 2 lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-keyslot-invalid-objects.img.sh b/tests/generators/generate-luks2-keyslot-invalid-objects.img.sh index 5fcfef2..46bedd5 100755 --- a/tests/generators/generate-luks2-keyslot-invalid-objects.img.sh +++ b/tests/generators/generate-luks2-keyslot-invalid-objects.img.sh @@ -12,7 +12,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c 'del(.keyslots."0".kdf) | .keyslots."0".kdf = 42 | del(.keyslots."0".af) | .keyslots."0".af = 42' $TMPDIR/json0) @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr1 } -function check() +check() { lib_hdr0_checksum || exit 2 lib_hdr1_checksum || exit 2 diff --git a/tests/generators/generate-luks2-keyslot-missing-digest.img.sh b/tests/generators/generate-luks2-keyslot-missing-digest.img.sh index 49aeff1..c675783 100755 --- a/tests/generators/generate-luks2-keyslot-missing-digest.img.sh +++ b/tests/generators/generate-luks2-keyslot-missing-digest.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str_orig < $TMPDIR/json0 arr_len=$(jq -c -M '.digests."0".keyslots | length' $TMPDIR/json0) @@ -27,7 +27,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh b/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh index 5ba55f1..d86efce 100755 --- a/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh +++ b/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # add keyslot 1 to second digest json_str=$(jq -r -c -M '.digests."1" = .digests."0" | .digests."1".keyslots = ["1"]' $TMPDIR/json0) @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh index 2a44678..248db11 100755 --- a/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh @@ -16,7 +16,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 128 KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K @@ -47,7 +47,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-128k.img.sh b/tests/generators/generate-luks2-metadata-size-128k.img.sh index 79cccbd..8fa8c49 100755 --- a/tests/generators/generate-luks2-metadata-size-128k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-128k.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 128KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh index f0e6e8d..b053428 100755 --- a/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh @@ -16,7 +16,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 16 KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE @@ -47,7 +47,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh index 25c19c1..61f7220 100755 --- a/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh @@ -16,7 +16,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 1 MiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M @@ -47,7 +47,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-1m.img.sh b/tests/generators/generate-luks2-metadata-size-1m.img.sh index 9228fe5..baced6e 100755 --- a/tests/generators/generate-luks2-metadata-size-1m.img.sh +++ b/tests/generators/generate-luks2-metadata-size-1m.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 1 MiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh index b4c1027..8d42cc5 100755 --- a/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh @@ -16,7 +16,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 256 KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K @@ -47,7 +47,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-256k.img.sh b/tests/generators/generate-luks2-metadata-size-256k.img.sh index 60ec878..d65d748 100755 --- a/tests/generators/generate-luks2-metadata-size-256k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-256k.img.sh @@ -16,7 +16,7 @@ # $2 full source luks2 image -function generate() +generate() { # 256KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K @@ -45,7 +45,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh index 0c68905..bc95c68 100755 --- a/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 2 MiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M @@ -46,7 +46,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-2m.img.sh b/tests/generators/generate-luks2-metadata-size-2m.img.sh index 0dbb521..9997bd4 100755 --- a/tests/generators/generate-luks2-metadata-size-2m.img.sh +++ b/tests/generators/generate-luks2-metadata-size-2m.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 2 MiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh index effd244..fe95d3a 100755 --- a/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh @@ -16,7 +16,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 32 KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K @@ -47,7 +47,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-32k.img.sh b/tests/generators/generate-luks2-metadata-size-32k.img.sh index f970144..f862e4f 100755 --- a/tests/generators/generate-luks2-metadata-size-32k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-32k.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 32KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh index f423850..837aab6 100755 --- a/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 4 MiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M @@ -46,7 +46,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-4m.img.sh b/tests/generators/generate-luks2-metadata-size-4m.img.sh index b15ad4b..55ce0b2 100755 --- a/tests/generators/generate-luks2-metadata-size-4m.img.sh +++ b/tests/generators/generate-luks2-metadata-size-4m.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 4 MiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh index 4980816..8a46817 100755 --- a/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh @@ -16,7 +16,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 512 KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K @@ -47,7 +47,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-512k.img.sh b/tests/generators/generate-luks2-metadata-size-512k.img.sh index f3da37f..a9a002e 100755 --- a/tests/generators/generate-luks2-metadata-size-512k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-512k.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 512KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh index 3913f03..6b3a906 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 64KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh index b01f933..02eb7de 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 64KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K @@ -45,7 +45,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh b/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh index 5b8517a..4487296 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 64KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K @@ -45,7 +45,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh index 9635ab7..a2ee1ac 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh @@ -16,7 +16,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 64 KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K @@ -47,7 +47,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-64k.img.sh b/tests/generators/generate-luks2-metadata-size-64k.img.sh index 50941b8..98285ac 100755 --- a/tests/generators/generate-luks2-metadata-size-64k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # 64KiB metadata TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh index d2ddd61..7eb41b5 100755 --- a/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M @@ -46,7 +46,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } -function check() +check() { lib_hdr0_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-metadata-size-invalid.img.sh b/tests/generators/generate-luks2-metadata-size-invalid.img.sh index 745fc5c..24113a1 100755 --- a/tests/generators/generate-luks2-metadata-size-invalid.img.sh +++ b/tests/generators/generate-luks2-metadata-size-invalid.img.sh @@ -15,7 +15,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } -function check() +check() { lib_hdr1_killed $TEST_MDA_SIZE || exit 2 diff --git a/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh b/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh index a0ca53c..ae364ea 100755 --- a/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh +++ b/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str_orig < $TMPDIR/json0 arr_len=$(jq -c -M '.digests."0".keyslots | length' $TMPDIR/json0) @@ -29,7 +29,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh b/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh index 84d7ed2..e5da89c 100755 --- a/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh +++ b/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str_orig < $TMPDIR/json0 # add missing keyslot reference in keyslots array of token '0' @@ -27,7 +27,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh b/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh index 300c2dc..0cbb3bc 100755 --- a/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh +++ b/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str_orig < $TMPDIR/json0 arr_len=$(jq -c -M '.digests."0".segments | length' $TMPDIR/json0) @@ -29,7 +29,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh b/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh index 9c5ed0b..7d7220c 100755 --- a/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh +++ b/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh @@ -17,7 +17,7 @@ PATTERN="\"config\":{" KEY="\"config_key\":\"" -function generate() +generate() { read -r json_str < $TMPDIR/json0 json_len=${#json_str} @@ -44,7 +44,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-non-compact-json-4k-token-0.img.sh b/tests/generators/generate-luks2-non-compact-json-4k-token-0.img.sh new file mode 100755 index 0000000..abbaf5a --- /dev/null +++ b/tests/generators/generate-luks2-non-compact-json-4k-token-0.img.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate LUKS2 header with non compact (valid!) +# json and additional token with id 0 with json +# format aligned to 4K boundary. +# +# The image is tested for correct LUKS2 write optimization +# where non compact json trailing bytes must not remain in LUKS2 json +# area after write of shorter (e.g. compact) json. + +# $1 full target dir +# $2 full source luks2 image + +generate() +{ + # add empty token + json_str=$(jq -c '.tokens."0" = {"type":"a", "keyslots":[]}' $TMPDIR/json0) + json_len_orig=${#json_str} + test $json_len_orig -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + # align to 4k and full 4K of whitespace if already aligned + json_fill_len=$((4096-(json_len_orig%4096))) + fill=$(repeat_str " " $json_fill_len) + json_str_new=$(echo -e $json_str | sed -e "s/\(\"type\":\)\(\"luks2\"\)/\1""$fill""\2/") + json_len_new=${#json_str_new} + + test $((json_len_new%4096)) -eq 0 || exit 2 + test $json_len_new -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + test $json_len_new -gt $json_len_orig || exit 2 + + printf '%s' "$json_str_new" | _dd of=$TMPDIR/json0 bs=4K conv=notrunc + printf '%s' "$json_str_new" | _dd of=$TMPDIR/json1 bs=4K conv=notrunc + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + + read -r json_str_res < $TMPDIR/json_res0 + test $((${#json_str_res}%4096)) -eq 0 || exit 2 + test ${#json_str_res} -gt $json_len_orig || exit 2 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-non-compact-json-token-0.img.sh b/tests/generators/generate-luks2-non-compact-json-token-0.img.sh new file mode 100755 index 0000000..e5f5208 --- /dev/null +++ b/tests/generators/generate-luks2-non-compact-json-token-0.img.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate LUKS2 header with non compact (valid!) +# json and additional token with id 0. +# +# The image is tested for correct LUKS2 write optimization +# where non compact json trailing bytes must not remain in LUKS2 json +# area after write of shorter (e.g. compact) json. + +# $1 full target dir +# $2 full source luks2 image + +generate() +{ + # add empty token + json_str=$(jq -c '.tokens."0" = {"type":"a", "keyslots":[]}' $TMPDIR/json0) + json_len_orig=${#json_str} + test $json_len_orig -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + json_str_new=$(echo -n $json_str | sed -e 's/\(\"type\":\)\(\"luks2\"\)/\1 \2/') + json_len_new=${#json_str_new} + + test $json_len_new -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + test $json_len_new -gt $json_len_orig || exit 2 + + printf '%s' "$json_str_new" | _dd of=$TMPDIR/json0 bs=1 conv=notrunc + printf '%s' "$json_str_new" | _dd of=$TMPDIR/json1 bs=1 conv=notrunc + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + + read -r json_str_res < $TMPDIR/json_res0 + test ${#json_str_res} -gt $json_len_orig || exit 2 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh b/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh index 6f4aa7d..27406eb 100755 --- a/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh +++ b/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { read -r json_str < $TMPDIR/json0 json_str="$json_str"X # add illegal 'X' beyond json format @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh b/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh index 18abf23..ec30c66 100755 --- a/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh +++ b/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh @@ -17,7 +17,7 @@ QUOTE="[Homer J. Simpson]: Keep looking shocked and move slowly towards the cake." SPACE=20 -function generate() +generate() { read -r json_str < $TMPDIR/json0 json_len_orig=${#json_str} @@ -29,7 +29,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh b/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh index 23883bb..60cd23e 100755 --- a/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh +++ b/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # copy area 6 offset and length into area 7 json_str=$(jq -c '.keyslots."7".area.offset = .keyslots."6".area.offset | @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh b/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh index 0733627..19ca941 100755 --- a/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh +++ b/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # make area 7 being included in area 6 json_str=$(jq -c '.keyslots."7".area.offset = (.keyslots."6".area.offset | tonumber + 1 | tostring ) | @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh b/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh index 6699b38..cd62a73 100755 --- a/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh +++ b/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # make area 7 being included in area 6 json_str=$(jq -c '.keyslots."7".area.offset = ([ .keyslots."6".area.offset, .keyslots."6".area.size ] | map(tonumber) | add - 1 | tostring)' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh b/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh index e035f94..296d18b 100755 --- a/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh +++ b/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # add keyslot 1 to second digest obj_len=$(jq -c -M '.keyslots."2".kdf | length' $TMPDIR/json0) @@ -26,7 +26,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh b/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh index d82c2bd..4e4f5bd 100755 --- a/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh +++ b/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # add keyslot 1 to second digest obj_len=$(jq -c -M '.keyslots."2".kdf | length' $TMPDIR/json0) @@ -26,7 +26,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 lib_hdr0_checksum || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-empty-encryption.img.sh b/tests/generators/generate-luks2-segment-crypt-empty-encryption.img.sh index ca17aac..4e1aa9b 100755 --- a/tests/generators/generate-luks2-segment-crypt-empty-encryption.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-empty-encryption.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".encryption = ""' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh b/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh index e92bc2a..cdd6216 100755 --- a/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c 'del(.segments."0".encryption)' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh b/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh index 77beb53..8c86ad5 100755 --- a/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c 'del(.segments."0".iv_tweak)' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh b/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh index 0609533..ab0b8ec 100755 --- a/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c 'del(.segments."0".sector_size)' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh index 9d7e584..a9bac8d 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".encryption = {}' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh index 0830a16..6611c32 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".iv_tweak = "dynamic"' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh index 069b6c0..d0d1449 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".sector_size = 1023' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh index c310ff1..d7fabe4 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".sector_size = "4096"' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh index b4b8b39..14dd258 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".sector_size = -1024' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-missing-offset.img.sh b/tests/generators/generate-luks2-segment-missing-offset.img.sh index 6d5811e..66562be 100755 --- a/tests/generators/generate-luks2-segment-missing-offset.img.sh +++ b/tests/generators/generate-luks2-segment-missing-offset.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c 'del(.segments."0".offset)' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-missing-size.img.sh b/tests/generators/generate-luks2-segment-missing-size.img.sh index 579858f..ccfc2dc 100755 --- a/tests/generators/generate-luks2-segment-missing-size.img.sh +++ b/tests/generators/generate-luks2-segment-missing-size.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c 'del(.segments."0".size)' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-missing-type.img.sh b/tests/generators/generate-luks2-segment-missing-type.img.sh index 5b74c5d..5cb0cf5 100755 --- a/tests/generators/generate-luks2-segment-missing-type.img.sh +++ b/tests/generators/generate-luks2-segment-missing-type.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c 'del(.segments."0".type)' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-two.img.sh b/tests/generators/generate-luks2-segment-two.img.sh index 798c5be..1ec0470 100755 --- a/tests/generators/generate-luks2-segment-two.img.sh +++ b/tests/generators/generate-luks2-segment-two.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".size = "512" | .segments."1" = {type:"some", offset: (.segments."0".offset | tonumber + 512 | tostring), size: "dynamic"}' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-unknown-type.img.sh b/tests/generators/generate-luks2-segment-unknown-type.img.sh index 814344a..653f4bd 100755 --- a/tests/generators/generate-luks2-segment-unknown-type.img.sh +++ b/tests/generators/generate-luks2-segment-unknown-type.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0" = {type:"some_type", offset: .segments."0".offset, size: .segments."0".size, a_field:0}' $TMPDIR/json0) @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh b/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh index 3ba9d47..a5bf806 100755 --- a/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # create illegal backup segment key (used to be bug in 32bit implementations) json_str=$(jq -c '.segments[(.segments | length + 1 | tostring)] = { "type" : "linear", "offset" : "512", "size" : "512", "flags":["backup-x"]}' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh b/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh index 11a94d7..084566d 100755 --- a/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # create illegal backup segment key (used to be bug in 32bit implementations) json_str=$(jq -c '(.segments."0".offset | tonumber) as $i | .segments[range(1;65) | tostring] = { "type" : "linear", "offset" : ($i + 512 | tostring), "size" : "512" } | .segments."268435472" = { "type":"linear","offset":"512","size":"512","flags":["backup-x"]}' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh b/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh index 72da1f1..39a1c38 100755 --- a/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".flags = [ "hello", 1 ]' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-flags.img.sh b/tests/generators/generate-luks2-segment-wrong-flags.img.sh index 19d6340..22ac9f7 100755 --- a/tests/generators/generate-luks2-segment-wrong-flags.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-flags.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".flags = "hello"' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-offset.img.sh b/tests/generators/generate-luks2-segment-wrong-offset.img.sh index c9b1b50..69a7043 100755 --- a/tests/generators/generate-luks2-segment-wrong-offset.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-offset.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".offset = "-42"' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-size-0.img.sh b/tests/generators/generate-luks2-segment-wrong-size-0.img.sh index b9227a7..0d9c1ae 100755 --- a/tests/generators/generate-luks2-segment-wrong-size-0.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-size-0.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".size = 4096' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-size-1.img.sh b/tests/generators/generate-luks2-segment-wrong-size-1.img.sh index 6be5031..c3e8933 100755 --- a/tests/generators/generate-luks2-segment-wrong-size-1.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-size-1.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".size = "automatic"' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-size-2.img.sh b/tests/generators/generate-luks2-segment-wrong-size-2.img.sh index 311c0e8..83d9c2f 100755 --- a/tests/generators/generate-luks2-segment-wrong-size-2.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-size-2.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".size = "511"' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-segment-wrong-type.img.sh b/tests/generators/generate-luks2-segment-wrong-type.img.sh index c041157..0f7a18e 100755 --- a/tests/generators/generate-luks2-segment-wrong-type.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-type.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # remove mandatory encryption field json_str=$(jq -c '.segments."0".type = 42' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-uint64-max-segment-size.img.sh b/tests/generators/generate-luks2-uint64-max-segment-size.img.sh index f966e1d..ac0c7ee 100755 --- a/tests/generators/generate-luks2-uint64-max-segment-size.img.sh +++ b/tests/generators/generate-luks2-uint64-max-segment-size.img.sh @@ -14,7 +14,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # UINT64_MAX - 511 (so that it's sector aligned) json_str=$(jq -c '.segments."0".size = "18446744073709551104"' $TMPDIR/json0) @@ -25,7 +25,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh b/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh index 4e064e4..9a3ada6 100755 --- a/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh +++ b/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { json_str=$(jq -c '.segments."0".size = "18446744073709551616"' $TMPDIR/json0) test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 @@ -23,7 +23,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh b/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh index 6687f35..2f16e70 100755 --- a/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh +++ b/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh @@ -13,7 +13,7 @@ # $1 full target dir # $2 full source luks2 image -function generate() +generate() { # UINT64_MAX + 1 (it's 512 sector aligned) json_str=$(jq -c '.segments."0".size = "-512"' $TMPDIR/json0) @@ -24,7 +24,7 @@ function generate() lib_mangle_json_hdr0_kill_hdr1 } -function check() +check() { lib_hdr1_killed || exit 2 diff --git a/tests/generators/lib.sh b/tests/generators/lib.sh index c0e9cc1..07365d7 100644 --- a/tests/generators/lib.sh +++ b/tests/generators/lib.sh @@ -28,13 +28,13 @@ repeat_str() { printf "$1"'%.0s' $(eval "echo {1.."$(($2))"}"); } -function strindex() +strindex() { local x="${1%%$2*}" [[ $x = $1 ]] && echo -1 || echo ${#x} } -function test_img_name() +test_img_name() { local str=$(basename $1) str=${str#generate-} @@ -44,14 +44,14 @@ function test_img_name() # read primary bin hdr # 1:from 2:to -function read_luks2_bin_hdr0() +read_luks2_bin_hdr0() { _dd if=$1 of=$2 bs=512 count=$LUKS2_BIN_HDR_SIZE } # read primary json area # 1:from 2:to 3:[json only size (defaults to 12KiB)] -function read_luks2_json0() +read_luks2_json0() { local _js=${4:-$LUKS2_JSON_SIZE} local _js=$((_js*512/4096)) @@ -60,14 +60,14 @@ function read_luks2_json0() # read secondary bin hdr # 1:from 2:to 3:[metadata size (defaults to 16KiB)] -function read_luks2_bin_hdr1() +read_luks2_bin_hdr1() { _dd if=$1 of=$2 skip=${3:-$LUKS2_HDR_SIZE} bs=512 count=$LUKS2_BIN_HDR_SIZE } # read secondary json area # 1:from 2:to 3:[json only size (defaults to 12KiB)] -function read_luks2_json1() +read_luks2_json1() { local _js=${3:-$LUKS2_JSON_SIZE} _dd if=$1 of=$2 bs=512 skip=$((2*LUKS2_BIN_HDR_SIZE+_js)) count=$_js @@ -75,7 +75,7 @@ function read_luks2_json1() # read primary metadata area (bin + json) # 1:from 2:to 3:[metadata size (defaults to 16KiB)] -function read_luks2_hdr_area0() +read_luks2_hdr_area0() { local _as=${3:-$LUKS2_HDR_SIZE} local _as=$((_as*512)) @@ -84,7 +84,7 @@ function read_luks2_hdr_area0() # read secondary metadata area (bin + json) # 1:from 2:to 3:[metadata size (defaults to 16KiB)] -function read_luks2_hdr_area1() +read_luks2_hdr_area1() { local _as=${3:-$LUKS2_HDR_SIZE} local _as=$((_as*512)) @@ -93,14 +93,14 @@ function read_luks2_hdr_area1() # write secondary bin hdr # 1:from 2:to 3:[metadata size (defaults to 16KiB)] -function write_luks2_bin_hdr1() +write_luks2_bin_hdr1() { _dd if=$1 of=$2 bs=512 seek=${3:-$LUKS2_HDR_SIZE} count=$LUKS2_BIN_HDR_SIZE conv=notrunc } # write primary metadata area (bin + json) # 1:from 2:to 3:[metadata size (defaults to 16KiB)] -function write_luks2_hdr0() +write_luks2_hdr0() { local _as=${3:-$LUKS2_HDR_SIZE} local _as=$((_as*512)) @@ -109,7 +109,7 @@ function write_luks2_hdr0() # write secondary metadata area (bin + json) # 1:from 2:to 3:[metadata size (defaults to 16KiB)] -function write_luks2_hdr1() +write_luks2_hdr1() { local _as=${3:-$LUKS2_HDR_SIZE} local _as=$((_as*512)) @@ -118,7 +118,7 @@ function write_luks2_hdr1() # write json (includes padding) # 1:json_string 2:to 3:[json size (defaults to 12KiB)] -function write_luks2_json() +write_luks2_json() { local _js=${3:-$LUKS2_JSON_SIZE} local len=${#1} @@ -126,23 +126,23 @@ function write_luks2_json() truncate -s $((_js*512)) $2 } -function kill_bin_hdr() +kill_bin_hdr() { printf "VACUUM" | _dd of=$1 bs=1 conv=notrunc } -function erase_checksum() +erase_checksum() { _dd if=/dev/zero of=$1 bs=1 seek=$(printf %d $LUKS2_BIN_HDR_CHKS_OFFSET) count=$LUKS2_BIN_HDR_CHKS_LENGTH conv=notrunc } -function read_sha256_checksum() +read_sha256_checksum() { _dd if=$1 bs=1 skip=$(printf %d $LUKS2_BIN_HDR_CHKS_OFFSET) count=32 | xxd -c 32 -p } # 1 - string with checksum -function write_checksum() +write_checksum() { test $# -eq 2 || return 1 test $((${#1}/2)) -le $LUKS2_BIN_HDR_CHKS_LENGTH || { echo "too long"; return 1; } @@ -150,19 +150,19 @@ function write_checksum() echo $1 | xxd -r -p | _dd of=$2 bs=1 seek=$(printf %d $LUKS2_BIN_HDR_CHKS_OFFSET) conv=notrunc } -function calc_sha256_checksum_file() +calc_sha256_checksum_file() { sha256sum $1 | cut -d ' ' -f 1 } -function calc_sha256_checksum_stdin() +calc_sha256_checksum_stdin() { sha256sum - | cut -d ' ' -f 1 } # merge bin hdr with json to form metadata area # 1:bin_hdr 2:json 3:to 4:[json size (defaults to 12KiB)] -function merge_bin_hdr_with_json() +merge_bin_hdr_with_json() { local _js=${4:-$LUKS2_JSON_SIZE} local _js=$((_js*512/4096)) @@ -170,16 +170,16 @@ function merge_bin_hdr_with_json() _dd if=$2 of=$3 bs=4096 seek=1 count=$_js } -function _dd() +_dd() { dd $@ status=none } -function write_bin_hdr_size() { +write_bin_hdr_size() { printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=1 conv=notrunc } -function write_bin_hdr_offset() { +write_bin_hdr_offset() { printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=32 conv=notrunc } @@ -190,7 +190,7 @@ function write_bin_hdr_offset() { # $TMPDIR/hdr1 - bin hdr2 # 1:target_dir 2:source_image -function lib_prepare() +lib_prepare() { test $# -eq 2 || exit 1 @@ -209,13 +209,13 @@ function lib_prepare() read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1 } -function lib_cleanup() +lib_cleanup() { rm -f $TMPDIR/* rm -fd $TMPDIR } -function lib_mangle_json_hdr0() +lib_mangle_json_hdr0() { local mda_sz=${1:-} local jsn_sz=${2:-} @@ -229,7 +229,7 @@ function lib_mangle_json_hdr0() write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $mda_sz } -function lib_mangle_json_hdr1() +lib_mangle_json_hdr1() { local mda_sz=${1:-} local jsn_sz=${2:-} @@ -243,7 +243,7 @@ function lib_mangle_json_hdr1() write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $mda_sz } -function lib_mangle_json_hdr0_kill_hdr1() +lib_mangle_json_hdr0_kill_hdr1() { lib_mangle_json_hdr0 @@ -251,7 +251,7 @@ function lib_mangle_json_hdr0_kill_hdr1() write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG } -function lib_hdr0_killed() +lib_hdr0_killed() { local mda_sz=${1:-} @@ -260,7 +260,7 @@ function lib_hdr0_killed() test "$str_res0" = "VACUUM" } -function lib_hdr1_killed() +lib_hdr1_killed() { local mda_sz=${1:-} @@ -269,13 +269,13 @@ function lib_hdr1_killed() test "$str_res1" = "VACUUM" } -function lib_hdr0_checksum() +lib_hdr0_checksum() { local chks_res0=$(read_sha256_checksum $TGT_IMG) test "$CHKS0" = "$chks_res0" } -function lib_hdr1_checksum() +lib_hdr1_checksum() { read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 local chks_res1=$(read_sha256_checksum $TMPDIR/hdr_res1) diff --git a/tests/integrity-compat-test b/tests/integrity-compat-test index a2aae8d..c40218c 100755 --- a/tests/integrity-compat-test +++ b/tests/integrity-compat-test @@ -30,6 +30,7 @@ cleanup() { [ -b /dev/mapper/$DEV_NAME2 ] && dmremove $DEV_NAME2 [ -n "$DEV_LOOP" ] && losetup -d "$DEV_LOOP" DEV_LOOP="" + IDEV="" rm -f $DEV $DEV2 $KEY_FILE $KEY_FILE2 >/dev/null 2>&1 } @@ -42,13 +43,16 @@ fail() exit 100 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + skip() { [ -n "$1" ] && echo "$1" exit 77 } -function dm_integrity_features() +dm_integrity_features() { VER_STR=$(dmsetup targets | grep integrity | cut -f2 -dv) [ -z "$VER_STR" ] && skip "Cannot find dm-integrity target, test skipped." @@ -58,6 +62,17 @@ function dm_integrity_features() VER_PTC=$(echo $VER_STR | cut -f 3 -d.) [ $VER_MAJ -lt 1 ] && return + [ $VER_MAJ -gt 1 ] && { + DM_INTEGRITY_META=1 + DM_INTEGRITY_RECALC=1 + DM_INTEGRITY_BITMAP=1 + DM_INTEGRITY_RESIZE_SUPPORTED=1 + DM_INTEGRITY_HMAC_FIX=1 + DM_INTEGRITY_RESET=1 + DM_INTEGRITY_INLINE=1 + DM_INTEGRITY_RECALCULATE_INLINE=1 + return + } [ $VER_MIN -gt 1 ] && { DM_INTEGRITY_META=1 DM_INTEGRITY_RECALC=1 @@ -74,6 +89,12 @@ function dm_integrity_features() [ $VER_MIN -gt 7 ] && { DM_INTEGRITY_RESET=1 } + [ $VER_MIN -ge 12 ] && { + DM_INTEGRITY_INLINE=1 + } + [ $VER_MIN -ge 13 ] && { + DM_INTEGRITY_RECALCULATE_INLINE=1 + } } add_device() { @@ -82,7 +103,19 @@ add_device() { dd if=/dev/urandom of=$KEY_FILE2 bs=1 count=32 >/dev/null 2>&1 dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1 dd if=/dev/zero of=$DEV2 bs=1M count=32 >/dev/null 2>&1 - sync + IDEV=$DEV + INLINE_PARAMS="" +} + +add_device_inline() { + cleanup + add_device + DEV_LOOP=$(losetup -f $DEV --show) + [ -z "$DEV_LOOP" ] && fail + dmsetup create $DEV_NAME2 --table "0 32768 integrity $DEV_LOOP 0 64 J 2 block_size:4096 fix_padding" + [ ! -b /dev/mapper/$DEV_NAME2 ] && fail + IDEV=/dev/mapper/$DEV_NAME2 + INLINE_PARAMS="--integrity-inline " } status_check() # name value @@ -97,7 +130,7 @@ status_check() # name value dump_check() # name value { - X=$($INTSETUP dump $DEV | grep "$1" | cut -d' ' -f 2) + X=$($INTSETUP dump $IDEV | grep "$1" | sed 's/.*: //' | cut -d' ' -f 1) if [ "$X" != "$2" ] ; then echo "[dump FAIL]" echo " Expecting $1:$2 got \"$X\"." @@ -115,7 +148,7 @@ kernel_param_check() # number value fi } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $INTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -125,7 +158,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${INTSETUP_VALGRIND} "$@" } @@ -154,7 +187,7 @@ int_check_sum() # alg checksum [keyfile keysize] dd if=/dev/zero of=/dev/mapper/$DEV_NAME bs=1M oflag=direct >/dev/null 2>&1 dmremove $DEV_NAME - $INTSETUP open $DEV $DEV_NAME --integrity $1 $KEY_PARAMS || fail "Cannot activate device." + $INTSETUP open $IDEV $DEV_NAME --integrity $1 $KEY_PARAMS || fail "Cannot activate device." int_check_sum_only $2 } @@ -176,7 +209,7 @@ intformat() # alg alg_out tagsize outtagsize sector_size csum [keyfile keysize] echo -n "[INTEGRITY:$2:$4:$5]" [ -n "$8" ] && echo -n "[KEYFILE:$8]" echo -n "[FORMAT]" - $INTSETUP format --integrity-legacy-padding -q --integrity $1 $TAG_PARAMS --sector-size $5 $KEY_PARAMS $DEV >/dev/null 2>&1 + $INTSETUP format --integrity-legacy-padding -q --integrity $1 $INLINE_PARAMS $TAG_PARAMS --sector-size $5 $KEY_PARAMS $IDEV >/dev/null 2>&1 if [ $? -ne 0 ] ; then if [[ $1 =~ "sha2" || $1 =~ "crc" ]] ; then fail "Cannot format device." @@ -185,18 +218,18 @@ intformat() # alg alg_out tagsize outtagsize sector_size csum [keyfile keysize] return fi - dump_check "tag_size" $4 - dump_check "sector_size" $5 + dump_check "tag size" $4 + dump_check "sector size" $5 echo -n "[ACTIVATE]" - $INTSETUP open $DEV $DEV_NAME --integrity $1 $KEY_PARAMS || fail "Cannot activate device." + $INTSETUP open $IDEV $DEV_NAME --integrity $1 $KEY_PARAMS || fail "Cannot activate device." if [ -n "$8" ]; then KEY_HEX=$(xxd -c 4096 -l $8 -p $7) [ -z "$KEY_HEX" ] && fail "Cannot decode key." dmsetup table --showkeys $DEV_NAME | grep -q $KEY_HEX || fail "Key mismatch." fi - status_check "tag size" $4 + status_check "tag size" "$4 [bytes]" status_check "integrity" $2 - status_check "sector size" "$5 bytes" + status_check "sector size" "$5 [bytes]" int_check_sum $1 $6 $7 $8 echo -n "[REMOVE]" $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." @@ -220,11 +253,11 @@ int_error_detection() # mode alg tagsize outtagsize sector_size key_file key_siz else TAG_PARAMS="" fi - dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1 + dd if=/dev/zero of=$IDEV bs=1M count=32 >/dev/null 2>&1 echo -n "[INTEGRITY:$1:$2:$4:$5]" echo -n "[FORMAT]" - $INTSETUP format -q --integrity $2 $TAG_PARAMS --sector-size $5 $KEY_PARAMS $DEV $INT_MODE >/dev/null 2>&1 + $INTSETUP format -q --integrity $2 $INLINE_PARAMS $TAG_PARAMS --sector-size $5 $KEY_PARAMS $IDEV $INT_MODE >/dev/null 2>&1 if [ $? -ne 0 ] ; then if [[ $2 =~ "sha2" || $2 =~ "crc" ]] ; then fail "Cannot format device." @@ -233,7 +266,7 @@ int_error_detection() # mode alg tagsize outtagsize sector_size key_file key_siz return fi echo -n "[ACTIVATE]" - $INTSETUP open $DEV $DEV_NAME --integrity $2 --integrity-no-journal $KEY_PARAMS $INT_MODE || fail "Cannot activate device." + $INTSETUP open $IDEV $DEV_NAME --integrity $2 --integrity-no-journal $KEY_PARAMS $INT_MODE || fail "Cannot activate device." if [ -n "$6" -a -n "$7" ]; then echo -n "[KEYED HASH]" @@ -247,15 +280,15 @@ int_error_detection() # mode alg tagsize outtagsize sector_size key_file key_siz $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." # find offset of data area - ARR=($(dd if=$DEV bs=512 2>/dev/null | hexdump -C | grep 'EXAMPLE TEXT')) + ARR=($(dd if=$IDEV bs=512 2>/dev/null | hexdump -C | grep 'EXAMPLE TEXT')) OFF_HEX=${ARR[0]} OFF_DEC=$((16#$OFF_HEX)) echo -n "[CORRUPT DATA:$OFF_DEC]" - echo -n "Z" | dd of=$DEV bs=1 seek=$OFF_DEC conv=notrunc >/dev/null 2>&1 || fail "Cannot write to device." + echo -n "Z" | dd of=$IDEV bs=1 seek=$OFF_DEC conv=notrunc >/dev/null 2>&1 || fail "Cannot write to device." echo -n "[DETECT ERROR]" - $INTSETUP open $DEV $DEV_NAME --integrity $2 $KEY_PARAMS $INT_MODE || fail "Cannot activate device." + $INTSETUP open $IDEV $DEV_NAME --integrity $2 $KEY_PARAMS $INT_MODE || fail "Cannot activate device." dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 && fail "Error detection failed." echo -n "[REMOVE]" $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." @@ -279,7 +312,7 @@ int_journal() # 1 alg, 2 tagsize, 3 sector_size, 4 watermark, 5 commit_time, 6 j dmsetup table --showkeys $DEV_NAME | grep -q $KEY_HEX || fail "Key mismatch." status_check "journal watermark" "${4}%" - status_check "journal commit time" "${5} ms" + status_check "journal commit time" "${5} [ms]" status_check "journal integrity MAC" $9 echo -n "[REMOVE]" @@ -404,7 +437,7 @@ test_resize() # description detached_metadata wipe args check_device_size $DEV_NAME $WHOLE_DISK_SIZE "Resizing disk to maximum size failed" echo -n "[EXPAND FIXED]" - fallocate $DEV --len 64M + truncate -s 64M $DEV || fail $INTSETUP resize -q $wipe_flag $DEV_NAME --device-size 40MiB || fail "Failed to expand the device to a fixed size." dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detected after expanding to a fixed size." check_device_size $DEV_NAME $(( 40*1024*1024 / 512 )) "Resizing disk after expanding to a fixed size failed" @@ -433,6 +466,7 @@ command -v xxd >/dev/null || skip "WARNING: xxd tool required." modprobe dm-integrity >/dev/null 2>&1 dm_integrity_features +echo "Integrity mode tests:" add_device intformat blake2s-256 blake2s-256 32 32 512 8e5fe4119558e117bfc40e3b0f13ade3abe497b52604d4c7cca0cfd6c7f4cf11 intformat blake2b-256 blake2b-256 32 32 512 8e5fe4119558e117bfc40e3b0f13ade3abe497b52604d4c7cca0cfd6c7f4cf11 @@ -460,11 +494,31 @@ int_error_detection J sha1 0 20 4096 int_error_detection J sha256 0 32 512 int_error_detection J sha256 0 32 4096 -command -v xxd >/dev/null || skip "WARNING: xxd tool required." int_error_detection J hmac-sha256 0 32 512 $KEY_FILE 32 int_error_detection J hmac-sha256 0 32 4096 $KEY_FILE 32 +if [ -n "$DM_INTEGRITY_INLINE" ] ; then + echo "Integrity mode tests (inline tags): " + add_device_inline + intformat crc32c crc32c 0 4 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 + intformat crc32 crc32 0 4 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 + intformat xxhash64 xxhash64 0 8 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 + intformat sha1 sha1 0 20 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 + intformat sha1 sha1 16 16 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 + intformat sha256 sha256 0 32 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 + intformat hmac-sha256 hmac\(sha256\) 0 32 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 $KEY_FILE 32 + intformat hmac-sha256 hmac\(sha256\) 0 32 4096 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 $KEY_FILE 4096 + echo "Error detection tests (inline tags):" + int_error_detection J crc32c 0 4 4096 + int_error_detection J crc32 0 4 4096 + int_error_detection J xxhash64 0 8 4096 + int_error_detection J sha1 0 20 4096 + int_error_detection J sha256 0 32 4096 + int_error_detection J hmac-sha256 0 32 4096 $KEY_FILE 32 +fi + echo "Journal parameters tests:" +add_device # Watermark is calculated in kernel, so it can be rounded down/up int_journal crc32 4 512 66 1000 hmac-sha256 $KEY_FILE 32 hmac\(sha256\) int_journal sha256 32 4096 34 5000 hmac-sha1 $KEY_FILE 16 hmac\(sha1\) @@ -485,26 +539,33 @@ int_mode sha256 32 512 int_mode hmac-sha256 32 512 $KEY_FILE 32 int_mode hmac-sha256 32 4096 $KEY_FILE 32 -echo -n "Recalculate tags in-kernel:" -add_device -if [ -n "$DM_INTEGRITY_RECALC" ] ; then - $INTSETUP format -q $DEV --no-wipe || fail "Cannot format device." - $INTSETUP open $DEV $DEV_NAME --integrity-recalculate || fail "Cannot activate device." +recalc_test() # $1 checksum +{ + $INTSETUP format -q $IDEV $INLINE_PARAMS --sector-size 4096 --no-wipe || fail "Cannot format device." + $INTSETUP open $IDEV $DEV_NAME --integrity-recalculate || fail "Cannot activate device." dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M 2>/dev/null || fail "Cannot recalculate tags in-kernel" - int_check_sum_only 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 + int_check_sum_only $1 $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo -n "[OK]" if [ -n "$DM_INTEGRITY_RESET" ] ; then - $INTSETUP open $DEV $DEV_NAME -I sha256 --integrity-recalculate-reset || fail "Cannot activate device." + $INTSETUP open $IDEV $DEV_NAME -I sha256 --integrity-recalculate-reset || fail "Cannot activate device." dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M 2>/dev/null || fail "Cannot reset recalculate tags in-kernel" - int_check_sum_only 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 + int_check_sum_only $1 $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo "[RESET OK]" else echo "[RESET N/A]" fi -else - echo "[N/A]" +} +if [ -n "$DM_INTEGRITY_RECALC" ] ; then + echo -n "Recalculate tags in-kernel:" + add_device + recalc_test eab969b9d69b73dd20bf3f3d2a14936710595fd7ec61be6729690dde86cc7ba6 + if [ -n "$DM_INTEGRITY_RECALCULATE_INLINE" ] ; then + echo -n "Recalculate tags in-kernel (inline tags):" + add_device_inline 65072 + recalc_test 98abca7cb88f35f1944dface4c5040423a99886f4e5a716f061fd153d8661fe8 + fi fi echo -n "Separate metadata device:" @@ -526,7 +587,7 @@ if [ -n "$DM_INTEGRITY_BITMAP" ] ; then $INTSETUP format -q $DEV --integrity-bitmap-mode $DEV2 || fail "Cannot format device." $INTSETUP open $DEV --integrity-bitmap-mode --bitmap-sectors-per-bit 65536 --bitmap-flush-time 5000 $DEV_NAME || fail "Cannot activate device." $INTSETUP status $DEV_NAME | grep -q 'bitmap 512-byte sectors per bit: 65536' || fail - $INTSETUP status $DEV_NAME | grep -q 'bitmap flush interval: 5000 ms' || fail + $INTSETUP status $DEV_NAME | grep -q 'bitmap flush interval: 5000 \[ms\]' || fail $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo "[OK]" echo "Bitmap error detection tests:" @@ -551,7 +612,7 @@ EOF [ ! -b /dev/mapper/$DEV_NAME2 ] && fail $INTSETUP format -q -s 512 --no-wipe /dev/mapper/$DEV_NAME2 $INTSETUP open /dev/mapper/$DEV_NAME2 $DEV_NAME || fail - D_SIZE=$($INTSETUP dump /dev/mapper/$DEV_NAME2 | grep provided_data_sectors | sed -e 's/.*provided_data_sectors\ \+//g') + D_SIZE=$($INTSETUP dump /dev/mapper/$DEV_NAME2 | grep "data size:" | cut -d' ' -f 3) A_SIZE=$(blockdev --getsz /dev/mapper/$DEV_NAME) # Compare strings (to avoid 64bit integers), not integers [ -n "$A_SIZE" -a "$D_SIZE" != "$A_SIZE" ] && fail @@ -626,12 +687,29 @@ $INTSETUP open -q $DEV $DEV_NAME $ARGS >/dev/null 2>&1 || fail "Cannot activate echo -n "[SHRINK]" $INTSETUP resize $DEV_NAME --device-size 1MiB >/dev/null 2>&1 || fail "Failed to resize the device to 1MiB." check_device_size $DEV_NAME $(( 1024*1024 / 512 )) "Shrinking device failed" -dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detectied after resize." +dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detected after resize." echo "[OK]" +if [ -n "$DM_INTEGRITY_INLINE" ] ; then + echo -n "[INTEGRITY BASIC RESIZE NOKEY (inline tags)]" + add_device_inline + ARGS="--integrity crc32" + + echo -n "[FORMAT]" + $INTSETUP format -q $IDEV $INLINE_PARAMS --sector-size 4096 $ARGS || fail "Cannot format device." + echo -n "[ACTIVATE]" + $INTSETUP open -q $IDEV $DEV_NAME $ARGS >/dev/null 2>&1 || fail "Cannot activate device." + echo -n "[RESIZE]" + $INTSETUP resize $DEV_NAME --device-size 1MiB >/dev/null 2>&1 || fail "Failed to resize the device to 1MiB." + check_device_size $DEV_NAME $(( 1024*1024 / 512 )) "Shrinking device failed" + $INTSETUP resize $DEV_NAME --device-size 8MiB >/dev/null 2>&1 || fail "Failed to resize the device to 8MiB." + check_device_size $DEV_NAME $(( 8*1024*1024 / 512 )) "Enlarging device failed" + dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detected after resize." + echo "[OK]" +fi + echo -n "[INTEGRITY BASIC RESIZE KEY]" add_device - ARGS="--integrity hmac-sha256 --integrity-key-size 128 --integrity-key-file $KEY_FILE --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE --journal-integrity-key-size 128 --journal-crypt ctr-aes --journal-crypt-key-size 16 --journal-crypt-key-file $KEY_FILE" echo -n "[FORMAT]" @@ -641,7 +719,7 @@ $INTSETUP open -q $DEV $DEV_NAME $ARGS >/dev/null 2>&1 || fail "Cannot activate echo -n "[SHRINK]" $INTSETUP resize $DEV_NAME --device-size 1MiB >/dev/null 2>&1 || fail "Failed to resize the device to 1MiB." check_device_size $DEV_NAME $(( 1024*1024 / 512 )) "Shrinking device failed" -dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detectied after resize." +dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detected after resize." echo "[OK]" test_resize "[INTEGRITY RESIZE NOKEY]" 0 0 "--integrity crc32" @@ -655,4 +733,13 @@ if [ -n "$DM_INTEGRITY_HMAC_FIX" ] ; then test_resize "[INTEGRITY RESIZE KEY DETACHED]" 1 1 "--integrity hmac-sha256 --integrity-key-size 128 --integrity-key-file $KEY_FILE --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE --journal-integrity-key-size 128 --journal-crypt ctr-aes --journal-crypt-key-size 16 --journal-crypt-key-file $KEY_FILE" fi +echo -n "Early check for active name:" +add_device +DM_BAD_NAME=x/x +DM_LONG_NAME=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef +$INTSETUP format -q $DEV --no-wipe || fail "Cannot format device." +$INTSETUP open $DEV $DM_BAD_NAME 2>/dev/null && fail "Cannot activate device." +$INTSETUP open $DEV $DM_LONG_NAME 2>/dev/null && fail "Cannot activate device." +echo "[OK]" + cleanup diff --git a/tests/keyring-compat-test b/tests/keyring-compat-test index dc4787d..36658fc 100755 --- a/tests/keyring-compat-test +++ b/tests/keyring-compat-test @@ -35,7 +35,7 @@ fi FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$NAME ] && dmsetup remove --retry $NAME @@ -47,14 +47,14 @@ function remove_mapping() rm -f $CHKS_DMCRYPT $CHKS_KEYRING } -function skip() +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -64,12 +64,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo "FAILED backtrace:" @@ -78,18 +78,21 @@ function fail() exit 2 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + # $1 hexbyte key # $2 type # $3 description # $4 keyring -function load_key() +load_key() { local tmp="$1" shift echo -n "$tmp" | xxd -r -p | keyctl padd $@ >/dev/null } -function dm_crypt_keyring_support() +dm_crypt_keyring_support() { VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -104,7 +107,7 @@ function dm_crypt_keyring_support() [ $VER_MIN -ge 15 ] } -function test_and_prepare_keyring() { +test_and_prepare_keyring() { keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped" TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null) test -n "$TEST_KEYRING" || skip "Failed to create keyring in user keyring" @@ -112,7 +115,7 @@ function test_and_prepare_keyring() { load_key "$HEXKEY_16" user test_key "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped." } -function fips_mode() +fips_mode() { [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] } diff --git a/tests/keyring-test b/tests/keyring-test index 38abcfb..6d75813 100755 --- a/tests/keyring-test +++ b/tests/keyring-test @@ -20,7 +20,7 @@ HEXKEY_32="bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; HEXKEY_32_BAD="bb21158c733229347bd4e68189XXXX3d94c685be6a5b84818afe7a78a6de7a1a" HEXKEY_31="bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a" -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_CRYPT ] && dmsetup remove --retry $DEV_CRYPT [ -b /dev/mapper/$DEV_ZERO ] && dmsetup remove --retry $DEV_ZERO @@ -29,14 +29,14 @@ function remove_mapping() [ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null } -function skip() +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo "FAILED backtrace:" @@ -49,12 +49,12 @@ function fail() # $2 description # $3 payload # $4 keyring -function load_key() +load_key() { keyctl add $@ >/dev/null } -function dm_crypt_keyring_support() +dm_crypt_keyring_support() { VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -67,7 +67,7 @@ function dm_crypt_keyring_support() [ $VER_MIN -ge 15 ] } -function test_and_prepare_keyring() { +test_and_prepare_keyring() { keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped" TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null) test -n "$TEST_KEYRING" || skip "Failed to create keyring in user keyring" diff --git a/tests/keyring-trusted-test b/tests/keyring-trusted-test new file mode 100755 index 0000000..757dea2 --- /dev/null +++ b/tests/keyring-trusted-test @@ -0,0 +1,187 @@ +#!/bin/bash + +# Encrypted and trusted keyring test; trusted keys can be emulated by TPM2. +# DO NOT use this in combination with a real TPM data, it can destroy them. +# +# Note that if trusted or tpm kernel module is built-in, emulated TPM2 cannot +# provide trusted keys (only encrypted keys will be tested then). + +[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." +CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup + +IMG=keyring_trusted_test.img +MAP="trusted_test" +KEYNAME=testxxx + +bin_check() +{ + command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." +} + +cleanup() { + clear_keys + + [ -S $SWTPM_STATE_DIR/ctrl.sock ] && { + # shutdown TPM via control socket + swtpm_ioctl -s --unix $SWTPM_STATE_DIR/ctrl.sock + sleep 1 + } + + # if graceful shutdown was successful, pidfile should be deleted + # if it is still present, we forcefully kill the process + [ -f "$SWTPM_PIDFILE" ] && { + kill -9 $(cat $SWTPM_PIDFILE) >/dev/null 2>&1 + } + + [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP + + [ -n "$SWTPM_PIDFILE" ] && rm -f $SWTPM_PIDFILE >/dev/null 2>&1 + [ -n "$SWTPM_STATE_DIR" ] && rm -rf $SWTPM_STATE_DIR >/dev/null 2>&1 + rm -f $IMG >/dev/null 2>&1 + + cleanup_modules +} + +cleanup_modules() +{ + [ -n "$SKIP_MODULE_UNLOAD" ] && return + + # This is a hack to avoid linking trusted key to another TPM. + # Without clean load tests do not work reliably. + modprobe -r dm-crypt 2>/dev/null + modprobe -r encrypted-keys 2>/dev/null + modprobe -r trusted 2>/dev/null + modprobe -r tpm_vtpm_proxy 2>/dev/null + modprobe -r tpm 2>/dev/null +} + +fail() +{ + echo "[FAILED]" + [ -n "$1" ] && echo "$1" + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + cleanup + exit 2 +} + +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() +{ + [ -n "$1" ] && echo "$1" + cleanup + exit 77 +} + +prepare_tpm() +{ + SWTPM_STATE_DIR=$(mktemp -d /tmp/systemd_swtpm_state.XXXXXX) + SWTPM_SEAL_KEY="$SWTPM_STATE_DIR/sealkey.ctxt" + SWTPM_PERSISTENT_HANDLE=0x81000001 + +if [ -z "$TPM_PATH" ]; then + bin_check swtpm + bin_check swtpm_ioctl + + SWTPM_PIDFILE=$(mktemp /tmp/systemd_swtpm_pid.XXXXXX) + + cleanup_modules + modprobe tpm_vtpm_proxy || fail "Failed to load tpm_vtpm_proxy kernel module, required for emulated TPM." + + SWTPM_LOG=$(swtpm chardev --vtpm-proxy --tpm2 --tpmstate dir=$SWTPM_STATE_DIR -d --pid file=$SWTPM_PIDFILE --ctrl type=unixio,path=$SWTPM_STATE_DIR/ctrl.sock) + TPM_PATH=$(echo $SWTPM_LOG | grep -Eo /dev/tpm\([0-9]\)+ | sed s/tpm/tpmrm/) + + [ -z "$TPM_PATH" ] && fail "No TPM_PATH set and swtpm failed, test skipped." + + echo "Virtual TPM set up at $TPM_PATH" + + # Trusted module needs to see TPM above. + sleep 1 + modprobe trusted 2>/dev/null || echo "Failed to load trusted keys kernel module." +else + SKIP_MODULE_UNLOAD=1 + echo "Preconfigured TPM set up at $TPM_PATH" +fi + # Create persistent store + tpm2_createprimary -Q -T device:$TPM_PATH --hierarchy o -G rsa2048 -c $SWTPM_SEAL_KEY || fail + tpm2_evictcontrol -Q -T device:$TPM_PATH -c $SWTPM_SEAL_KEY $SWTPM_PERSISTENT_HANDLE || fail +} + +prepare_vk_keyring() +{ + local s_desc=$(keyctl rdescribe @s | cut -d';' -f5) + local us_desc=$(keyctl rdescribe @us | cut -d';' -f5) + + if [ "$s_desc" = "$us_desc" -a -n "$s_desc" ]; then + echo "Session keyring is missing, initializing new one." + keyctl new_session > /dev/null || fail + fi +} + +clear_keys() +{ + keyctl revoke %encrypted:$KEYNAME 2>/dev/null + keyctl revoke %user:$KEYNAME 2>/dev/null + + if [ -n "$TRUSTED_SUPPORTED" ]; then + keyctl revoke %trusted:$KEYNAME 2>/dev/null + tpm2_evictcontrol -Q -T device:$TPM_PATH -C o -c $SWTPM_PERSISTENT_HANDLE 2>/dev/null + fi +} + +[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." +bin_check keyctl + +prepare_vk_keyring + +# Prevent using TPM by default +if [ -n "$RUN_KEYRING_TRUSTED_TEST" ]; then + prepare_tpm + # Trusted keyring key + keyctl add trusted $KEYNAME "new 32 keyhandle=$SWTPM_PERSISTENT_HANDLE" @s >/dev/null 2>&1 && TRUSTED_SUPPORTED=1 + if [ -n "$TRUSTED_SUPPORTED" ]; then + keyctl print %trusted:$KEYNAME >/dev/null || fail "Cannot read trusted key blob." + fi +else + echo "WARNING: Variable RUN_KEYRING_TRUSTED_TEST must be defined, TPM trusted test skipped." + TRUSTED_SUPPORTED= +fi + +# Prepare encrypted key +modprobe encrypted-keys 2>/dev/null || skip "Failed to load encrypted keys kernel module." + +# Encrypted keyring key (encrypted with user key) +# User key needed for encrypted key +keyctl add -x user $KEYNAME bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a @s >/dev/null 2>&1 || skip "User key load failed, test skipped." +keyctl print %user:$KEYNAME >/dev/null || fail "Cannot read user key." + +keyctl add encrypted $KEYNAME "new user:$KEYNAME 32" @s >/dev/null || fail "Encrypted keys are not supported." +keyctl print %encrypted:$KEYNAME >/dev/null || fail "Cannot read encrypted key blob." + +dd if=/dev/zero of=$IMG bs=1M count=32 >/dev/null 2>&1 + +echo -n "Plain with trusted volume key " +if [ -n "$TRUSTED_SUPPORTED" ]; then + $CRYPTSETUP open --type plain $IMG $MAP --key-size=256 --cipher=aes-xts-plain64 --volume-key-keyring=%trusted:$KEYNAME || fail + dmsetup table --showkeys $MAP | grep -q ":32:trusted:$KEYNAME" || fail + $CRYPTSETUP status $MAP | grep -q "key location: keyring" || fail + $CRYPTSETUP close $MAP || fail + echo "[OK]" +else + echo "[N/A]" +fi + +echo -n "Plain with encrypted volume key " +$CRYPTSETUP open --type plain $IMG $MAP --key-size=256 --cipher=aes-xts-plain64 --volume-key-keyring=%encrypted:$KEYNAME ||fail +dmsetup table --showkeys $MAP | grep -q ":32:encrypted:$KEYNAME" || fail +$CRYPTSETUP status $MAP | grep -q "key location: keyring" || fail +$CRYPTSETUP resize $MAP --size 100 || fail +$CRYPTSETUP status $MAP | grep "size:" | grep -q "100 \[512-byte units\]" || fail +$CRYPTSETUP resize $MAP || fail +$CRYPTSETUP close $MAP || fail +echo "[OK]" + +cleanup +exit 0 diff --git a/tests/loopaes-test b/tests/loopaes-test index 62fe772..394fc4d 100755 --- a/tests/loopaes-test +++ b/tests/loopaes-test @@ -21,12 +21,12 @@ KEYv2=key_v2 KEYv3=key_v3 LOOPDEV=$(losetup -f 2>/dev/null) -function dmremove() { # device +dmremove() { # device udevadm settle >/dev/null 2>&1 dmsetup remove --retry $1 >/dev/null 2>&1 } -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME2 ] && dmremove $DEV_NAME2 [ -b /dev/mapper/$DEV_NAME ] && dmremove $DEV_NAME @@ -34,7 +34,7 @@ function remove_mapping() rm -f $IMG $KEYv1 $KEYv2 $KEYv3 >/dev/null 2>&1 } -function fail() +fail() { echo "FAILED backtrace:" while caller $frame; do ((frame++)); done @@ -42,14 +42,17 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { remove_mapping [ -n "$1" ] && echo "$1" exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -59,12 +62,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function prepare() +prepare() { remove_mapping dd if=/dev/zero of=$IMG $LOOP_DD_PARAM >/dev/null 2>&1 @@ -80,12 +83,12 @@ function prepare() [ -n "$1" ] && echo -n "$1 " } -function check_exists() +check_exists() { [ -b /dev/mapper/$DEV_NAME ] || fail } -function get_offset_params() # $offset +get_offset_params() # $offset { offset=$1 if [ "${offset:0:1}" = "@" ] ; then @@ -95,7 +98,7 @@ function get_offset_params() # $offset fi } -function get_expsum() # $offset +get_expsum() # $offset { case $1 in 0) @@ -112,7 +115,7 @@ function get_expsum() # $offset esac } -function check_sum() # $key $keysize $offset [stdin|keyfile] +check_sum() # $key $keysize $offset [stdin|keyfile] { $CRYPTSETUP close $DEV_NAME || fail @@ -133,7 +136,7 @@ function check_sum() # $key $keysize $offset [stdin|keyfile] fi } -function check_sum_losetup() # $key $alg +check_sum_losetup() # $key $alg { [ ! -x $LOSETUP_AES ] && echo && return @@ -153,7 +156,7 @@ function check_sum_losetup() # $key $alg losetup -d $LOOPDEV >/dev/null 2>&1 } -function check_version() +check_version() { VER_STR=$(dmsetup version | grep Driver) VER_MIN=$(echo $VER_STR | cut -f 2 -d.) diff --git a/tests/luks1-compat-test b/tests/luks1-compat-test index c0de983..2ef2359 100755 --- a/tests/luks1-compat-test +++ b/tests/luks1-compat-test @@ -6,6 +6,8 @@ TST_DIR=luks1-images MAP=luks1tst KEYFILE=keyfile1 +CRYPTOCHECK=./crypto-check + if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then CRYPTSETUP_VALGRIND=$CRYPTSETUP else @@ -15,13 +17,13 @@ fi [ -z "$srcdir" ] && srcdir="." -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP rm -rf $TST_DIR } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo " [FAILED]" @@ -31,14 +33,17 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -48,39 +53,38 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function remove_imgs() +remove_imgs() { echo "WARNING: $1 not available, not testing some images." rm $(ls $TST_DIR/*$1*.img) } -function test_one() +test_one() { - $CRYPTSETUP benchmark -c "$1" -s "$2" | grep -v "#" || remove_imgs $1 + $CRYPTOCHECK cipher $1 $2 $3 || remove_imgs "$1-$2" } -function test_required() +test_required() { echo "REQUIRED KDF TEST" - $CRYPTSETUP benchmark -h whirlpool | grep "N/A" && remove_imgs whirlpool + $CRYPTOCHECK hash whirlpool || remove_imgs whirlpool echo "REQUIRED CIPHERS TEST" - echo "# Algorithm | Key | Encryption | Decryption" - - test_one aes-xts 256 - test_one twofish-xts 256 - test_one serpent-xts 256 - test_one aes-cbc 256 - test_one aes-lrw 256 + test_one aes xts 256 + test_one twofish xts 256 + test_one serpent xts 256 + test_one aes cbc 256 + test_one aes lrw 256 } export LANG=C [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ ! -x "$CRYPTOCHECK" ] && skip "Cannot find $CRYPTOCHECK, test skipped." command -v blkid >/dev/null || skip "blkid tool required, test skipped." [ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run [ ! -d $TST_DIR ] && tar xJf $srcdir/luks1-images.tar.xz --no-same-owner diff --git a/tests/luks2-integrity-test b/tests/luks2-integrity-test index ff41ebf..09ec5b9 100755 --- a/tests/luks2-integrity-test +++ b/tests/luks2-integrity-test @@ -5,6 +5,7 @@ [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup DEV_NAME=dmi_test +DEV_NAME2=dmi_test_xdif DEV=mode-test.img HEADER_IMG=mode-test-detached.img PWD1=nHjJHjI23JK @@ -20,12 +21,15 @@ fi dmremove() { # device udevadm settle >/dev/null 2>&1 - dmsetup remove $1 >/dev/null 2>&1 + dmsetup remove --retry $1 >/dev/null 2>&1 } cleanup() { [ -b /dev/mapper/$DEV_NAME ] && dmremove $DEV_NAME + [ -b /dev/mapper/$DEV_NAME2 ] && dmremove $DEV_NAME2 [ -b /dev/mapper/"$DEV_NAME"_dif ] && dmremove "$DEV_NAME"_dif + [ -n "$DEV_LOOP" ] && losetup -d "$DEV_LOOP" + DEV_LOOP="" rm -f $DEV $KEY_FILE $HEADER_IMG >/dev/null 2>&1 } @@ -39,13 +43,16 @@ fail() exit 100 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + skip() { [ -n "$1" ] && echo "$1" exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -55,16 +62,42 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } +dm_integrity_inline_support() +{ + VER_STR=$(dmsetup targets | grep integrity | cut -f2 -dv) + [ -z "$VER_STR" ] && fail "Failed to parse dm-integrity version." + + VER_MAJ=$(echo $VER_STR | cut -f 1 -d.) + VER_MIN=$(echo $VER_STR | cut -f 2 -d.) + + [ $VER_MAJ -gt 1 ] && return 0 + if [ $VER_MIN -ge 12 ]; then + return 0 + fi + return 1 +} + add_device() { cleanup dd if=/dev/urandom of=$KEY_FILE bs=1 count=512 >/dev/null 2>&1 dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1 - sync + IDEV=$DEV + INLINE_PARAMS="" +} + +add_device_inline() { + add_device + DEV_LOOP=$(losetup -f $DEV --show) + [ -z "$DEV_LOOP" ] && fail + dmsetup create $DEV_NAME2 --table "0 32768 integrity $DEV_LOOP 0 64 J 2 block_size:4096 fix_padding" + [ ! -b /dev/mapper/$DEV_NAME2 ] && fail + IDEV=/dev/mapper/$DEV_NAME2 + INLINE_PARAMS="--integrity-inline " } set_LO_DEV() { # file @@ -79,6 +112,7 @@ status_check() # name value [detached] else PARAMS="$DEV_NAME" fi + X=$($CRYPTSETUP status $PARAMS | grep -m1 "$1" | sed -e 's/.*:[ \t]\+//' | cut -d' ' -f1) if [ "$X" != "$2" ] ; then echo "[status FAIL]" @@ -89,7 +123,7 @@ status_check() # name value [detached] dump_check() # name value { - X=$($CRYPTSETUP luksDump $DEV | grep -m1 "$1" | sed -e 's/.*:[ \t]\+//' | cut -d' ' -f1) + X=$($CRYPTSETUP luksDump $IDEV | grep -m1 "$1" | sed -e 's/.*:[ \t]\+//' | cut -d' ' -f1) if [ "$X" != "$2" ] ; then echo "[dump FAIL]" echo " Expecting $1:$2 got \"$X\"." @@ -109,21 +143,33 @@ int_check_sum() # alg checksum fi } -int_error_detection() # alg int sector_size +int_error_detection() # [test_hdr] { echo -n "[DETECT_CORRUPTION]" - echo -n "XXXXX" | dd of=$DEV bs=1M seek=28 count=1 conv=notrunc >/dev/null 2>&1 || fail "Cannot write to device." - $CRYPTSETUP open -d $KEY_FILE $DEV $DEV_NAME || fail "Cannot activate device." + echo -n "XXXXX" | dd of=$IDEV bs=1M seek=8 count=1 conv=notrunc >/dev/null 2>&1 || fail "Cannot write to device." + if [ -n "$1" ] ; then + $CRYPTSETUP open -d $KEY_FILE $IDEV --header $1 $DEV_NAME || fail "Cannot activate device." + else + $CRYPTSETUP open -d $KEY_FILE $IDEV $DEV_NAME || fail "Cannot activate device." + fi dd if=/dev/mapper/$DEV_NAME of=/dev/null >/dev/null 2>&1 && fail "Error detection failed." $CRYPTSETUP close $DEV_NAME || fail "Cannot deactivate device." } intformat() # alg integrity integrity_out key_size int_key_size sector_size csum [test_hdr] { - echo -n "[$1:$2:$4:$6]" + echo -n "[$1:$2:$4:$6:$5]" echo -n "[FORMAT]" - $CRYPTSETUP luksFormat --type luks2 -q -c $1 --integrity $2 --sector-size $6 -s $4 \ - $FAST_PBKDF_OPT -d $KEY_FILE $DEV --offset 8192 --integrity-legacy-padding >/dev/null 2>&1 + + # just trick, if int key size is not multiple of 16, use explicit flag + if [ $(($5 % 16)) -eq 0 ]; then + INT_PARAMS="--integrity $2 --integrity-legacy-padding" + else + INT_PARAMS="--integrity $2 --integrity-key-size $5 --integrity-legacy-padding" + fi + + $CRYPTSETUP luksFormat --type luks2 -q -c $1 $INT_PARAMS $INLINE_PARAMS --sector-size $6 -s $4 \ + $FAST_PBKDF_OPT -d $KEY_FILE $IDEV --offset 8192 >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "[N/A]" return @@ -133,8 +179,8 @@ intformat() # alg integrity integrity_out key_size int_key_size sector_size csum dump_check "integrity" $3 dump_check "Key:" $(($4 + $5)) echo -n "[ACTIVATE]" - $CRYPTSETUP open -d $KEY_FILE $DEV $DEV_NAME || fail "Cannot activate device." - set_LO_DEV $DEV + $CRYPTSETUP open -d $KEY_FILE $IDEV $DEV_NAME || fail "Cannot activate device." + set_LO_DEV $IDEV status_check "cipher" $1 status_check "sector size" $6 status_check "integrity:" $3 @@ -142,16 +188,35 @@ intformat() # alg integrity integrity_out key_size int_key_size sector_size csum [ -n "$LO_DEV" ] && status_check "device:" $LO_DEV [ $5 -gt 0 ] && status_check "integrity keysize:" $5 int_check_sum $1 $7 + echo -n "[SUSPEND]" + $CRYPTSETUP luksSuspend $DEV_NAME || fail "Cannot suspend device." + dmsetup info $DEV_NAME | grep -q SUSPENDED || fail "Not suspended." + if [ -z "$INLINE_PARAMS" ]; then + dmsetup info "$DEV_NAME"_dif | grep -q SUSPENDED || fail "Not suspended." + else + # this hw-inline device must not be suspended + dmsetup info "$DEV_NAME2" | grep -q ACTIVE || fail + $CRYPTSETUP status $DEV_NAME | grep -q "(inline HW tags)" || fail "(inline hw tags) missing." + fi + echo -n "[RESUME]" + $CRYPTSETUP luksResume -d $KEY_FILE $DEV_NAME || fail "Cannot resume device." + dmsetup info $DEV_NAME | grep -q ACTIVE || fail "Not resumed." + if [ -z "$INLINE_PARAMS" ]; then + dmsetup info "$DEV_NAME"_dif | grep -q ACTIVE || fail "Not resumed." + fi echo -n "[REMOVE]" $CRYPTSETUP close $DEV_NAME || fail "Cannot deactivate device." + [ -b /dev/mapper/"$DEV_NAME"_dif ] && fail + int_error_detection # check detached header activation if [ -n "$8" ] ; then echo -n "[DETACHED_HDR]" - $CRYPTSETUP luksHeaderBackup -q --header-backup-file $HEADER_IMG $DEV || fail - wipefs -a $DEV >/dev/null 2>&1 || fail - $CRYPTSETUP open --header $HEADER_IMG -d $KEY_FILE $DEV $DEV_NAME || fail "Cannot activate device." - set_LO_DEV $DEV + wipefs -a $IDEV >/dev/null 2>&1 || fail + $CRYPTSETUP luksFormat --type luks2 -q -c $1 $INT_PARAMS $INLINE_PARAMS --sector-size $6 -s $4 \ + $FAST_PBKDF_OPT -d $KEY_FILE $IDEV --header $HEADER_IMG --offset 8192 >/dev/null 2>&1 + $CRYPTSETUP open --header $HEADER_IMG -d $KEY_FILE $IDEV $DEV_NAME || fail "Cannot activate device." + set_LO_DEV $IDEV status_check "cipher" $1 1 status_check "sector size" $6 1 status_check "integrity:" $3 1 @@ -166,12 +231,15 @@ intformat() # alg integrity integrity_out key_size int_key_size sector_size csum status_check "keysize:" $(($4 + $5)) [ -n "$LO_DEV" ] && status_check "device:" $LO_DEV [ $5 -gt 0 ] && status_check "integrity keysize:" $5 + if [ -n "$INLINE_PARAMS" ]; then + $CRYPTSETUP status $DEV_NAME --header $HEADER_IMG | grep -q "(inline HW tags)" || fail "(inline hw tags) missing." + fi $CRYPTSETUP close $DEV_NAME || fail "Cannot deactivate device." - $CRYPTSETUP luksHeaderRestore -q --header-backup-file $HEADER_IMG $DEV || fail + [ -b /dev/mapper/"$DEV_NAME"_dif ] && fail + int_error_detection $HEADER_IMG rm -f $HEADER_IMG fi - int_error_detection echo "[OK]" } @@ -182,6 +250,7 @@ modprobe dm-integrity >/dev/null 2>&1 dmsetup targets | grep integrity >/dev/null 2>&1 || skip "Cannot find dm-integrity target, test skipped." command -v wipefs >/dev/null || skip "Cannot find wipefs, test skipped." +echo "LUKS2 authenticated mode test" add_device intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 128 256 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c 1 @@ -206,6 +275,9 @@ intformat aes-xts-random hmac-sha512 hmac\(sha512\) 512 512 4096 621f6c03f intformat aes-xts-plain64 hmac-sha1 hmac\(sha1\) 512 160 4096 7370c66a92708fb71b186931468be6aa9b26f4f88373b00b1c57360b9ee1304e intformat aes-xts-random hmac-sha1 hmac\(sha1\) 512 160 4096 8c0463f5ac09613674bdf40b0ff6f985edbc3de04e51fdc688873cb333ef3cda +intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 512 264 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c +intformat aes-xts-plain64 hmac-sha512 hmac\(sha512\) 512 792 512 9040d276d8bfab30bbc4bf389e152e08c13ac6fa84d49d11c1bee6e1638fd8f1 + intformat aes-gcm-random aead aead 128 0 512 5f6f3f6be03c74d9aaaeaf40dd310c99a20e2786045f78a1fc6a0b189d231f57 intformat aes-gcm-random aead aead 128 0 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b intformat aes-gcm-random aead aead 256 0 512 5f6f3f6be03c74d9aaaeaf40dd310c99a20e2786045f78a1fc6a0b189d231f57 @@ -224,4 +296,23 @@ intformat chacha20-random poly1305 poly1305 256 0 4096 358d6beceddf593aff6b22c3 intformat aegis128-random aead aead 128 0 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c 1 intformat aegis128-random aead aead 128 0 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b 1 +if dm_integrity_inline_support; then + echo "LUKS2 authenticated mode test (inline tags)" + add_device_inline + + intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 128 256 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 256 256 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 256 256 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 1 + intformat aes-xts-random hmac-sha256 hmac\(sha256\) 256 256 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 256 256 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 512 256 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + + intformat aes-gcm-random aead aead 128 0 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + + intformat chacha20-plain64 poly1305 poly1305 256 0 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + intformat chacha20-random poly1305 poly1305 256 0 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 + + intformat aegis128-random aead aead 128 0 4096 cfadd44a103cbd6d5726fa07b27d7aad2f67ed3930ff96901c486a5beaf7e723 1 +fi + cleanup diff --git a/tests/luks2-reencryption-mangle-test b/tests/luks2-reencryption-mangle-test index 79b813d..afbce11 100755 --- a/tests/luks2-reencryption-mangle-test +++ b/tests/luks2-reencryption-mangle-test @@ -23,13 +23,13 @@ CS_PWPARAMS="--disable-keyring --key-file $KEY1" CS_PARAMS="-q --disable-locks $CS_PWPARAMS" JSON_MSIZE=16384 -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME rm -f $IMG $IMG_HDR $IMG_HDR_BCP $IMG_JSON $KEY1 >/dev/null 2>&1 } -function fail() +fail() { local frame=0 [ -n "$1" ] && echo "$1" @@ -39,19 +39,22 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function bin_check() +bin_check() { command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." } -function img_json_save() +img_json_save() { local _hdr=$IMG [ -z "$1" ] || _hdr="$1" @@ -59,24 +62,24 @@ function img_json_save() $CRYPTSETUP luksDump --dump-json-metadata $_hdr | jq -c -M . | tr -d '\n' >$IMG_JSON } -function img_json_dump() +img_json_dump() { img_json_save jq . $IMG_JSON } -function img_hash_save() +img_hash_save() { IMG_HASH=$(sha256sum $IMG | cut -d' ' -f 1) } -function img_hash_unchanged() +img_hash_unchanged() { local IMG_HASH2=$(sha256sum $IMG | cut -d' ' -f 1) [ "$IMG_HASH" != "$IMG_HASH2" ] && fail "Image changed!" } -function img_prepare_raw() # $1 options +img_prepare_raw() # $1 options { remove_mapping @@ -88,7 +91,7 @@ function img_prepare_raw() # $1 options $CRYPTSETUP luksFormat $FAST_PBKDF2 $CS_PARAMS --luks2-metadata-size $JSON_MSIZE $IMG $1 || fail } -function img_prepare() # $1 options +img_prepare() # $1 options { img_prepare_raw $CRYPTSETUP reencrypt $IMG $CS_PARAMS -q --init-only --resilience none $1 >/dev/null 2>&1 @@ -97,13 +100,13 @@ function img_prepare() # $1 options img_hash_save } -function _dd() +_dd() { dd $@ status=none conv=notrunc bs=1 } # header mangle functions -function img_update_json() +img_update_json() { local _hdr="$IMG" local LUKS2_BIN1_OFFSET=448 @@ -142,7 +145,7 @@ function img_update_json() img_hash_save } -function img_check_ok() +img_check_ok() { if [ $(id -u) == 0 ]; then $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME || fail @@ -152,13 +155,13 @@ function img_check_ok() $CRYPTSETUP repair $IMG $CS_PARAMS || fail } -function img_check_dump_ok() +img_check_dump_ok() { $CRYPTSETUP luksDump $IMG >/dev/null || fail img_check_fail } -function img_check_fail() +img_check_fail() { if [ $(id -u) == 0 ]; then $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME 2>/dev/null && fail @@ -168,23 +171,23 @@ function img_check_fail() img_hash_unchanged } -function img_run_reenc_ok() +img_run_reenc_ok() { $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS -q --disable-locks --force-offline-reencrypt --resilience none || fail } -function img_run_reenc_ok_data_shift() +img_run_reenc_ok_data_shift() { $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS -q --disable-locks --force-offline-reencrypt || fail } -function img_run_reenc_fail() +img_run_reenc_fail() { $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --force-offline-reencrypt --disable-locks -q 2>/dev/null && fail "Reencryption passed (should have failed)." img_hash_unchanged } -function img_check_fail_repair() +img_check_fail_repair() { if [ $(id -u) == 0 ]; then $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME 2>/dev/null && fail @@ -198,19 +201,19 @@ function img_check_fail_repair() img_check_ok } -function img_check_fail_repair_ok() +img_check_fail_repair_ok() { img_check_fail_repair img_run_reenc_ok } -function img_check_fail_repair_ok_data_shift() +img_check_fail_repair_ok_data_shift() { img_check_fail_repair img_run_reenc_ok_data_shift } -function valgrind_setup() +valgrind_setup() { bin_check valgrind [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -222,7 +225,7 @@ function valgrind_setup() CRYPTSETUP_RAW="./valg.sh ${CRYPTSETUP_VALGRIND}" } -function valgrind_run() +valgrind_run() { export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" $CRYPTSETUP_RAW "$@" diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test index a5f020e..11823ee 100755 --- a/tests/luks2-reencryption-test +++ b/tests/luks2-reencryption-test @@ -26,21 +26,37 @@ HEADER_LUKS2_PV=blkid-luks2-pv.img IMG_FS=xfs_512_block_size.img KEY1=key1 VKEY1=vkey1 +VKEY2=vkey2 +BACKUP_FILE=reenc_header_baseline.img PWD1="93R4P4pIqAH8" PWD2="1cND4319812f" PWD3="1-9Qu5Ejfnqv" +PWD4="d54uVMKW-'7M" +PWD5="oDe{yCiZ_';_" +PWD6="T'E'Y_}<'9=q" +PWD7="UR%]T;x*w{3V" + DEV_LINK="reenc-test-link" KEYRING="luks2_reencryption_test_kr" KEY_TYPE="user" KEY_NAME1="luks2-reencryption-test1" KEY_NAME2="luks2-reencryption-test2" +KEY_NAME3="luks2-reencryption-test3" +KEY_NAME4="luks2-reencryption-test4" +KEY_NAME5="luks2-reencryption-test5" +KEY_NAME6="luks2-reencryption-test6" +KEY_NAME7="luks2-reencryption-key-desc1" +KEY_NAME_VK1="luks2-reencryption-test-vk1" +KEY_NAME_VK2="luks2-reencryption-test-vk2" KEY_SPEC1="${KEYRING}::%${KEY_TYPE}:${KEY_NAME1}" KEY_SPEC2="${KEYRING}::%${KEY_TYPE}:${KEY_NAME2}" HAVE_KEYRING=0 +JSON_MSIZE=16384 +IMG_JSON=luks2-digest-1.json FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) -function dm_crypt_features() +dm_crypt_features() { VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -63,7 +79,7 @@ function dm_crypt_features() fi } -function dm_delay_features() +dm_delay_features() { local _ver_str=$(dmsetup targets | grep delay | cut -f2 -dv) [ -z "$_ver_str" ] && return 1 @@ -85,7 +101,7 @@ scsi_debug_teardown() { test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 } -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME ] && { dmsetup resume $DEV_NAME @@ -111,19 +127,19 @@ function remove_mapping() [ -b /dev/mapper/$OVRDEV-err ] && dmsetup remove --retry $OVRDEV-err 2>/dev/null [ -n "$LOOPDEV" ] && losetup -d $LOOPDEV unset LOOPDEV - rm -f $IMG $IMG_HDR $KEY1 $VKEY1 $DEVBIG $DEV_LINK $HEADER_LUKS2_PV $IMG_FS >/dev/null 2>&1 + rm -f $IMG $IMG_JSON $IMG_HDR $KEY1 $VKEY1 $VKEY2 $BACKUP_FILE $DEVBIG $DEV_LINK $HEADER_LUKS2_PV $IMG_FS >/dev/null 2>&1 rmmod scsi_debug >/dev/null 2>&1 scsi_debug_teardown $DEV } -function cleanup_keyring() +cleanup_keyring() { if [ $HAVE_KEYRING -eq 1 ]; then keyctl unlink %:$KEYRING "@s" >/dev/null 2>&1 || echo "Failed to unlink test keyring." fi } -function fail() +fail() { local frame=0 [ -n "$1" ] && echo "$1" @@ -134,7 +150,10 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" remove_mapping @@ -142,12 +161,12 @@ function skip() exit 77 } -function fips_mode() +fips_mode() { [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] } -function add_scsi_device() { +add_scsi_device() { scsi_debug_teardown $DEV if [ -d /sys/module/scsi_debug ] ; then echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." @@ -164,7 +183,7 @@ function add_scsi_device() { [ -b $DEV ] || fail "Cannot find $DEV." } -function open_crypt() # $1 pwd, $2 hdr +open_crypt() # $1 pwd, $2 hdr { if [ -n "$2" ] ; then echo "$1" | $CRYPTSETUP luksOpen $DEV $DEV_NAME --header $2 || fail @@ -175,12 +194,12 @@ function open_crypt() # $1 pwd, $2 hdr fi } -function wipe_dev_head() # $1 dev, $2 length (in MiBs) +wipe_dev_head() # $1 dev, $2 length (in MiBs) { dd if=/dev/zero of=$1 bs=1M count=$2 conv=notrunc >/dev/null 2>&1 } -function wipe_dev() # $1 dev +wipe_dev() # $1 dev { if [ -b $1 ] ; then blkdiscard --zeroout $1 2>/dev/null || dd if=/dev/zero of=$1 bs=1M conv=notrunc >/dev/null 2>&1 @@ -189,20 +208,20 @@ function wipe_dev() # $1 dev fi else local size=$(stat --printf="%s" $1) - truncate -s 0 $1 + truncate -s 0 $1 || fail if [ $# -gt 2 ]; then local diff=$((size-$2*1024*1024)) echo "size: $size, diff: $diff" - truncate -s $diff $1 + truncate -s $diff $1 || fail # wipe_dev_head $1 $((diff/(1024*1024))) dd if=/dev/urandom of=$1 bs=1M seek=$2 size=$((diff/(1024*1024))) conv=notrunc >/dev/null 2>&1 else - truncate -s $size $1 + truncate -s $size $1 || fail fi fi } -function wipe() # $1 pass, $2 hdr +wipe() # $1 pass, $2 hdr { open_crypt $1 $2 wipe_dev /dev/mapper/$DEV_NAME @@ -210,7 +229,7 @@ function wipe() # $1 pass, $2 hdr $CRYPTSETUP luksClose $DEV_NAME || fail } -function prepare() # $1 dev1_siz +prepare() # $1 dev1_siz { remove_mapping @@ -223,10 +242,15 @@ function prepare() # $1 dev1_siz echo -n $'\x9c\x03\xba\xbe\x4d\x0f\x9a\x75\xb3\x90\x70\x32\x0a\xf8\xae\xc4'>>$VKEY1 fi +# if [ ! -e $VKEY2 ]; then +# echo -n $'\x41\xc6\x74\x4f\x41\x4e\x50\xc0\x79\xc2\x2d\x5b\x5f\x68\x84\x17' >$VKEY2 +# echo -n $'\x9c\x03\xba\xbe\x4d\x0f\x9a\x75\xb3\x90\x70\x32\x0a\xf8\xae\xc5'>>$VKEY2 +# fi + add_scsi_device $@ } -function preparebig() # $1 dev1_siz +preparebig() # $1 dev1_siz { remove_mapping @@ -234,46 +258,68 @@ function preparebig() # $1 dev1_siz dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 fi - truncate -s "$1"M $DEVBIG + truncate -s "$1"M $DEVBIG || fail LOOPDEV=$(losetup -f) losetup -f $DEVBIG || fail DEV=$LOOPDEV } -function check_hash_dev() # $1 dev, $2 hash +check_hash_dev() # $1 dev, $2 hash { HASH=$(sha1sum $1 | cut -d' ' -f 1) [ $HASH != "$2" ] && fail "HASH differs (expected: $2) (result $HASH)" } -function check_hash() # $1 pwd, $2 hash, $3 hdr +check_hash() # $1 pwd, $2 hash, $3 hdr { open_crypt $1 $3 check_hash_dev /dev/mapper/$DEV_NAME $2 $CRYPTSETUP remove $DEV_NAME || fail } -function check_hash_dev_head() # $1 dev, $2 len, $3 hash +check_hash_dev_head() # $1 dev, $2 len, $3 hash { local hash=$(dd if=$1 bs=512 count=$2 2>/dev/null | sha1sum | cut -d' ' -f1) [ $hash != "$3" ] && fail "HASH differs (expected: $3) (result $hash)" } -function check_hash_head() # $1 pwd, $2 len, $3 hash, $4 hdr +check_hash_head() # $1 pwd, $2 len, $3 hash, $4 hdr { open_crypt $1 $4 check_hash_dev_head /dev/mapper/$DEV_NAME $2 $3 $CRYPTSETUP remove $DEV_NAME || fail } -function resize_file() # $1 dev, $2 shrink bytes +resize_file() # $1 dev, $2 shrink bytes { local size=$(stat --printf="%s" $1) - truncate -s $(($size + $2)) $1 + truncate -s $(($size + $2)) $1 || fail losetup -c $LOOPDEV } -function error_writes() { # $1 dmdev, $2 data dev, $3 offset, $4 size +error_io() { # $1 dmdev, $2 data dev, $3 offset, $4 size + local _dev_size=$(blockdev --getsz /dev/mapper/$1) + local _offset=$(($3+$4)) + local _size=$((_dev_size-_offset)) + local _table= + dmsetup create $1-err --table "0 $_dev_size error" || fail + + if [ $3 -ne 0 ]; then + _table="0 $3 linear $2 0\n" + fi + + _table=$_table"$3 $4 error" + + if [ $_size -ne 0 ]; then + _table="$_table\n$_offset $_size linear $2 $_offset" + fi + + echo -e "$_table" | dmsetup load $1 || fail + dmsetup resume $1 || fail + blockdev --setra 0 /dev/mapper/$1 +} + +error_writes() { # $1 dmdev, $2 data dev, $3 offset, $4 size local _dev_size=$(blockdev --getsz /dev/mapper/$1) local _offset=$(($3+$4)) local _size=$((_dev_size-_offset)) @@ -297,14 +343,14 @@ function error_writes() { # $1 dmdev, $2 data dev, $3 offset, $4 size blockdev --setra 0 /dev/mapper/$_err } -function fix_writes() { # $1 dmdev, $2 data dev +fix_writes() { # $1 dmdev, $2 data dev local _dev_size=$(blockdev --getsz /dev/mapper/$1) dmsetup load $1 --table "0 $_dev_size linear $2 0" || fail dmsetup resume $1 || fail dmsetup remove --retry $1-err 2>/dev/null || fail } -function prepare_linear_dev() { +prepare_linear_dev() { local _sizemb=$1 shift @@ -320,7 +366,7 @@ function prepare_linear_dev() { DEV=/dev/mapper/$OVRDEV } -function get_error_offsets() # $1 devsize, $2 minimal offset, $3 sector_size [512 if omitted], $4 max offset +get_error_offsets() # $1 devsize, $2 minimal offset, $3 sector_size [512 if omitted], $4 max offset { local _devsize=$(($1*1024*2)) local _sector_size=${3:-512} @@ -335,7 +381,7 @@ function get_error_offsets() # $1 devsize, $2 minimal offset, $3 sector_size [51 ERROFFSET=$(($ERROFFSET-($ERROFFSET%$_sector_size))) } -function reencrypt_recover() { # $1 sector size, $2 resilience, $3 digest, [$4 header] +reencrypt_recover() { # $1 sector size, $2 resilience, $3 digest, [$4 header] echo -n "resilience mode: $2 ..." local _hdr="" test -z "$4" || _hdr="--header $4" @@ -354,7 +400,7 @@ function reencrypt_recover() { # $1 sector size, $2 resilience, $3 digest, [$4 h echo "[OK]" } -function reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest, [$4 header] +reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest, [$4 header] echo -n "resilience mode: $2 ..." local _hdr="" test -z "$4" || _hdr="--header $4" @@ -382,7 +428,7 @@ function reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest echo "[OK]" } -function reencrypt_recover_online_vk() { # $1 sector size, $2 resilience, $3 digest, [$4 header] +reencrypt_recover_online_vk() { # $1 sector size, $2 resilience, $3 digest, [$4 header] echo -n "resilience mode: $2 ..." local _hdr="" test -z "$4" || _hdr="--header $4" @@ -414,7 +460,7 @@ function reencrypt_recover_online_vk() { # $1 sector size, $2 resilience, $3 dig echo "[OK]" } -function encrypt_recover() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest +encrypt_recover() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest wipe_dev $DEV check_hash_dev $DEV $5 @@ -439,7 +485,7 @@ function encrypt_recover() { # $1 sector size, $2 reduce size, $3 digest, $4 dev echo "[OK]" } -function encrypt_recover_online() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest +encrypt_recover_online() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest wipe_dev $DEV check_hash_dev $DEV $5 @@ -470,7 +516,7 @@ function encrypt_recover_online() { # $1 sector size, $2 reduce size, $3 digest, echo "[OK]" } -function encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr +encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr wipe_dev $DEV check_hash_dev $DEV $3 @@ -492,7 +538,7 @@ function encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest echo "[OK]" } -function encrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr +encrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr wipe_dev $DEV check_hash_dev $DEV $3 @@ -524,7 +570,7 @@ function encrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 echo "[OK]" } -function decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr +decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size $1 --header $4 $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $4 check_hash $PWD1 $3 $4 @@ -550,7 +596,7 @@ function decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest echo "[OK]" } -function decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr +decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size $1 --header $4 $FAST_PBKDF_ARGON $DEV || fail echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail wipe_dev /dev/mapper/$DEV_NAME @@ -582,7 +628,7 @@ function decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 echo "[OK]" } -function decrypt_recover() { # $1 hash, $2 hdr, $3 dev size, $4 resilience, $5 hotzone size +decrypt_recover() { # $1 hash, $2 hdr, $3 dev size, $4 resilience, $5 hotzone size local _res="" local _maxhz="" test -z "$4" || _res="--resilience $4" @@ -610,7 +656,7 @@ function decrypt_recover() { # $1 hash, $2 hdr, $3 dev size, $4 resilience, $5 h echo -n "[OK]" } -function decrypt_recover_online() { # $1 hash, $2 hdr, $3 dev size +decrypt_recover_online() { # $1 hash, $2 hdr, $3 dev size local _res="" local _maxhz="" test -z "$4" || _res="--resilience $4" @@ -639,7 +685,7 @@ function decrypt_recover_online() { # $1 hash, $2 hdr, $3 dev size echo -n "[OK]" } -function decrypt_recover_online_moved() { # $1 hash, $2 hdr, $3 dev size +decrypt_recover_online_moved() { # $1 hash, $2 hdr, $3 dev size local _res="" local _maxhz="" test -z "$4" || _res="--resilience $4" @@ -672,7 +718,7 @@ function decrypt_recover_online_moved() { # $1 hash, $2 hdr, $3 dev size # orig size # orig size digest # hdr (optional) -function reencrypt_offline_fixed_size() { +reencrypt_offline_fixed_size() { local _esz=$(($1>>9)) local _hdr="" # round-up fixed size to megabytes @@ -715,7 +761,7 @@ function reencrypt_offline_fixed_size() { # orig size # orig size digest # hdr -function encrypt_offline_fixed_size() { +encrypt_offline_fixed_size() { local _esz=$(($1>>9)) # reencrypt with fixed device size @@ -750,7 +796,7 @@ function encrypt_offline_fixed_size() { # orig size # orig size digest # hdr -function decrypt_offline_fixed_size() { +decrypt_offline_fixed_size() { local _esz=$(($1>>9)) # decrypt with fixed device size @@ -787,7 +833,7 @@ function decrypt_offline_fixed_size() { # orig size # orig size digest # hdr (optional) -function reencrypt_online_fixed_size() { +reencrypt_online_fixed_size() { local _esz=$(($1>>9)) local _hdr="" test -z "$7" || _hdr="--header $7" @@ -803,7 +849,7 @@ function reencrypt_online_fixed_size() { echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP resize $DEV_NAME $_hdr --size $2 || fail echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --resilience $4 || fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "$2 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "$2 \[512-byte units\]" || fail $CRYPTSETUP close $DEV_NAME || fail check_hash_head $PWD1 $2 $3 $7 wipe $PWD1 $7 @@ -814,7 +860,7 @@ function reencrypt_online_fixed_size() { echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --init-only || fail echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --device-size $(($2-_esz))s --resilience $4 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --device-size $2s --resilience $4 || fail - $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "$2 sectors" || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "$2 \[512-byte units\]" || fail $CRYPTSETUP close $DEV_NAME || fail check_hash_head $PWD1 $2 $3 $7 @@ -839,7 +885,28 @@ function reencrypt_online_fixed_size() { [ -n "$7" -a -f "$7" ] && rm -f $7 } -function prepare_vk_keyring() +reformat_reencrypt_device() { + if [ ! -e $BACKUP_FILE ]; then + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -S0 $FAST_PBKDF_ARGON $DEV || fail + echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey -S2 $FAST_PBKDF_ARGON $DEV || fail + echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey -S4 $FAST_PBKDF_ARGON $DEV || fail + echo -e "$PWD1\n$PWD4" | $CRYPTSETUP -q luksAddKey -S6 $FAST_PBKDF_ARGON $DEV || fail + echo -e "$PWD1\n$PWD5" | $CRYPTSETUP -q luksAddKey -S8 $FAST_PBKDF_ARGON $DEV || fail + echo -e "$PWD1\n$PWD6" | $CRYPTSETUP -q luksAddKey -S10 $FAST_PBKDF_ARGON $DEV || fail + echo -e "$PWD1\n$PWD7" | $CRYPTSETUP -q luksAddKey -S12 $FAST_PBKDF_ARGON $DEV || fail + + $CRYPTSETUP token add $DEV --token-id 1 --key-description $KEY_NAME3 -S6 + $CRYPTSETUP token add $DEV --token-id 2 --key-description $KEY_NAME4 -S8 + $CRYPTSETUP token add $DEV --token-id 3 --key-description $KEY_NAME5 -S10 + echo -e "{\"type\":\"luks2-keyring\",\"keyslots\":[\"4\", \"12\"],\"key_description\":\"$KEY_NAME6\"}" | $CRYPTSETUP token import $DEV --token-id 4 --json-file - + + $CRYPTSETUP -q luksHeaderBackup --header-backup-file $BACKUP_FILE $DEV || fail + else + $CRYPTSETUP -q luksHeaderRestore --header-backup-file $BACKUP_FILE $DEV || fail + fi +} + +prepare_vk_keyring() { local s_desc=$(keyctl rdescribe @s | cut -d';' -f5) local us_desc=$(keyctl rdescribe @us | cut -d';' -f5) @@ -851,9 +918,14 @@ function prepare_vk_keyring() keyctl newring $KEYRING "@s" >/dev/null || fail "Failed to setup test keyring environment" keyctl search "@s" keyring $KEYRING >/dev/null 2>&1 || fail "Could not find test keyring in a session keyring." + + echo -n $PWD4 | keyctl padd user $KEY_NAME3 %:$KEYRING > /dev/null || fail + echo -n "wRonG_passFrejz" | keyctl padd user $KEY_NAME5 %:$KEYRING > /dev/null || fail + echo -n $PWD7 | keyctl padd user $KEY_NAME6 %:$KEYRING > /dev/null || fail + echo -n $PWD2 | keyctl padd user $KEY_NAME7 %:$KEYRING > /dev/null || fail } -function setup_luks2_env() { +setup_luks2_env() { echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c aes-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail local check_keyring=$($CRYPTSETUP status $DEV_NAME | grep "key location: keyring") @@ -867,7 +939,7 @@ function setup_luks2_env() { $CRYPTSETUP close $DEV_NAME || fail } -function check_blkid() { +check_blkid() { bin_check blkid xz -dkf $HEADER_LUKS2_PV.xz if ! $($CRYPTSETUP --version | grep -q "BLKID"); then @@ -881,7 +953,7 @@ function check_blkid() { fi } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -891,16 +963,67 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function bin_check() +bin_check() { command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." } +_dd() +{ + dd $@ status=none conv=notrunc bs=1 +} + +img_json_save() +{ + local _hdr=$IMG + [ -z "$1" ] || _hdr="$1" + # FIXME: why --json-file cannot be used? + $CRYPTSETUP luksDump --dump-json-metadata $_hdr | jq -c -M . | tr -d '\n' >$IMG_JSON +} + +# header mangle functions +img_update_json() +{ + local _hdr="$IMG" + local LUKS2_BIN1_OFFSET=448 + local LUKS2_BIN2_OFFSET=$((LUKS2_BIN1_OFFSET + $JSON_MSIZE)) + local LUKS2_JSON_SIZE=$(($JSON_MSIZE - 4096)) + + # if present jq script, mangle JSON + if [ -n "$1" ]; then + local JSON=$(cat $IMG_JSON) + echo $JSON | jq -M -c "$1" >$IMG_JSON || fail + local JSON=$(cat $IMG_JSON) + echo $JSON | tr -d '\n' >$IMG_JSON || fail + fi + + [ -z "$2" ] || _hdr="$2" + + # wipe JSON areas + _dd if=/dev/zero of=$_hdr count=$LUKS2_JSON_SIZE seek=4096 + _dd if=/dev/zero of=$_hdr count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) + + # write JSON data + _dd if=$IMG_JSON of=$_hdr count=$LUKS2_JSON_SIZE seek=4096 + _dd if=$IMG_JSON of=$_hdr count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) + + # erase sha256 checksums + _dd if=/dev/zero of=$_hdr count=64 seek=$LUKS2_BIN1_OFFSET + _dd if=/dev/zero of=$_hdr count=64 seek=$LUKS2_BIN2_OFFSET + + # calculate sha256 and write chexksums + local SUM1_HEX=$(_dd if=$_hdr count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM1_HEX | xxd -r -p | _dd of=$_hdr seek=$LUKS2_BIN1_OFFSET count=64 || fail + + local SUM2_HEX=$(_dd if=$_hdr skip=$JSON_MSIZE count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM2_HEX | xxd -r -p | _dd of=$_hdr seek=$LUKS2_BIN2_OFFSET count=64 || fail +} + [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." fips_mode && skip "This test cannot be run in FIPS mode." @@ -908,6 +1031,9 @@ modprobe --dry-run scsi_debug >/dev/null 2>&1 || skip "This kernel seems to not modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load" modprobe dm-delay > /dev/null 2>&1 dm_crypt_features +bin_check jq +bin_check sha256sum +bin_check xxd if [ -n "$DM_SECTOR_SIZE" ]; then TEST_SECTORS="512 4096" @@ -948,9 +1074,9 @@ prepare dev_size_mb=32 setup_luks2_env # Check that we can use other ciphers than AES in userspace backend. -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c twofish-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c twofish-xts-plain64 $FAST_PBKDF_ARGON $DEV || skip "Cannot use Twofish cipher, test skipped" echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>/dev/null || skip "Cannot use Twofish cipher, test skipped" -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c serpent-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c serpent-xts-plain64 $FAST_PBKDF_ARGON $DEV || skip "Cannot use Serpent cipher, test skipped" echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>/dev/null || skip "Cannot use Serpent cipher, test skipped." wipe_dev $DEV @@ -1102,6 +1228,50 @@ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M --ini check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q || fail check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 +$CRYPTSETUP close $DEV_NAME || fail + +# encryption with both data shift and reduced data size +prepare_linear_dev 65 + +# --reduce-device-size + --device-size (1MiB+512B) is larger than real device size +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --init-only --device-size 2049s --reduce-device-size 64M -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail +$CRYPTSETUP isLuks --type luks2 $DEV && fail +# no changes in data device +check_hash_dev_head $DEV 2048 $HASH2 + +# --reduce-device-size (1MiB+8KiB) + --device-size (64MiB - (8KiB-512B)) is larger than real device size +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --init-only --device-size 131057s --reduce-device-size 2064s -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail +$CRYPTSETUP isLuks --type luks2 $DEV && fail +# no changes in data device +check_hash_dev_head $DEV 2048 $HASH2 + +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --device-size 1M --reduce-device-size 32M -q $FAST_PBKDF_ARGON || fail +check_hash_head $PWD1 2048 $HASH2 + +# test limit values (--device-size + --reduce-device-size = real device size) +wipe_dev_head $DEV 43 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --device-size 43M --reduce-device-size 22M -q $FAST_PBKDF_ARGON || fail +check_hash_head $PWD1 88064 $HASH6 + +wipe_dev_head $DEV 1 +# check reencryption code does not touch data in-between --device-size and --reduce-device-size +# data device: [ reduce-device-size / 2 ] [ device-size ] [ error minefield ] [ reduce-device-size / 2] +ERROFFSET=34816 +ERRLENGTH=65536 +error_io $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --device-size 1M --reduce-device-size 32M -q $FAST_PBKDF_ARGON || fail +fix_writes $OVRDEV $OLD_DEV +check_hash_head $PWD1 2048 $HASH2 + +wipe_dev_head $DEV 43 + +ERROFFSET=104448 +ERRLENGTH=12288 +# data device: [ reduce-device-size / 2 ] [ device-size ] [ error minefield ] [ reduce-device-size / 2] +error_io $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --device-size 43M --reduce-device-size 16M -q $FAST_PBKDF_ARGON || fail +fix_writes $OVRDEV $OLD_DEV +check_hash_head $PWD1 88064 $HASH6 echo "[3] Encryption with detached header" preparebig 256 @@ -1726,7 +1896,7 @@ prepare dev_size_mb=32 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 256 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 -echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -S0 $FAST_PBKDF_ARGON --volume-key-file $VKEY1 -s 128 || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -S0 $FAST_PBKDF_ARGON --new-volume-key-file $VKEY1 --new-key-size 128 || fail check_hash $PWD1 $HASH1 $CRYPTSETUP luksErase -q $DEV || fail echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_ARGON --volume-key-file $VKEY1 -s 128 $DEV || fail @@ -1751,14 +1921,16 @@ if [ $HAVE_KEYRING -gt 0 ]; then fi $CRYPTSETUP close $DEV_NAME -# simulate LUKS2 device with cipher_null in both keyslot and segment (it can be created only by up conversion from LUKS1) -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF2 $DEV || fail -$CRYPTSETUP convert -q --type luks2 $DEV || fail -wipe $PWD1 -echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON >/dev/null || fail -check_hash $PWD1 $HASH1 -# both keyslot and segment cipher must not be null after reencryption with default params -$CRYPTSETUP luksDump $DEV | grep -q "cipher_null" && fail +# FIXME: Add test luks2 image with both keyslot and data using cipher_null and verify LUKS2 reencryption fixes this. + +## simulate LUKS2 device with cipher_null in both keyslot and segment (it can be created only by up conversion from LUKS1) +#echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF2 $DEV || fail +#$CRYPTSETUP convert -q --type luks2 $DEV || fail +#wipe $PWD1 +#echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON >/dev/null || fail +#check_hash $PWD1 $HASH1 +## both keyslot and segment cipher must not be null after reencryption with default params +#$CRYPTSETUP luksDump $DEV | grep -q "cipher_null" && fail # multistep reencryption with initial cipher_null preparebig 64 @@ -2160,6 +2332,17 @@ echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --header $IMG_HDR --active-name check_hash_dev_head $DEV 2048 $HASH2 rm -f $IMG_HDR +# Regression test for decryption with detached header and digest id != 0 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +img_json_save $DEV +# replace digest id 0 with 1 +img_update_json '.digests."1" = .digests."0" | del(.digests."0")' $DEV +wipe $PWD1 +check_hash $PWD1 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --header $IMG_HDR $DEV || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + echo "[33] Decryption with datashift recovery (error in shift area)." prepare_linear_dev 32 echo "sector size 512" @@ -2316,6 +2499,212 @@ wipe_dev /dev/mapper/$DEV_NAME echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail check_hash_dev_head $DEV 2048 $HASH2 +echo "[38] Reencrypt by keyslot context (new initialization and resume methods)" +prepare dev_size_mb=32 + +# keyslot0 - pass1 +# keyslot2 - pass2 +# keyslot4 - pass3, token4 (wrong pass) +# keyslot6 - pass4, token1 +# keyslot8 - pass5, token2 (missing) +# keyslot10 - pass6, token3 (wrong pass) +# keyslot12 - pass7, token4 +reformat_reencrypt_device + +# tokens +$CRYPTSETUP reencrypt -q --token-id 1 $DEV <&- || fail +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --token-only $DEV <&- || fail +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --token-type luks2-keyring $DEV <&- || fail + +reformat_reencrypt_device +# keyslots 6 and 12 are unlocked by tokens 1 and 4 +echo -e "$PWD1\n$PWD2\n$PWD3\n$PWD5\n$PWD6" | $CRYPTSETUP reencrypt -q $DEV || fail + +# keyfile +echo -n $PWD2 > $KEY1 +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --key-file $KEY1 $DEV 2>/dev/null <&- && fail +$CRYPTSETUP reencrypt -q --key-file $KEY1 -S4 $DEV 2>/dev/null <&- && fail +$CRYPTSETUP reencrypt -q --key-file $KEY1 -S2 $DEV <&- || fail + +# passphrase in keyring +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --key-description $KEY_NAME7 $DEV 2>/dev/null <&- && fail +$CRYPTSETUP reencrypt -q --key-description $KEY_NAME7 -S4 $DEV 2>/dev/null <&- && fail +$CRYPTSETUP reencrypt -q --key-description $KEY_NAME7 -S2 $DEV <&- || fail + +# tokens +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --token-id 1 $DEV --init-only <&- || fail +$CRYPTSETUP open --token-id 1 $DEV $DEV_NAME <&- || fail +$CRYPTSETUP reencrypt -q --token-id 1 $DEV --resume-only <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --token-only --init-only $DEV <&- || fail +$CRYPTSETUP open --token-only $DEV $DEV_NAME <&- || fail +$CRYPTSETUP reencrypt -q --token-only --resume-only $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --token-type luks2-keyring --init-only $DEV <&- || fail +$CRYPTSETUP open --token-type luks2-keyring $DEV $DEV_NAME <&- || fail +$CRYPTSETUP reencrypt -q --token-type luks2-keyring --resume-only $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +reformat_reencrypt_device +echo -e "$PWD1\n$PWD2\n$PWD3\n$PWD5\n$PWD6" | $CRYPTSETUP reencrypt --init-only -q $DEV || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +echo -e $PWD1 | $CRYPTSETUP reencrypt --resume-only -q $DEV || fail +$CRYPTSETUP close $DEV_NAME || fail + +# keyfile +echo -n $PWD2 > $KEY1 +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --init-only --key-file $KEY1 $DEV 2>/dev/null <&- && fail +$CRYPTSETUP reencrypt -q --init-only --key-file $KEY1 -S4 $DEV 2>/dev/null <&- && fail + +$CRYPTSETUP reencrypt -q --init-only --key-file $KEY1 -S2 $DEV <&- || fail +$CRYPTSETUP open --key-file $KEY1 $DEV $DEV_NAME <&- || fail +$CRYPTSETUP reencrypt -q --resume-only --key-file $KEY1 $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +# passphrase in keyring +reformat_reencrypt_device +$CRYPTSETUP reencrypt -q --init-only --key-description $KEY_NAME7 $DEV 2>/dev/null <&- && fail +$CRYPTSETUP reencrypt -q --init-only --key-description $KEY_NAME7 -S4 $DEV 2>/dev/null <&- && fail +$CRYPTSETUP reencrypt -q --init-only --key-description $KEY_NAME7 -S2 $DEV <&- || fail +$CRYPTSETUP open -q --key-description $KEY_NAME7 $DEV $DEV_NAME <&- || fail +$CRYPTSETUP reencrypt -q --resume-only --key-description $KEY_NAME7 $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +# volume key +reformat_reencrypt_device +echo $PWD1 | $CRYPTSETUP luksDump --dump-volume-key --volume-key-file $VKEY2 $DEV >/dev/null || fail + +$CRYPTSETUP -q reencrypt --force-no-keyslots --volume-key-file $VKEY2 --new-volume-key-file $VKEY1 --new-key-size 256 $DEV <&- || fail + +# missing key size information (no active keyslot) +$CRYPTSETUP open --test-passphrase --volume-key-file $VKEY1 $DEV <&- 2>/dev/null && fail +$CRYPTSETUP open --test-passphrase --volume-key-file $VKEY1 --key-size 256 $DEV <&- || fail +$CRYPTSETUP open --test-passphrase --volume-key-file $VKEY2 --key-size 512 $DEV 2>/dev/null <&- && fail + +echo $PWD1 | $CRYPTSETUP luksAddKey --volume-key-file $VKEY1 --key-size 256 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail + +reformat_reencrypt_device +$CRYPTSETUP -q reencrypt --init-only --force-no-keyslots --volume-key-file $VKEY2 --new-volume-key-file $VKEY1 --new-key-size 256 $DEV <&- || fail + +# For unlock operation we do not require specific --volume-key-file ordering (unlike in reencryption initialization) +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY1 --key-size 256 --volume-key-file $VKEY2 --key-size 512 $DEV <&- || fail + +# with 2 --volume-key-files options --key-size must be also supplied twice +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY1 --volume-key-file $VKEY2 --key-size 512 $DEV 2>/dev/null <&- && fail +# Missing old volume key +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY2 --key-size 512 $DEV <&- 2>/dev/null && fail + +$CRYPTSETUP -q open --volume-key-file $VKEY2 --key-size 512 --volume-key-file $VKEY1 --key-size 256 $DEV $DEV_NAME <&- || fail + +$CRYPTSETUP -q reencrypt --resume-only --volume-key-file $VKEY2 --new-volume-key-file $VKEY1 --key-size 512 --new-key-size 256 $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +# wrong key size +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY1 --key-size 512 $DEV <&- 2>/dev/null && fail +# wrong key +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY2 --key-size 256 $DEV <&- 2>/dev/null && fail + +# missing key size +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY1 $DEV <&- 2>/dev/null && fail +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY1 --key-size 256 $DEV <&- || fail + +# no remaining keyslots test (--force-no-keyslots is not needed) +reformat_reencrypt_device +$CRYPTSETUP -q luksErase $DEV || fail + +$CRYPTSETUP -q reencrypt --volume-key-file $VKEY2 -s 512 --new-volume-key-file $VKEY1 --new-key-size 256 $DEV <&- || fail +$CRYPTSETUP open --test-passphrase --volume-key-file $VKEY1 --key-size 256 $DEV <&- || fail + +reformat_reencrypt_device +$CRYPTSETUP -q luksErase $DEV || fail +$CRYPTSETUP -q reencrypt --init-only --volume-key-file $VKEY2 -s 512 --new-volume-key-file $VKEY1 --new-key-size 256 $DEV <&- || fail + +# For unlock operation we do not require specific --volume-key-file ordering (unlike in reencryption initialization) +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY1 --key-size 256 --volume-key-file $VKEY2 --key-size 512 $DEV <&- || fail + +# with 2 --volume-key-files options --key-size must be also supplied twice +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY1 --volume-key-file $VKEY2 --key-size 512 $DEV 2>/dev/null <&- && fail +# Missing old volume key +$CRYPTSETUP -q open --test-passphrase --volume-key-file $VKEY2 --key-size 512 $DEV <&- 2>/dev/null && fail + +$CRYPTSETUP -q open --volume-key-file $VKEY2 --key-size 512 --volume-key-file $VKEY1 --key-size 256 $DEV $DEV_NAME <&- || fail + +$CRYPTSETUP -q reencrypt --resume-only --volume-key-file $VKEY2 --new-volume-key-file $VKEY1 --key-size 512 --new-key-size 256 $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +# reencryption by volume key in kernel keyring +reformat_reencrypt_device +head -c 64 $VKEY2 | keyctl padd user $KEY_NAME_VK2 %:$KEYRING > /dev/null || fail +head -c 32 $VKEY1 | keyctl padd user $KEY_NAME_VK1 %:$KEYRING > /dev/null || fail + +$CRYPTSETUP -q reencrypt --force-no-keyslots --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- || fail + +# test unlock with key after reencryption +$CRYPTSETUP open --test-passphrase --volume-key-keyring $KEY_NAME_VK1 $DEV <&- || fail +$CRYPTSETUP open --test-passphrase --volume-key-keyring $KEY_NAME_VK2 $DEV <&- 2>/dev/null && fail + +reformat_reencrypt_device +$CRYPTSETUP -q reencrypt --init-only --force-no-keyslots --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- || fail + +# For unlock operation we do not require specific --volume-key-file ordering (unlike in reencryption initialization) +$CRYPTSETUP -q open --test-passphrase --volume-key-keyring $KEY_NAME_VK1 --volume-key-keyring $KEY_NAME_VK2 $DEV <&- || fail + +# Missing old volume key +$CRYPTSETUP -q open --test-passphrase --volume-key-keyring $KEY_NAME_VK1 $DEV <&- 2>/dev/null && fail + +$CRYPTSETUP -q open --volume-key-keyring $KEY_NAME_VK1 --volume-key-keyring $KEY_NAME_VK2 $DEV $DEV_NAME <&- || fail + +$CRYPTSETUP -q reencrypt --resume-only --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +# no remaining keyslots test (--force-no-keyslots is not needed) +reformat_reencrypt_device +$CRYPTSETUP -q luksErase $DEV || fail + +$CRYPTSETUP -q reencrypt --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- || fail + +reformat_reencrypt_device +$CRYPTSETUP -q luksErase $DEV || fail +$CRYPTSETUP -q reencrypt --init-only --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- || fail + +# For unlock operation we do not require specific --volume-key-file ordering (unlike in reencryption initialization) +$CRYPTSETUP -q open --test-passphrase --volume-key-keyring $KEY_NAME_VK1 --volume-key-keyring $KEY_NAME_VK2 $DEV <&- || fail + +# Missing old volume key +$CRYPTSETUP -q open --test-passphrase --volume-key-keyring $KEY_NAME_VK2 $DEV <&- 2>/dev/null && fail + +$CRYPTSETUP -q open --volume-key-keyring $KEY_NAME_VK1 --volume-key-keyring $KEY_NAME_VK2 $DEV $DEV_NAME <&- || fail + +$CRYPTSETUP -q reencrypt --resume-only --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- || fail +$CRYPTSETUP close $DEV_NAME || fail + +# test b0rked kernel keys +reformat_reencrypt_device +$CRYPTSETUP -q luksErase $DEV || fail + +head -c 63 $VKEY2 | keyctl padd user $KEY_NAME_VK2 %:$KEYRING > /dev/null || fail +$CRYPTSETUP -q reencrypt --init-only --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- 2>/dev/null && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail "Failed initialization with reencryption flag" + +head -c 64 $VKEY2 | keyctl padd user $KEY_NAME_VK2 %:$KEYRING > /dev/null || fail +$CRYPTSETUP open --test-passphrase --volume-key-keyring $KEY_NAME_VK2 $DEV || fail + +# new key size incompatible with cipher +head -c 31 $VKEY1 | keyctl padd user $KEY_NAME_VK1 %:$KEYRING > /dev/null || fail +$CRYPTSETUP -q reencrypt --init-only --volume-key-keyring $KEY_NAME_VK2 --new-volume-key-keyring $KEY_NAME_VK1 $DEV <&- 2>/dev/null && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail "Failed initialization with reencryption flag" + remove_mapping cleanup_keyring exit 0 diff --git a/tests/luks2-validation-test b/tests/luks2-validation-test index 545c38e..47e631f 100755 --- a/tests/luks2-validation-test +++ b/tests/luks2-validation-test @@ -25,12 +25,12 @@ FAILS=0 [ -z "$srcdir" ] && srcdir="." -function remove_mapping() +remove_mapping() { rm -rf $IMG $TST_IMGS >/dev/null 2>&1 } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo "FAILED backtrace:" @@ -40,19 +40,22 @@ function fail() exit 2 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + fail_count() { echo "$1" FAILS=$((FAILS+1)) } -function skip() +skip() { [ -n "$1" ] && echo "$1" exit 77 } -function prepare() # $1 dev1_size +prepare() # $1 dev1_size { remove_mapping @@ -63,13 +66,27 @@ function prepare() # $1 dev1_size cp $ORIG_IMG $IMG } -function test_load() +test_load() { local _debug= test -z "$_DEBUG" || _debug="--debug" case "$1" in + T) + if [ -n "$_debug" ]; then + $CRYPTSETUP token remove --token-id 0 $_debug $IMG + else + $CRYPTSETUP token remove --token-id 0 $IMG > /dev/null 2>&1 + fi + test $? -eq 0 || return 1 + if [ -n "$_debug" ]; then + $CRYPTSETUP luksDump $_debug $IMG + else + $CRYPTSETUP luksDump $IMG > /dev/null 2>&1 + fi + test $? -eq 0 || return 1 + ;; R) if [ -n "$_debug" ]; then $CRYPTSETUP luksDump $_debug $IMG @@ -94,7 +111,7 @@ function test_load() esac } -function RUN() +RUN() { echo -n "Test image: $1..." cp $TST_IMGS/$1 $IMG || fail "Missing test image" @@ -106,7 +123,7 @@ function RUN() fi } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -116,7 +133,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } @@ -125,6 +142,7 @@ function valgrind_run() [ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run command -v jq >/dev/null || skip "Cannot find jq, test skipped." +command -v xxd >/dev/null || skip "Cannot find xxd, test skipped." prepare @@ -251,6 +269,10 @@ RUN luks2-keyslot-invalid-area-size.img "F" "Invalid keyslot area size that ca RUN luks2-keyslot-invalid-objects.img "F" "Invalid keyslot objects not rejected" RUN luks2-keyslot-invalid-af.img "F" "Invalid keyslot objects types not rejected" +echo "[8] Test non compact json does not break write optimization" +RUN luks2-non-compact-json-token-0.img "T" "Non compact json area corrupted after write" +RUN luks2-non-compact-json-4k-token-0.img "T" "Non compact 4K aligned json area corrupted after write" + remove_mapping test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)" diff --git a/tests/meson.build b/tests/meson.build index f4aed61..f8e6a65 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -59,6 +59,17 @@ api_test_2 = executable('api-test-2', ], include_directories: includes_lib) +crypto_check = executable('crypto-check', + [ + 'crypto-check.c', + ], + link_with: libcrypto_backend, + c_args: [ + '-Wall', + '-O2', + ], + include_directories: includes_lib) + vectors_test = executable('vectors-test', [ 'crypto-vectors.c', @@ -354,6 +365,7 @@ if get_option('cryptsetup') is_parallel: false, depends: [ cryptsetup, + crypto_check, ]) test('luks1-compat-test', find_program('./luks1-compat-test'), @@ -362,6 +374,7 @@ if get_option('cryptsetup') is_parallel: false, depends: [ cryptsetup, + crypto_check, ]) test('device-test', find_program('./device-test'), @@ -379,6 +392,14 @@ if get_option('cryptsetup') depends: [ cryptsetup, ]) + test('keyring-trusted-test', + find_program('./keyring-trusted-test'), + workdir: meson.current_build_dir(), + timeout: 14400, + is_parallel: false, + depends: [ + cryptsetup, + ]) test('luks2-validation-test', find_program('./luks2-validation-test'), workdir: meson.current_build_dir(), diff --git a/tests/mode-test b/tests/mode-test index c9c8c05..fa483e5 100755 --- a/tests/mode-test +++ b/tests/mode-test @@ -46,13 +46,16 @@ fail() exit 100 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + skip() { [ -n "$1" ] && echo "$1" exit 77 } -function dm_crypt_capi_support() +dm_crypt_capi_support() { VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -61,6 +64,7 @@ function dm_crypt_capi_support() VER_MIN=$(echo $VER_STR | cut -f 2 -d.) VER_PTC=$(echo $VER_STR | cut -f 3 -d.) + [ $VER_MAJ -gt 1 ] && return 0 if [ $VER_MIN -ge 16 ]; then return 0 fi @@ -68,7 +72,7 @@ function dm_crypt_capi_support() return 1 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -78,7 +82,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } @@ -143,33 +147,39 @@ dmcrypt() [ -z "$OUT" ] && OUT=$1 printf "%-31s" "$1" + echo -n -e "PLAIN:" echo $PASSWORD | $CRYPTSETUP create -h sha256 -c $1 -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME >/dev/null 2>&1 if [ $? -eq 0 ] ; then - echo -n -e "PLAIN:" dmcrypt_check "$DEV_NAME"_tstdev $OUT else echo -n "[N/A]" fi + echo -n -e " LUKS1:" echo $PASSWORD | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF2 -c $1 -s 256 /dev/mapper/$DEV_NAME >/dev/null 2>&1 if [ $? -eq 0 ] ; then - echo -n -e " LUKS1:" echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_tstdev >/dev/null 2>&1 || fail dmcrypt_check "$DEV_NAME"_tstdev $OUT + else + echo -n "[N/A]" fi + echo -n -e " LUKS2:" echo $PASSWORD | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 $FAST_PBKDF2 -c $1 -s 256 --offset 8192 /dev/mapper/$DEV_NAME >/dev/null 2>&1 if [ $? -eq 0 ] ; then - echo -n -e " LUKS2:" echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_tstdev >/dev/null 2>&1 || fail dmcrypt_check "$DEV_NAME"_tstdev $OUT + else + echo -n "[N/A]" fi # repeated device creation must return the same checksum + echo -n -e " CHECKSUM:" echo $PASSWORD | $CRYPTSETUP create -h sha256 -c $1 -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME >/dev/null 2>&1 if [ $? -eq 0 ] ; then - echo -n -e " CHECKSUM:" dmcrypt_check_sum "$1" "$DEV_NAME"_tstdev + else + echo -n "[N/A]" fi echo } diff --git a/tests/password-hash-test b/tests/password-hash-test index e777390..a1ca415 100755 --- a/tests/password-hash-test +++ b/tests/password-hash-test @@ -28,7 +28,7 @@ cleanup() { exit $1 } -function fail() +fail() { echo " $1 [FAILED]" echo "FAILED backtrace:" @@ -36,13 +36,16 @@ function fail() cleanup 2 } +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + skip() { echo "TEST SKIPPED: $1" cleanup 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -52,7 +55,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test index 7a6301e..a14a5b4 100755 --- a/tests/reencryption-compat-test +++ b/tests/reencryption-compat-test @@ -32,18 +32,18 @@ MNT_DIR=./mnt_luks START_DIR=$(pwd) FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) -function fips_mode() +fips_mode() { [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] } -function del_scsi_device() +del_scsi_device() { rmmod scsi_debug >/dev/null 2>&1 sleep 1 } -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME @@ -55,7 +55,7 @@ function remove_mapping() del_scsi_device } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo "FAILED backtrace:" @@ -65,13 +65,16 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -81,12 +84,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function add_scsi_device() { +add_scsi_device() { del_scsi_device if [ -d /sys/module/scsi_debug ] ; then echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." @@ -103,7 +106,7 @@ function add_scsi_device() { [ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV." } -function open_crypt() # $1 pwd, $2 hdr +open_crypt() # $1 pwd, $2 hdr { if [ -n "$2" ] ; then echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME --header $2 || fail @@ -114,12 +117,12 @@ function open_crypt() # $1 pwd, $2 hdr fi } -function wipe_dev() # $1 dev +wipe_dev() # $1 dev { dd if=/dev/zero of=$1 bs=256k >/dev/null 2>&1 } -function wipe() # $1 pass +wipe() # $1 pass { open_crypt $1 wipe_dev /dev/mapper/$DEV_NAME @@ -127,50 +130,52 @@ function wipe() # $1 pass $CRYPTSETUP luksClose $DEV_NAME || fail } -function prepare() # $1 dev1_siz +prepare() # $1 dev1_siz { remove_mapping - dd if=/dev/zero of=$IMG bs=1k count=$1 >/dev/null 2>&1 + dd if=/dev/zero of=$IMG bs=1k count=$1 >/dev/null 2>&1 LOOPDEV1=$(losetup -f 2>/dev/null) [ -z "$LOOPDEV1" ] && fail "No free loop device" - losetup $LOOPDEV1 $IMG + losetup $LOOPDEV1 $IMG || fail if [ ! -e $KEY1 ]; then dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 fi } -function check_hash_dev() # $1 dev, $2 hash +check_hash_dev() # $1 dev, $2 hash { HASH=$(sha256sum $1 | cut -d' ' -f 1) [ $HASH != "$2" ] && fail "HASH differs ($HASH)" } -function check_hash() # $1 pwd, $2 hash, $3 hdr +check_hash() # $1 pwd, $2 hash, $3 hdr { open_crypt $1 $3 check_hash_dev /dev/mapper/$DEV_NAME $2 $CRYPTSETUP remove $DEV_NAME || fail } -function backup_orig() +backup_orig() { sync losetup -d $LOOPDEV1 + udevadm settle >/dev/null 2>&1 cp $IMG $ORIG_IMG - losetup $LOOPDEV1 $IMG + losetup $LOOPDEV1 $IMG || fail } -function rollback() +rollback() { sync losetup -d $LOOPDEV1 + udevadm settle >/dev/null 2>&1 cp $ORIG_IMG $IMG - losetup $LOOPDEV1 $IMG + losetup $LOOPDEV1 $IMG || fail } -function check_slot() #space separated list of ENABLED key slots +check_slot() #space separated list of ENABLED key slots { local _KS0=DISABLED local _KS1=$_KS0 _KS2=$_KS0 _KS3=$_KS0 _KS4=$_KS0 _KS5=$_KS0 _KS6=$_KS0 _KS7=$_KS0 @@ -195,7 +200,7 @@ function check_slot() #space separated list of ENABLED key slots return 0 } -function simple_scsi_reenc() +simple_scsi_reenc() { echo -n "$1" echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF $SCSI_DEV || fail @@ -211,7 +216,7 @@ function simple_scsi_reenc() $CRYPTSETUP luksClose $DEV_NAME || fail } -function mount_and_test() { +mount_and_test() { test -d $MNT_DIR || mkdir -p $MNT_DIR mount $@ $MNT_DIR 2>/dev/null || { echo -n "[N/A]" @@ -232,13 +237,13 @@ function mount_and_test() { echo -n [OK] } -function test_logging_tmpfs() { +test_logging_tmpfs() { echo -n "[tmpfs]" mount_and_test -t tmpfs none -o size=$[25*1024*1024] || return 1 echo } -function test_logging() { +test_logging() { echo -n "$1:" for img in $(ls img_fs*img.xz) ; do wipefs -a $SCSI_DEV > /dev/null @@ -249,7 +254,7 @@ function test_logging() { echo } -function check_blkid() { +check_blkid() { xz -dkf $HEADER_LUKS2_PV.xz if ! $($CRYPTSETUP --version | grep -q "BLKID"); then HAVE_BLKID=0 diff --git a/tests/run-all-symbols b/tests/run-all-symbols index 58a1ba6..53c10e8 100755 --- a/tests/run-all-symbols +++ b/tests/run-all-symbols @@ -3,13 +3,13 @@ [ -z "$LIBCRYPTSETUP_DIR" ] && LIBCRYPTSETUP_DIR=../.libs FILE=$LIBCRYPTSETUP_DIR/libcryptsetup.so -function fail() +fail() { [ -n "$1" ] && echo "$1" exit 2 } -function skip() +skip() { [ -n "$1" ] && echo "$1" exit 77 diff --git a/tests/ssh-test-plugin b/tests/ssh-test-plugin index 2475034..4587e8c 100755 --- a/tests/ssh-test-plugin +++ b/tests/ssh-test-plugin @@ -39,19 +39,19 @@ fi CRYPTSETUP_SSH="$CRYPTSETUP_PATH/../tokens/ssh/cryptsetup-ssh" } -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP rm -f $IMG >/dev/null 2>&1 } -function remove_user() +remove_user() { id -u $USER >/dev/null 2>&1 && userdel -r -f $USER >/dev/null 2>&1 rm -f $SSH_KEY_PATH "$SSH_KEY_PATH.pub" >/dev/null 2>&1 } -function create_user() +create_user() { id -u $USER >/dev/null 2>&1 [ $? -eq 0 ] && skip "User account $USER exists, aborting." @@ -63,18 +63,18 @@ function create_user() [ $? -ne 0 ] && remove_user && skip "Failed to create SSH key." } -function ssh_check() +ssh_check() { # try to use netcat to check port 22 nc -zv $SSH_SERVER 22 >/dev/null 2>&1 || skip "SSH server does not seem to be running, skipping." } -function bin_check() +bin_check() { command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." } -function ssh_setup() +ssh_setup() { # copy the ssh key [ -d "/home/$USER/.ssh" ] || mkdir /home/$USER/.ssh @@ -93,7 +93,7 @@ function ssh_setup() [ $? -ne 0 ] && remove_user && fail "Failed to connect using SSH." } -function fail() +fail() { echo "[FAILED]" [ -n "$1" ] && echo "$1" @@ -104,14 +104,17 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -121,12 +124,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } -function valgrind_run_ssh() +valgrind_run_ssh() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_SSH_VALGRIND} "$@" } diff --git a/tests/systemd-test-plugin b/tests/systemd-test-plugin index 7515f76..9ddc4af 100755 --- a/tests/systemd-test-plugin +++ b/tests/systemd-test-plugin @@ -8,12 +8,12 @@ FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" IMG=systemd_token_test.img MAP="systemd_tpm2_test" -function bin_check() +bin_check() { command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." } -function cleanup() { +cleanup() { [ -S $SWTPM_STATE_DIR/ctrl.sock ] && { # shutdown TPM via control socket swtpm_ioctl -s --unix $SWTPM_STATE_DIR/ctrl.sock @@ -33,7 +33,7 @@ function cleanup() { rm -f $IMG >/dev/null 2>&1 } -function fail() +fail() { echo "[FAILED]" [ -n "$1" ] && echo "$1" @@ -43,7 +43,10 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" cleanup @@ -153,9 +156,6 @@ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup echo "Virtual TPM set up at $TPM_PATH" } -if [ -n "$SSH_BUILD_DIR" ]; then - CUSTOM_TOKENS_PATH="--external-tokens-path $SSH_BUILD_DIR" -fi FAKE_TPM_PATH="$(pwd)/fake_systemd_tpm_path.so" [ ! -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ] && FAKE_TPM_PATH="$CRYPTSETUP_PATH/../tests/fake_systemd_tpm_path.so" [ -f $FAKE_TPM_PATH ] || skip "Please compile $FAKE_TPM_PATH." @@ -164,29 +164,36 @@ export LD_PRELOAD="$LD_PRELOAD:$FAKE_TPM_PATH" export TPM_PATH=$TPM_PATH echo "TPM path is $TPM_PATH" +if [ -z "$CRYPTSETUP_TOKENS_PATH" ]; then + echo "Running with system cryptsetup plugins path" + CRYPTSETUP_EXTERNAL_PATH_PARAM= +else + CRYPTSETUP_EXTERNAL_PATH_PARAM="--external-tokens-path $CRYPTSETUP_TOKENS_PATH" +fi + dd if=/dev/zero of=$IMG bs=1M count=32 >/dev/null 2>&1 echo $PASSWD | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $IMG --force-password -q echo "Enrolling the device to TPM 2 using systemd-cryptenroll.." LD_PRELOAD="$LD_PRELOAD:$CRYPTENROLL_LD_PRELOAD" PASSWORD="$PASSWD" $SYSTEMD_CRYPTENROLL $IMG --tpm2-device=$TPM_PATH >/dev/null 2>&1 -$CRYPTSETUP luksDump --external-tokens-path $CRYPTSETUP_TOKENS_PATH $IMG | grep -q "tpm2-blob" || fail "Failed to dump $IMG using systemd_tpm2 token (no tpm2-blob in output)." +$CRYPTSETUP luksDump $CRYPTSETUP_EXTERNAL_PATH_PARAM $IMG | grep -q "tpm2-blob" || fail "Failed to dump $IMG using systemd_tpm2 token (no tpm2-blob in output)." echo "Activating the device via TPM2 external token.." -$CRYPTSETUP open --external-tokens-path $CRYPTSETUP_TOKENS_PATH --token-only $IMG $MAP >/dev/null 2>&1 || fail "Failed to open $IMG using systemd_tpm2 token." +$CRYPTSETUP open $CRYPTSETUP_EXTERNAL_PATH_PARAM --token-only $IMG $MAP >/dev/null 2>&1 || fail "Failed to open $IMG using systemd_tpm2 token." $CRYPTSETUP close $MAP >/dev/null 2>&1 || fail "Failed to close $MAP." echo "Adding passphrase via TPM2 token.." -echo $PASSWD2 | $CRYPTSETUP luksAddKey --external-tokens-path $CRYPTSETUP_TOKENS_PATH $FAST_PBKDF_OPT $IMG --force-password -q --token-only >/dev/null 2>&1 || fail "Failed to add passphrase by tpm2 token." +echo $PASSWD2 | $CRYPTSETUP luksAddKey $CRYPTSETUP_EXTERNAL_PATH_PARAM $FAST_PBKDF_OPT $IMG --force-password -q --token-only >/dev/null 2>&1 || fail "Failed to add passphrase by tpm2 token." echo $PASSWD2 | $CRYPTSETUP open $IMG --test-passphrase --disable-external-tokens >/dev/null 2>&1 || fail "Failed to test passphrase added by tpm2 token." echo "Exporting and removing TPM2 token.." EXPORTED_TOKEN=$($CRYPTSETUP token export $IMG --token-id 0) $CRYPTSETUP token remove $IMG --token-id 0 -$CRYPTSETUP open --external-tokens-path $CRYPTSETUP_TOKENS_PATH $IMG --test-passphrase --token-only >/dev/null 2>&1 && fail "Activating without passphrase should fail after TPM2 token removal." +$CRYPTSETUP open $CRYPTSETUP_EXTERNAL_PATH_PARAM $IMG --test-passphrase --token-only >/dev/null 2>&1 && fail "Activating without passphrase should fail after TPM2 token removal." echo "Re-importing TPM2 token.." echo $EXPORTED_TOKEN | $CRYPTSETUP token import $IMG --token-id 0 || fail "Failed to re-import deleted token." -$CRYPTSETUP open --external-tokens-path $CRYPTSETUP_TOKENS_PATH $IMG --test-passphrase --token-only >/dev/null 2>&1 || fail "Failed to activate after re-importing deleted token." +$CRYPTSETUP open $CRYPTSETUP_EXTERNAL_PATH_PARAM $IMG --test-passphrase --token-only >/dev/null 2>&1 || fail "Failed to activate after re-importing deleted token." cleanup exit 0 diff --git a/tests/tcrypt-compat-test b/tests/tcrypt-compat-test index 0708b32..d22d1a9 100755 --- a/tests/tcrypt-compat-test +++ b/tests/tcrypt-compat-test @@ -10,6 +10,10 @@ PASSWORD="aaaaaaaaaaaa" PASSWORD_HIDDEN="bbbbbbbbbbbb" PASSWORD_72C="aaaaaaaaaaaabbbbbbbbbbbbccccccccccccddddddddddddeeeeeeeeeeeeffffffffffff" PIM=1234 +LOOP_SYS="" +PART_IMG=tctst-part-img + +CRYPTOCHECK=./crypto-check if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then CRYPTSETUP_VALGRIND=$CRYPTSETUP @@ -20,15 +24,16 @@ fi [ -z "$srcdir" ] && srcdir="." -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP [ -b /dev/mapper/"$MAP"_1 ] && dmsetup remove --retry "$MAP"_1 [ -b /dev/mapper/"$MAP"_2 ] && dmsetup remove --retry "$MAP"_2 - rm -rf $TST_DIR + [ -n "$LOOP_SYS" ] && losetup -d $LOOP_SYS + rm -rf $TST_DIR $PART_IMG } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo " [FAILED]" @@ -38,29 +43,31 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" remove_mapping exit 77 } -function test_one() # cipher mode keysize rm_pattern +test_one() # cipher mode keysize rm_pattern { - $CRYPTSETUP benchmark -c "$1-$2" -s "$3" >/dev/null 2>&1 + $CRYPTOCHECK cipher $1 $2 $3 if [ $? -ne 0 ] ; then echo "$1-$2 [N/A]" IMGS=$(ls $TST_DIR/[tv]c* | grep "$4") [ -n "$IMGS" ] && rm $IMGS - #echo $IMGS else echo "$1-$2 [OK]" fi } -function test_kdf() # hash img_hash +test_kdf() # hash img_hash { - $CRYPTSETUP benchmark -h "$1" >/dev/null 2>&1 + $CRYPTOCHECK hash $1 if [ $? -ne 0 ] ; then echo "pbkdf2-$1 [N/A]" IMGS=$(ls $TST_DIR/[tv]c* | grep "$2") @@ -70,16 +77,17 @@ function test_kdf() # hash img_hash fi } -function get_HASH_CIPHER() # filename +get_HASH_CIPHER() # filename { # speed up the test by limiting options for hash and (first) cipher HASH=$(echo $file | cut -d'-' -f3) CIPHER=$(echo $file | cut -d'-' -f5) } -function test_required() +test_required() { command -v blkid >/dev/null || skip "blkid tool required, test skipped." + [ ! -x "$CRYPTOCHECK" ] && skip "Cannot find $CRYPTOCHECK, test skipped." echo "REQUIRED KDF TEST" test_kdf sha256 sha256 @@ -115,7 +123,13 @@ function test_required() ls $TST_DIR/[tv]c* >/dev/null 2>&1 || skip "No remaining images, test skipped." } -function valgrind_setup() +check_uuid() +{ + UUID=$(blkid -p -o value -s UUID /dev/mapper/$MAP) + [ "$UUID" != "$1" ] && fail "UUID check failed." +} + +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." @@ -125,7 +139,7 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } @@ -184,7 +198,6 @@ for file in $(ls $TST_DIR/[tv]ck_*) ; do echo " [OK]" done - if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run activation part of test, test skipped." remove_mapping @@ -192,23 +205,70 @@ if [ $(id -u) != 0 ]; then fi echo "ACTIVATION FS UUID CHECK" -for file in $(ls $TST_DIR/[tv]c_* $TST_DIR/vcpim_* $TST_DIR/sys_[tv]c_*) ; do +for file in $(ls $TST_DIR/[tv]c_* $TST_DIR/vcpim_*) ; do echo -n " $file" PIM_OPT="" [[ $file =~ vcpim.* ]] && PIM_OPT="--veracrypt-pim $PIM" - SYS_OPT="" - [[ $file =~ sys_.* ]] && SYS_OPT="--tcrypt-system" get_HASH_CIPHER $file - out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen $SYS_OPT $PIM_OPT -r -h $HASH -c $CIPHER $file $MAP 2>&1) + out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen $PIM_OPT -r -h $HASH -c $CIPHER $file $MAP 2>&1) ret=$? [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue [ $ret -ne 0 ] && fail $CRYPTSETUP status $MAP >/dev/null || fail $CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail - UUID=$(blkid -p -o value -s UUID /dev/mapper/$MAP) - $CRYPTSETUP remove $MAP || fail - [ "$UUID" != "DEAD-BABE" ] && fail "UUID check failed." + check_uuid DEAD-BABE + $CRYPTSETUP close $MAP || fail + echo " [OK]" +done + +echo "ACTIVATION SYSTEM FS UUID CHECK" +for file in $(ls $TST_DIR/sys_[tv]c_*) ; do + echo -n " $file" + LOOP_SYS=$(losetup -r -f --show -P $file) + if [ -z "$LOOP_SYS" ]; then + echo " [N/A]" + continue + fi + if [[ $file =~ _gpt_ ]]; then + LOOP_PART="$LOOP_SYS"p3 + else + LOOP_PART="$LOOP_SYS"p1 + fi + if [ ! -b "$LOOP_PART" ]; then + echo " [N/A]" + losetup -d $LOOP_SYS + LOOP_SYS="" + continue + fi + get_HASH_CIPHER $file + # map through partition name + echo -n " [PART]" + echo $PASSWORD | $CRYPTSETUP tcryptOpen --tcrypt-system -r -h $HASH -c $CIPHER $LOOP_PART $MAP || fail + check_uuid DEAD-BABE + $CRYPTSETUP close $MAP || fail + if [[ $file =~ _part ]]; then + # map through image only (TCRYPT hdr contains partition offset and size) + echo -n "[IMG]" + echo $PASSWORD | $CRYPTSETUP tcryptOpen --tcrypt-system -r -h $HASH -c $CIPHER $file $MAP 2>/dev/null || fail + check_uuid DEAD-BABE + $CRYPTSETUP close $MAP || fail + # map through full device (TCRYPT hdr contains partition offset and size) + echo -n "[DRIVE]" + echo $PASSWORD | $CRYPTSETUP tcryptOpen --tcrypt-system -r -h $HASH -c $CIPHER $LOOP_SYS $MAP || fail + check_uuid DEAD-BABE + $CRYPTSETUP close $MAP || fail + elif [[ $file =~ _full ]]; then + # map through image + header in real partition (whole system) + dd if=$LOOP_PART of=$PART_IMG bs=1M >/dev/null 2>&1 + echo -n "[PART+IMG]" + echo $PASSWORD | $CRYPTSETUP tcryptOpen --tcrypt-system -r -h $HASH -c $CIPHER --header $LOOP_PART $PART_IMG $MAP || fail + check_uuid DEAD-BABE + $CRYPTSETUP close $MAP || fail + rm $PART_IMG + fi + losetup -d $LOOP_SYS + LOOP_SYS="" echo " [OK]" done @@ -221,9 +281,8 @@ for file in $(ls $TST_DIR/[tv]c_*-hidden) ; do [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue [ $ret -ne 0 ] && fail - UUID=$(blkid -p -o value -s UUID /dev/mapper/$MAP) - $CRYPTSETUP remove $MAP || fail - [ "$UUID" != "CAFE-BABE" ] && fail "UUID check failed." + check_uuid CAFE-BABE + $CRYPTSETUP close $MAP || fail echo " [OK]" done diff --git a/tests/tcrypt-images.tar.xz b/tests/tcrypt-images.tar.xz index 5ccef088975b25433d5d40f46d4e4972194dba87..388c142663a75bd01391e411ea717ed94603a756 100644 GIT binary patch literal 351900 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

P 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

w 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%0AN0ohKrpnAgFA8)yf9N+F|8l=v^pyOr71HYkx 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¬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 literal 325760 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

sNltqdZ_uhg-RR>hnw5J9>yvw(~$!zbY$S;ffm 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

TmxYiB>WAk7>g(Kn7;y@6XT4K>wjJ=-kr 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�b0X0HQ0Fz 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 z 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

3r? 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

LH%|Cw99OS(NE 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 O2MYJE5GJkG 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 z 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 o{wqoG2v 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 @@ -17,11 +17,11 @@ #include #include #include -#ifdef KERNEL_KEYRING +#if KERNEL_KEYRING # include # include #endif -#ifdef HAVE_SYS_SYSMACROS_H +#if HAVE_SYS_SYSMACROS_H # include #endif #include @@ -41,7 +41,7 @@ struct loop_config { static char last_error[256]; static char global_log[4096]; -static uint32_t t_dm_crypt_flags = 0; +static uint64_t t_dm_crypt_flags = 0; char *THE_LOOP_DEV = NULL; int _debug = 0; @@ -486,7 +486,7 @@ int _system(const char *command, int warn) static int _keyring_check(void) { -#ifdef KERNEL_KEYRING +#if KERNEL_KEYRING return syscall(__NR_request_key, "logon", "dummy", NULL, 0) == -1l && errno != ENOSYS; #else return 0; @@ -555,6 +555,12 @@ static void t_dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj, if (t_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch)) t_dm_crypt_flags |= T_DM_CRYPT_NO_WORKQUEUE_SUPPORTED; + + if (t_dm_satisfies_version(1, 26, 0, crypt_maj, crypt_min, crypt_patch)) + t_dm_crypt_flags |= T_DM_CRYPT_HIGH_PRIORITY_SUPPORTED; + + if (t_dm_satisfies_version(1, 28, 0, crypt_maj, crypt_min, crypt_patch)) + t_dm_crypt_flags |= T_DM_CRYPT_INTEGRITY_KEY_SIZE_OPT_SUPPORTED; } static void t_dm_set_verity_compat(const char *dm_version __attribute__((unused)), @@ -585,6 +591,10 @@ static void t_dm_set_verity_compat(const char *dm_version __attribute__((unused) if (t_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch)) t_dm_crypt_flags |= T_DM_VERITY_TASKLETS_SUPPORTED; + + /* There is actually no correct version set, just use the last available */ + if (t_dm_satisfies_version(1, 10, 0, verity_maj, verity_min, verity_patch)) + t_dm_crypt_flags |= T_DM_VERITY_ERROR_AS_CORRUPTION_SUPPORTED; } static void t_dm_set_integrity_compat(const char *dm_version __attribute__((unused)), @@ -612,6 +622,9 @@ static void t_dm_set_integrity_compat(const char *dm_version __attribute__((unus if (t_dm_satisfies_version(1, 8, 0, integrity_maj, integrity_min, integrity_patch)) t_dm_crypt_flags |= T_DM_INTEGRITY_RESET_RECALC_SUPPORTED; + + if (t_dm_satisfies_version(1, 12, 0, integrity_maj, integrity_min, integrity_patch)) + t_dm_crypt_flags |= T_DM_INTEGRITY_INLINE_MODE_SUPPORTED; } int t_dm_check_versions(void) diff --git a/tests/unit-utils-crypt.c b/tests/unit-utils-crypt.c index bc17d6c..e2e9012 100644 --- a/tests/unit-utils-crypt.c +++ b/tests/unit-utils-crypt.c @@ -2,7 +2,7 @@ /* * cryptsetup crypto name and hex conversion helper test vectors * - * Copyright (C) 2022-2024 Milan Broz + * Copyright (C) 2022-2025 Milan Broz */ #include @@ -108,7 +108,7 @@ static int test_parse_integrity_mode(void) key_size = -1; memset(integrity, 0, sizeof(integrity)); if (integrity_test_vectors[i].int_mode && - (crypt_parse_integrity_mode(integrity_test_vectors[i].input, integrity, &key_size) < 0 || + (crypt_parse_integrity_mode(integrity_test_vectors[i].input, integrity, &key_size, 0) < 0 || strcmp(integrity_test_vectors[i].integrity, integrity) || integrity_test_vectors[i].key_size != key_size)) { printf("[FAILED (%s / %i)]\n", integrity, key_size); diff --git a/tests/unit-utils-io.c b/tests/unit-utils-io.c index 7390cc5..eaa7e8f 100644 --- a/tests/unit-utils-io.c +++ b/tests/unit-utils-io.c @@ -2,7 +2,7 @@ /* * simple unit test for utils_io.c (blockwise low level functions) * - * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved. */ #include diff --git a/tests/unit-wipe-test b/tests/unit-wipe-test index a898354..82b32ed 100755 --- a/tests/unit-wipe-test +++ b/tests/unit-wipe-test @@ -9,13 +9,13 @@ DEVSIZE=$((DEVSIZEMB*$MB_BYTES)) HASH_EMPTY=2daeb1f36095b44b318410b3f4e8b5d989dcc7bb023d1426c492dab0a3053e74 -function cleanup() { +cleanup() { rm -f $FILE $FILE_RAND 2> /dev/null sleep 1 rmmod scsi_debug >/dev/null 2>&1 } -function fail() +fail() { if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi echo "FAILED backtrace:" @@ -24,14 +24,17 @@ function fail() exit 100 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { echo "TEST SKIPPED: $1" cleanup exit 77 } -function add_device() +add_device() { rmmod scsi_debug >/dev/null 2>&1 if [ -d /sys/module/scsi_debug ] ; then @@ -47,13 +50,13 @@ function add_device() [ -b $DEV ] || fail "Cannot find $DEV." } -function check_hash() # $1 dev, $2 hash +check_hash() # $1 dev, $2 hash { local HASH=$(sha256sum $1 | cut -d' ' -f 1) [ $HASH == "$2" ] } -function init_hash_dd() # $1 dev, $dev orig +init_hash_dd() # $1 dev, $dev orig { dd if=/dev/urandom of=$2 bs=1M count=$DEVSIZEMB conv=notrunc 2> /dev/null dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null @@ -67,7 +70,7 @@ function init_hash_dd() # $1 dev, $dev orig dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null } -function add_file() +add_file() { dd if=/dev/zero of=$FILE bs=1M count=$DEVSIZEMB 2> /dev/null || fail dd if=/dev/zero of=$FILE_RAND bs=1M count=$DEVSIZEMB 2> /dev/null || fail @@ -76,7 +79,7 @@ function add_file() dd if=$FILE of=/dev/null bs=4096 count=1 iflag=direct >/dev/null 2>&1 || FILE_NODIO=1 } -function test_wipe_full() # $1 dev, $2 block size, [$3 flags] +test_wipe_full() # $1 dev, $2 block size, [$3 flags] { # wipe random and back to zero $WIPE_UNIT $1 random 0 $DEVSIZE $2 $3 || fail @@ -86,7 +89,7 @@ function test_wipe_full() # $1 dev, $2 block size, [$3 flags] } # wipe MB blocks, with zero, random and special and back to original -function test_wipe_blocks() # $1 dev $2 block sizem [$3 flags] +test_wipe_blocks() # $1 dev $2 block sizem [$3 flags] { init_hash_dd $1 $FILE_RAND check_hash $1 $HASH_0 || fail diff --git a/tests/unit-wipe.c b/tests/unit-wipe.c index c246664..cd0fd37 100644 --- a/tests/unit-wipe.c +++ b/tests/unit-wipe.c @@ -2,7 +2,7 @@ /* * unit test helper for crypt_wipe API call * - * Copyright (C) 2022-2024 Milan Broz + * Copyright (C) 2022-2025 Milan Broz */ #include diff --git a/tests/verity-compat-test b/tests/verity-compat-test index d16dbb3..2856e90 100755 --- a/tests/verity-compat-test +++ b/tests/verity-compat-test @@ -21,7 +21,7 @@ FEC_DEV=tst_fec123 DEV_SALT=9e7457222290f1bac0d42ad2de2d602a87bb871c22ab70ca040bad450578a436 DEV_UUID=a60c98d2-ae9b-4865-bfcb-b4e3ace11033 -function remove_mapping() +remove_mapping() { [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 >/dev/null 2>&1 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME >/dev/null 2>&1 @@ -31,7 +31,7 @@ function remove_mapping() LOOPDEV2="" } -function fail() +fail() { [ -n "$1" ] && echo "$1" echo "FAILED backtrace:" @@ -41,13 +41,16 @@ function fail() exit 2 } -function skip() +_sigchld() { local c=$?; [ $c -eq 139 ] && fail "Segfault"; [ $c -eq 134 ] && fail "Aborted"; } +trap _sigchld CHLD + +skip() { [ -n "$1" ] && echo "$1" exit 77 } -function prepare() # $1 dev1_siz [$2 dev2_size] +prepare() # $1 dev1_siz [$2 dev2_size] { remove_mapping @@ -60,18 +63,18 @@ function prepare() # $1 dev1_siz [$2 dev2_size] LOOPDEV2=$IMG_HASH } -function wipe() +wipe() { dd if=/dev/zero of=$LOOPDEV1 bs=256k >/dev/null 2>&1 rm -f $IMG_HASH $DEV_OUT >/dev/null 2>&1 } -function check_exists() +check_exists() { [ -b /dev/mapper/$DEV_NAME ] || fail } -function check_version() # MAJ MIN +check_version() # MAJ MIN { VER_STR=$(dmsetup targets | grep verity | cut -f 3 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-verity version." @@ -80,18 +83,34 @@ function check_version() # MAJ MIN VER_MIN=$(echo $VER_STR | cut -f 2 -d.) test $VER_MAJ -gt $1 && return 0 + test $VER_MAJ -lt $1 && return 1 test $VER_MIN -ge $2 && return 0 + + return 1 +} + +check_version_kernel() +{ + KER_STR=$(uname -r) + [ -z "$KER_STR" ] && fail "Failed to parse kernel version." + KER_MAJ=$(echo $KER_STR | cut -f 1 -d.) + KER_MIN=$(echo $KER_STR | cut -f 2 -d.) + + test $KER_MAJ -gt $1 && return 0 + test $KER_MAJ -lt $1 && return 1 + test $KER_MIN -ge $2 && return 0 + return 1 } -function compare_out() # $1 what, $2 expected +compare_out() # $1 what, $2 expected { OPT=$(grep -v "^#" $DEV_OUT | grep -i "$1" | sed -e s/.*\:\ // ) [ -z "$OPT" ] && fail [ $OPT != $2 ] && fail "$1 differs ($2)" } -function check_root_hash_fail() +check_root_hash_fail() { echo -n "Root hash check " ROOT_HASH=$($VERITYSETUP format $IMG $IMG_HASH --fec-device $FEC_DEV --fec-roots 2 -h sha256 | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ") @@ -116,7 +135,7 @@ function check_root_hash_fail() echo "[OK]" } -function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 offset] +check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 offset] { local FORMAT_PARAMS local VERIFY_PARAMS @@ -206,7 +225,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 done } -function corrupt_device() # $1 device, $2 device_size(in bytes), $3 #{corrupted_bytes} +corrupt_device() # $1 device, $2 device_size(in bytes), $3 #{corrupted_bytes} { # Repeatable magic corruption :-) CORRUPT=$3 @@ -222,7 +241,7 @@ function corrupt_device() # $1 device, $2 device_size(in bytes), $3 #{corrupted_ # $1 data_device, $2 hash_device, $3 fec_device, $4 data/hash_block_size(in bytes), # $5 data_size(in blocks), $6 device_size(in blocks), $7 hash_offset(in bytes), # $8 fec_offset(in bytes), $9 fec_roots, ${10} corrupted_bytes, [${11} superblock(y/n), ${12} salt] -function check_fec() +check_fec() { INDEX=25 dd if=/dev/zero of=$1 bs=$4 count=$6 > /dev/null 2>&1 @@ -290,22 +309,22 @@ function check_fec() return $RET } -function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI option, $7 status option +check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 status option, $7-$8 CLI options { DEV_PARAMS="$LOOPDEV1 $LOOPDEV2" FORMAT_PARAMS="--format=$4 --data-block-size=$1 --hash-block-size=$1 --hash=$5 --salt=$3" - echo -n "Option $6 " + echo -n "Option $7 / $6 " $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >/dev/null 2>&1 || fail - $VERITYSETUP create $DEV_NAME $DEV_PARAMS $2 $6 >/dev/null 2>&1 || fail + $VERITYSETUP create $DEV_NAME $DEV_PARAMS $2 $7 $8 >/dev/null 2>&1 || fail check_exists - $VERITYSETUP status $DEV_NAME 2>/dev/null | grep flags | grep -q $7 || fail - dmsetup table $DEV_NAME 2>/dev/null | grep -q $7 || fail + $VERITYSETUP status $DEV_NAME 2>/dev/null | grep flags | grep -q $6 || fail + dmsetup table $DEV_NAME 2>/dev/null | grep -q $6 || fail $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail echo "[OK]" } -function valgrind_setup() +valgrind_setup() { command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $VERITYSETUP_VALGRIND ] && fail "Unable to get location of veritysetup executable." @@ -315,12 +334,12 @@ function valgrind_setup() fi } -function valgrind_run() +valgrind_run() { INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${VERITYSETUP_VALGRIND} "$@" } -function checkOffsetBug() # $1 size, $2 hash-offset, $3 data-blocks +checkOffsetBug() # $1 size, $2 hash-offset, $3 data-blocks { echo -n "Size :: $1 B | Hash-offset :: $2 blocks | Data-blocks :: $3 " dd if=/dev/zero of=$IMG bs=1 count=0 seek=$1 >/dev/null 2>&1 @@ -329,7 +348,7 @@ function checkOffsetBug() # $1 size, $2 hash-offset, $3 data-blocks remove_mapping } -function checkOverlapBug() # $1 size, $2 hash-offset, $3 data-blocks, $4 block_size, $5 fec_offset +checkOverlapBug() # $1 size, $2 hash-offset, $3 data-blocks, $4 block_size, $5 fec_offset { echo -n "Device-size :: $1 B | " [ $# -ge 3 ] && echo -n "Data-blocks :: $3 blocks| " @@ -372,7 +391,7 @@ function checkOverlapBug() # $1 size, $2 hash-offset, $3 data-blocks, $4 block_s # $1 size, $2 block size, $3 roots, $4 hash offset, $5 fec offset, # $6 one dev(1 - one device, 2 - one device for data and hash, one device for fec data, 3 - three separate devices), # $7 #{corrupted bytes} -function checkUserSpaceRepair() +checkUserSpaceRepair() { BS=512 COUNT=50000 @@ -404,7 +423,7 @@ function checkUserSpaceRepair() echo "[OK]" } -function check_concurrent() # $1 hash +check_concurrent() # $1 hash { DEV_PARAMS="$LOOPDEV1 $LOOPDEV2" @@ -424,6 +443,8 @@ function check_concurrent() # $1 hash wait grep -q "Command failed with code .* (wrong or missing parameters)" $DEV_OUT && fail grep -q "Command failed with code .* (wrong device or file specified)." $DEV_OUT && fail + # Some distros have strange udev rules, settle here seems to be necessary + udevadm settle >/dev/null 2>&1 check_exists rm $DEV_OUT $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail @@ -476,20 +497,24 @@ if check_version 1 3; then SALT=e48da609055204e89ae53b655ca2216dd983cf3cb829f34f63a297d106d53e2d HASH=9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 prepare 8192 1024 - check_option 512 $HASH $SALT 1 sha256 "--ignore-corruption" "ignore_corruption" - check_option 512 $HASH $SALT 1 sha256 "--restart-on-corruption" "restart_on_corruption" - check_option 512 $HASH $SALT 1 sha256 "--ignore-zero-blocks" "ignore_zero_blocks" - check_option 512 $HASH $SALT 1 sha256 "--ignore-corruption --ignore-zero-blocks" "ignore_corruption" + check_option 512 $HASH $SALT 1 sha256 ignore_corruption --ignore-corruption + check_option 512 $HASH $SALT 1 sha256 restart_on_corruption --restart-on-corruption + check_option 512 $HASH $SALT 1 sha256 ignore_zero_blocks --ignore-zero-blocks + check_option 512 $HASH $SALT 1 sha256 ignore_corruption --ignore-corruption --ignore-zero-blocks if check_version 1 4; then - check_option 512 $HASH $SALT 1 sha256 "--check-at-most-once" "check_at_most_once" + check_option 512 $HASH $SALT 1 sha256 check_at_most_once --check-at-most-once fi if check_version 1 7; then - check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption" + check_option 512 $HASH $SALT 1 sha256 panic_on_corruption --panic-on-corruption + fi + if check_version_kernel 6 12; then # dm-verity 1.10+ but they forget bump version + check_option 512 $HASH $SALT 1 sha256 panic_on_error --error-as-corruption --panic-on-corruption + check_option 512 $HASH $SALT 1 sha256 restart_on_error --error-as-corruption --restart-on-corruption fi if check_version 1 9; then echo "Verity data performance options test." - check_option 512 $HASH $SALT 1 sha256 "--use-tasklets" "try_verify_in_tasklet" + check_option 512 $HASH $SALT 1 sha256 try_verify_in_tasklet --use-tasklets fi fi @@ -564,5 +589,14 @@ else echo "[N/A]" fi +echo -n "Early check for active name:" +prepare 8192 1024 +DM_BAD_NAME=x/x +DM_LONG_NAME=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef +$VERITYSETUP format $LOOPDEV1 $IMG_HASH --format=1 --data-block-size=512 --hash-block-size=512 --hash=sha256 --salt=$SALT >/dev/null 2>&1 || fail "Cannot format device." +$VERITYSETUP open $LOOPDEV1 $DM_BAD_NAME $DEV $IMG_HASH 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 2>/dev/null && fail +$VERITYSETUP open $LOOPDEV1 $DM_LONG_NAME $DEV $IMG_HASH 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 2>/dev/null && fail +echo "[OK]" + remove_mapping exit 0 diff --git a/tokens/ssh/cryptsetup-ssh.c b/tokens/ssh/cryptsetup-ssh.c index eb68ba6..dfb561d 100644 --- a/tokens/ssh/cryptsetup-ssh.c +++ b/tokens/ssh/cryptsetup-ssh.c @@ -2,8 +2,8 @@ /* * Example of LUKS2 token storing third party metadata (EXPERIMENTAL EXAMPLE) * - * Copyright (C) 2016-2024 Milan Broz - * Copyright (C) 2021-2024 Vojtech Trefny + * Copyright (C) 2016-2025 Milan Broz + * Copyright (C) 2021-2025 Vojtech Trefny * * Use: * - generate ssh example token diff --git a/tokens/ssh/libcryptsetup-token-ssh.c b/tokens/ssh/libcryptsetup-token-ssh.c index 2b9ee0b..cb13e77 100644 --- a/tokens/ssh/libcryptsetup-token-ssh.c +++ b/tokens/ssh/libcryptsetup-token-ssh.c @@ -2,8 +2,8 @@ /* * Example of LUKS2 ssh token handler (EXPERIMENTAL) * - * Copyright (C) 2016-2024 Milan Broz - * Copyright (C) 2020-2024 Vojtech Trefny + * Copyright (C) 2016-2025 Milan Broz + * Copyright (C) 2020-2025 Vojtech Trefny * * Use: * - generate LUKS device diff --git a/tokens/ssh/meson.build b/tokens/ssh/meson.build index dba1d76..a090666 100644 --- a/tokens/ssh/meson.build +++ b/tokens/ssh/meson.build @@ -12,6 +12,8 @@ if get_option('ssh-token') jsonc, libssh, ], + install: true, + install_dir: luks2_external_tokens_path, link_with: libcryptsetup, link_args: token_link_args, include_directories: includes_tools + ['..']) @@ -34,6 +36,8 @@ if get_option('ssh-token') popt, pwquality, ], + install: true, + install_dir: get_option('sbindir'), link_with: libcryptsetup, include_directories: includes_tools + ['..']) endif diff --git a/tokens/ssh/ssh-utils.c b/tokens/ssh/ssh-utils.c index df75e04..5005e52 100644 --- a/tokens/ssh/ssh-utils.c +++ b/tokens/ssh/ssh-utils.c @@ -2,8 +2,8 @@ /* * ssh plugin utilities * - * Copyright (C) 2016-2024 Milan Broz - * Copyright (C) 2020-2024 Vojtech Trefny + * Copyright (C) 2016-2025 Milan Broz + * Copyright (C) 2020-2025 Vojtech Trefny */ #include diff --git a/tokens/ssh/ssh-utils.h b/tokens/ssh/ssh-utils.h index 2a7eb37..6c0a5e0 100644 --- a/tokens/ssh/ssh-utils.h +++ b/tokens/ssh/ssh-utils.h @@ -2,8 +2,8 @@ /* * ssh plugin utilities * - * Copyright (C) 2016-2024 Milan Broz - * Copyright (C) 2020-2024 Vojtech Trefny + * Copyright (C) 2016-2025 Milan Broz + * Copyright (C) 2020-2025 Vojtech Trefny */ #ifndef SSH_UTILS_H