Compare commits

..

35 Commits

Author SHA1 Message Date
Milan Broz
c67861e875 Update README. 2022-01-13 10:24:00 +01:00
Milan Broz
f566d7c911 Fix reencrypt mangle test for older jq. 2022-01-13 10:09:54 +01:00
Milan Broz
f21b07fb1b Version 2.4.3. 2022-01-12 18:42:14 +01:00
Milan Broz
904cdd1161 Add Release Notes. 2022-01-12 18:42:10 +01:00
Milan Broz
5d75632a16 Update LUKS2 on-disk description. 2022-01-12 18:42:06 +01:00
Ondrej Kozina
da8bcf7270 Allow reencryption metadata repair from cryptsetup. 2022-01-12 18:42:02 +01:00
Ondrej Kozina
bbc3ff69db Add CRYPT_REENCRYPT_REPAIR_NEEDED flag.
crypt_reencrypt_status() returns this flag if old
online-reencrypt requirement is detected and reencryption
keyslot digest is missing.

crypt_reencrypt_init_by_passphrase() with same flag applied
repairs (upgrade) reencryption metadata so that
automatic reencryption recovery during activation
is again possible and reencryption operation can be resumed
post CVE-2021-4122 fix.
2022-01-12 18:41:58 +01:00
Milan Broz
7ef0d9c73a Add reencryption mangle test 2022-01-12 18:41:55 +01:00
Ondrej Kozina
8ced413876 Make reencryption flag and keyslot inseparable.
LUKS2 validation code now requires reencrypt keyslot together with
online-reencryption flag or none of those.
2022-01-12 18:41:50 +01:00
Ondrej Kozina
80a77bce2a Rename LUKS2_keyslot_reencrypt_create function.
The function never writes on-disk. Also removed validation
function call-in since it will be called later before
writing on-disk and metadata does not have to be complete
at the moment of LUKS2_keyslot_reencrypt_allocate call.
2022-01-12 18:41:46 +01:00
Ondrej Kozina
334606b6aa Add segments validation for reencryption.
Effective segments during LUKS2 reencryption must
match key characteristics of backup segment
(cipher, sector_size, segment type).
2022-01-12 18:41:39 +01:00
Ondrej Kozina
1162f1e1e3 Split requirements validation from config section validation. 2022-01-12 14:49:11 +01:00
Ondrej Kozina
47a1d9a6d6 Expose json_segment_contains_flag to internal library. 2022-01-12 14:49:11 +01:00
Ondrej Kozina
c257ae1eb4 Move requirement helpers for later changes. 2022-01-12 14:49:11 +01:00
Milan Broz
d37c3f0db2 Add disable-luks2 reencryption configure option.
The option --disable-luks2-reencryption completely disable
LUKS2 reencryption code.

When used, the libcryptsetup library can read metadata with
reencryption code, but all reencryption API calls and cryptsetup
reencrypt commands are disabled.

Devices with online reencryption in progress cannot be activated.

This option can cause some incompatibilities. Please use with care.
2022-01-12 14:49:11 +01:00
Milan Broz
4a974ec582 Print better error if resilience hash is not available. 2022-01-12 14:49:11 +01:00
Milan Broz
c95a88f815 Do not run reencryption recovery when not needed. 2022-01-12 14:49:11 +01:00
Milan Broz
4af4a4a631 Reenc keyslot must have key_size == 1. 2022-01-12 14:49:11 +01:00
Milan Broz
3d269a5ae3 Fix debug message. 2022-01-12 14:49:11 +01:00
Ondrej Kozina
de98f01141 Fix CVE-2021-4122 - LUKS2 reencryption crash recovery attack
Fix possible attacks against data confidentiality through LUKS2 online
reencryption extension crash recovery.

An attacker can modify on-disk metadata to simulate decryption in
progress with crashed (unfinished) reencryption step and persistently
decrypt part of the LUKS device.

This attack requires repeated physical access to the LUKS device but
no knowledge of user passphrases.

The decryption step is performed after a valid user activates
the device with a correct passphrase and modified metadata.
There are no visible warnings for the user that such recovery happened
(except using the luksDump command). The attack can also be reversed
afterward (simulating crashed encryption from a plaintext) with
possible modification of revealed plaintext.

The problem was caused by reusing a mechanism designed for actual
reencryption operation without reassessing the security impact for new
encryption and decryption operations. While the reencryption requires
calculating and verifying both key digests, no digest was needed to
initiate decryption recovery if the destination is plaintext (no
encryption key). Also, some metadata (like encryption cipher) is not
protected, and an attacker could change it. Note that LUKS2 protects
visible metadata only when a random change occurs. It does not protect
against intentional modification but such modification must not cause
a violation of data confidentiality.

The fix introduces additional digest protection of reencryption
metadata. The digest is calculated from known keys and critical
reencryption metadata. Now an attacker cannot create correct metadata
digest without knowledge of a passphrase for used keyslots.
For more details, see LUKS2 On-Disk Format Specification version 1.1.0.
2022-01-12 14:49:11 +01:00
Vojtech Trefny
4d28153e53 bitlk: Fix support for startup key with new metadata entry
Windows 11 now includes the BitLocker volume GUID in the BEK file
metadata entries. This was previously not included so cryptsetup
refused to open the file because there was an unknown metadata
entry in the startup key.

Fixes: #690
2022-01-10 21:29:50 +01:00
Ondrej Kozina
dd864f5a61 Remove LUKS2 encryption data size restriction.
LUKS2 encryption with data shift required remaining
data size (size remaining after substracting --reduce-data-size value)
to be at least --reduce-data-size. This was wrong. Remaining
data size restriction should be correctly at least single sector
(whatever sector size is selected or auto-detected).
2022-01-10 21:29:32 +01:00
Josef Andersson
ca54398eec po: update sv.po (from translationproject.org) 2022-01-10 21:26:04 +01:00
Мирослав Николић
97cd16b8b9 po: update sr.po (from translationproject.org) 2022-01-10 21:25:55 +01:00
Antonio Ceballos
86d0d4f68e po: update es.po (from translationproject.org) 2022-01-10 21:25:44 +01:00
Tianjia Zhang
1a7d98b3ba Fix manual typo. 2022-01-10 21:25:30 +01:00
Sean
025a96df73 Update README.md 2022-01-10 21:25:17 +01:00
Milan Broz
e6edbc1fe5 Run CI on stable branches.
The stable branch is named "v2.<minor>.x".
2021-12-01 22:50:37 +01:00
Milan Broz
ed68b51526 Do not mix tabs and spaces in GitHub CI script. 2021-12-01 22:50:37 +01:00
Milan Broz
bcace16aa2 Do not mix tabs and spaces in Gitlab CI script. 2021-12-01 22:50:37 +01:00
Milan Broz
97aa31d32f Fix tabs in GitLab CI scripts and remove gcc comment.
The -Wall changes according to gcc versions.
2021-12-01 22:50:37 +01:00
Milan Broz
36a78ed17b Fix missing backslash in CI. 2021-12-01 22:50:37 +01:00
Milan Broz
0d4ecd92f1 Add limitation to cryptsetup group again in CI. 2021-12-01 22:50:37 +01:00
daniel.zatovic
94143c3428 Remove LLVM repo script 2021-12-01 22:50:37 +01:00
Daniel Zaťovič
af17d2256d Add compilation tests and static analysis on the Gitlab shared runner. 2021-12-01 22:50:37 +01:00
471 changed files with 35793 additions and 87637 deletions

View File

@@ -1,31 +0,0 @@
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

View File

@@ -4,10 +4,9 @@ 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-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client
sshpass asciidoctor meson ninja-build
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
)
COMPILER="${COMPILER:?}"

View File

@@ -2,9 +2,9 @@ name: Build test
on:
push:
branches:
- 'main'
- 'master'
- 'wip-luks2'
- 'v2.*.x'
- 'v2.3.x'
paths-ignore:
- 'docs/**'
@@ -16,11 +16,11 @@ jobs:
fail-fast: false
matrix:
env:
- { COMPILER: "gcc", COMPILER_VERSION: "14", RUN_SSH_PLUGIN_TEST: "1" }
- { COMPILER: "gcc", COMPILER_VERSION: "11", RUN_SSH_PLUGIN_TEST: "1" }
env: ${{ matrix.env }}
steps:
- name: Repository checkout
uses: actions/checkout@v4
uses: actions/checkout@v1
- name: Ubuntu setup
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
- name: Configure & Make

View File

@@ -1,53 +0,0 @@
name: "CodeQL"
on:
push:
branches:
- 'main'
- 'wip-luks2'
- 'v2.*.x'
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
if: github.repository == 'mbroz/cryptsetup'
concurrency:
group: ${{ github.workflow }}-${{ matrix.language }}-${{ github.ref }}
cancel-in-progress: true
permissions:
actions: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-extended,security-and-quality
config-file: .codeql-config.yml
- name: Install dependencies
run: |
sudo -E .github/workflows/cibuild-setup-ubuntu.sh
# Force autoconf for now, meson is broken in analysis step
rm meson.build
env: { COMPILER: "gcc", COMPILER_VERSION: "14", RUN_SSH_PLUGIN_TEST: "1" }
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

View File

@@ -12,12 +12,12 @@ jobs:
if: github.repository == 'mbroz/cryptsetup'
steps:
- name: Repository checkout
uses: actions/checkout@v4
uses: actions/checkout@v1
- name: Ubuntu setup
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
env:
COMPILER: "gcc"
COMPILER_VERSION: "14"
COMPILER_VERSION: "11"
- name: Install Coverity
run: |
wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=mbroz/cryptsetup" -O cov-analysis-linux64.tar.gz

6
.gitignore vendored
View File

@@ -6,8 +6,6 @@ Makefile.in.in
*.lo
*.la
*.o
*.so
*.8
**/*.dirstamp
.deps/
.libs/
@@ -17,7 +15,6 @@ ABOUT-NLS
aclocal.m4
autom4te.cache/
compile
compile_commands.json
config.guess
config.h
config.h.in
@@ -57,6 +54,3 @@ tests/luks1-images
tests/tcrypt-images
tests/unit-utils-io
tests/vectors-test
tests/test-symbols-list.h
tests/all-symbols-test
tests/fuzz/LUKS2.pb*

View File

@@ -1,23 +1,113 @@
stages:
- test
- test-opal
.fail_if_coredump_generated:
after_script:
- '[ "$(ls -A /var/coredumps)" ] && exit 1 || true'
.debian-prep:
before_script:
- sudo apt-get -y update --fix-missing
- >
sudo apt-get -y install -y -qq git gcc make
autoconf automake autopoint pkg-config libtool libtool-bin gettext
libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev
libpwquality-dev sharutils dmsetup jq xxd expect keyutils
netcat passwd openssh-client sshpass
- sudo apt-get -y build-dep cryptsetup
- sudo -E git clean -xdf
- ./autogen.sh
- ./configure --enable-libargon2
.dnf-openssl-backend:
before_script:
- >
sudo dnf -y -q install
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
libargon2-devel libblkid-devel libpwquality-devel libselinux-devel
libssh-devel libtool libuuid-devel make popt-devel
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
- sudo -E git clean -xdf
- ./autogen.sh
- ./configure --enable-fips --enable-pwquality --enable-libargon2 --with-crypto_backend=openssl
# Merge request: Build and run only non-root tests
test-mergerq-job-debian-noroot:
extends:
- .debian-prep
tags:
- libvirt
- debian10
stage: test
interruptible: true
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
- make check
# For main branch commit, run all tests as root
test-main-commit-job-debian:
extends:
- .debian-prep
tags:
- libvirt
- debian10
stage: test
interruptible: 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$/
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
- sudo -E make clean
test-main-commit-job-dnf:
extends:
- .dnf-openssl-backend
tags:
- libvirt
- fedora-rawhide
stage: test
interruptible: 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$/
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-mergerq-job-dnf:
extends:
- .dnf-openssl-backend
tags:
- libvirt
- fedora-rawhide
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_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
include:
- local: .gitlab/ci/debian.yml
- local: .gitlab/ci/fedora.yml
- local: .gitlab/ci/fedora-opal.yml
- local: .gitlab/ci/centos.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/debian-i686.yml
- local: .gitlab/ci/cifuzz.yml

View File

@@ -1,57 +0,0 @@
.alpinelinux-dependencies:
variables:
DISTRO: cryptsetup-alpine-edge
extends:
- .fail_if_coredump_generated
before_script:
- >
sudo apk add
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
test-main-commit-job-alpinelinux:
extends:
- .alpinelinux-dependencies
tags:
- libvirt
- cryptsetup-alpine-edge
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "0"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-mergerq-job-alpinelinux:
extends:
- .alpinelinux-dependencies
tags:
- libvirt
- cryptsetup-alpine-edge
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "0"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check

View File

@@ -1,18 +0,0 @@
test-main-commit-job-annocheck:
extends:
- .fail_if_coredump_generated
tags:
- libvirt
- 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:
- sudo /opt/run-annocheck.sh

View File

@@ -1,32 +0,0 @@
#!/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

View File

@@ -1,111 +0,0 @@
.centos-openssl-backend:
extends:
- .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 swtpm swtpm-tools
tpm2-tools
- 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-centos-stream9:
extends:
- .centos-openssl-backend
tags:
- libvirt
- 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_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-stream9:
extends:
- .centos-openssl-backend
tags:
- libvirt
- 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
- 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

View File

@@ -4,21 +4,17 @@ 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-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client
sshpass asciidoctor
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
)
COMPILER="${COMPILER:?}"
COMPILER_VERSION="${COMPILER_VERSION:?}"
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
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
@@ -31,7 +27,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 -n "deb http://apt.llvm.org/${RELEASE}/ llvm-toolchain-${RELEASE}-${COMPILER_VERSION} main"
add-apt-repository "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)
@@ -40,8 +36,14 @@ else
exit 1
fi
#apt-get -y update --fix-missing
(r=3;while ! apt-get -y update --fix-missing ; do ((--r))||exit;sleep 5;echo "Retrying";done)
apt-get -y update --fix-missing
DEBIAN_FRONTEND=noninteractive apt-get -yq install "${PACKAGES[@]}"
apt-get -y build-dep cryptsetup
echo "====================== VERSIONS ==================="
if [[ $COMPILER == "clang" ]]; then
scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --help
fi
${COMPILER}-$COMPILER_VERSION -v
echo "====================== END VERSIONS ==================="

View File

@@ -1,46 +0,0 @@
cifuzz:
variables:
OSS_FUZZ_PROJECT_NAME: cryptsetup
CFL_PLATFORM: gitlab
CIFUZZ_DEBUG: "True"
FUZZ_SECONDS: 300 # 5 minutes per fuzzer
ARCHITECTURE: "x86_64"
DRY_RUN: "False"
LOW_DISK_SPACE: "True"
BAD_BUILD_CHECK: "True"
LANGUAGE: "c"
DOCKER_HOST: "tcp://docker:2375"
DOCKER_IN_DOCKER: "true"
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
image:
name: gcr.io/oss-fuzz-base/cifuzz-base
entrypoint: [""]
services:
- docker:dind
stage: test
parallel:
matrix:
- SANITIZER: [address, undefined, memory]
rules:
# Default code change.
# - if: $CI_PIPELINE_SOURCE == "merge_request_event"
# variables:
# MODE: "code-change"
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $BUILD_AND_RUN_FUZZERS != null
before_script:
# Get gitlab's container id.
- export CFL_CONTAINER_ID=`cut -c9- < /proc/1/cpuset`
script:
# Will build and run the fuzzers.
# We use a hack to override CI_JOB_ID, because otherwise a bad path is used
# in GitLab CI environment
- CI_JOB_ID="$CI_PROJECT_NAMESPACE/$CI_PROJECT_TITLE" python3 "/opt/oss-fuzz/infra/cifuzz/cifuzz_combined_entrypoint.py"
artifacts:
# Upload artifacts when a crash makes the job fail.
when: always
paths:
- artifacts/

View File

@@ -15,19 +15,19 @@ CLANG="clang${COMPILER_VERSION:+-$COMPILER_VERSION}"
#PEDANTIC="-pedantic -std=gnu99 -Wno-variadic-macros"
#CONVERSION="-Wconversion"
EXTRA="\
-Wextra \
EXTRA="-Wextra \
-Wsign-compare \
-Wcast-align
-Werror-implicit-function-declaration \
-Wpointer-arith \
-Wwrite-strings \
-Wswitch \
-Wmissing-format-attribute \
-Winit-self \
-Wdeclaration-after-statement \
-Wold-style-definition \
-Wno-missing-field-initializers \
-Wunused-parameter \
-Wno-unused-parameter \
-Wno-attributes \
-Wno-long-long"
exec $CLANG $PEDANTIC $CONVERSION \
@@ -43,6 +43,13 @@ exec $CLANG $PEDANTIC $CONVERSION \
-Wnested-externs \
-Wcomment \
-Winline \
-Wcast-align \
-Wcast-qual \
-Wredundant-decls $EXTRA \
"$@"
"$@" 2>&1 | {
if [[ $USE_FILTER -eq 1 ]]; then
.gitlab/ci/warnings_filter.py
else
cat
fi
}

View File

@@ -3,86 +3,23 @@ test-clang-compilation:
- .gitlab-shared-clang
script:
- export CFLAGS="-Wall -Werror"
- ./autogen.sh
- $CC --version
- ./configure
- ./configure --enable-pwquality --enable-libargon2
- make -j
- make -j check-programs
test-clang-Wall-script-ubuntu:
# Clang doesn't support json output, so we cannot use the warnings filter
# test-clang-Wall-script:
# extends:
# - .gitlab-shared-clang
# script:
# - export CFLAGS="-g -O0"
# - export CC=".gitlab/ci/clang-Wall"
# - ./configure --enable-pwquality --enable-libargon2
# - make -j CFLAGS="-g -O0 -Werror"
test-scan-build:
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-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"
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0" --enable-internal-sse-argon2 --enable-pwquality --enable-libargon2
- 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
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -maxloop 10 make -j

View File

@@ -3,83 +3,22 @@ test-gcc-compilation:
- .gitlab-shared-gcc
script:
- export CFLAGS="-Wall -Werror"
- ./autogen.sh
- $CC --version
- ./configure
- ./configure --enable-pwquality --enable-libargon2
- make -j
- make -j check-programs
test-gcc-Wall-script-ubuntu:
test-gcc-Wall-script:
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
- export CC=".gitlab/ci/gcc-Wall"
- USE_FILTER=0 ./configure --enable-pwquality --enable-libargon2
- USE_FILTER=1 make -j CFLAGS="-g -O0 -fdiagnostics-format=json"
test-gcc-Wall-script-alpine:
extends:
- .gitlab-shared-gcc-alpine
allow_failure: true
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-ubuntu:
test-gcc-fanalyzer:
extends:
- .gitlab-shared-gcc
script:
- ./autogen.sh
- $CC --version
- ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" --host=x86_64
- export CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events"
- ./configure --enable-pwquality --enable-libargon2
- 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

View File

@@ -1,20 +0,0 @@
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

View File

@@ -1,33 +0,0 @@
test-gcc-disable-compiles:
extends:
- .gitlab-shared-gcc
parallel:
matrix:
- DISABLE_FLAGS: [
"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"
- ./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

View File

@@ -1,36 +0,0 @@
.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:
- .dnf-csmock
tags:
- libvirt
- cryptsetup-fedora-rawhide
stage: test
interruptible: true
allow_failure: true
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:
- .gitlab/ci/build_srpm
- .gitlab/ci/run_csmock
artifacts:
when: always
paths:
- cryptsetup-csmock-results.tar.xz

View File

@@ -1,43 +0,0 @@
test-mergerq-job-debian-i686:
extends:
- .debian-prep
tags:
- libvirt
- cryptsetup-debian-12i686
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12i686
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-main-commit-job-debian-i686:
extends:
- .debian-prep
tags:
- libvirt
- cryptsetup-debian-12i686
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12i686
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

View File

@@ -1,104 +0,0 @@
.debian-prep:
extends:
- .fail_if_coredump_generated
before_script:
- 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-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
- ./configure --enable-libargon2 --enable-asciidoc
test-mergerq-job-debian:
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-debian:
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:
- 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-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-debian-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

View File

@@ -1,145 +0,0 @@
.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"

View File

@@ -1,63 +0,0 @@
.dnf-openssl-backend:
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 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
test-main-commit-job-rawhide:
extends:
- .dnf-openssl-backend
tags:
- libvirt
- 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
- 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-rawhide:
extends:
- .dnf-openssl-backend
tags:
- libvirt
- 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
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check

View File

@@ -16,8 +16,6 @@ GCC="gcc${COMPILER_VERSION:+-$COMPILER_VERSION}"
#CONVERSION="-Wconversion"
# -Wpacked \
# This does more than expected for gcc (mixed code with declarations)
# -Wdeclaration-after-statement \
EXTRA="-Wextra \
-Wsign-compare \
@@ -29,15 +27,14 @@ EXTRA="-Wextra \
-Wstrict-aliasing=3 \
-Winit-self \
-Wunsafe-loop-optimizations \
-Wdeclaration-after-statement \
-Wold-style-definition \
-Wno-missing-field-initializers \
-Wunused-parameter \
-Wno-unused-parameter \
-Wno-attributes \
-Wno-long-long \
-Wmaybe-uninitialized \
-Wvla \
-Wformat-overflow \
-Wformat-truncation \
-Wstringop-overread"
-Wvla"
exec $GCC $PEDANTIC $CONVERSION \
-Wall $Wuninitialized \
@@ -52,7 +49,13 @@ exec $GCC $PEDANTIC $CONVERSION \
-Wnested-externs \
-Wcomment \
-Winline \
-Wcast-align=strict \
-Wcast-align \
-Wcast-qual \
-Wredundant-decls $EXTRA \
"$@"
"$@" 2>&1 | {
if [[ $USE_FILTER -eq 1 ]]; then
.gitlab/ci/warnings_filter.py
else
cat
fi
}

View File

@@ -1,61 +1,29 @@
# Ubuntu
.gitlab-shared-docker-ubuntu:
image: ubuntu:noble
.gitlab-shared-docker:
image: ubuntu:focal
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$/
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
before_script:
- .gitlab/ci/cibuild-setup-ubuntu.sh
- export CC="${COMPILER}${COMPILER_VERSION:+-$COMPILER_VERSION}"
- export CXX="${COMPILER}++${COMPILER_VERSION:+-$COMPILER_VERSION}"
# 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}"
- ./autogen.sh
.gitlab-shared-gcc:
extends:
- .gitlab-shared-docker-ubuntu
- .gitlab-shared-docker
variables:
COMPILER: "gcc"
COMPILER_VERSION: "14"
CC: "gcc-14"
COMPILER_VERSION: "11"
RUN_SSH_PLUGIN_TEST: "1"
.gitlab-shared-clang:
extends:
- .gitlab-shared-docker-ubuntu
- .gitlab-shared-docker
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"
CC: "clang"
COMPILER_VERSION: "13"
RUN_SSH_PLUGIN_TEST: "1"

View File

@@ -1,22 +0,0 @@
#!/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

View File

@@ -1,31 +0,0 @@
#!/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

31
.gitlab/ci/warnings_filter.py Executable file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/python3
import sys
import json
import linecache
if __name__ == "__main__":
json_string = sys.stdin.read()
if json_string in [None, ""]:
sys.exit(0)
parsed = json.loads(json_string)
#print(json.dumps(parsed, indent=4, sort_keys=True))
r = 0
for o in parsed:
kind = o["kind"]
start = o["locations"][0]["caret"]
l = linecache.getline(start["file"], int(start["line"]))
ignored = "json_object_object_foreach" in l
print(f"{o['kind']} {'ignored' if ignored else 'FOUND'} in {start['file']}:{start['line']}:{start['column']} {o['message']}")
print(f"line contains:\n\t{l}", end="")
if not ignored:
r = 1
sys.exit(r)

View File

@@ -9,10 +9,7 @@
### Debug log
<!-- Paste a debug log of the failing command (add --debug option) between the markers below (to keep raw debug format).-->
<!-- We need a lot of information from the debug log; without it, we cannot process your report. -->
<!-- Debug log does not contain any private information. Do not paste private data; we'll ask you for more information if needed. -->
```
Output with --debug option:
```
<!-- NOTE: WITHOUT DEBUG LOG, THE BUG REPORT WILL BE CLOSED. ALSO, PLEASE DO NOT TRY TO REMOVE PARTS OF THE DEBUG LOG! -->

View File

@@ -1,158 +0,0 @@
Contributing to cryptsetup
==========================
For basic information about the cryptsetup project, please read [README](README.md).
The Cryptsetup project uses free, open-source licenses; details are described in [licensing](README.licensing).
For contribution code or documentation to the cryptsetup project, you must have the necessary rights to the content, and your contribution must be provided under the required license.
We welcome contributions from everyone.
Cryptsetup is an independent project with much volunteer effort, and our resources are limited.
Following the guidelines specified in this file makes it easier for us to process your issue.
Project maintainers can remove or reject abusive or otherwise unacceptable comments or code.
Git repository
--------------
The primary repository is located at [gitlab.com/cryptsetup/cryptsetup](https://gitlab.com/cryptsetup/cryptsetup).
The development branch is ``main``; minor stable releases can use their branches with cherry-picked or backported patches.
There are backup mirrors located at [github.com/mbroz/cryptsetup](https://github.com/mbroz/cryptsetup) and [git.kernel.org/pub/scm/utils/cryptsetup/cryptsetup.git](https://git.kernel.org/pub/scm/utils/cryptsetup/cryptsetup.git).
How to make a bug report
------------------------
To report an issue or feature request, please use GitLab [cryptsetup issue tracker](https://gitlab.com/cryptsetup/cryptsetup/-/issues).
Before reporting an issue, please try to search documentation and existing issues. Always try to reproduce the problem on the latest supported release.
Please *always* collect and attach ``--debug`` log and other information as instructed in the issue template.
Even if you think the problem is obvious, we need logged information about the environment (like versions of kernel modules, etc.).
Please do not report distribution-specific issues if they are not present in the latest upstream release.
For such reports, please use downstream distribution-specific trackers.
If the issue is related to upstream, downstream maintainers will redirect you here, or upstream maintainers will join the discussion.
If you think that you found some security bug, please follow the instructions in the [SECURITY](SECURITY.md) file.
How to contribute changes to cryptsetup
---------------------------------------
The following notes are a very short introduction to cryptsetup internal processes and an overview of generic rules that should be followed for all changes.
Changes from developers and external contributors should go through the GitLab repository [merge reguests](https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests).
Alternatively (for trivial changes), you can send a patch to [cryptsetup mailing list](mailto:cryptsetup@lists.linux.dev).
Please do not write personal emails with questions or patches to maintainers and developers.
### Project structure
Cryptsetup projects include a libcryptsetup library, tools, token plugins, documentation, and a test suite.
Cryptsetup library (libcryptsetup) exports [versioned symbols](lib/libcryptsetup.sym).
Tools (cryptsetup, veritysetup, integritysetup) use libcryptsetup shared library.
Some isolated parts in the lib directory can be reused for tools (the source is recompiled).
The basic directory structure in the repository is
```
├── docs - Documentation and release notes.
├── lib - libcryptsetup implementation
│   ├── bitlk - Bitlocker format
│   ├── crypto_backend - Cryptography backend
│   ├── fvault2 - FileVault2 format
│   ├── integrity - Linux dm-integrity interface
│   ├── loopaes - Linux LoopAES format
│   ├── luks1 - LUKS1 format
│   ├── luks2 - LUKS2 format including OPAL2 SED
│   ├── tcrypt - TrueCrypt / VeraCrypt format
│   └── verity - Linux dm-verity interface
├── man - Manual pages (in AsciiDoc format)
├── misc - Miscellaneous additions
├── po - Translation files
├── scripts - Scripts for system configuration
├── src - Tools implementation
├── tests - Testsuite (test units, regression tests, fuzzing)
└── tokens - Token plugins
```
### Coordination with other projects
The cryptsetup tools and library use low-level functions that depend on many other subsystems.
Currently, the project is supported only for Linux (it will not work on Android or other systems).
Cryptsetup project requires some parts of the Linux kernel, notably the *Device Mapper* (dm-crypt, dm-integrity, dm-verity, dm-zero modules) and kernel *userspace cryptographic interface*.
Missing kernel interface can significantly limit (or even disallow) cryptsetup functionality.
Integration in operating systems also depends on several other projects, most notably *systemd* (that implements its own tooling using libcryptsetup) and *util-Linux* (*blkid* parsing of supported format metadata). Some changes must be synchronized in all needed places (kernel, blkid, libcryptsetup).
Several other projects implement their own token metadata (either through binary token plugins or through generic libcryptsetup JSON token access functions).
### Used cryptography algorithms
Cryptsetup avoids implementing cryptographic primitives but uses cryptographic libraries.
Exceptions were PBKDF internal implementations - PBKDF2 and Argon2 until these were integrated into major cryptographic libraries.
Cryptsetup can be compiled with several cryptographic libraries backend (OpenSSL, libgcrypt, Nettle, NSS, and Linux kernel userspace API).
OpenSSL is the default and strongly recommended configuration.
If the cryptographic library does not implement some cryptographic primitive (for example, if running in a FIPS-140 environment or just
because it does not include it at all), functionality could be limited.
### Configuration and versioning
Cryptsetup can be configured using *Autoconf* or *Meson*. Autoconf support is being deprecated in the long term.
Currently, all new configuration options must be implemented in both systems.
Cryptsetup intentionally does not use a system configuration file (located in /etc).
All functionality must be determined dynamically.
All related /etc configuration files (crypttab, fstab and others) are maintained by systemd (in some legacy distributions by cryptsetup downstream).
Cryptsetup uses [semantic versioning](https://semver.org/).
Major and minor releases are always based on the main git branch; the minor stable (patch) versions can have some specific branch with backported or cherry-picked patches (from the main branch).
Usually, minor releases happen twice per year and stable patch updates according to reported bugs (in 1-3 month intervals).
### Compilation and debugging
The library and tools are written in C language; we require C99 and support gcc and Clang compilers.
Manual pages are generated from AsciiDoc sources and libcryptsetup API documentation by Doxygen (from libcryptsetup.h comments).
Testsuite is a combination of local C utilities, fuzzing implementation in C++, bash scripts, and uses many other system utilities.
All tools contain compiled-in debug messages that are available through --debug options.
With Autoconf and libtool, you can run the cryptsetup tool in the debugger without installation using this one-line script:
```
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://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).
- Split patches per change; do not submit huge patches combining several changes.
- 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 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).
Do not use assert for user-defined input (this should be a normal error path).
- The code style is quite relaxed in testing scripts (code there is not intended for production use).
### General rules and testing
- Cryptsetup should work on all architectures supported by the Linux kernel.
Only very few functionalities require specific hardware (notably Opal SED support).
If you want to introduce some specific hardware support, please discuss it with the maintainers first.
- All code changes should go through merge requests and reviews.
Code can be merged after review approval (done by someone with the commit right to the development repository), but reviews from external people are very welcome, too.
- All new functionality must come with at least rudimentary coverage in the test suite.
Always run the test suite before opening the merge request (``make check`` with root privilege).
- We have continuous integration (CI) that runs many tests automatically, but the output is not directly visible for external merge request authors (for security reasons).
All CI scripts are available in .gitlab and .github folders in the project repository.
Maintainers will provide you log files if anything fails. Your code must produce no warnings before it is merged.
- We run compilation with many extended [gcc](.gitlab/ci/gcc-Wall) and [Clang](.gitlab/ci/clang-Wall) warnings and include some analyzers, notably
- [Coverity](https://scan.coverity.com), GitHub CodeQL, Clang scan-build, and gcc static analyzer, and
- fuzzing integrated in [OSS-fuzz project](https://github.com/google/oss-fuzz/tree/master/projects/cryptsetup).
- Testsuite can also partially run under Valgrind dynamic analyzer with ``make valgrind-check``.

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,5 @@
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 \
lib/crypto_backend/meson.build \
lib/meson.build \
man/meson.build \
po/meson.build \
scripts/meson.build \
src/meson.build \
tests/meson.build \
tests/fuzz/meson.build \
tokens/meson.build \
tokens/ssh/meson.build
SUBDIRS = po tests tests/fuzz
EXTRA_DIST = README.md COPYING.LGPL FAQ docs misc autogen.sh
SUBDIRS = po tests
CLEANFILES =
DISTCLEAN_TARGETS =
@@ -25,17 +11,12 @@ AM_CPPFLAGS = \
-DLIBDIR=\""$(libdir)"\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DVERSION=\""$(VERSION)"\"
-DVERSION=\""$(VERSION)"\" \
-DEXTERNAL_LUKS2_TOKENS_PATH=\"${EXTERNAL_LUKS2_TOKENS_PATH}\"
AM_CFLAGS = -Wall
AM_CXXFLAGS = -Wall
AM_LDFLAGS =
if ENABLE_FUZZ_TARGETS
AM_CFLAGS += -fsanitize=fuzzer-no-link
AM_CXXFLAGS += -fsanitize=fuzzer-no-link
endif
LDADD = $(LTLIBINTL)
LDADD = $(LTLIBINTL) -lm
tmpfilesddir = @DEFAULT_TMPFILESDIR@
@@ -46,7 +27,6 @@ sbin_PROGRAMS =
man8_MANS =
tmpfilesd_DATA =
pkgconfig_DATA =
dist_noinst_DATA =
include man/Makemodule.am
@@ -66,7 +46,7 @@ ACLOCAL_AMFLAGS = -I m4
DISTCHECK_CONFIGURE_FLAGS = \
--with-tmpfilesdir=$$dc_install_base/usr/lib/tmpfiles.d \
--enable-internal-argon2 --enable-internal-sse-argon2 \
--enable-external-tokens --enable-ssh-token --enable-asciidoc
--enable-external-tokens --enable-ssh-token
distclean-local:
-find . -name \*~ -o -name \*.orig -o -name \*.rej | xargs rm -f
@@ -80,11 +60,3 @@ install-data-local:
uninstall-local:
rmdir $(DESTDIR)/${EXTERNAL_LUKS2_TOKENS_PATH} 2>/dev/null || :
check-programs: libcryptsetup.la
$(MAKE) -C tests $@
if ENABLE_FUZZ_TARGETS
fuzz-targets: libcryptsetup.la libcrypto_backend.la
$(MAKE) -C tests/fuzz $@
endif

View File

@@ -1,20 +0,0 @@
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.

172
README.md
View File

@@ -2,136 +2,106 @@
What the ...?
=============
**Cryptsetup** is an open-source utility used to conveniently set up disk encryption based
on the [dm-crypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
**Cryptsetup** is a utility used to conveniently set up disk encryption based
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
These formats are supported:
* **plain** volumes,
* **LUKS** volumes,
* **loop-AES**,
* **TrueCrypt** (including **VeraCrypt** extension),
* **BitLocker**, and
* **FileVault2**.
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
The project also includes a **veritysetup** utility used to conveniently setup
[dm-verity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity)
block integrity checking kernel module and **integritysetup** to setup
[dm-integrity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMIntegrity)
block integrity kernel module.
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
and **integritysetup** to setup
[DMIntegrity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMIntegrity) block integrity kernel module.
LUKS Design
-----------
**LUKS** is the standard for Linux disk encryption. By providing a standardized on-disk format,
it not only facilitate compatibility among distributions, but also enables secure management
of multiple user passwords. LUKS stores all necessary setup information in the partition header,
which enables users to transport or migrate data seamlessly.
**LUKS** is the standard for Linux hard disk encryption. By providing a standard on-disk-format, it does not
only facilitate compatibility among distributions, but also provides secure management of multiple user passwords.
LUKS stores all necessary setup information in the partition header, enabling to transport or migrate data seamlessly.
### Specification and documentation
* The latest version of the
[LUKS2 format specification](https://gitlab.com/cryptsetup/LUKS2-docs).
* The latest version of the
[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)
### Specifications
Last version of the LUKS2 format specification is
[available here](https://gitlab.com/cryptsetup/LUKS2-docs).
Last version of the LUKS1 format specification is
[available here](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
Why LUKS?
---------
* compatibility via standardization,
* secure against low entropy attacks,
* support for multiple keys,
* effective passphrase revocation,
* free.
[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://cdn.kernel.org/pub/linux/utils/cryptsetup/).
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
**The latest stable cryptsetup release version is 2.8.1**
* [cryptsetup-2.8.1.tar.xz](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.1.tar.xz)
* Signature [cryptsetup-2.8.1.tar.sign](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.1.tar.sign)
**The latest stable cryptsetup version is 2.4.3**
* [cryptsetup-2.4.3.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.3.tar.xz)
* Signature [cryptsetup-2.4.3.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.3.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.8.1 Release Notes](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/v2.8.1-ReleaseNotes).
* [Cryptsetup 2.4.3 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/v2.4.3-ReleaseNotes).
[Previous versions](https://cdn.kernel.org/pub/linux/utils/cryptsetup)
Previous versions
* [Version 2.3.7](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.7.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.7.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.7-ReleaseNotes).
* [Version 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).
Source and API documentation
----------------------------
For development version code, please refer to the
[source](https://gitlab.com/cryptsetup/cryptsetup/tree/master) page, with mirrors
at [kernel.org](https://git.kernel.org/cgit/utils/cryptsetup/cryptsetup.git/) and
[GitHub](https://github.com/mbroz/cryptsetup).
Source and API docs
-------------------
For development version code, please refer to [source](https://gitlab.com/cryptsetup/cryptsetup/tree/master) page,
mirror on [kernel.org](https://git.kernel.org/cgit/utils/cryptsetup/cryptsetup.git/) or [GitHub](https://github.com/mbroz/cryptsetup).
For libcryptsetup documentation see
[libcryptsetup API](https://mbroz.fedorapeople.org/libcryptsetup_API/) page.
For libcryptsetup documentation see [libcryptsetup API](https://mbroz.fedorapeople.org/libcryptsetup_API/) page.
NLS PO files are maintained by
[TranslationProject](https://translationproject.org/domain/cryptsetup.html).
The libcryptsetup API/ABI changes are tracked in [compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).
NLS PO files are maintained by [TranslationProject](https://translationproject.org/domain/cryptsetup.html).
Required packages
-----------------
All major Linux distributions provide cryptsetup as a bundled package. If you need
to compile cryptsetup yourself, various additional packages are required.
Any distribution-specific build tools are preferred when manually configuring cryptsetup.
All distributions provide cryptsetup as distro package. If you need to compile cryptsetup yourself, some packages are required for compilation. Please always prefer distro specific build tools to manually configuring cryptsetup.
For available compile options, check ``configure --help`` for more info. If you are using a git snapshot, you need to generate a configure script with ``autogen.sh`` script.
Below are the packages needed to build for certain Linux distributions:
Here is the list of packages needed for the compilation of project for particular 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`. Optionally `libargon2-devel libpwquality-devel`. To run the internal testsuite you also need to install `sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openssh-clients openssh sshpass`.
**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 rubygem-asciidoctor
* For Debian and Ubuntu: `git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev libjson-c-dev libssh-dev libblkid-dev tar`. Optionally `libargon2-0-dev libpwquality-dev`. To run the internal testsuite you also need to install `sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass`
Optionally: libargon2-devel libpwquality-devel
```
To run the internal testsuite (make check) you also need to install
```
sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openssh-clients openssh sshpass
```
**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 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-openbsd passwd openssh-client sshpass
```
Note that the list may change as Linux distributions evolve.
Compilation
-----------
The cryptsetup project uses **automake** and **autoconf** system to generate all files needed to build.
When building from a git snapshot,, use **./autogen.sh && ./configure && make**
to compile the project. When building from a release **tar.xz** tarball, the configure script
is pre-generated (no need to run **autoconf.sh**).
See **./configure --help** and use the **--disable-[feature]** and **--enable-[feature]** options.
To run the test suite that come with the project, type **make check**.
Note that most tests will need root user privileges and will run dangerous storage failure simulations.
Do **not** run tests with root privilege on production systems! Some tests will need the **scsi_debug**
kernel module to be installed.
For more details, please refer to the
[automake](https://www.gnu.org/software/automake/manual/automake.html) and
[autoconf](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf.html) documentation.
Note that the list could change as the distributions evolve.
Help!
-----
### Documentation
Please read the following before posting questions to the mailing list so that
you can ask better questions and better understand answers.
* [Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions),
* [LUKS Specifications](#specification-and-documentation), and
### Documentation
Please read the following documentation before posting questions in the mailing list. You will be able to ask better questions and better understand the answers.
* [FAQ](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
* LUKS Specifications
* manuals (aka man page, man pages, man-page)
The FAQ is available online and in the source code for the project. The specifications are
referenced above in this document. The man pages live within the source tree and should be
available after installation using standard man commands, e.g. **man cryptsetup**.
The FAQ is online and in the source code for the project. The Specifications are referenced above in this document. The man pages are in source and should be available after installation using standard man commands. e.g. man cryptsetup
### Mailing List
For cryptsetup and LUKS related questions, please use the cryptsetup mailing list
[cryptsetup@lists.linux.dev](mailto:cryptsetup@lists.linux.dev),
hosted at [kernel.org subspace](https://subspace.kernel.org/lists.linux.dev.html).
To subscribe send an empty email message to
[cryptsetup+subscribe@lists.linux.dev](mailto:cryptsetup+subscribe@lists.linux.dev).
You can also browse and/or search the mailing [list archive](https://lore.kernel.org/cryptsetup/).
USEnet News (NNTP), Atom feed and git access to the public inbox is available through
[lore.kernel.org](https://lore.kernel.org) service.
For cryptsetup and LUKS related questions, please use the dm-crypt mailing list, [dm-crypt@saout.de](mailto:dm-crypt@saout.de). To subscribe send an empty mail to [dm-crypt-subscribe@saout.de](mailto:dm-crypt-subscribe@saout.de).
The former **dm-crypt** [list archive](https://lore.kernel.org/dm-crypt/) is also available.
You can also browse and/or search the mailing list archives using the following resources:
* [list archive](https://www.saout.de/pipermail/dm-crypt/)
* [web interface on lore.kernel.org](https://lore.kernel.org/dm-crypt/)
* [marc.info](https://marc.info/?l=dm-crypt).

View File

@@ -1,10 +0,0 @@
# Reporting a Security Bug in cryptsetup project
If you think you have discovered a security issue, please report it through
the project issue tracker [New issue](https://gitlab.com/cryptsetup/cryptsetup/issues)
as a confidential issue (select confidential checkbox).
An alternative is to send PGP encrypted mail to the cryptsetup maintainer.
Current maintainer is [Milan Broz](mailto:gmazyland@gmail.com), use PGP key
with fingerprint 2A29 1824 3FDE 4664 8D06 86F9 D9B0 577B D93E 98FC.

View File

@@ -74,7 +74,7 @@ autopoint --force $AP_OPTS
libtoolize --force --copy
aclocal -I m4 $AL_OPTS
autoheader $AH_OPTS
automake --force-missing --add-missing --copy --gnu $AM_OPTS
automake --add-missing --copy --gnu $AM_OPTS
autoconf $AC_OPTS
echo

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[2.9.0-git])
AC_INIT([cryptsetup],[2.4.3])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=23:0:11
LIBCRYPTSETUP_VERSION_INFO=19:0:7
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR(src/cryptsetup.c)
@@ -28,13 +28,13 @@ AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
AC_ENABLE_STATIC(no)
LT_INIT
PKG_PROG_PKG_CONFIG
AM_ICONV
dnl ==========================================================================
dnl define PKG_CHECK_VAR for old pkg-config <= 0.28
@@ -53,33 +53,12 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])
])
])
dnl ==========================================================================
dnl AsciiDoc manual pages
AC_ARG_ENABLE([asciidoc],
AS_HELP_STRING([--disable-asciidoc], [do not generate man pages from asciidoc]),
[], [enable_asciidoc=yes]
)
AC_PATH_PROG([ASCIIDOCTOR], [asciidoctor])
if test "x$enable_asciidoc" = xyes -a "x$ASCIIDOCTOR" = x; then
AC_MSG_ERROR([Building man pages requires asciidoctor installed.])
fi
AM_CONDITIONAL([ENABLE_ASCIIDOC], [test "x$enable_asciidoc" = xyes])
have_manpages=no
AS_IF([test -f "$srcdir/man/cryptsetup-open.8"], [
AC_MSG_NOTICE([re-use already generated man-pages.])
have_manpages=yes]
)
AM_CONDITIONAL([HAVE_MANPAGES], [test "x$have_manpages" = xyes])
dnl ==========================================================================
AC_C_RESTRICT
AC_HEADER_DIRENT
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h uchar.h sys/ioctl.h sys/mman.h \
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h stdint.h)
AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
[[
@@ -128,10 +107,12 @@ if test "x$enable_largefile" = "xno"; then
AC_MSG_ERROR([Building with --disable-largefile is not supported, it can cause data corruption.])
fi
AC_C_CONST
AC_C_BIGENDIAN
AC_TYPE_OFF_T
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
AC_PROG_GCC_TRADITIONAL
AC_FUNC_STRERROR_R
dnl ==========================================================================
@@ -149,7 +130,6 @@ if test "x$enable_external_tokens" = "xyes"; then
AC_SUBST(DL_LIBS, $LIBS)
LIBS=$saved_LIBS
fi
AM_CONDITIONAL(EXTERNAL_TOKENS, test "x$enable_external_tokens" = "xyes")
AC_ARG_ENABLE([ssh-token],
AS_HELP_STRING([--disable-ssh-token], [disable LUKS2 ssh-token]),
@@ -213,17 +193,6 @@ if test "x$enable_pwquality" = "xyes"; then
PWQUALITY_STATIC_LIBS="$PWQUALITY_LIBS -lcrack -lz"
fi
dnl ==========================================================================
dnl fuzzers, it requires own static library compilation later
AC_ARG_ENABLE([fuzz-targets],
AS_HELP_STRING([--enable-fuzz-targets], [enable building fuzz targets]))
AM_CONDITIONAL(ENABLE_FUZZ_TARGETS, test "x$enable_fuzz_targets" = "xyes")
if test "x$enable_fuzz_targets" = "xyes"; then
AX_CHECK_COMPILE_FLAG([-fsanitize=fuzzer-no-link],,
AC_MSG_ERROR([Required compiler options not supported; use clang.]), [-Werror])
fi
dnl ==========================================================================
dnl passwdqc library (cryptsetup CLI only)
AC_ARG_ENABLE([passwdqc],
@@ -265,9 +234,6 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
GCRYPT_REQ_VERSION=1.1.42
fi
use_internal_pbkdf2=0
use_internal_argon2=1
dnl libgcrypt rejects to use pkgconfig, use AM_PATH_LIBGCRYPT from gcrypt-devel here.
dnl Do not require gcrypt-devel if other crypto backend is used.
m4_ifdef([AM_PATH_LIBGCRYPT],[
@@ -291,24 +257,7 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
NO_FIPS([])
fi
m4_ifdef([AM_PATH_LIBGCRYPT],[
AC_ARG_ENABLE([gcrypt-argon2],
dnl Check if we can use gcrypt Argon2 (1.11.0 supports empty password)
AS_HELP_STRING([--disable-gcrypt-argon2], [force disable internal gcrypt Argon2]),
[],
[AM_PATH_LIBGCRYPT([1.11.0], [use_internal_argon2=0], [use_internal_argon2=1])])
AM_PATH_LIBGCRYPT($GCRYPT_REQ_VERSION,,[AC_MSG_ERROR([You need the gcrypt library.])])],
AC_MSG_ERROR([Missing support for gcrypt: install gcrypt and regenerate configure.]))
AC_MSG_CHECKING([if internal cryptsetup Argon2 is compiled-in])
if test $use_internal_argon2 = 0; then
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
fi
AC_CHECK_DECLS([GCRY_CIPHER_MODE_XTS], [], [], [#include <gcrypt.h>])
AC_CHECK_DECLS([GCRY_KDF_ARGON2], [], [], [#include <gcrypt.h>])
if test "x$enable_static_cryptsetup" = "xyes"; then
saved_LIBS=$LIBS
@@ -328,25 +277,19 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
])
AC_DEFUN([CONFIGURE_OPENSSL], [
PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto >= 0.9.8],,
PKG_CHECK_MODULES([OPENSSL], [openssl >= 0.9.8],,
AC_MSG_ERROR([You need openssl library.]))
CRYPTO_CFLAGS=$LIBCRYPTO_CFLAGS
CRYPTO_LIBS=$LIBCRYPTO_LIBS
CRYPTO_CFLAGS=$OPENSSL_CFLAGS
CRYPTO_LIBS=$OPENSSL_LIBS
use_internal_pbkdf2=0
use_internal_argon2=1
if test "x$enable_static_cryptsetup" = "xyes"; then
saved_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES([LIBCRYPTO_STATIC], [libcrypto])
CRYPTO_STATIC_LIBS=$LIBCRYPTO_STATIC_LIBS
PKG_CHECK_MODULES([OPENSSL_STATIC], [openssl])
CRYPTO_STATIC_LIBS=$OPENSSL_STATIC_LIBS
PKG_CONFIG=$saved_PKG_CONFIG
fi
saved_LIBS=$LIBS
AC_CHECK_DECLS([OSSL_get_max_threads], [], [], [#include <openssl/thread.h>])
AC_CHECK_DECLS([OSSL_KDF_PARAM_ARGON2_VERSION], [use_internal_argon2=0], [], [#include <openssl/core_names.h>])
LIBS=$saved_LIBS
])
AC_DEFUN([CONFIGURE_NSS], [
@@ -367,7 +310,6 @@ AC_DEFUN([CONFIGURE_NSS], [
CRYPTO_CFLAGS=$NSS_CFLAGS
CRYPTO_LIBS=$NSS_LIBS
use_internal_pbkdf2=1
use_internal_argon2=1
NO_FIPS([])
])
@@ -378,7 +320,6 @@ AC_DEFUN([CONFIGURE_KERNEL], [
# [AC_MSG_ERROR([You need Linux kernel with userspace crypto interface.])],
# [#include <sys/socket.h>])
use_internal_pbkdf2=1
use_internal_argon2=1
NO_FIPS([])
])
@@ -395,24 +336,6 @@ AC_DEFUN([CONFIGURE_NETTLE], [
CRYPTO_STATIC_LIBS=$CRYPTO_LIBS
use_internal_pbkdf2=0
use_internal_argon2=1
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([])
])
@@ -439,6 +362,11 @@ AC_ARG_ENABLE([veritysetup],
[], [enable_veritysetup=yes])
AM_CONDITIONAL(VERITYSETUP, test "x$enable_veritysetup" = "xyes")
AC_ARG_ENABLE([cryptsetup-reencrypt],
AS_HELP_STRING([--disable-cryptsetup-reencrypt], [disable cryptsetup-reencrypt tool]),
[], [enable_cryptsetup_reencrypt=yes])
AM_CONDITIONAL(REENCRYPT, test "x$enable_cryptsetup_reencrypt" = "xyes")
AC_ARG_ENABLE([integritysetup],
AS_HELP_STRING([--disable-integritysetup], [disable integritysetup support]),
[], [enable_integritysetup=yes])
@@ -491,14 +419,14 @@ if test "x$enable_ssh_token" = "xyes"; then
AC_CHECK_DECLS([ssh_session_is_known_server], [], [], [#include <libssh/libssh.h>])
AC_CHECK_HEADER([argp.h], [], AC_MSG_ERROR([You need argp library.]))
saved_LIBS=$LIBS
AC_SEARCH_LIBS([argp_parse],[argp])
AC_SEARCH_LIBS([argp_usage],[argp])
AC_SUBST(ARGP_LIBS, $LIBS)
LIBS=$saved_LIBS
fi
dnl Crypto backend configuration.
AC_ARG_WITH([crypto_backend],
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle/mbedtls) [openssl]]),
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [openssl]]),
[], [with_crypto_backend=openssl])
dnl Kernel crypto API backend needed for benchmark and tcrypt
@@ -518,7 +446,6 @@ 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")
@@ -526,7 +453,6 @@ 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])
@@ -539,21 +465,12 @@ AC_ARG_ENABLE([internal-argon2],
AC_ARG_ENABLE([libargon2],
AS_HELP_STRING([--enable-libargon2], [enable external libargon2 (PHC) library (disables internal bundled version)]))
if test $use_internal_argon2 = 0 || ( test "x$enable_internal_argon2" = "xno" && test "x$enable_libargon2" != "xyes" ); then
if test "x$enable_internal_argon2" = "xyes" || test "x$enable_libargon2" = "xyes"; then
AC_MSG_NOTICE([Argon2 in $with_crypto_backend lib is used; internal Argon2 options are ignored.])
fi
enable_internal_argon2=no
enable_internal_sse_argon2=no
enable_libargon2=no
use_internal_argon2=0
elif test "x$enable_libargon2" = "xyes" ; then
if test "x$enable_libargon2" = "xyes" ; then
AC_CHECK_HEADERS(argon2.h,,
[AC_MSG_ERROR([You need libargon2 development library installed.])])
AC_CHECK_DECL(Argon2_id,,[AC_MSG_ERROR([You need more recent Argon2 library with support for Argon2id.])], [#include <argon2.h>])
PKG_CHECK_MODULES([LIBARGON2], [libargon2],,[LIBARGON2_LIBS="-largon2"])
enable_internal_argon2=no
use_internal_argon2=0
else
AC_MSG_WARN([Argon2 bundled (slow) reference implementation will be used, please consider to use system library with --enable-libargon2.])
@@ -572,10 +489,11 @@ else
fi
fi
if test "x$enable_internal_argon2" = "xyes"; then
AC_DEFINE(USE_INTERNAL_ARGON2, 1, [Use internal Argon2])
fi
AM_CONDITIONAL(CRYPTO_INTERNAL_ARGON2, test "x$enable_internal_argon2" = "xyes")
AM_CONDITIONAL(CRYPTO_INTERNAL_SSE_ARGON2, test "x$enable_internal_sse_argon2" = "xyes")
dnl If libargon is in use, we have defined HAVE_ARGON2_H
AC_DEFINE_UNQUOTED(USE_INTERNAL_ARGON2, [$use_internal_argon2], [Use internal Argon2])
dnl Link with blkid to check for other device types
AC_ARG_ENABLE([blkid],
@@ -610,27 +528,6 @@ AM_CONDITIONAL(HAVE_BLKID, test "x$enable_blkid" = "xyes")
AM_CONDITIONAL(HAVE_BLKID_WIPE, test "x$enable_blkid_wipe" = "xyes")
AM_CONDITIONAL(HAVE_BLKID_STEP_BACK, test "x$enable_blkid_step_back" = "xyes")
AC_ARG_ENABLE([hw-opal],
AS_HELP_STRING([--disable-hw-opal], [disable use of hardware-backed OPAL for device encryption]),
[],
[enable_hw_opal=yes])
if test "x$enable_hw_opal" = "xyes"; then
have_opal=yes
AC_CHECK_DECLS([ OPAL_FL_SUM_SUPPORTED,
IOC_OPAL_GET_LR_STATUS,
IOC_OPAL_GET_GEOMETRY
],
[],
[have_opal=no],
[#include <linux/sed-opal.h>])
if test "x$have_opal" = "xyes"; then
AC_DEFINE([HAVE_HW_OPAL], 1, [Define to 1 to enable OPAL support.])
else
AC_MSG_WARN([Can not compile with OPAL support, kernel headers are too old, requires v6.4.])
fi
fi
dnl Magic for cryptsetup.static build.
if test "x$enable_static_cryptsetup" = "xyes"; then
saved_PKG_CONFIG=$PKG_CONFIG
@@ -663,53 +560,8 @@ if test "x$enable_static_cryptsetup" = "xyes"; then
PKG_CONFIG=$saved_PKG_CONFIG
fi
dnl Check compiler support for symver function attribute
AC_MSG_CHECKING([for symver attribute support])
saved_CFLAGS=$CFLAGS
CFLAGS="-O0 -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
void _test_sym(void);
__attribute__((__symver__("sym@VERSION_4.2"))) void _test_sym(void) {}
]],
[[ _test_sym() ]]
)],[
AC_DEFINE([HAVE_ATTRIBUTE_SYMVER], 1, [Define to 1 to use __attribute__((symver))])
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
])
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])
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
PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no])
AC_MSG_RESULT([$systemd_tmpfilesdir])
AC_SUBST([DEVMAPPER_LIBS])
@@ -733,22 +585,6 @@ AC_SUBST([LIBSSH_LIBS])
AC_SUBST([LIBCRYPTSETUP_VERSION])
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
dnl Set Requires.private for libcryptsetup.pc
dnl pwquality is used only by tools
PKGMODULES="uuid devmapper json-c"
case $with_crypto_backend in
gcrypt) PKGMODULES="$PKGMODULES libgcrypt" ;;
openssl) PKGMODULES="$PKGMODULES openssl" ;;
nss) PKGMODULES="$PKGMODULES nss" ;;
nettle) PKGMODULES="$PKGMODULES nettle" ;;
esac
if test "x$enable_libargon2" = "xyes"; then
PKGMODULES="$PKGMODULES libargon2"
fi
if test "x$enable_blkid" = "xyes"; then
PKGMODULES="$PKGMODULES blkid"
fi
AC_SUBST([PKGMODULES])
dnl ==========================================================================
AC_ARG_ENABLE([dev-random],
AS_HELP_STRING([--enable-dev-random], [use /dev/random by default for key generation (otherwise use /dev/urandom)]))
@@ -784,9 +620,9 @@ AC_DEFUN([CS_ABSPATH], [
])
dnl ==========================================================================
CS_STR_WITH([plain-hash], [password hashing function for plain mode], [sha256])
CS_STR_WITH([plain-hash], [password hashing function for plain mode], [ripemd160])
CS_STR_WITH([plain-cipher], [cipher for plain mode], [aes])
CS_STR_WITH([plain-mode], [cipher mode for plain mode], [xts-plain64])
CS_STR_WITH([plain-mode], [cipher mode for plain mode], [cbc-essiv:sha256])
CS_NUM_WITH([plain-keybits],[key length in bits for plain mode], [256])
CS_STR_WITH([luks1-hash], [hash function for LUKS1 header], [sha256])
@@ -823,9 +659,8 @@ 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])
AC_ARG_WITH([tmpfilesdir],
AS_HELP_STRING([--with-tmpfilesdir=DIR], [override default path to directory with systemd temporary files]),
[], [with_tmpfilesdir=$systemd_tmpfilesdir])
CS_STR_WITH([tmpfilesdir], [override default path to directory with systemd temporary files], [])
test -z "$with_tmpfilesdir" && with_tmpfilesdir=$systemd_tmpfilesdir
test "x$with_tmpfilesdir" = "xno" || {
CS_ABSPATH([${with_tmpfilesdir}],[with-tmpfilesdir])
DEFAULT_TMPFILESDIR=$with_tmpfilesdir
@@ -844,9 +679,7 @@ 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)
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=""])
CS_STR_WITH([luks2-external-tokens-path], [path to directory with LUKSv2 external token handlers (plugins)], [LIBDIR/cryptsetup])
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
@@ -854,17 +687,6 @@ 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],
@@ -885,6 +707,5 @@ lib/libcryptsetup.pc
po/Makefile.in
scripts/cryptsetup.conf
tests/Makefile
tests/fuzz/Makefile
])
AC_OUTPUT

View File

@@ -74,7 +74,7 @@
2012-03-16 Milan Broz <gmazyland@gmail.com>
* Add --keyfile-offset and --new-keyfile-offset parameters to API and CLI.
* Add repair command and crypt_repair() for known LUKS metadata problems repair.
* Allow one to specify --align-payload only for luksFormat.
* Allow to specify --align-payload only for luksFormat.
2012-03-16 Milan Broz <mbroz@redhat.com>
* Unify password verification option.
@@ -228,7 +228,7 @@
* Fix password callback call.
* Fix default plain password entry from terminal in activate_by_passphrase.
* Add --dump-master-key option for luksDump to allow volume key dump.
* Allow one to activate by internally cached volume key
* Allow to activate by internally cached volume key
(format/activate without keyslots active - used for temporary devices).
* Initialize volume key from active device in crypt_init_by_name()
* Fix cryptsetup binary exitcodes.

View File

@@ -12,53 +12,30 @@ no longer stored directly in dm-crypt target. Starting with cryptsetup 2.0 we
load VK in kernel keyring by default for LUKSv2 devices (when dm-crypt with the
feature is available).
Currently, cryptsetup loads VK in 'logon' type kernel key so that VK is passed in
the kernel and can't be read from userspace afterwards. Also, cryptsetup loads VK in
the thread keyring (before passing the reference to dm-crypt target) so that the key
Currently cryptsetup loads VK in 'logon' type kernel key so that VK is passed in
the kernel and can't be read from userspace afterward. Also cryptsetup loads VK in
thread keyring (before passing the reference to dm-crypt target) so that the key
lifetime is directly bound to the process that performs the dm-crypt setup. When
cryptsetup process exits (for whatever reason) the key gets unlinked in the kernel
cryptsetup process exits (for whatever reason) the key gets unlinked in kernel
automatically. In summary, the key description visible in dm-crypt table line is
a reference to VK that usually no longer exists in kernel keyring service if you
used cryptsetup for device activation.
used cryptsetup to for device activation.
Using this feature dm-crypt no longer maintains a direct key copy (but there's
always at least one copy in the kernel crypto layer).
Additionally, libcryptsetup supports the linking of volume keys to
user-specified kernel keyring with crypt_set_keyring_to_link(). The user may
specify keyring name, key type ('user' or 'logon') and key description where
libcryptsetup should link the verified volume key upon subsequent device
activation (or key verification alone).
The volume key(s) (provided the key type is 'user') linked in the user keyring
can be later used to activate the device via crypt_activate_by_keyslot_context()
with CRYPT_KC_TYPE_VK_KEYRING type keyslot context
(acquired by crypt_keyslot_context_init_by_vk_in_keyring()).
Example of how to use volume key linked in custom user keyring from cryptsetup
utility:
1) Open the device and store the volume key to the session keyring:
# cryptsetup open <device> --link-vk-to-keyring "@s::%user:testkey" tst
2) Add a keyslot using the stored volume key in a keyring:
# cryptsetup luksAddKey <device> --volume-key-keyring "%user:testkey"
3) Activate the device using the volume key cached in a keyring ('user' type key)
# cryptsetup open <device> <active_name> --volume-key-keyring "testkey"
always at least one copy in kernel crypto layer).
II) Keyslot passphrase
The second use case for kernel keyring is to allow cryptsetup reading the keyslot
passphrase stored in kernel keyring instead. The user may load the passphrase in the kernel
passphrase stored in kernel keyring instead. The user may load passphrase in kernel
keyring and notify cryptsetup to read it from there later. Currently, cryptsetup
cli supports kernel keyring for passphrase only via LUKS2 internal token
(luks2-keyring). The library also provides a general method for device activation by
reading the passphrase from the keyring: crypt_activate_by_keyring(). The key type
(luks2-keyring). Library also provides a general method for device activation by
reading passphrase from keyring: crypt_activate_by_keyring(). The key type
for use case II) must always be 'user' since we need to read the actual key
data from userspace unlike with VK in I). The ability to read keyslot passphrases
from kernel keyring also allows easy auto-activate LUKS2 devices.
data from userspace unlike with VK in I). Ability to read keyslot passphrase
from kernel keyring also allows easily auto-activate LUKS2 devices.
Simple example of how to use kernel keyring for keyslot passphrase:
Simple example how to use kernel keyring for keyslot passphrase:
1) create LUKS2 keyring token for keyslot 0 (in LUKS2 device/image)
cryptsetup token add --key-description my:key -S 0 /dev/device
@@ -66,7 +43,7 @@ cryptsetup token add --key-description my:key -S 0 /dev/device
2) Load keyslot passphrase in user keyring
read -s -p "Keyslot passphrase: "; echo -n $REPLY | keyctl padd user my:key @u
3) Activate the device using the passphrase stored in the kernel keyring
3) Activate device using passphrase stored in kernel keyring
cryptsetup open /dev/device my_unlocked_device
4a) unlink the key when no longer needed by
@@ -75,5 +52,5 @@ keyctl unlink %user:my:key @u
4b) or revoke it immediately by
keyctl revoke %user:my:key
If cryptsetup asks for a passphrase in step 3) something went wrong with keyring
If cryptsetup asks for passphrase in step 3) something went wrong with keyring
activation. See --debug output then.

View File

@@ -5,7 +5,7 @@ Why
~~~
LUKS2 format keeps two identical copies of metadata stored consecutively
at the head of the metadata device (file or bdev). The metadata
at the head of metadata device (file or bdev). The metadata
area (both copies) must be updated in a single atomic operation to avoid
header corruption during concurrent write.
@@ -15,17 +15,17 @@ locking with legacy format was not so obvious as it is with the LUKSv2 format.
With LUKS2 the boundary between read-only and read-write is blurry and what
used to be the exclusively read-only operation (i.e., cryptsetup open command) may
easily become read-update operation silently without the user's knowledge.
A major feature of the LUKS2 format is resilience against accidental
easily become read-update operation silently without user's knowledge.
Major feature of LUKS2 format is resilience against accidental
corruption of metadata (i.e., partial header overwrite by parted or cfdisk
while creating a partition on a mistaken block device).
Such header corruption is detected early on the header read and the auto-recovery
while creating partition on mistaken block device).
Such header corruption is detected early on header read and auto-recovery
procedure takes place (the corrupted header with checksum mismatch is being
replaced by the secondary one if that one is intact).
On current Linux systems header load operation may be triggered without the user
direct intervention for example by an udev rule or from a systemd service.
Such a clash of header read and auto-recovery procedure could have severe
consequences with the worst case of having a LUKS2 device inaccessible or being
On current Linux systems header load operation may be triggered without user
direct intervention for example by udev rule or from systemd service.
Such clash of header read and auto-recovery procedure could have severe
consequences with the worst case of having LUKS2 device unaccessible or being
broken beyond repair.
The whole locking of LUKSv2 device headers split into two categories depending
@@ -36,17 +36,17 @@ I) block device
We perform flock() on file descriptors of files stored in a private
directory (by default /run/lock/cryptsetup). The file name is derived
from major:minor couple of the affected block device. Note we recommend
that access to the private locking directory is supposed to be limited
to the superuser only. For this method to work the distribution needs
from major:minor couple of affected block device. Note we recommend
that access to private locking directory is supposed to be limited
to superuser only. For this method to work the distribution needs
to install the locking directory with appropriate access rights.
II) regular files
~~~~~~~~~~~~~~~~~
A first notable difference between headers stored in a file
First notable difference between headers stored in a file
vs. headers stored in a block device is that headers in a file may be
manipulated by the regular user, unlike headers on block devices. Therefore
manipulated by the regular user unlike headers on block devices. Therefore
we perform flock() protection on file with the luks2 header directly.
Limitations
@@ -58,40 +58,4 @@ while locking is enabled.
We do not suppress any other negative effect that two or more concurrent
writers of the same header may cause.
b) The locking is not cluster-aware in any way.
Additional LUKS2 locks
======================
LUKS2 reencryption device lock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Device in LUKS2 reencryption is protected by an exclusive lock placed in the default
locking directory. The lock's purpose is to exclude multiple processes from
performing reencryption on the same device (identified by LUKS uuid). The lock
is taken no matter the LUKS2 reencryption mode (online or offline).
LUKS2 memory hard global lock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An optional global lock that makes libcryptsetup serialize memory hard
pbkdf function when deriving a key encryption key from passphrase on unlocking
LUKS2 keyslot. The lock has to be enabled via the CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
flag. The lock is placed in the default locking directory.
LUKS2 OPAL lock
~~~~~~~~~~~~~~~
Exclusive per device lock taken when manipulating LUKS2 device configured for use with
SED OPAL2 locking range.
Lock ordering
=============
To avoid a deadlock following rules must apply:
- LUKS2 reencrytpion lock must be taken before LUKS2 OPAL lock.
- LUKS2 OPAL lock must be taken before LUKS2 metadata lock.
- LUKS2 memory hard global lock can not be used with other locks.
b) The locking is not cluster aware in any way.

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.9.8
# Doxyfile 1.9.1
#---------------------------------------------------------------------------
# Project related configuration options
@@ -10,9 +10,9 @@ PROJECT_BRIEF = "Public cryptsetup API"
PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen_api_docs
CREATE_SUBDIRS = NO
CREATE_SUBDIRS_LEVEL = 8
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
OUTPUT_TEXT_DIRECTION = None
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
@@ -39,7 +39,6 @@ OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
MARKDOWN_ID_STYLE = DOXYGEN
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
@@ -53,7 +52,6 @@ INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = YES
LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1
TIMESTAMP = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@@ -74,7 +72,6 @@ INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_HEADERFILE = YES
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
@@ -104,12 +101,9 @@ QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_IF_INCOMPLETE_DOC = YES
WARN_NO_PARAMDOC = NO
WARN_IF_UNDOC_ENUM_VAL = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LINE_FORMAT = "at line $line of file $file"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
@@ -117,7 +111,6 @@ WARN_LOGFILE =
INPUT = doxygen_index.h \
../lib/libcryptsetup.h
INPUT_ENCODING = UTF-8
INPUT_FILE_ENCODING =
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
@@ -133,7 +126,6 @@ FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
FORTRAN_COMMENT_AFTER = 72
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
@@ -166,17 +158,15 @@ HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE = AUTO_LIGHT
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_CODE_FOLDING = YES
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_FEEDURL =
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
@@ -187,7 +177,6 @@ GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
SITEMAP_URL =
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
@@ -200,16 +189,14 @@ GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
FULL_SIDEBAR = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
OBFUSCATE_EMAILS = YES
HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
FORMULA_MACROFILE =
USE_MATHJAX = NO
MATHJAX_VERSION = MathJax_2
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
MATHJAX_EXTENSIONS =
@@ -240,7 +227,9 @@ PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
@@ -251,6 +240,7 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@@ -271,17 +261,12 @@ XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to Sqlite3 output
#---------------------------------------------------------------------------
GENERATE_SQLITE3 = NO
SQLITE3_OUTPUT = sqlite3
SQLITE3_RECREATE_DB = YES
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
@@ -309,14 +294,15 @@ ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to diagram generator tools
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
@@ -332,20 +318,18 @@ CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DIR_GRAPH_MAX_DEPTH = 1
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
DIA_PATH =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
MSCGEN_TOOL =
MSCFILE_DIRS =

View File

@@ -1,8 +1,21 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* libcryptsetup API log example
*
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>

View File

@@ -1,8 +1,21 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* libcryptsetup API - using LUKS device example
*
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>

View File

@@ -1,202 +0,0 @@
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.

View File

@@ -1,428 +0,0 @@
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.

View File

@@ -1,354 +0,0 @@
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 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.

Binary file not shown.

View File

@@ -85,7 +85,7 @@ Libcryptsetup API additions:
* Fix optional password callback handling.
* Allow one to activate by internally cached volume key immediately after
* Allow to activate by internally cached volume key immediately after
crypt_format() without active slot (for temporary devices with
on-disk metadata)

View File

@@ -24,7 +24,7 @@ Changes since version 1.4.1
* Fix header check to support old (cryptsetup 1.0.0) header alignment.
(Regression in 1.4.0)
* Allow one to specify --align-payload only for luksFormat.
* Allow to specify --align-payload only for luksFormat.
* Add --master-key-file option to luksOpen (open using volume key).

View File

@@ -32,7 +32,7 @@ Changes since version 1.4.2
Device-mapper now retry removal if device is busy.
* Allow "private" activation (skip some udev global rules) flag.
Cryptsetup library API now allows one to specify CRYPT_ACTIVATE_PRIVATE,
Cryptsetup library API now allows to specify CRYPT_ACTIVATE_PRIVATE,
which means that some udev rules are not processed.
(Used for temporary devices, like internal keyslot mappings where
it is not desirable to run any device scans.)

View File

@@ -4,7 +4,7 @@ Cryptsetup 1.6.0 Release Notes
Changes since version 1.6.0-rc1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Change LUKS default cipher to use XTS encryption mode,
* Change LUKS default cipher to to use XTS encryption mode,
aes-xts-plain64 (i.e. using AES128-XTS).
XTS mode becomes standard in hard disk encryption.
@@ -209,7 +209,7 @@ Important changes
WARNING: these tests do not use dmcrypt, only crypto API.
You have to benchmark the whole device stack and you can get completely
different results. But it is usable for basic comparison.
different results. But is is usable for basic comparison.
(Note for example AES-NI decryption optimization effect in example above.)
Features

View File

@@ -8,7 +8,7 @@ Changes since version 1.6.1
* Fix cipher specification string parsing (found by gcc -fsanitize=address option).
* Try to map TCRYPT system encryption through partition
(allows one to activate mapping when other partition on the same device is mounted).
(allows to activate mapping when other partition on the same device is mounted).
* Print a warning if system encryption is used and device is a partition.
(TCRYPT system encryption uses whole device argument.)

View File

@@ -25,7 +25,7 @@ Changes since version 1.6.3
Please refer to cryptsetup FAQ for detail how to fix this situation.
* Allow one to use --disable-gcrypt-pbkdf2 during configuration
* Allow to use --disable-gcrypt-pbkdf2 during configuration
to force use internal PBKDF2 code.
* Require gcrypt 1.6.1 for imported implementation of PBKDF2

View File

@@ -38,7 +38,7 @@ Changes since version 1.6.4
The command "cryptsetup status" will print basic info, even if you
do not provide detached header argument.
* Allow one to specify ECB mode in cryptsetup benchmark.
* Allow to specify ECB mode in cryptsetup benchmark.
* Add some LUKS images for regression testing.
Note that if image with Whirlpool fails, the most probable cause is that

View File

@@ -35,14 +35,14 @@ Changes since version 1.6.6
* Support permanent device decryption for cryptsetup-reencrypt.
To remove LUKS encryption from a device, you can now use --decrypt option.
* Allow one to use --header option in all LUKS commands.
* Allow to use --header option in all LUKS commands.
The --header always takes precedence over positional device argument.
* Allow luksSuspend without need to specify a detached header.
* Detect if O_DIRECT is usable on a device allocation.
There are some strange storage stack configurations which wrongly allows
one to open devices with direct-io but fails on all IO operations later.
to open devices with direct-io but fails on all IO operations later.
Cryptsetup now tries to read the device first sector to ensure it can use
direct-io.

View File

@@ -30,7 +30,7 @@ Changes since version 1.6.7
cryptsetup resize will try to resize underlying loop device as well.
(It can be used to grow up file-backed device in one step.)
* Cryptsetup now allows one to use empty password through stdin pipe.
* Cryptsetup now allows to use empty password through stdin pipe.
(Intended only for testing in scripts.)
Cryptsetup API NOTE:

View File

@@ -3,7 +3,7 @@ Cryptsetup 1.7.4 Release Notes
Changes since version 1.7.3
* Allow one to specify LUKS1 hash algorithm in Python luksFormat wrapper.
* Allow to specify LUKS1 hash algorithm in Python luksFormat wrapper.
* Use LUKS1 compiled-in defaults also in Python wrapper.

View File

@@ -89,7 +89,7 @@ Important features
Integritysetup is intended to be used for settings that require
non-cryptographic data integrity protection with no data encryption.
For setting integrity protected encrypted devices, see disk authenticated
Fo setting integrity protected encrypted devices, see disk authenticated
encryption below.
Note that after formatting the checksums need to be initialized;
@@ -583,7 +583,7 @@ Unfinished things & TODO for next releases
in kernel (more on this later).
NOTE: Currently available authenticated modes (GCM, Chacha20-poly1305)
in kernel have too small 96-bit nonces that are problematic with
randomly generated IVs (the collision probability is not negligible).
randomly generated IVs (the collison probability is not negligible).
For the GCM, nonce collision is a fatal problem.
* Authenticated encryption do not set encryption for dm-integrity journal.

View File

@@ -30,7 +30,7 @@ Changes since version 2.0.1
* Add LUKS2 specific options for cryptsetup-reencrypt.
Tokens and persistent flags are now transferred during reencryption;
change of PBKDF keyslot parameters is now supported and allows one
change of PBKDF keyslot parameters is now supported and allows
to set precalculated values (no benchmarks).
* Do not allow LUKS2 --persistent and --test-passphrase cryptsetup flags

View File

@@ -28,7 +28,7 @@ Changes since version 2.0.2
* New API extensions for unbound keyslots (LUKS2 only)
crypt_keyslot_get_key_size() and crypt_volume_key_get()
These functions allow one to get key and key size for unbound keyslots.
These functions allow to get key and key size for unbound keyslots.
* New enum value CRYPT_SLOT_UNBOUND for keyslot status (LUKS2 only).

View File

@@ -170,21 +170,21 @@ These new calls are now exported, for details see libcryptsetup.h:
* crypt_get_metadata_size
* crypt_set_metadata_size
allows one to set/get area sizes in LUKS header
allows to set/get area sizes in LUKS header
(according to specification).
* crypt_get_default_type
get default compiled-in LUKS type (version).
* crypt_get_pbkdf_type_params
allows one to get compiled-in PBKDF parameters.
allows to get compiled-in PBKDF parameters.
* crypt_keyslot_set_encryption
* crypt_keyslot_get_encryption
allows one to set/get per-keyslot encryption algorithm for LUKS2.
allows to set/get per-keyslot encryption algorithm for LUKS2.
* crypt_keyslot_get_pbkdf
allows one to get PBKDF parameters per-keyslot.
allows to get PBKDF parameters per-keyslot.
and these new defines:
* CRYPT_LOG_DEBUG_JSON (message type for JSON debug)

View File

@@ -9,7 +9,7 @@ native read-write access to BitLocker Full Disk Encryption devices.
The BITLK implementation is based on publicly available information
and it is an independent and opensource implementation that allows
one to access this proprietary disk encryption.
to access this proprietary disk encryption.
Changes since version 2.2.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -18,7 +18,7 @@ Changes since version 2.3.1
The slot number --key-slot (-S) option is mandatory here.
An unbound keyslot store a key is that is not assigned to data
area on disk (LUKS2 allows one to store arbitrary keys).
area on disk (LUKS2 allows to store arbitrary keys).
* Rephrase some error messages and remove redundant end-of-lines.

View File

@@ -75,7 +75,7 @@ Changes since version 2.3.3
If users want to use blake2b/blake2s, the kernel algorithm name includes
a dash (like "blake2s-256").
These algorithms can now be used for integritysetup devices.
Theses algorithms can now be used for integritysetup devices.
* Fix crypto backend to properly handle ECB mode.

View File

@@ -1,291 +0,0 @@
Cryptsetup 2.5.0 Release Notes
==============================
Stable release with new features and bug fixes.
Changes since version 2.4.3
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Split manual pages into per-action pages and use AsciiDoc format.
Manual pages are now generated from AsciiDoc format, allowing easy
conditional modifications for per-action options.
Generation of man pages requires the asciidoctor tool installed.
Pre-generated man pages are also included in the distribution tarball.
You can use --disable-asciidoc configure option to skip man page
generation completely. In this case, pre-generated man pages will be
used for installation.
For cryptsetup, there is main man page (cryptsetup.8) that references
separate man pages for each command (for example, cryptsetup-open.8).
You can open such a man page by simply running "man cryptsetup open".
Also, man pages for action aliases are available (cryptsetup-luksOpen.8
is an alias for cryptsetup-open.8, etc.)
LUKS volume reencryption changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Remove cryptsetup-reencrypt tool from the project and move reencryption
to already existing "cryptsetup reencrypt" command.
Cryptsetup reencrypt now handles both LUKS1 and LUKS2 reencryption,
encryption, and decryption.
If you need to emulate the old cryptsetup-reencrypt binary, use simple
wrappers script running "exec cryptsetup reencrypt $@".
All command line options should be compatible. An exception is the
reencryption of LUKS2 volumes with old LUKS1 reencryption code that was
replaced by native and more resilient LUKS2 reencryption.
* LUKS2: implement --decryption option that allows LUKS removal. The
operation can run online or offline and supports the data shift option.
During the initialization, the LUKS2 header is exported to a file.
The first data segment is moved to the head of the data device in place
of the original header.
The feature internally introduces several new resilience modes
(combination of existing modes datashift and "checksum" or "journal").
Datashift resilience mode is applied for data moved towards the first
segment, and the first segment is then decrypted in place.
This decryption mode is not backward compatible with prior LUKS2
reencryption. Interrupted operations in progress cannot be resumed
using older cryptsetup releases.
* Reencryption metadata options that are not compatible with recent code
(features implemented in more recent releases) are now only read, but
code will not activate or modify such metadata.
Reencryption metadata contains a version that is validated when
reencryption is resumed.
For more info, see the updated LUKS2 on-disk format specification.
Safe operation of reencryption is to always finish the operation with
only one version of the tools.
* Fix decryption operation with --active-name option and restrict
it to be used only with LUKS2.
* Do not refresh reencryption digest when not needed.
This should speed up the reencryption resume process.
* Store proper resilience data in LUKS2 reencrypt initialization.
Resuming reencryption now does not require specification of resilience
type parameters if these are the same as during initialization.
* Properly wipe the unused area after reencryption with datashift in
the forward direction.
* Check datashift value against larger sector size.
For example, it could cause an issue if misaligned 4K sector appears
during decryption.
* Do not allow sector size increase reencryption in offline mode.
The eventual logical block size increase on the dm-crypt device above
may lead to an unusable filesystem. Do not allow offline reencryption
when sector size increase is requested.
You can use --force-offline-reencrypt option to override this check
(and potentially destroy the data).
* Do not allow dangerous sector size change during reencryption.
By changing the encryption sector size during reencryption, a user
may increase the effective logical block size for the dm-crypt active
device.
Do not allow encryption sector size to be increased over the value
provided by fs superblock in BLOCK_SIZE property.
* Ask the user for confirmation before resuming reencryption.
The prompt is not shown in batch mode or when the user explicitly asks
for a reencryption resume via --resume-only.
* Do not resume reencryption with conflicting parameters.
For example, if the operation was initialized as --encrypt, do not
allow resume with opposing parameter --decrypt and vice versa.
Also, the code now checks for conflicting resilience parameters
(datashift cannot be changed after initialization).
* Add --force-offline-reencrypt option.
It can be used to enforce offline reencryption in batch mode when
the device is a regular file; therefore, cryptsetup cannot detect
properly active devices using it.
Also, it may be useful to override the active device auto-detection
for specific storage configurations (dangerous!).
* Do not allow nested encryption in LUKS reencrypt.
Avoid accidental nested encryption via cryptsetup reencrypt --encrypt.
* Fix --test-passphrase when the device is in reencryption.
* Do not upload keys in keyring during offline reencryption.
Reencryption runs in userspace, so the kernel does not need the key.
* Support all options allowed with luksFormat with encrypt action.
* Add prompt if LUKS2 decryption is run with a detached header.
* Add warning for reencryption of file image and mention
the possible use of --force-offline-reencrypt option.
Other changes
~~~~~~~~~~~~~
* Add resize action to integritysetup.
This allows resizing of standalone integrity devices.
* Support --device-size option (that allows unit specification) for plain
devices (existing --size option requires 512-byte sectors units).
* Fix detection of encryption sector size if a detached header is used.
* Remove obsolete dracut plugin reencryption example.
* Fix possible keyslot area size overflow during conversion to LUKS2.
If keyslots are not sorted according to binary area offset, the area
size calculation was wrong and could overflow.
* Hardening and fixes to LUKS2 validation functions:
* Log a visible error if convert fails due to validation check.
* Check for interval (keyslot and segment area) overflow.
* Check cipher availability before LUKS conversion to LUKS2.
Some historic incompatibilities are ignored for LUKS1 but do not
work for LUKS2.
* Add empty string check to LUKS2 metadata JSON validation.
Most of the LUKS2 fields cannot be empty.
* Fix JSON objects validation to check JSON object type properly.
* TCRYPT: Properly apply retry count and continue if some PBKDF variant
is unavailable.
* BITLK: Add a warning when activating a device with the wrong size
stored in metadata.
* BITLK: Add BitLocker volume size to dump command.
* BITLK: Fix possible UTF16 buffer overflow in volume key dump.
* BITLK: Skip question if the batch mode is set for volume key dump.
* BITLK: Check dm-zero availability in the kernel.
Bitlocker compatible mode uses dm-zero to mask metadata area.
The device cannot be activated if dm-zero is not available.
* Fix error message for LUKS2-only cryptsetup commands to explicitly
state LUKS2 version is required.
* Fix error message for incompatible dm-integrity metadata.
If the integritysetup tool is too old, kernel dm-integrity may use
a more recent version of dm-integrity metadata.
* Properly deactivate the integrity device even if the LUKS2 header
is no longer available.
If LUKS2 is used with integrity protection, there is always
a dm-integrity device underneath that must be deactivated.
* Allow use of --header option for cryptsetup close.
This can be used to check that the activated device has the same UUID.
* Fix activation of LUKS2 device with integrity and detached header.
The kernel-parsed dm-integrity superblock is always located on the
data device, the incorrectly used detached header device here.
* Add ZEROOUT IOCTL support for crypt_wipe API call.
For block devices, we can use optimized in-kernel BLKZEROOUT ioctl.
* VERITY: set loopback sector size according to dm-verity block sizes.
Verity block size has the same limits, so we can optimize the loop
device to increase performance.
* Other Documentation and man page improvements:
* Update LUKS2 on-disk format description.
* Add per-keyslot LUKS2 options to the man page.
Some options were missing for LUKS2 luksAddKey and luksChangeKey.
* Fix cryptsetup manpage to use PBKDF consistently.
* Add compile info to README. This information was lost when we removed
the default automake INSTALL file.
* Use volume key consistently in FAQ and man pages.
* Use markdown version of FAQ directly for installation.
* Clarify graceful reencryption interruption.
Currently, it can be interrupted by both SIGINT and SIGTERM signals.
* Add new mailing list info.
* Mention non-cryptographic xxhash64 hash for integrity protection.
* veritysetup: dump device sizes.
Calculating device sizes for verity devices is a little bit tricky.
Data, hash, and FEC can share devices or be separate devices.
Now dump command prints used device sizes, but it requires that
the user specifies all values that are not stored in superblock
(like FEC device and FEC roots).
* Fix check for argp_usage in configure if argp-standalone lib is used.
* Add constant time memcmp and hexa print implementation and use it for
cryptographic keys handling.
* Display progress when wiping the end of the resized device.
* LUKS2 token: prefer token PIN query before passphrase in some cases.
When a user provides --token-type or specific --token-id, a token PIN
query is preferred to a passphrase query.
* LUKS2 token: allow tokens to be replaced with --token-replace option
for cryptsetup token command.
* LUKS2 token: do not continue operation when interrupted in PIN prompt.
* Add --progress-json parameter to utilities.
Progress data can now be printed out in JSON format suitable for
machine processing.
* Embedded Argon2 PBKDF: optimize and simplify thread exit.
* Avoid using SHA1 in tests and fix new enforcements introduced in FIPS
provider for OpenSSL3 (like minimal parameters for PBKDF2).
* Use custom UTF conversion and avoid linking to iconv as a dependency.
* Reimplement BASE64 with simplified code instead of coreutils version.
* Fix regression when warning messages were not displayed
if some kernel feature is not supported (2.4.2).
* Add support for --key-slot option in luksResume action.
Libcryptsetup API extensions and changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Properly define uint32_t constants in API.
This is not a real change, but it avoids strict compiler warnings.
* crypt_resume_by_token_pin() - Resume crypt device using LUKS2 token.
* crypt_get_label() - Get the label of the LUKS2 device.
* crypt_get_subsystem() - Get the subsystem label of the LUKS2 device.
* Make CRYPT_WIPE_ENCRYPTED_ZERO crypt_wipe() option obsolete.
It was never implemented (the idea was to speed up wipe), but with
the recent RNG performance changes, it makes no longer sense.
* Add struct crypt_params_reencrypt changes related to decryption.
* Improve crypt_reencrypt_status() return values.
Empty or any non-LUKS types now returns CRYPT_REENCRYPT_INVALID status.
For LUKS1 devices, it returns CRYPT_REENCRYPT_NONE.

View File

@@ -1,236 +0,0 @@
Cryptsetup 2.6.0 Release Notes
==============================
Stable release with new features and bug fixes.
Changes since version 2.5.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Introduce support for handling macOS FileVault2 devices (FVAULT2).
Cryptsetup now supports the mapping of FileVault2 full-disk encryption
by Apple for the macOS operating system using a native Linux kernel.
You can open an existing USB FileVault portable device and (with
the hfsplus filesystem driver) access the native data read/write.
Cryptsetup supports only (legacy) FileVault2 based on Core Storage
and HFS+ filesystem (introduced in MacOS X 10.7 Lion).
It does NOT support the new version of FileVault based on the APFS
filesystem used in recent macOS versions.
Header formatting and changes are not supported; cryptsetup never
changes the metadata on the device.
FVAULT2 extension requires kernel userspace crypto API and kernel
driver for HFS+ (hfsplus) filesystem (available on most systems today).
Example of using FileVault2 formatted USB device:
A typical encrypted device contains three partitions; the FileVault
encrypted partition is here sda2:
$ lsblk -o NAME,FSTYPE,LABEL /dev/sda
NAME FSTYPE LABEL
sda
|-sda1 vfat EFI
|-sda2
`-sda3 hfsplus Boot OS X
Note: blkid does not recognize FileVault2 format yet.
To dump metadata information about the device, you can use
the fvault2Dump command:
$ cryptsetup fvault2Dump /dev/sda2
Header information for FVAULT2 device /dev/sda2.
Physical volume UUID: 6f353c05-daae-4e76-a0ee-6a9569a22d81
Family UUID: f82cceb0-a788-4815-945a-53d57fcd55a8
Logical volume offset: 67108864 [bytes]
Logical volume size: 3288334336 [bytes]
Cipher: aes
Cipher mode: xts-plain64
PBKDF2 iterations: 97962
PBKDF2 salt: 173a4ec7447662ec79ca7a47df6c2a01
To activate the device, use open --type fvault2 option:
$ cryptsetup open --type fvault2 /dev/sda2 test
Enter passphrase for /dev/sda2: ...
And check the status of the active device:
$ cryptsetup status test
/dev/mapper/test is active.
type: FVAULT2
cipher: aes-xts-plain64
keysize: 256 bits
key location: dm-crypt
device: /dev/sda2
sector size: 512
offset: 131072 sectors
size: 6422528 sectors
mode: read/write
Now, if the kernel contains hfsplus filesystem driver, you can mount
decrypted content:
$ mount /dev/mapper/test /mnt/test
For more info about implementation, please refer to the master thesis
by Pavel Tobias, which was the source for this extension.
https://is.muni.cz/th/p0aok/?lang=en
* libcryptsetup: no longer use global memory locking through mlockall()
For many years, libcryptsetup locked all memory (including dependent
library address space) to prevent swapping sensitive content outside
of RAM.
This strategy no longer works as the locking of basic libraries exceeds
the memory locking limit if running as a non-root user.
Libcryptsetup now locks only memory ranges containing sensitive
material (keys) through crypt_safe_alloc() calls.
This change solves many reported mysterious problems of unexpected
failures. If the initial lock was still under the limit and succeeded,
some following memory allocation could fail later as it exceeded
the locking limit. If the initial locking fails, memory locking
was quietly ignored completely.
The whole crypt_memory_lock() API call is deprecated; it no longer
calls memlockall().
* libcryptsetup: process priority is increased only for key derivation
(PBKDF) calls.
Increasing priority was tight to memory locking and works only if
running under superuser.
Only PBKDF calls and benchmarking now increase the process priority.
* Add new LUKS keyslot context handling functions and API.
In practice, the luksAddKey action does two operations.
It unlocks the existing device volume key and stores the unlocked
volume key in a new keyslot.
Previously the options were limited to key files and passphrases.
Newly available methods (keyslot contexts) are passphrase, keyfile,
key (binary representation), and LUKS2 token.
To unlock a keyslot user may:
- provide existing passphrase via interactive prompt (default method)
- use --key-file option to provide a file with a valid passphrase
- provide volume key directly via --volume-key-file
- unlock keyslot via all available LUKS2 tokens by --token-only
- unlock keyslot via specific token with --token-id
- unlock keyslot via specific token type by --token-type
To provide the passphrase for a new keyslot, a user may:
- provide existing passphrase via interactive prompt (default method)
- use --new-keyfile to read the passphrase from the file
- use --new-token-id to select LUKS2 token to get passphrase
for new keyslot. The new keyslot is assigned to the selected token
id if the operation is successful.
* The volume key may now be extracted using a passphrase, keyfile, or
token. For LUKS devices, it also returns the volume key after
a successful crypt_format call.
* Fix --disable-luks2-reencryption configuration option.
* cryptsetup: Print a better error message and warning if the format
produces an image without space available for data.
Activation now fails early with a more descriptive message.
* Print error if anti-forensic LUKS2 hash setting is not available.
If the specified hash was not available, activation quietly failed.
* Fix internal crypt segment compare routine if the user
specified cipher in kernel format (capi: prefix).
* cryptsetup: Add token unassign action.
This action allows removing token binding on specific keyslot.
* veritysetup: add support for --use-tasklets option.
This option sets try_verify_in_tasklet kernel dm-verity option
(available since Linux kernel 6.0) to allow some performance
improvement on specific systems.
* Provide pkgconfig Require.private settings.
While we do not completely provide static build on udev systems,
it helps produce statically linked binaries in certain situations.
* Always update automake library files if autogen.sh is run.
For several releases, we distributed older automake scripts by mistake.
* reencryption: Fix user defined moved segment size in LUKS2 decryption.
The --hotzone-size argument was ignored in cases where the actual data
size was less than the original LUKS2 data offset.
* Delegate FIPS mode detection to configured crypto backend.
System FIPS mode check no longer depends on /etc/system-fips file.
* tests: externally provided systemd plugin is now optionally compiled
from systemd git and tested with cryptsetup
* tests: initial integration to OSS-fuzz project with basic crypt_load()
test for LUKS2 and JSON mutated fuzzing.
For more info, see README in tests/fuzz directory.
* Update documentation, including FAQ and man pages.
Libcryptsetup API extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The libcryptsetup API is backward compatible with existing symbols.
New symbols:
crypt_keyslot_context_init_by_passphrase
crypt_keyslot_context_init_by_keyfile
crypt_keyslot_context_init_by_token
crypt_keyslot_context_init_by_volume_key
crypt_keyslot_context_get_error
crypt_keyslot_context_set_pin
crypt_keyslot_context_get_type
crypt_keyslot_context_free
crypt_keyslot_add_by_keyslot_context
crypt_volume_key_get_by_keyslot_context
New defines:
CRYPT_FVAULT2 "FVAULT2" (FileVault2 compatible mode)
Keyslot context types:
CRYPT_KC_TYPE_PASSPHRASE
CRYPT_KC_TYPE_KEYFILE
CRYPT_KC_TYPE_TOKEN
CRYPT_KC_TYPE_KEY
CRYPT_ACTIVATE_TASKLETS (dm-verity: use tasklets activation flag)
WARNING!
~~~~~~~~
The next version of cryptsetup will change the encryption mode and key
derivation option for the PLAIN format.
This change will cause backward incompatibility.
For this reason, the user will have to specify the exact parameters
for cipher, key size, and key derivation parameters for plain format.
The default encryption mode will be AES-XTS with 512bit key (AES-256).
The CBC mode is no longer considered the best default, as it allows easy
bit-flipped ciphertext modification attacks and performance problems.
For the passphrase hashing in plain mode, the encryption key is directly
derived through iterative hashing from a user-provided passphrase
(except a keyfile that is not hashed).
The default hash is RIPEMD160, which is no longer the best default
option. The exact change will be yet discussed but should include
the possibility of using a password-based key derivation function
instead of iterative hashing.

View File

@@ -1,50 +0,0 @@
Cryptsetup 2.6.1 Release Notes
==============================
Stable bug-fix release with minor extensions.
All users of cryptsetup 2.6.0 should upgrade to this version.
Changes since version 2.6.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* bitlk: Fixes for BitLocker-compatible on-disk metadata parser
(found by new cryptsetup OSS-Fuzz fuzzers).
- Fix a possible memory leak if the metadata contains more than
one description field.
- Harden parsing of metadata entries for key and description entries.
- Fix broken metadata parsing that can cause a crash or out of memory.
* Fix possible iteration overflow in OpenSSL2 PBKDF2 crypto backend.
OpenSSL2 uses a signed integer for PBKDF2 iteration count.
As cryptsetup uses an unsigned value, this can lead to overflow and
a decrease in the actual iteration count.
This situation can happen only if the user specifies
--pbkdf-force-iterations option.
OpenSSL3 (and other supported crypto backends) are not affected.
* Fix compilation for new ISO C standards (gcc with -std=c11 and higher).
* fvault2: Fix compilation with very old uuid.h.
* verity: Fix possible hash offset setting overflow.
* bitlk: Fix use of startup BEK key on big-endian platforms.
* Fix compilation with latest musl library.
Recent musl no longer implements lseek64() in some configurations.
Use lseek() as 64-bit offset is mandatory for cryptsetup.
* Do not initiate encryption (reencryption command) when the header and
data devices are the same.
If data device reduction is not requsted, this leads to data corruption
since LUKS metadata was written over the data device.
* Fix possible memory leak if crypt_load() fails.
* Always use passphrases with a minimal 8 chars length for benchmarking.
Some enterprise distributions decided to set an unconditional check
for PBKDF2 password length when running in FIPS mode.
This questionable change led to unexpected failures during LUKS format
and keyslot operations, where short passwords were used for
benchmarking PBKDF2 speed.
PBKDF2 benchmark calculations should not be affected by this change.

View File

@@ -1,437 +0,0 @@
Cryptsetup 2.7.0 Release Notes
==============================
Stable release with new features and bug fixes.
Changes since version 2.6.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Introduce support for hardware OPAL disk encryption.
Some SATA and NVMe devices support hardware encryption through OPAL2
TCG interface (SEDs - self-encrypting drives). Using hardware disk
encryption is controversial as you must trust proprietary hardware.
On the other side, using both software and hardware encryption
layers increases the security margin by adding an additional layer
of protection. There is usually no performance drop if OPAL encryption
is used (the drive always operates with full throughput), and it does
not add any utilization to the main CPU.
LUKS2 now supports hardware encryption through the Linux kernel
SED OPAL interface (CONFIG_BLK_SED_OPAL Linux kernel option must be
enabled). Cryptsetup OPAL is never enabled by default; you have to use
luksFormat parameters to use it. OPAL support can be disabled during
the build phase with --disable-hw-opal configure option.
LUKS2 OPAL encryption is configured the same way as software encryption
- it stores metadata in the LUKS2 header and activates encryption for
the data area on the disk (configured OPAL locking range).
LUKS2 header metadata must always be visible (thus not encrypted).
The key stored in LUKS2 keyslots contains two parts - volume key
for software (dm-crypt) encryption and unlocking key for OPAL.
OPAL unlocking key is independent of the dm-crypt volume key and is
always 256 bits long. Cryptsetup does not support full drive OPAL
encryption; only a specific locking range is always used.
If the OPAL device is in its initial factory state (after factory
reset), cryptsetup needs to configure the OPAL admin user and password.
If the OPAL admin user is already set, the OPAL password must be
provided during luksFormat.
The provided password is needed only to configure or reset the OPAL
locking range; LUKS device activation requires LUKS passphrase only.
LUKS passphrase should be different from OPAL password (OPAL admin user
is configured inside OPAL hardware while LUKS unlocking passphrase
unlocks LUKS keyslot).
OPAL encryption can be used in combination with software (dm-crypt)
encryption (--hw-opal option) or without the software layer
(--hw-opal-only option).
You can see the configured segment parameters in the luksDump command.
LUKS2 devices with OPAL segments set a new requirement flag in
the LUKS2 header to prevent older cryptsetup metadata manipulation.
Do not use hardware-only encryption if you do not fully trust your
hardware vendor.
Compatibility notes:
- Linux kernel SED interface does NOT work through USB external
adapters due to the missing compatibility layer in Linux USB storage
drivers (even if USB hardware itself can support OPAL commands).
- other TCG security subsystems like Ruby or Pyrite are not
supported. Note that many drives support only Pyrite subsystem that
does NOT encrypt data (it provides only authentication).
- compatibility among OPAL-enabled drives is often very problematic,
specifically for older drives. Many drives have bugs in the firmware
that make the Linux kernel interface unusable.
- if you forget the OPAL admin password, the only way to recover is
the full drive factory reset through the PSID key (usually printed
on the drive itself) that wipes all data on the drive (not only the
LUKS area).
- cryptsetup reencryption is not supported for LUKS2 OPAL-enabled
devices
- most OPAL drives use AES-XTS cipher mode (older drives can use
AES-CBC). This information is not available through kernel SED API.
- locked OPAL locking ranges return IO errors while reading; this
can produce a lot of scary messages in the log if some tools (like
blkid) try to read the locked area.
Examples:
* Formatting the drive
Use --hw-opal with luksFormat (or --hw-opal-only for hardware only
encryption):
# cryptsetup luksFormat --hw-opal <device>
Enter passphrase for <device>: ***
Enter OPAL Admin password: ***
* Check configuration with luksDump.
Note "hw-opal-crypt" segment that uses both dm-crypt and OPAL
encryption - keyslot stores 768 bits key (512 sw + 256 bits OPAL key).
# cryptsetup luksDump <device>
LUKS header information
Version: 2
...
Data segments:
0: hw-opal-crypt
offset: 16777216 [bytes]
length: ... [bytes]
cipher: aes-xts-plain64
sector: 512 [bytes]
HW OPAL encryption:
OPAL segment number: 1
OPAL key: 256 bits
OPAL segment length: ... [bytes]
Keyslots:
0: luks2
Key: 768 bits
...
For devices with OPAL encryption ONLY (only 256 bits OPAL unlocking
key is stored):
LUKS header information
Version: 2
...
Data segments:
0: hw-opal
offset: 16777216 [bytes]
length: ... [bytes]
cipher: (no SW encryption)
HW OPAL encryption:
OPAL segment number: 1
OPAL key: 256 bits
OPAL segment length: ... [bytes]
Keyslots:
0: luks2
Key: 256 bits
...
* Activation and deactivation (open, close, luksSuspend, luksResume)
with OPAL works the same as for the LUKS2 device.
* Erase LUKS metadata (keyslots) and remove OPAL locking range:
# cryptsetup luksErase <device>
Enter OPAL Admin password: ***
The LUKS header is destroyed (unlike in normal LUKS luksErase) as
data are no longer accessible even with previous volume key knowledge.
* Factory reset OPAL drive (if you do not know the Admin password).
You need the PSID (physical presence security ID), which is usually
printed on the device label. Note this will reset the device to
factory state, erasing all data on it (not only LUKS).
# cryptsetup luksErase --hw-opal-factory-reset <device>
Enter OPAL PSID: ***
* plain mode: Set default cipher to aes-xts-plain64 and password hashing
to sha256.
NOTE: this is a backward incompatible change for plain mode (if you
rely on defaults). It is not relevant for LUKS devices.
The default plain encryption mode was CBC for a long time, with many
performance problems. Using XTS mode aligns it with LUKS defaults.
The hash algorithm for plain mode was ripemd160, which is considered
deprecated, so the new default is sha256.
The default key size remains 256 bits (it means using AES-128 as XTS
requires two keys).
Always specify cipher, hash, and key size for plain mode (or even
better, use LUKS as it stores all options in its metadata on disk).
As we need to upgrade algorithms from time to time because of security
reasons, cryptsetup now warns users to specify these options explicitly
in the open cryptsetup command if plain mode is used.
Cryptsetup does not block using any legacy encryption type; just it
must be specified explicitly on the cryptsetup command line.
You can configure these defaults during build time if you need to
enforce backward compatibility.
To get the backward-compatible setting, use:
--with-plain-hash=ripemd160 --with-plain-cipher=aes
--with-plain-mode=cbc-essiv:sha256
Compiled-in defaults are visible in cryptsetup --help output.
* Allow activation (open), luksResume, and luksAddKey to use the volume
key stored in a keyring.
* Allow to store volume key to a user-specified keyring in open and
luksResume commands.
These options are intended to be used for integration with other
systems for automation.
Users can now use the volume key (not passphrase) stored in arbitrary
kernel keyring and directly use it in particular cryptsetup commands
with --volume-key-keyring option. The keyring can use various policies
(set outside of the cryptsetup scope, for example, by keyctl).
The --volume-key-keyring option takes a key description in
keyctl-compatible syntax and can either be a numeric key ID or
a string name in the format [%<key type>:]<key name>.
The default key type is "user".
To store the volume key in a keyring, you can use cryptsetup with
--link-vk-to-keyring option that is available for open and luksResume
cryptsetup command. The option argument has a more complex format:
<keyring_description>::<key_description>.
The <keyring_description> contains the existing kernel keyring
description (numeric id or keyctl format). The <keyring_description>
may be optionally prefixed with "%:" or "%keyring:". The string "::" is
a delimiter that separates keyring and key descriptions.
The <key_description> has the same syntax as used in the
--volume-key-keyring option.
Example:
Open the device and store the volume key to the keyring:
# cryptsetup open <device> --link-vk-to-keyring "@s::%user:testkey" tst
Add keyslot using the stored key in a keyring:
# cryptsetup luksAddKey <device> --volume-key-keyring "%user:testkey"
* Do not flush IO operations if resize grows the device.
This can help performance in specific cases where the encrypted device
is extended automatically while running many IO operations.
* Use only half of detected free memory for Argon2 PBKDF on systems
without swap (for LUKS2 new keyslot or format operations).
This should avoid out-of-memory crashes on low-memory systems without
swap. The benchmark for memory-hard KDF during format is tricky, and
it seems that relying on the maximum half of physical memory is not
enough; relying on free memory should bring the needed security margin
while still using Argon2.
There is no change for systems with active swap.
Note, for very-low memory-constrained systems, a user should avoid
memory-hard PBKDF completely (manually select legacy PBKDF2 instead
of Argon2); cryptsetup does not change PBKDF automatically.
* Add the possibility to specify a directory for external LUKS2 token
handlers (plugins).
Use --external-tokens-path parameter in cryptsetup or
crypt_token_set_external_path API call. The parameter is required to be
an absolute path, and it is set per process context. This parameter is
intended mainly for testing and developing new tokens.
* Do not allow reencryption/decryption on LUKS2 devices with
authenticated encryption or hardware (OPAL) encryption.
The operation fails later anyway; cryptsetup now detects incompatible
parameters early.
* Do not fail LUKS format if the operation was interrupted on subsequent
device wipe.
Device wipe (used with authenticated encryption) is an optional
operation and can be interrupted; not yet wiped part of the device will
only report integrity errors (until overwritten with new data).
* Fix the LUKS2 keyslot option to be used while activating the device
by a token.
It can also be used to check if a specific token (--token-id) can
unlock a specific keyslot (--key-slot option) when --test-passphrase
option is specified.
* Properly report if the dm-verity device cannot be activated due to
the inability to verify the signed root hash (ENOKEY).
* Fix to check passphrase for selected keyslot only when adding
new keyslot.
If the user specifies the exact keyslot to unlock, cryptsetup no longer
checks other keyslots.
* Fix to not wipe the keyslot area before in-place overwrite.
If the LUKS2 keyslot area has to be overwritten (due to lack of free
space for keyslot swap), cryptsetup does not wipe the affected area as
the first step (it will be overwritten later anyway).
Previously, there was an unnecessary risk of losing the keyslot data
if the code crashed before adding the new keyslot.
If there is enough space in the keyslot area, cryptsetup never
overwrites the older keyslot before the new one is written correctly
(even if the keyslot number remains the same).
* bitlk: Fix segfaults when attempting to verify the volume key.
Also, clarify that verifying the volume key is impossible without
providing a passphrase or recovery key.
* Add --disable-blkid command line option to avoid blkid device check.
* Add support for the meson build system.
All basic operations are supported (compile, test, and dist) with some
minor exceptions; please see the meson manual for more info.
The Meson build system will completely replace autotools in some future
major release. Both autotools and meson build systems are supported,
and the release archive is built with autotools.
* Fix wipe operation that overwrites the whole device if used for LUKS2
header with no keyslot area.
Formatting a LUKS2 device with no defined keyslots area is a very
specific operation, and the code now properly recognizes such
configuration.
* Fix luksErase to work with detached LUKS header.
* Disallow the use of internal kernel crypto driver names in "capi"
specification.
The common way to specify cipher mode in cryptsetup is to use
cipher-mode-iv notation (like aes-xts-plain64).
With the introduction of authenticated ciphers, we also allow
"capi:<spec>" notation that is directly used by dm-crypt
(e.g., capi:xts(aes)-plain64).
CAPI specification was never intended to be used directly in the LUKS
header; unfortunately, the code allowed it until now.
Devices with CAPI specification in metadata can no longer be activated;
header repair is required.
CAPI specification could allow attackers to change the cipher
specification to enforce loading some specific kernel crypto driver
(for example, load driver with known side-channel issues).
This can be problematic, specifically in a cloud environment
(modifying LUKS2 metadata in container image).
Thanks to Jan Wichelmann, Luca Wilke, and Thomas Eisenbarth from
University of Luebeck for noticing the problems with this code.
* Fix reencryption to fail early for unknown cipher.
* tcrypt: Support new Blake2 hash for VeraCrypt.
VeraCrypt introduces support for Blake2 PRF for PBKDF2; also support it
in cryptsetup compatible tcrypt format.
* tcrypt: use hash values as substring for limiting KDF check.
This allows the user to specify --hash sha or --hash blake2 to limit
the KDF scan without the need to specify the full algorithm name
(similar to cipher where we already use substring match).
* Add Aria cipher support and block size info.
Aria cipher is similar to AES and is supported in Linux kernel crypto
API in recent releases.
It can be now used also for LUKS keyslot encryption.
* Do not decrease PBKDF parameters if the user forces them.
If a user explicitly specifies PBKDF parameters (like iterations,
used memory, or threads), do not limit them, even if it can cause
resource exhaustion.
The force options were mostly used for decreasing parameters, but it
should work even opposite - despite the fact it can mean an
out-of-memory crash.
The only limits are hard limits per the PBKDF algorithm.
* Support OpenSSL 3.2 Argon2 implementation.
Argon2 is now available directly in OpenSSL, so the code no longer
needs to use libargon implementation.
Configure script should detect this automatically.
* Add support for Argon2 from libgcrypt
(requires yet unreleased gcrypt 1.11).
Argon2 has been available since version 1.10, but we need version 1.11,
which will allow empty passwords.
* Used Argon2 PBKDF implementation is now reported in debug mode
in the cryptographic backend version. For native support in
OpenSSL 3.2 or libgcrypt 1.11, "argon2" is displayed.
If libargon2 is used, "cryptsetup libargon2" (for embedded
library) or "external libargon2" is displayed.
* Link only libcrypto from OpenSSL.
This reduces dependencies as other OpenSSL libraries are not needed.
* Disable reencryption for Direct-Access (DAX) devices.
Linux kernel device-mapper cannot stack DAX/non-DAX devices in
the mapping table, so online reencryption cannot work. Detect DAX
devices and warn users during LUKS format. Also, DAX or persistent
memory devices do not provide atomic sector updates; any single
modification can corrupt the whole encryption block.
* Print a warning message if the device is not aligned to sector size.
If a partition is resized after format, activation could fail when
the device is not multiple of a sector size. Print at least a warning
here, as the activation error message is visible only in kernel syslog.
* Fix sector size and integrity fields display for non-LUKS2 crypt
devices for the status command.
* Fix suspend for LUKS2 with authenticated encryption (also suspend
dm-integrity device underneath).
This should stop the dm-integrity device from issuing journal updates
and possibly corrupt data if the user also tries to modify the
underlying device.
* Update keyring and locking documentation and LUKS2 specification
for OPAL2 support.
Libcryptsetup API extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The libcryptsetup API is backward compatible for all existing symbols.
New symbols:
crypt_activate_by_keyslot_context
crypt_format_luks2_opal
crypt_get_hw_encryption_type
crypt_get_hw_encryption_key_size
crypt_keyslot_context_init_by_keyring
crypt_keyslot_context_init_by_vk_in_keyring
crypt_keyslot_context_init_by_signed_key
crypt_resume_by_keyslot_context
crypt_token_set_external_path
crypt_set_keyring_to_link
crypt_wipe_hw_opal
New defines (hw encryption status):
CRYPT_SW_ONLY
CRYPT_OPAL_HW_ONLY
CRYPT_SW_AND_OPAL_HW
New keyslot context types:
CRYPT_KC_TYPE_KEYRING
CRYPT_KC_TYPE_VK_KEYRING
CRYPT_KC_TYPE_SIGNED_KEY
New requirement flag:
CRYPT_REQUIREMENT_OPAL

View File

@@ -1,30 +0,0 @@
Cryptsetup 2.7.1 Release Notes
==============================
Stable bug-fix release with minor extensions.
All users of cryptsetup 2.7.0 should upgrade to this version.
Changes since version 2.7.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix interrupted LUKS1 decryption resume.
With the replacement of the cryptsetup-reencrypt tool by the cryptsetup
reencrypt command, resuming the interrupted LUKS1 decryption operation
could fail. LUKS2 was not affected.
* Allow --link-vk-to-keyring with --test-passphrase option.
This option allows uploading the volume key in a user-specified kernel
keyring without activating the device.
* Fix crash when --active-name was used in decryption initialization.
* Updates and changes to man pages, including indentation, sorting options
alphabetically, fixing mistakes in crypt_set_keyring_to_link, and fixing
some typos.
* Fix compilation with libargon2 when --disable-internal-argon2 was used.
* Do not require installed argon2.h header and never compile internal
libargon2 code if the crypto library directly supports Argon2.
* Fixes to regression tests to support older Linux distributions.

View File

@@ -1,31 +0,0 @@
Cryptsetup 2.7.2 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.7 should upgrade to this version.
Changes since version 2.7.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix activation of OPAL-only encrypted LUKS device with tokens.
The issue was caused by an invalid volume key check (assert)
that is impossible without software encryption.
* Fix formatting of OPAL devices with 4096-byte sector size.
* Fix incorrect OPAL locking range alignment calculation if used
over an unaligned device partition.
* Add --hw-opal-factory-reset option description to the manual page.
* Do not check the passphrase quality for OPAL Admin PIN,
as this passphrase already exists.
* Update license for FAQ document to CC BY-SA 4.0.
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.

View File

@@ -1,114 +0,0 @@
Cryptsetup 2.7.3 Release Notes
==============================
Stable bug-fix release with security fixes.
All users of cryptsetup 2.7 must upgrade to this version.
Changes since version 2.7.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Do not allow formatting LUKS2 with Opal SED (hardware encryption)
if the reported logical sector size for the block device and Opal
encryption logical block differs.
Such a configuration can lead to a partially encrypted Opal locking
range or data destruction following the expected locking range.
Some NVMe drives support multiple LBAF profiles (typically supporting
512-byte and 4096-byte sector size). Some broken Opal NVMe firmware can
report bogus encryption size that disagrees with real used sector size.
This usually happens after low-level NVMe reformatting (LBAF profile
change with nvme utility) to different sector size.
Moreover, some firmware versions do not properly reset this even after
explicit PSID revert.
Cryptsetup calculates the Opal locking range using the reported block
size in Opal geometry ioctl. Unfortunately, the broken firmware drive
internally uses the logical block size of the block device, which can
differ. This can lead to two possible situations:
- Opal reports a smaller block size (512-byte) while the drive uses
a 4096-byte sector. The configured locking range is then much larger,
destroying data following the expected locking range setting.
- Opal reports a larger block size (4096-byte) while the drive uses
a 512-byte sector. The configured locking range is then much smaller,
leaving the remaining space in the locking range unencrypted (violating
the confidentiality of data).
Cryptsetup now detects this discrepancy and disallows LUKS2 format with
Opal hardware encryption in such a case.
For already formatted devices, you will see this warning:
"Bogus OPAL logical block size differs from device block size."
If you also used software encryption (dm-crypt over Opal), data will
still be fully encrypted with software dm-crypt.
With hw-only encryption, your configuration is probably already broken
(insecure or accessing data beyond the assigned area).
Note that this is caused by bad firmware (seen with multiple vendors),
and the problem was reported, at least for drives we have access to.
* Fixes to wiping LUKS2 headers after Opal locking area erase.
As the hardware locking range is destroyed (cryptsetup erase command),
the LUKS2 header is no longer usable and was partially wiped.
Now the code fully wipes also the secondary header, as the previous
code wiped only the primary LUKS area.
Note that this is an exception, as the normal erase command wipes only
the keyslots, keeping the LUKS2 header in place. With Opal encryption,
the data segment is no longer valid, so the whole LUKS2 header is no
longer usable.
* Mention the need for possible PSID revert before Opal format for some
drives (man page).
* Fix Bitlocker-compatible code to ignore newly seen metadata entries.
Recent Windows OS versions started to include new (undocumented)
metadata entries in Bitlocker. These entries are now quietly ignored,
allowing Bitlocker images to open with cryptsetup again.
* Fix interactive query retry if LUKS2 unbound keyslot is present.
If an unbound keyslot is present, the password query retry count is
now properly applied.
* Detect unsupported zoned devices for LUKS header devices.
Zoned devices cannot be written with direct-io and used for LUKS header
logic in general. Code now rejects placing the LUKS header on a zoned
device, while you can still create a detached header and use a zoned
device for encrypted data.
* Allow "capi" cipher format for benchmark command and fix parsing
of plain IV in "capi" format.
Some ciphers can be specified only in Linux kernel crypto notation
(in short, "capi"). Code now allows this format also for benchmark,
for example, "benchmark -c capi:xts\(aes\)-plain64"
(that is equivalent to -c aes-xts-plain64).
* Add support for HCTR2 encryption mode.
The HCTR2 encryption mode was added to the Linux kernel for fscrypt,
but as it is a length-preserving mode (with sector tweak), it can be
easily used for disk encryption, too.
The mode has the same property as wide modes (any change is propagated
to the whole sector instead of only one block as in XTS mode).
As it needs a larger initialization vector (32 bytes), we need to add
an exception in the userspace format code.
You can now use --cipher aes-hctr2-plain64 for the format operation.
* Source code now uses SPDX license identifiers instead of full
license preambles.
* Fix missing includes for cryptographic backend that could cause
compilation errors for some systems.
* Fix tests to work correctly in FIPS mode with recent OpenSSL 3.2.
* Fix various (mostly false positive) issues detected by Coverity.

View File

@@ -1,62 +0,0 @@
Cryptsetup 2.7.4 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.7 should upgrade to this version.
Changes since version 2.7.3
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Detect device busy failure for device-mapper table-referenced devices.
Some device-mapper ioctl failures can disappear in libdevmapper,
causing the libcryptsetup wrapper to return an invalid error (EINVAL)
instead of EEXIST or EBUSY. One such case is when there is a device
creation race, and the device-mapper device name is created, but
the following mapping table load fails. This can happen because some
block devices used in table mapping have already been claimed by
another process (the kernel needs exclusive access).
The kernel ioctl properly returns EBUSY; this errno is lost in
libdevmapper (dm_task_get_errno returns 0). It should be fixed by
libdevmapper in the future.
Such behavior was seen in the systemd way of handling dm-verity
devices. With these changes, the code should react for EEXIST and
EBUSY, as another process has already activated the device.
Code calling libcryptsetup also must not check the underlying device
with an exclusive open flag (O_EXCL). Otherwise, it could cause a race
in the kernel device-mapper, resulting in no process succeeding device
activation (see also CRYPT_ACTIVATE_SHARED flag below).
* Fix shared activation for dm-verity devices.
The CRYPT_ACTIVATE_SHARED flag was silently ignored when activating
dm-verity devices. Dm-verity shared activation is generally safe
since all verity devices are read-only.
The shared flag is a way to skip the exclusive access check for the
device, allowing it to create multiple mappings with the same device or
properly handle a racy concurrent activation of devices with the same
name from different processes.
* Add --shared option for veritysetup open action.
The option allows the data device to be used in multiple device-mapper
table mappings (skip exclusive access check) or to allow concurrent
dm-verity device activation of the same device (only one process
succeeds in this case; the other will return EEXIST or EBUSY).
* Do not use exclusive flag for the allocated backing loop files.
Using this flag is an undefined operation for opening an existing file.
The flag should be used only for allocated loop (block) devices.
* Fixes for problems found by static analyzers and Valgrind.
These include fixes for non-default libgcrypt, NSS, and Nettle
cryptographic backends, buffer operations to avoid partial read/write,
and several other workarounds for mostly false positive warnings.
* Fixes to tests and CI scripts.

View File

@@ -1,23 +0,0 @@
Cryptsetup 2.7.5 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.7 must upgrade to this version.
Changes since version 2.7.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix possible online reencryption data corruption (only in 2.7.x).
In some situations (initializing a suspended device-mapper device),
cryptsetup disabled direct-io device access. This caused unsafe
online reencryption operations that could lead to data corruption.
The code now adds strict checks (and aborts the operation) and
changes direct-io detection code to prevent data corruption.
* Fix a clang compilation error in SSH token plugin.
As clang linker treats missing symbols as errors, the linker phase
for the SSH token failed as the optional cryptsetup_token_buffer_free
was not defined.
* Fix crypto backend initialization in crypt_format_luks2_opal API call.

View File

@@ -1,328 +0,0 @@
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 <nvme device>" and then you can reformat to the selected profile
(with complete data loss) with "nvme format -l <lbaf>.
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 <device> [--no-wipe]
# integritysetup open <device> test
# integritysetup status test
/dev/mapper/test is active.
type: INTEGRITY
tag size: 4 [bytes]
integrity: crc32c
device: <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 <device> [--integrity-no-wipe]
# cryptsetup open <device> test
# cryptsetup luksDump <device>
...
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 <device>
Keyslot 2 binary data could be corrupted.
Suspected offset: 0x88000
You can use hexdump -v -C -n 128 -s <offset_0xXXXX> <device> 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

View File

@@ -1,40 +0,0 @@
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.

View File

@@ -33,6 +33,7 @@ libcryptsetup_la_LIBADD = \
@JSON_C_LIBS@ \
@BLKID_LIBS@ \
@DL_LIBS@ \
$(LTLIBICONV) \
$(LTLIBINTL) \
libcrypto_backend.la \
libutils_io.la
@@ -53,6 +54,8 @@ libcryptsetup_la_SOURCES = \
lib/utils_loop.h \
lib/utils_devpath.c \
lib/utils_wipe.c \
lib/utils_fips.c \
lib/utils_fips.h \
lib/utils_device.c \
lib/utils_keyring.c \
lib/utils_keyring.h \
@@ -67,14 +70,14 @@ libcryptsetup_la_SOURCES = \
lib/volumekey.c \
lib/random.c \
lib/crypt_plain.c \
lib/base64.h \
lib/base64.c \
lib/integrity/integrity.h \
lib/integrity/integrity.c \
lib/loopaes/loopaes.h \
lib/loopaes/loopaes.c \
lib/tcrypt/tcrypt.h \
lib/tcrypt/tcrypt.c \
lib/keyslot_context.h \
lib/keyslot_context.c \
lib/luks1/af.h \
lib/luks1/af.c \
lib/luks1/keyencryption.c \
@@ -103,11 +106,7 @@ libcryptsetup_la_SOURCES = \
lib/luks2/luks2_token.c \
lib/luks2/luks2_internal.h \
lib/luks2/luks2.h \
lib/luks2/hw_opal/hw_opal.c \
lib/luks2/hw_opal/hw_opal.h \
lib/utils_blkid.c \
lib/utils_blkid.h \
lib/bitlk/bitlk.h \
lib/bitlk/bitlk.c \
lib/fvault2/fvault2.h \
lib/fvault2/fvault2.c
lib/bitlk/bitlk.c

605
lib/base64.c Normal file
View File

@@ -0,0 +1,605 @@
/* base64.c -- Encode binary data using printable characters.
Copyright (C) 1999-2001, 2004-2006, 2009-2019 Free Software Foundation, Inc.
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, 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, see <https://www.gnu.org/licenses/>. */
/* Written by Simon Josefsson. Partially adapted from GNU MailUtils
* (mailbox/filter_trans.c, as of 2004-11-28). Improved by review
* from Paul Eggert, Bruno Haible, and Stepan Kasal.
*
* See also RFC 4648 <https://www.ietf.org/rfc/rfc4648.txt>.
*
* Be careful with error checking. Here is how you would typically
* use these functions:
*
* bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
* if (!ok)
* FAIL: input was not valid base64
* if (out == NULL)
* FAIL: memory allocation error
* OK: data in OUT/OUTLEN
*
* size_t outlen = base64_encode_alloc (in, inlen, &out);
* if (out == NULL && outlen == 0 && inlen != 0)
* FAIL: input too long
* if (out == NULL)
* FAIL: memory allocation error
* OK: data in OUT/OUTLEN.
*
*/
#include <config.h>
/* Get prototype. */
#include "base64.h"
/* Get malloc. */
#include <stdlib.h>
/* Get UCHAR_MAX. */
#include <limits.h>
#include <string.h>
/* C89 compliant way to cast 'char' to 'unsigned char'. */
static unsigned char
to_uchar (char ch)
{
return ch;
}
static const char b64c[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* Base64 encode IN array of size INLEN into OUT array. OUT needs
to be of length >= BASE64_LENGTH(INLEN), and INLEN needs to be
a multiple of 3. */
static void
base64_encode_fast (const char *restrict in, size_t inlen, char *restrict out)
{
while (inlen)
{
*out++ = b64c[(to_uchar (in[0]) >> 2) & 0x3f];
*out++ = b64c[((to_uchar (in[0]) << 4) + (to_uchar (in[1]) >> 4)) & 0x3f];
*out++ = b64c[((to_uchar (in[1]) << 2) + (to_uchar (in[2]) >> 6)) & 0x3f];
*out++ = b64c[to_uchar (in[2]) & 0x3f];
inlen -= 3;
in += 3;
}
}
/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
terminate the output buffer. */
void
base64_encode (const char *restrict in, size_t inlen,
char *restrict out, size_t outlen)
{
/* Note this outlen constraint can be enforced at compile time.
I.E. that the output buffer is exactly large enough to hold
the encoded inlen bytes. The inlen constraints (of corresponding
to outlen, and being a multiple of 3) can change at runtime
at the end of input. However the common case when reading
large inputs is to have both constraints satisfied, so we depend
on both in base_encode_fast(). */
if (outlen % 4 == 0 && inlen == outlen / 4 * 3)
{
base64_encode_fast (in, inlen, out);
return;
}
while (inlen && outlen)
{
*out++ = b64c[(to_uchar (in[0]) >> 2) & 0x3f];
if (!--outlen)
break;
*out++ = b64c[((to_uchar (in[0]) << 4)
+ (--inlen ? to_uchar (in[1]) >> 4 : 0))
& 0x3f];
if (!--outlen)
break;
*out++ =
(inlen
? b64c[((to_uchar (in[1]) << 2)
+ (--inlen ? to_uchar (in[2]) >> 6 : 0))
& 0x3f]
: '=');
if (!--outlen)
break;
*out++ = inlen ? b64c[to_uchar (in[2]) & 0x3f] : '=';
if (!--outlen)
break;
if (inlen)
inlen--;
if (inlen)
in += 3;
}
if (outlen)
*out = '\0';
}
/* Allocate a buffer and store zero terminated base64 encoded data
from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
the length of the encoded data, excluding the terminating zero. On
return, the OUT variable will hold a pointer to newly allocated
memory that must be deallocated by the caller. If output string
length would overflow, 0 is returned and OUT is set to NULL. If
memory allocation failed, OUT is set to NULL, and the return value
indicates length of the requested memory block, i.e.,
BASE64_LENGTH(inlen) + 1. */
size_t
base64_encode_alloc (const char *in, size_t inlen, char **out)
{
size_t outlen = 1 + BASE64_LENGTH (inlen);
/* Check for overflow in outlen computation.
*
* If there is no overflow, outlen >= inlen.
*
* If the operation (inlen + 2) overflows then it yields at most +1, so
* outlen is 0.
*
* If the multiplication overflows, we lose at least half of the
* correct value, so the result is < ((inlen + 2) / 3) * 2, which is
* less than (inlen + 2) * 0.66667, which is less than inlen as soon as
* (inlen > 4).
*/
if (inlen > outlen)
{
*out = NULL;
return 0;
}
*out = malloc (outlen);
if (!*out)
return outlen;
base64_encode (in, inlen, *out, outlen);
return outlen - 1;
}
/* With this approach this file works independent of the charset used
(think EBCDIC). However, it does assume that the characters in the
Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX
1003.1-2001 require that char and unsigned char are 8-bit
quantities, though, taking care of that problem. But this may be a
potential problem on non-POSIX C99 platforms.
IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
as the formal parameter rather than "x". */
#define B64(_) \
((_) == 'A' ? 0 \
: (_) == 'B' ? 1 \
: (_) == 'C' ? 2 \
: (_) == 'D' ? 3 \
: (_) == 'E' ? 4 \
: (_) == 'F' ? 5 \
: (_) == 'G' ? 6 \
: (_) == 'H' ? 7 \
: (_) == 'I' ? 8 \
: (_) == 'J' ? 9 \
: (_) == 'K' ? 10 \
: (_) == 'L' ? 11 \
: (_) == 'M' ? 12 \
: (_) == 'N' ? 13 \
: (_) == 'O' ? 14 \
: (_) == 'P' ? 15 \
: (_) == 'Q' ? 16 \
: (_) == 'R' ? 17 \
: (_) == 'S' ? 18 \
: (_) == 'T' ? 19 \
: (_) == 'U' ? 20 \
: (_) == 'V' ? 21 \
: (_) == 'W' ? 22 \
: (_) == 'X' ? 23 \
: (_) == 'Y' ? 24 \
: (_) == 'Z' ? 25 \
: (_) == 'a' ? 26 \
: (_) == 'b' ? 27 \
: (_) == 'c' ? 28 \
: (_) == 'd' ? 29 \
: (_) == 'e' ? 30 \
: (_) == 'f' ? 31 \
: (_) == 'g' ? 32 \
: (_) == 'h' ? 33 \
: (_) == 'i' ? 34 \
: (_) == 'j' ? 35 \
: (_) == 'k' ? 36 \
: (_) == 'l' ? 37 \
: (_) == 'm' ? 38 \
: (_) == 'n' ? 39 \
: (_) == 'o' ? 40 \
: (_) == 'p' ? 41 \
: (_) == 'q' ? 42 \
: (_) == 'r' ? 43 \
: (_) == 's' ? 44 \
: (_) == 't' ? 45 \
: (_) == 'u' ? 46 \
: (_) == 'v' ? 47 \
: (_) == 'w' ? 48 \
: (_) == 'x' ? 49 \
: (_) == 'y' ? 50 \
: (_) == 'z' ? 51 \
: (_) == '0' ? 52 \
: (_) == '1' ? 53 \
: (_) == '2' ? 54 \
: (_) == '3' ? 55 \
: (_) == '4' ? 56 \
: (_) == '5' ? 57 \
: (_) == '6' ? 58 \
: (_) == '7' ? 59 \
: (_) == '8' ? 60 \
: (_) == '9' ? 61 \
: (_) == '+' ? 62 \
: (_) == '/' ? 63 \
: -1)
static const signed char b64[0x100] = {
B64 (0), B64 (1), B64 (2), B64 (3),
B64 (4), B64 (5), B64 (6), B64 (7),
B64 (8), B64 (9), B64 (10), B64 (11),
B64 (12), B64 (13), B64 (14), B64 (15),
B64 (16), B64 (17), B64 (18), B64 (19),
B64 (20), B64 (21), B64 (22), B64 (23),
B64 (24), B64 (25), B64 (26), B64 (27),
B64 (28), B64 (29), B64 (30), B64 (31),
B64 (32), B64 (33), B64 (34), B64 (35),
B64 (36), B64 (37), B64 (38), B64 (39),
B64 (40), B64 (41), B64 (42), B64 (43),
B64 (44), B64 (45), B64 (46), B64 (47),
B64 (48), B64 (49), B64 (50), B64 (51),
B64 (52), B64 (53), B64 (54), B64 (55),
B64 (56), B64 (57), B64 (58), B64 (59),
B64 (60), B64 (61), B64 (62), B64 (63),
B64 (64), B64 (65), B64 (66), B64 (67),
B64 (68), B64 (69), B64 (70), B64 (71),
B64 (72), B64 (73), B64 (74), B64 (75),
B64 (76), B64 (77), B64 (78), B64 (79),
B64 (80), B64 (81), B64 (82), B64 (83),
B64 (84), B64 (85), B64 (86), B64 (87),
B64 (88), B64 (89), B64 (90), B64 (91),
B64 (92), B64 (93), B64 (94), B64 (95),
B64 (96), B64 (97), B64 (98), B64 (99),
B64 (100), B64 (101), B64 (102), B64 (103),
B64 (104), B64 (105), B64 (106), B64 (107),
B64 (108), B64 (109), B64 (110), B64 (111),
B64 (112), B64 (113), B64 (114), B64 (115),
B64 (116), B64 (117), B64 (118), B64 (119),
B64 (120), B64 (121), B64 (122), B64 (123),
B64 (124), B64 (125), B64 (126), B64 (127),
B64 (128), B64 (129), B64 (130), B64 (131),
B64 (132), B64 (133), B64 (134), B64 (135),
B64 (136), B64 (137), B64 (138), B64 (139),
B64 (140), B64 (141), B64 (142), B64 (143),
B64 (144), B64 (145), B64 (146), B64 (147),
B64 (148), B64 (149), B64 (150), B64 (151),
B64 (152), B64 (153), B64 (154), B64 (155),
B64 (156), B64 (157), B64 (158), B64 (159),
B64 (160), B64 (161), B64 (162), B64 (163),
B64 (164), B64 (165), B64 (166), B64 (167),
B64 (168), B64 (169), B64 (170), B64 (171),
B64 (172), B64 (173), B64 (174), B64 (175),
B64 (176), B64 (177), B64 (178), B64 (179),
B64 (180), B64 (181), B64 (182), B64 (183),
B64 (184), B64 (185), B64 (186), B64 (187),
B64 (188), B64 (189), B64 (190), B64 (191),
B64 (192), B64 (193), B64 (194), B64 (195),
B64 (196), B64 (197), B64 (198), B64 (199),
B64 (200), B64 (201), B64 (202), B64 (203),
B64 (204), B64 (205), B64 (206), B64 (207),
B64 (208), B64 (209), B64 (210), B64 (211),
B64 (212), B64 (213), B64 (214), B64 (215),
B64 (216), B64 (217), B64 (218), B64 (219),
B64 (220), B64 (221), B64 (222), B64 (223),
B64 (224), B64 (225), B64 (226), B64 (227),
B64 (228), B64 (229), B64 (230), B64 (231),
B64 (232), B64 (233), B64 (234), B64 (235),
B64 (236), B64 (237), B64 (238), B64 (239),
B64 (240), B64 (241), B64 (242), B64 (243),
B64 (244), B64 (245), B64 (246), B64 (247),
B64 (248), B64 (249), B64 (250), B64 (251),
B64 (252), B64 (253), B64 (254), B64 (255)
};
#if UCHAR_MAX == 255
# define uchar_in_range(c) true
#else
# define uchar_in_range(c) ((c) <= 255)
#endif
/* Return true if CH is a character from the Base64 alphabet, and
false otherwise. Note that '=' is padding and not considered to be
part of the alphabet. */
bool
isbase64 (char ch)
{
return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
}
/* Initialize decode-context buffer, CTX. */
void
base64_decode_ctx_init (struct base64_decode_context *ctx)
{
ctx->i = 0;
}
/* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and
none of those four is a newline, then return *IN. Otherwise, copy up to
4 - CTX->i non-newline bytes from that range into CTX->buf, starting at
index CTX->i and setting CTX->i to reflect the number of bytes copied,
and return CTX->buf. In either case, advance *IN to point to the byte
after the last one processed, and set *N_NON_NEWLINE to the number of
verified non-newline bytes accessible through the returned pointer. */
static const char *
get_4 (struct base64_decode_context *ctx,
char const *restrict *in, char const *restrict in_end,
size_t *n_non_newline)
{
if (ctx->i == 4)
ctx->i = 0;
if (ctx->i == 0)
{
char const *t = *in;
if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
{
/* This is the common case: no newline. */
*in += 4;
*n_non_newline = 4;
return (const char *) t;
}
}
{
/* Copy non-newline bytes into BUF. */
char const *p = *in;
while (p < in_end)
{
char c = *p++;
if (c != '\n')
{
ctx->buf[ctx->i++] = c;
if (ctx->i == 4)
break;
}
}
*in = p;
*n_non_newline = ctx->i;
return ctx->buf;
}
}
#define return_false \
do \
{ \
*outp = out; \
return false; \
} \
while (false)
/* Decode up to four bytes of base64-encoded data, IN, of length INLEN
into the output buffer, *OUT, of size *OUTLEN bytes. Return true if
decoding is successful, false otherwise. If *OUTLEN is too small,
as many bytes as possible are written to *OUT. On return, advance
*OUT to point to the byte after the last one written, and decrement
*OUTLEN to reflect the number of bytes remaining in *OUT. */
static bool
decode_4 (char const *restrict in, size_t inlen,
char *restrict *outp, size_t *outleft)
{
char *out = *outp;
if (inlen < 2)
return false;
if (!isbase64 (in[0]) || !isbase64 (in[1]))
return false;
if (*outleft)
{
*out++ = ((b64[to_uchar (in[0])] << 2)
| (b64[to_uchar (in[1])] >> 4));
--*outleft;
}
if (inlen == 2)
return_false;
if (in[2] == '=')
{
if (inlen != 4)
return_false;
if (in[3] != '=')
return_false;
}
else
{
if (!isbase64 (in[2]))
return_false;
if (*outleft)
{
*out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
| (b64[to_uchar (in[2])] >> 2));
--*outleft;
}
if (inlen == 3)
return_false;
if (in[3] == '=')
{
if (inlen != 4)
return_false;
}
else
{
if (!isbase64 (in[3]))
return_false;
if (*outleft)
{
*out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
| b64[to_uchar (in[3])]);
--*outleft;
}
}
}
*outp = out;
return true;
}
/* Decode base64-encoded input array IN of length INLEN to output array
OUT that can hold *OUTLEN bytes. The input data may be interspersed
with newlines. Return true if decoding was successful, i.e. if the
input was valid base64 data, false otherwise. If *OUTLEN is too
small, as many bytes as possible will be written to OUT. On return,
*OUTLEN holds the length of decoded bytes in OUT. Note that as soon
as any non-alphabet, non-newline character is encountered, decoding
is stopped and false is returned. If INLEN is zero, then process
only whatever data is stored in CTX.
Initially, CTX must have been initialized via base64_decode_ctx_init.
Subsequent calls to this function must reuse whatever state is recorded
in that buffer. It is necessary for when a quadruple of base64 input
bytes spans two input buffers.
If CTX is NULL then newlines are treated as garbage and the input
buffer is processed as a unit. */
bool
base64_decode_ctx (struct base64_decode_context *ctx,
const char *restrict in, size_t inlen,
char *restrict out, size_t *outlen)
{
size_t outleft = *outlen;
bool ignore_newlines = ctx != NULL;
bool flush_ctx = false;
unsigned int ctx_i = 0;
if (ignore_newlines)
{
ctx_i = ctx->i;
flush_ctx = inlen == 0;
}
while (true)
{
size_t outleft_save = outleft;
if (ctx_i == 0 && !flush_ctx)
{
while (true)
{
/* Save a copy of outleft, in case we need to re-parse this
block of four bytes. */
outleft_save = outleft;
if (!decode_4 (in, inlen, &out, &outleft))
break;
in += 4;
inlen -= 4;
}
}
if (inlen == 0 && !flush_ctx)
break;
/* Handle the common case of 72-byte wrapped lines.
This also handles any other multiple-of-4-byte wrapping. */
if (inlen && *in == '\n' && ignore_newlines)
{
++in;
--inlen;
continue;
}
/* Restore OUT and OUTLEFT. */
out -= outleft_save - outleft;
outleft = outleft_save;
{
char const *in_end = in + inlen;
char const *non_nl;
if (ignore_newlines)
non_nl = get_4 (ctx, &in, in_end, &inlen);
else
non_nl = in; /* Might have nl in this case. */
/* If the input is empty or consists solely of newlines (0 non-newlines),
then we're done. Likewise if there are fewer than 4 bytes when not
flushing context and not treating newlines as garbage. */
if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
{
inlen = 0;
break;
}
if (!decode_4 (non_nl, inlen, &out, &outleft))
break;
inlen = in_end - in;
}
}
*outlen -= outleft;
return inlen == 0;
}
/* Allocate an output buffer in *OUT, and decode the base64 encoded
data stored in IN of size INLEN to the *OUT buffer. On return, the
size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL,
if the caller is not interested in the decoded length. *OUT may be
NULL to indicate an out of memory error, in which case *OUTLEN
contains the size of the memory block needed. The function returns
true on successful decoding and memory allocation errors. (Use the
*OUT and *OUTLEN parameters to differentiate between successful
decoding and memory error.) The function returns false if the
input was invalid, in which case *OUT is NULL and *OUTLEN is
undefined. */
bool
base64_decode_alloc_ctx (struct base64_decode_context *ctx,
const char *in, size_t inlen, char **out,
size_t *outlen)
{
/* This may allocate a few bytes too many, depending on input,
but it's not worth the extra CPU time to compute the exact size.
The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the
input ends with "=" and minus another 1 if the input ends with "==".
Dividing before multiplying avoids the possibility of overflow. */
size_t needlen = 3 * (inlen / 4) + 3;
*out = malloc (needlen);
if (!*out)
return true;
if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
{
free (*out);
*out = NULL;
return false;
}
if (outlen)
*outlen = needlen;
return true;
}

68
lib/base64.h Normal file
View File

@@ -0,0 +1,68 @@
/* base64.h -- Encode binary data using printable characters.
Copyright (C) 2004-2006, 2009-2019 Free Software Foundation, Inc.
Written by Simon Josefsson.
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, 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, see <https://www.gnu.org/licenses/>. */
#ifndef BASE64_H
# define BASE64_H
/* Get size_t. */
# include <stddef.h>
/* Get bool. */
# include <stdbool.h>
# ifdef __cplusplus
extern "C" {
# endif
/* This uses that the expression (n+(k-1))/k means the smallest
integer >= n/k, i.e., the ceiling of n/k. */
# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4)
struct base64_decode_context
{
unsigned int i;
char buf[4];
};
extern bool isbase64 (char ch) __attribute__ ((__const__));
extern void base64_encode (const char *restrict in, size_t inlen,
char *restrict out, size_t outlen);
extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out);
extern void base64_decode_ctx_init (struct base64_decode_context *ctx);
extern bool base64_decode_ctx (struct base64_decode_context *ctx,
const char *restrict in, size_t inlen,
char *restrict out, size_t *outlen);
extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx,
const char *in, size_t inlen,
char **out, size_t *outlen);
#define base64_decode(in, inlen, out, outlen) \
base64_decode_ctx (NULL, in, inlen, out, outlen)
#define base64_decode_alloc(in, inlen, out, outlen) \
base64_decode_alloc_ctx (NULL, in, inlen, out, outlen)
# ifdef __cplusplus
}
# endif
#endif /* BASE64_H */

View File

@@ -1,16 +1,30 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* BITLK (BitLocker-compatible) volume handling
*
* Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2025 Milan Broz
* Copyright (C) 2019-2025 Vojtech Trefny
* Copyright (C) 2019-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2021 Milan Broz
* Copyright (C) 2019-2021 Vojtech Trefny
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <errno.h>
#include <string.h>
#include <uuid/uuid.h>
#include <time.h>
#include <iconv.h>
#include <limits.h>
#include "bitlk.h"
@@ -111,7 +125,6 @@ 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;
@@ -133,32 +146,6 @@ 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;
@@ -247,11 +234,86 @@ static const char* get_bitlk_type_string(BITLKEncryptionType type)
}
}
/* TODO -- move to some utils file */
static void hexprint(struct crypt_device *cd, const char *d, int n, const char *sep)
{
int i;
for(i = 0; i < n; i++)
log_std(cd, "%02hhx%s", (const char)d[i], sep);
}
static uint64_t filetime_to_unixtime(uint64_t time)
{
return (time - EPOCH_AS_FILETIME) / HUNDREDS_OF_NANOSECONDS;
}
static int convert_to_utf8(struct crypt_device *cd, uint8_t *input, size_t inlen, char **out)
{
char *outbuf = NULL;
iconv_t ic;
size_t ic_inlen = inlen;
size_t ic_outlen = inlen;
char *ic_outbuf = NULL;
size_t r = 0;
outbuf = malloc(inlen);
if (outbuf == NULL)
return -ENOMEM;
memset(outbuf, 0, inlen);
ic_outbuf = outbuf;
ic = iconv_open("UTF-8", "UTF-16LE");
r = iconv(ic, (char **) &input, &ic_inlen, &ic_outbuf, &ic_outlen);
iconv_close(ic);
if (r == 0)
*out = strdup(outbuf);
else {
*out = NULL;
log_dbg(cd, "Failed to convert volume description: %s", strerror(errno));
r = 0;
}
free(outbuf);
return r;
}
static int passphrase_to_utf16(struct crypt_device *cd, char *input, size_t inlen, char **out)
{
char *outbuf = NULL;
iconv_t ic;
size_t ic_inlen = inlen;
size_t ic_outlen = inlen * 2;
char *ic_outbuf = NULL;
size_t r = 0;
if (inlen == 0)
return r;
outbuf = crypt_safe_alloc(inlen * 2);
if (outbuf == NULL)
return -ENOMEM;
memset(outbuf, 0, inlen * 2);
ic_outbuf = outbuf;
ic = iconv_open("UTF-16LE", "UTF-8");
r = iconv(ic, &input, &ic_inlen, &ic_outbuf, &ic_outlen);
iconv_close(ic);
if (r == 0) {
*out = outbuf;
} else {
*out = NULL;
crypt_safe_free(outbuf);
log_dbg(cd, "Failed to convert passphrase: %s", strerror(errno));
r = -errno;
}
return r;
}
static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, int end, struct bitlk_vmk **vmk)
{
uint16_t key_entry_size = 0;
@@ -262,23 +324,19 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
const char *key = NULL;
struct volume_key *vk = NULL;
bool supported = false;
int r = 0;
/* only passphrase or recovery passphrase 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;
while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
while (end - start > 2) {
/* size of this entry */
memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
key_entry_size = le16_to_cpu(key_entry_size);
if (key_entry_size == 0)
break;
if (key_entry_size > (end - start))
return -EINVAL;
/* type and value of this entry */
memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
memcpy(&key_entry_value,
@@ -297,24 +355,20 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
}
/* stretch key with salt, skip 4 B (encryption method of the stretch key) */
if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY) {
if ((end - start) < (BITLK_ENTRY_HEADER_LEN + BITLK_SALT_SIZE + 4))
return -EINVAL;
if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY)
memcpy((*vmk)->salt,
data + start + BITLK_ENTRY_HEADER_LEN + 4,
BITLK_SALT_SIZE);
sizeof((*vmk)->salt));
/* AES-CCM encrypted key */
} else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE))
return -EINVAL;
else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
/* nonce */
memcpy((*vmk)->nonce,
data + start + BITLK_ENTRY_HEADER_LEN,
BITLK_NONCE_SIZE);
sizeof((*vmk)->nonce));
/* MAC tag */
memcpy((*vmk)->mac_tag,
data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
BITLK_VMK_MAC_TAG_SIZE);
sizeof((*vmk)->mac_tag));
/* AES-CCM encrypted key */
key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
@@ -338,20 +392,10 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
/* unknown timestamps in recovery protected VMK */
} else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
;
/* optional hint (?) string (masked email?), we can safely ignore it */
} else if (key_entry_value == BITLK_ENTRY_VALUE_HINT) {
;
} else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
if (key_entry_size < BITLK_ENTRY_HEADER_LEN)
return -EINVAL;
string = malloc((key_entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
if (!string)
return -ENOMEM;
r = crypt_utf16_to_utf8(&string, CONST_CAST(char16_t *)(data + start + BITLK_ENTRY_HEADER_LEN),
key_entry_size - BITLK_ENTRY_HEADER_LEN);
if (r < 0 || !string) {
free(string);
if (convert_to_utf8(cd, data + start + BITLK_ENTRY_HEADER_LEN, key_entry_size - BITLK_ENTRY_HEADER_LEN, &string) < 0) {
log_err(cd, _("Invalid string found when parsing Volume Master Key."));
free(string);
return -EINVAL;
} else if ((*vmk)->name != NULL) {
if (supported) {
@@ -370,9 +414,6 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
/* no idea what this is, lets hope it's not important */
} else if (key_entry_value == BITLK_ENTRY_VALUE_USE_KEY && (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY) {
;
/* quietly ignore unsupported TPM key */
} else if (key_entry_value == BITLK_ENTRY_VALUE_TPM_KEY && (*vmk)->protection == BITLK_PROTECTION_TPM) {
;
} else {
if (supported) {
log_err(cd, _("Unexpected metadata entry value '%u' found when parsing supported Volume Master Key."), key_entry_value);
@@ -388,54 +429,6 @@ 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)
@@ -450,8 +443,10 @@ void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk)
struct bitlk_vmk *vmk_next = NULL;
while (vmk) {
free(vmk->guid);
free(vmk->name);
if (vmk->guid)
free(vmk->guid);
if (vmk->name)
free(vmk->name);
crypt_free_volume_key(vmk->vk);
vmk_next = vmk->next;
free(vmk);
@@ -465,8 +460,8 @@ void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata)
return;
free(metadata->guid);
free(metadata->description);
free(metadata->validation);
if (metadata->description)
free(metadata->description);
BITLK_bitlk_vmk_free(metadata->vmks);
BITLK_bitlk_fvek_free(metadata->fvek);
}
@@ -478,25 +473,19 @@ 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;
int end = 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;
@@ -510,8 +499,8 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
/* read and check the signature */
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), &sig, sizeof(sig), 0) != sizeof(sig)) {
log_dbg(cd, "Failed to read BITLK signature from %s.", device_path(device));
r = -EIO;
log_err(cd, _("Failed to read BITLK signature from %s."), device_path(device));
r = -EINVAL;
goto out;
}
@@ -522,7 +511,7 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
params->togo = true;
fve_offset = BITLK_HEADER_METADATA_OFFSET_TOGO;
} else {
log_dbg(cd, "Invalid or unknown signature for BITLK device.");
log_err(cd, _("Invalid or unknown signature for BITLK device."));
r = -EINVAL;
goto out;
}
@@ -571,80 +560,15 @@ 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]);
fve_validated_block = malloc(BITLK_FVE_METADATA_SIZE);
if (fve_validated_block == NULL) {
r = -ENOMEM;
goto out;
}
log_dbg(cd, "Reading BITLK FVE metadata of size %zu on device %s, offset %" PRIu64 ".",
sizeof(fve), device_path(device), params->metadata_offset[0]);
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(&params->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 *)&params->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));
/* 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));
r = -EINVAL;
goto out;
}
@@ -657,8 +581,8 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
le16_to_cpu(fve.curr_state), le16_to_cpu(fve.next_state));
}
params->volume_size = le64_to_cpu(fve.volume_size);
params->metadata_version = le16_to_cpu(fve.fve_version);
fve_metadata_size = le32_to_cpu(fve.metadata_size);
switch (le16_to_cpu(fve.encryption)) {
/* AES-CBC with Elephant difuser */
@@ -713,57 +637,40 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
params->creation_time = filetime_to_unixtime(le64_to_cpu(fve.creation_time));
fve_metadata_size = le32_to_cpu(fve.metadata_size);
if (fve_metadata_size < (BITLK_FVE_METADATA_HEADER_LEN + sizeof(entry_size) + sizeof(entry_type)) ||
fve_metadata_size > BITLK_FVE_METADATA_SIZE) {
r = -EINVAL;
goto out;
}
fve_entries_size = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
/* read and parse all FVE metadata entries */
fve_entries = malloc(fve_entries_size);
fve_entries = malloc(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN);
if (!fve_entries) {
r = -ENOMEM;
goto out;
}
memset(fve_entries, 0, fve_entries_size);
memset(fve_entries, 0, (fve_metadata_size - BITLK_FVE_METADATA_HEADER_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);
log_dbg(cd, "Reading BITLK FVE metadata entries of size %" PRIu32 " on device %s, offset %" PRIu64 ".",
fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN, device_path(device),
params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
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));
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), fve_entries, fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN,
params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN)) {
log_err(cd, _("Failed to read BITLK metadata entries 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))) {
end = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
while (end - start > 2) {
/* size of this entry */
memcpy(&entry_size, fve_entries + start, sizeof(entry_size));
entry_size = le16_to_cpu(entry_size);
if (entry_size == 0)
break;
if (entry_size > (fve_entries_size - start)) {
r = -EINVAL;
goto out;
}
/* type of this entry */
memcpy(&entry_type, fve_entries + start + sizeof(entry_size), sizeof(entry_type));
entry_type = le16_to_cpu(entry_type);
/* VMK */
if (entry_type == BITLK_ENTRY_TYPE_VMK) {
if (entry_size < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_vmk))) {
r = -EINVAL;
goto out;
}
/* skip first four variables in the entry (entry size, type, value and version) */
memcpy(&entry_vmk,
fve_entries + start + BITLK_ENTRY_HEADER_LEN,
@@ -800,11 +707,7 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
vmk_p = vmk;
vmk = vmk->next;
/* FVEK */
} else if (entry_type == BITLK_ENTRY_TYPE_FVEK && !params->fvek) {
if (entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE)) {
r = -EINVAL;
goto out;
}
} else if (entry_type == BITLK_ENTRY_TYPE_FVEK) {
params->fvek = malloc(sizeof(struct bitlk_fvek));
if (!params->fvek) {
r = -ENOMEM;
@@ -812,11 +715,11 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
}
memcpy(params->fvek->nonce,
fve_entries + start + BITLK_ENTRY_HEADER_LEN,
BITLK_NONCE_SIZE);
sizeof(params->fvek->nonce));
/* MAC tag */
memcpy(params->fvek->mac_tag,
fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
BITLK_VMK_MAC_TAG_SIZE);
sizeof(params->fvek->mac_tag));
/* AES-CCM encrypted key */
key_size = entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
key = (const char *) fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
@@ -828,43 +731,28 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
/* volume header info (location and size) */
} else if (entry_type == BITLK_ENTRY_TYPE_VOLUME_HEADER) {
struct bitlk_entry_header_block entry_header;
if ((fve_entries_size - start) < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_header))) {
r = -EINVAL;
goto out;
}
memcpy(&entry_header,
fve_entries + start + BITLK_ENTRY_HEADER_LEN,
sizeof(entry_header));
params->volume_header_offset = le64_to_cpu(entry_header.offset);
params->volume_header_size = le64_to_cpu(entry_header.size);
/* volume description (utf-16 string) */
} else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION && !params->description) {
if (entry_size < BITLK_ENTRY_HEADER_LEN) {
r = -EINVAL;
goto out;
}
description = malloc((entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
if (!description) {
r = -ENOMEM;
goto out;
}
r = crypt_utf16_to_utf8(&description, CONST_CAST(char16_t *)(fve_entries + start + BITLK_ENTRY_HEADER_LEN),
entry_size - BITLK_ENTRY_HEADER_LEN);
} else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION) {
r = convert_to_utf8(cd, fve_entries + start + BITLK_ENTRY_HEADER_LEN,
entry_size - BITLK_ENTRY_HEADER_LEN,
&(params->description));
if (r < 0) {
free(description);
BITLK_bitlk_vmk_free(vmk);
log_err(cd, _("Failed to convert BITLK volume description"));
goto out;
}
params->description = description;
}
start += entry_size;
}
out:
free(fve_entries);
free(fve_validated_block);
out:
if (fve_entries)
free(fve_entries);
return r;
}
@@ -872,7 +760,6 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
{
struct volume_key *vk_p;
struct bitlk_vmk *vmk_p;
char time[32];
int next_id = 0;
int i = 0;
@@ -880,13 +767,11 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
log_std(cd, "Version: \t%u\n", params->metadata_version);
log_std(cd, "GUID: \t%s\n", params->guid);
log_std(cd, "Sector size: \t%u [bytes]\n", params->sector_size);
log_std(cd, "Volume size: \t%" PRIu64 " [bytes]\n", params->volume_size);
if (ctime_r((time_t *)&params->creation_time, time))
log_std(cd, "Created: \t%s", time);
log_std(cd, "Created: \t%s", ctime((time_t *)&(params->creation_time)));
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");
@@ -900,20 +785,20 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
log_std(cd, "\tGUID: \t%s\n", vmk_p->guid);
log_std(cd, "\tProtection: \t%s\n", get_vmk_protection_string (vmk_p->protection));
log_std(cd, "\tSalt: \t");
crypt_log_hex(cd, (const char *) vmk_p->salt, 16, "", 0, NULL);
hexprint(cd, (const char *) vmk_p->salt, 16, "");
log_std(cd, "\n");
vk_p = vmk_p->vk;
while (vk_p) {
log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(vk_p));
vk_p = crypt_volume_key_next(vk_p);
log_std(cd, "\tKey data size:\t%zu [bytes]\n", vk_p->keylength);
vk_p = vk_p->next;
}
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", crypt_volume_key_length(params->fvek->vk));
log_std(cd, "\tKey data size:\t%zu [bytes]\n", params->fvek->vk->keylength);
log_std(cd, "\n");
@@ -950,13 +835,13 @@ static int get_recovery_key(struct crypt_device *cd,
- each part is a number dividable by 11
*/
if (passwordLen != BITLK_RECOVERY_KEY_LEN) {
if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
/* looks like a recovery key with an extra newline, possibly from a key file */
passwordLen--;
log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
} else
return 0;
}
if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
/* looks like a recovery key with an extra newline, possibly from a key file */
passwordLen--;
log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
} else
return 0;
}
for (i = BITLK_RECOVERY_PART_LEN; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1) {
if (password[i] != '-')
@@ -999,16 +884,13 @@ static int parse_external_key_entry(struct crypt_device *cd,
struct bitlk_guid guid;
char guid_buf[UUID_STR_LEN] = {0};
while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
while (end - start > 2) {
/* size of this entry */
memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
key_entry_size = le16_to_cpu(key_entry_size);
if (key_entry_size == 0)
break;
if (key_entry_size > (end - start))
return -EINVAL;
/* type and value of this entry */
memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
memcpy(&key_entry_value,
@@ -1023,8 +905,6 @@ static int parse_external_key_entry(struct crypt_device *cd,
}
if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + 4))
return -EINVAL;
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);
@@ -1036,8 +916,6 @@ static int parse_external_key_entry(struct crypt_device *cd,
;
/* GUID of the BitLocker device we are trying to open with this key */
else if (key_entry_value == BITLK_ENTRY_VALUE_GUID) {
if ((end - start) < (ssize_t)(BITLK_ENTRY_HEADER_LEN + sizeof(struct bitlk_guid)))
return -EINVAL;
memcpy(&guid, data + start + BITLK_ENTRY_HEADER_LEN, sizeof(struct bitlk_guid));
guid_to_string(&guid, guid_buf);
if (strcmp(guid_buf, params->guid) != 0) {
@@ -1071,7 +949,7 @@ static int get_startup_key(struct crypt_device *cd,
uint16_t key_entry_type = 0;
uint16_t key_entry_value = 0;
if (passwordLen < (BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value)))
if (passwordLen < BITLK_BEK_FILE_HEADER_LEN)
return -EPERM;
memcpy(&bek_header, password, BITLK_BEK_FILE_HEADER_LEN);
@@ -1083,14 +961,13 @@ static int get_startup_key(struct crypt_device *cd,
else
return -EPERM;
if (le32_to_cpu(bek_header.metadata_version) != 1) {
log_err(cd, _("Unsupported BEK metadata version %" PRIu32), le32_to_cpu(bek_header.metadata_version));
if (bek_header.metadata_version != 1) {
log_err(cd, _("Unsupported BEK metadata version %" PRIu32), bek_header.metadata_version);
return -ENOTSUP;
}
if (le32_to_cpu(bek_header.metadata_size) != passwordLen) {
log_err(cd, _("Unexpected BEK metadata size %" PRIu32 " does not match BEK file length"),
le32_to_cpu(bek_header.metadata_size));
if (bek_header.metadata_size != passwordLen) {
log_err(cd, _("Unexpected BEK metadata size %" PRIu32 " does not match BEK file length"), bek_header.metadata_size);
return -EINVAL;
}
@@ -1121,7 +998,8 @@ static int get_startup_key(struct crypt_device *cd,
}
}
static int bitlk_kdf(const char *password,
static int bitlk_kdf(struct crypt_device *cd,
const char *password,
size_t passwordLen,
bool recovery,
const uint8_t *salt,
@@ -1130,8 +1008,7 @@ static int bitlk_kdf(const char *password,
struct bitlk_kdf_data kdf = {};
struct crypt_hash *hd = NULL;
int len = 0;
char16_t *utf16Password = NULL;
size_t utf16Len = 0;
char *utf16Password = NULL;
int i = 0;
int r = 0;
@@ -1148,17 +1025,11 @@ static int bitlk_kdf(const char *password,
if (!recovery) {
/* passphrase: convert to UTF-16 first, then sha256(sha256(pw)) */
utf16Password = crypt_safe_alloc(sizeof(char16_t) * (passwordLen + 1));
if (!utf16Password) {
r = -ENOMEM;
goto out;
}
r = crypt_utf8_to_utf16(&utf16Password, CONST_CAST(char*)password, passwordLen);
r = passphrase_to_utf16(cd, CONST_CAST(char*)password, passwordLen, &utf16Password);
if (r < 0)
goto out;
utf16Len = crypt_char16_strlen(utf16Password);
crypt_hash_write(hd, (char*)utf16Password, utf16Len * 2);
crypt_hash_write(hd, utf16Password, passwordLen * 2);
r = crypt_hash_final(hd, kdf.initial_sha256, len);
if (r < 0)
goto out;
@@ -1204,14 +1075,11 @@ static int decrypt_key(struct crypt_device *cd,
int r;
uint16_t key_size = 0;
outbuf = crypt_safe_alloc(crypt_volume_key_length(enc_key));
outbuf = crypt_safe_alloc(enc_key->keylength);
if (!outbuf)
return -ENOMEM;
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),
r = crypt_bitlk_decrypt_key(key->key, key->keylength, enc_key->key, outbuf, enc_key->keylength,
(const char*)iv, iv_size, (const char*)tag, tag_size);
if (r < 0) {
if (r == -ENOTSUP)
@@ -1222,10 +1090,9 @@ 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 (crypt_volume_key_length(enc_key) != key_size) {
if (enc_key->keylength != key_size) {
log_err(cd, _("Unexpected key data size."));
log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "",
crypt_volume_key_length(enc_key), key_size);
log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", enc_key->keylength, key_size);
r = -EINVAL;
goto out;
@@ -1235,7 +1102,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 */
crypt_safe_memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
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;
}
@@ -1259,13 +1126,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) {
if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) {
r = bitlk_kdf(password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
r = bitlk_kdf(cd, password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
if (r) {
/* something wrong happened, but we still want to check other key slots */
next_vmk = next_vmk->next;
@@ -1285,8 +1151,7 @@ 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(crypt_volume_key_get_key(recovery_key),
crypt_volume_key_length(recovery_key),
r = bitlk_kdf(cd, recovery_key->key, recovery_key->keylength,
true, next_vmk->salt, &vmk_dec_key);
crypt_free_volume_key(recovery_key);
if (r)
@@ -1322,36 +1187,6 @@ int BITLK_get_volume_key(struct crypt_device *cd,
}
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,
params->fvek->nonce, BITLK_NONCE_SIZE, true);
@@ -1394,7 +1229,7 @@ static int _activate_check(struct crypt_device *cd,
next_vmk = params->vmks;
while (next_vmk) {
if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
log_err(cd, _("Activation of BITLK device with clear key protection is not supported."));
log_err(cd, _("Activation of partially decrypted BITLK device is not supported."));
return -ENOTSUP;
}
next_vmk = next_vmk->next;
@@ -1423,7 +1258,7 @@ static int _activate(struct crypt_device *cd,
uint64_t next_start = 0;
uint64_t next_end = 0;
uint64_t last_segment = 0;
uint64_t dmt_flags = 0;
uint32_t dmt_flags;
r = _activate_check(cd, params);
if (r)
@@ -1434,11 +1269,6 @@ static int _activate(struct crypt_device *cd,
if (r)
return r;
if (dmd.size * SECTOR_SIZE != params->volume_size)
log_std(cd, _("WARNING: BitLocker volume size %" PRIu64 " does not match the underlying device size %" PRIu64 ""),
params->volume_size,
dmd.size * SECTOR_SIZE);
/* there will be always 4 dm-zero segments: 3x metadata, 1x FS header */
for (i = 0; i < 3; i++) {
segments[num_segments].offset = params->metadata_offset[i] / SECTOR_SIZE;
@@ -1547,7 +1377,7 @@ static int _activate(struct crypt_device *cd,
crypt_get_cipher_spec(cd),
segments[i].iv_offset,
segments[i].iv_offset,
NULL, 0, 0,
NULL, 0,
params->sector_size);
if (r)
goto out;
@@ -1569,31 +1399,60 @@ static int _activate(struct crypt_device *cd,
log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK Elephant diffuser."));
r = -ENOTSUP;
}
if ((dmd.flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED)) {
log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for large sector size."));
r = -ENOTSUP;
}
if (dm_flags(cd, DM_ZERO, &dmt_flags) < 0) {
log_err(cd, _("Cannot activate device, kernel dm-zero module is missing."));
r = -ENOTSUP;
}
}
out:
dm_targets_free(cd, &dmd);
return r;
}
int BITLK_activate_by_volume_key(struct crypt_device *cd,
int BITLK_activate_by_passphrase(struct crypt_device *cd,
const char *name,
struct volume_key *vk,
const char *password,
size_t passwordLen,
const struct bitlk_metadata *params,
uint32_t flags)
{
int r;
int r = 0;
struct volume_key *open_fvek_key = NULL;
r = _activate_check(cd, params);
if (r)
return r;
return _activate(cd, name, vk, params, flags);
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,
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;
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;
}

View File

@@ -1,10 +1,23 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* BITLK (BitLocker-compatible) header definition
*
* Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2025 Milan Broz
* Copyright (C) 2019-2025 Vojtech Trefny
* Copyright (C) 2019-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2021 Milan Broz
* Copyright (C) 2019-2021 Vojtech Trefny
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRYPTSETUP_BITLK_H
@@ -21,8 +34,6 @@ 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
@@ -67,7 +78,6 @@ typedef enum {
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
BITLK_ENTRY_VALUE_GUID = 0x0017,
BITLK_ENTRY_VALUE_HINT = 0x0018,
} BITLKFVEEntryValue;
struct bitlk_vmk {
@@ -87,16 +97,8 @@ 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;
bool togo;
bool state;
BITLKEncryptionType type;
@@ -110,10 +112,8 @@ 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);
@@ -126,9 +126,17 @@ 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,
struct volume_key *vk,
const char *volume_key,
size_t volume_key_size,
const struct bitlk_metadata *params,
uint32_t flags);

View File

@@ -10,13 +10,13 @@
#include <stdint.h>
#include <sys/param.h>
#if HAVE_BYTESWAP_H
#if defined(HAVE_BYTESWAP_H)
# include <byteswap.h>
#endif
#if HAVE_ENDIAN_H
#if defined(HAVE_ENDIAN_H)
# include <endian.h>
#elif HAVE_SYS_ENDIAN_H /* BSDs have them here */
#elif defined(HAVE_SYS_ENDIAN_H) /* BSDs have them here */
# include <sys/endian.h>
#endif

View File

@@ -1,10 +1,23 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* cryptsetup plain device helper functions
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
@@ -92,7 +105,7 @@ int crypt_plain_hash(struct crypt_device *cd,
log_dbg(cd, "Too short plain passphrase.");
return -EINVAL;
}
crypt_safe_memcpy(key, passphrase, hash_size);
memcpy(key, passphrase, hash_size);
r = 0;
} else
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);

View File

@@ -9,12 +9,9 @@ libcrypto_backend_la_SOURCES = \
lib/crypto_backend/crypto_storage.c \
lib/crypto_backend/pbkdf_check.c \
lib/crypto_backend/crc32.c \
lib/crypto_backend/base64.c \
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/memutils.c
lib/crypto_backend/cipher_check.c
if CRYPTO_BACKEND_GCRYPT
libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_gcrypt.c
@@ -31,9 +28,6 @@ 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

View File

@@ -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] = {0};
uint8_t out_buffer[BLAKE2B_OUTBYTES];
uint8_t in_buffer[BLAKE2B_OUTBYTES];
TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));

View File

@@ -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 HAVE_EXPLICIT_BZERO
#elif defined(HAVE_EXPLICIT_BZERO)
void secure_wipe_memory(void *v, size_t n) {
explicit_bzero(v, n);
}
@@ -279,6 +279,7 @@ static void *fill_segment_thr(void *thread_data)
{
argon2_thread_data *my_data = thread_data;
fill_segment(my_data->instance_ptr, my_data->pos);
argon2_thread_exit();
return 0;
}
@@ -356,9 +357,12 @@ static int fill_memory_blocks_mt(argon2_instance_t *instance) {
}
fail:
free(thread);
free(thr_data);
if (thread != NULL) {
free(thread);
}
if (thr_data != NULL) {
free(thr_data);
}
return rc;
}

View File

@@ -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 - (52 - '0'))) | (EQ(x, 62) & '+') |
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
(EQ(x, 63) & '/');
}

View File

@@ -1,28 +0,0 @@
libargon2_sources = files(
'blake2/blake2b.c',
'argon2.c',
'core.c',
'encoding.c',
'thread.c',
)
if use_internal_sse_argon2
libargon2_sources += files(
'opt.c',
)
else
libargon2_sources += files(
'ref.c',
)
endif
libargon2 = static_library('argon2',
libargon2_sources,
override_options : ['c_std=c89', 'optimization=3'],
build_by_default : false,
include_directories: include_directories(
'blake2',
),
dependencies : [
threads,
])

View File

@@ -46,4 +46,12 @@ int argon2_thread_join(argon2_thread_handle_t handle) {
#endif
}
void argon2_thread_exit(void) {
#if defined(_WIN32)
_endthreadex(0);
#else
pthread_exit(NULL);
#endif
}
#endif /* ARGON2_NO_THREADS */

View File

@@ -58,5 +58,10 @@ int argon2_thread_create(argon2_thread_handle_t *handle,
*/
int argon2_thread_join(argon2_thread_handle_t handle);
/* Terminate the current thread. Must be run inside a thread created by
* argon2_thread_create.
*/
void argon2_thread_exit(void);
#endif /* ARGON2_NO_THREADS */
#endif

View File

@@ -1,30 +1,42 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Argon2 PBKDF2 library wrapper
*
* Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2025 Milan Broz
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <errno.h>
#include "crypto_backend_internal.h"
/* Check for HAVE_ARGON2_H is run only if libargon2 code is used */
#if USE_INTERNAL_ARGON2 || HAVE_ARGON2_H
#define CONST_CAST(x) (x)(uintptr_t)
#if HAVE_ARGON2_H
#include <argon2.h>
#else
#include "argon2/argon2.h"
#endif
#define CONST_CAST(x) (x)(uintptr_t)
int argon2(const char *type, 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)
{
#if !USE_INTERNAL_ARGON2 && !HAVE_ARGON2_H
return -EINVAL;
#else
argon2_type atype;
argon2_context context = {
.flags = ARGON2_DEFAULT_FLAGS,
@@ -42,9 +54,6 @@ int argon2(const char *type, const char *password, size_t password_length,
};
int r;
/* This code must not be run if crypt backend library natively supports Argon2 */
assert(!(crypt_backend_flags() & CRYPT_BACKEND_ARGON2));
if (!strcmp(type, "argon2i"))
atype = Argon2_i;
else if(!strcmp(type, "argon2id"))
@@ -66,33 +75,5 @@ int argon2(const char *type, const char *password, size_t password_length,
}
return r;
}
#else /* USE_INTERNAL_ARGON2 || HAVE_ARGON2_H */
#pragma GCC diagnostic ignored "-Wunused-parameter"
int argon2(const char *type, 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)
{
return -EINVAL;
}
#endif
/* Additional string for crypt backend version */
const char *crypt_argon2_version(void)
{
const char *version = "";
if (crypt_backend_flags() & CRYPT_BACKEND_ARGON2)
return version;
#if HAVE_ARGON2_H /* this has priority over internal argon2 */
version = " [external libargon2]";
#elif USE_INTERNAL_ARGON2
version = " [cryptsetup libargon2]";
#endif
return version;
}

View File

@@ -1,263 +0,0 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Base64 "Not encryption" helpers, copied and adapted from systemd project.
*
* Copyright (C) 2010 Lennart Poettering
*
* cryptsetup related changes
* Copyright (C) 2021-2025 Milan Broz
*/
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include "crypto_backend.h"
#define WHITESPACE " \t\n\r"
/* https://tools.ietf.org/html/rfc4648#section-4 */
static char base64char(int x)
{
static const char table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
return table[x & 63];
}
static int unbase64char(char c)
{
unsigned offset;
if (c >= 'A' && c <= 'Z')
return c - 'A';
offset = 'Z' - 'A' + 1;
if (c >= 'a' && c <= 'z')
return c - 'a' + offset;
offset += 'z' - 'a' + 1;
if (c >= '0' && c <= '9')
return c - '0' + offset;
offset += '9' - '0' + 1;
if (c == '+')
return offset;
offset++;
if (c == '/')
return offset;
return -EINVAL;
}
int crypt_base64_encode(char **out, size_t *out_length, const char *in, size_t in_length)
{
char *r, *z;
const uint8_t *x;
assert(in || in_length == 0);
assert(out);
/* three input bytes makes four output bytes, padding is added so we must round up */
z = r = malloc(4 * (in_length + 2) / 3 + 1);
if (!r)
return -ENOMEM;
for (x = (const uint8_t *)in; x < (const uint8_t*)in + (in_length / 3) * 3; x += 3) {
/* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
*(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
*(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
*(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
*(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
}
switch (in_length % 3) {
case 2:
*(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
*(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
*(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */
*(z++) = '=';
break;
case 1:
*(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
*(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
*(z++) = '=';
*(z++) = '=';
break;
}
*z = 0;
*out = r;
if (out_length)
*out_length = z - r;
return 0;
}
static int unbase64_next(const char **p, size_t *l)
{
int ret;
assert(p);
assert(l);
/* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We
* greedily skip all preceding and all following whitespace. */
for (;;) {
if (*l == 0)
return -EPIPE;
if (!strchr(WHITESPACE, **p))
break;
/* Skip leading whitespace */
(*p)++, (*l)--;
}
if (**p == '=')
ret = INT_MAX; /* return padding as INT_MAX */
else {
ret = unbase64char(**p);
if (ret < 0)
return ret;
}
for (;;) {
(*p)++, (*l)--;
if (*l == 0)
break;
if (!strchr(WHITESPACE, **p))
break;
/* Skip following whitespace */
}
return ret;
}
int crypt_base64_decode(char **out, size_t *out_length, const char *in, size_t in_length)
{
uint8_t *buf = NULL;
const char *x;
uint8_t *z;
size_t len;
int r;
assert(in || in_length == 0);
assert(out);
assert(out_length);
if (in_length == (size_t) -1)
in_length = strlen(in);
/* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
* bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
len = (in_length / 4) * 3 + (in_length % 4 != 0 ? (in_length % 4) - 1 : 0);
buf = malloc(len + 1);
if (!buf)
return -ENOMEM;
for (x = in, z = buf;;) {
int a, b, c, d; /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
a = unbase64_next(&x, &in_length);
if (a == -EPIPE) /* End of string */
break;
if (a < 0) {
r = a;
goto err;
}
if (a == INT_MAX) { /* Padding is not allowed at the beginning of a 4ch block */
r = -EINVAL;
goto err;
}
b = unbase64_next(&x, &in_length);
if (b < 0) {
r = b;
goto err;
}
if (b == INT_MAX) { /* Padding is not allowed at the second character of a 4ch block either */
r = -EINVAL;
goto err;
}
c = unbase64_next(&x, &in_length);
if (c < 0) {
r = c;
goto err;
}
d = unbase64_next(&x, &in_length);
if (d < 0) {
r = d;
goto err;
}
if (c == INT_MAX) { /* Padding at the third character */
if (d != INT_MAX) { /* If the third character is padding, the fourth must be too */
r = -EINVAL;
goto err;
}
/* b == 00YY0000 */
if (b & 15) {
r = -EINVAL;
goto err;
}
if (in_length > 0) { /* Trailing rubbish? */
r = -ENAMETOOLONG;
goto err;
}
*(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
break;
}
if (d == INT_MAX) {
/* c == 00ZZZZ00 */
if (c & 3) {
r = -EINVAL;
goto err;
}
if (in_length > 0) { /* Trailing rubbish? */
r = -ENAMETOOLONG;
goto err;
}
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
break;
}
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
*(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
}
*z = 0;
*out_length = (size_t) (z - buf);
*out = (char *)buf;
return 0;
err:
free(buf);
/* Ignore other errors in crypt_backend */
if (r != -ENOMEM)
r = -EINVAL;
return r;
}

View File

@@ -1,9 +1,22 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Cipher performance check
*
* Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2025 Milan Broz
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <errno.h>
@@ -42,36 +55,43 @@ static int time_ms(struct timespec *start, struct timespec *end, double *ms)
return 0;
}
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)
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)
{
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)
return r;
break;
done += block;
}
return 0;
}
crypt_cipher_destroy_kernel(&cipher);
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)
return r;
}
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)
{
struct timespec start, end;
int r;
@@ -83,7 +103,7 @@ static int cipher_measure(struct crypt_cipher_kernel *cipher, char *buffer, size
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start) < 0)
return -EINVAL;
r = cipher_perf_one(cipher, buffer, buffer_size, iv, iv_size, encrypt);
r = cipher_perf_one(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, encrypt);
if (r < 0)
return r;
@@ -111,20 +131,15 @@ 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(&cipher, buffer, buffer_size, iv, iv_size, 1, &ms);
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 1, &ms);
if (r < 0)
goto out;
return r;
ms_enc += ms;
repeat_enc++;
}
@@ -132,9 +147,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(&cipher, buffer, buffer_size, iv, iv_size, 0, &ms);
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 0, &ms);
if (r < 0)
goto out;
return r;
ms_dec += ms;
repeat_dec++;
}
@@ -142,8 +157,5 @@ 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);
r = 0;
out:
crypt_cipher_destroy_kernel(&cipher);
return r;
return 0;
}

View File

@@ -1,15 +1,27 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Linux kernel cipher generic utilities
*
* Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2025 Milan Broz
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include "crypto_backend.h"
struct cipher_alg {
@@ -39,7 +51,6 @@ static const struct cipher_alg cipher_algs[] = {
{ "xchacha12,aes", "adiantum", 32, false },
{ "xchacha20,aes", "adiantum", 32, false },
{ "sm4", NULL, 16, false },
{ "aria", NULL, 16, false },
{ NULL, NULL, 0, false }
};
@@ -64,9 +75,6 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
if (!ca)
return -EINVAL;
if (mode && !strcasecmp(mode, "hctr2"))
return 32;
if (mode && !strcasecmp(mode, "ecb"))
return 0;
@@ -79,21 +87,3 @@ int crypt_cipher_wrapped_key(const char *name, const char *mode)
return ca ? (int)ca->wrapped_key : 0;
}
bool crypt_fips_mode_kernel(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');
}

View File

@@ -38,6 +38,8 @@
*
*/
#include <stdio.h>
#include "crypto_backend.h"
static const uint32_t crc32_tab[] = {
@@ -95,87 +97,18 @@ static const uint32_t crc32_tab[] = {
0x2d02ef8dL
};
static const uint32_t crc32c_tab[] = {
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL,
0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL,
0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L,
0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L,
0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL,
0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L,
0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L,
0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L,
0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL,
0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L,
0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L,
0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL,
0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L,
0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL,
0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L,
0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL,
0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL,
0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL,
0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L,
0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL,
0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL,
0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L,
0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL,
0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L,
0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L,
0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL,
0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L,
0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L,
0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L,
0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L,
0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L,
0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L,
0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL,
0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L,
0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L,
0xAD7D5351L
};
/*
* This a generic crc32() function, it takes seed as an argument,
* and does __not__ xor at the end. Then individual users can do
* whatever they need.
*/
static uint32_t compute_crc32(
const uint32_t *crc32_table,
uint32_t seed,
const unsigned char *buf,
size_t len)
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
{
uint32_t crc = seed;
const unsigned char *p = buf;
while(len-- > 0)
crc = crc32_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8);
return crc;
}
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len)
{
return compute_crc32(crc32_tab, seed, buf, len);
}
uint32_t crypt_crc32c(uint32_t seed, const unsigned char *buf, size_t len)
{
return compute_crc32(crc32c_tab, seed, buf, len);
}

View File

@@ -1,45 +1,43 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* crypto backend implementation
*
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRYPTO_BACKEND_H
#define _CRYPTO_BACKEND_H
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#if HAVE_UCHAR_H
#include <uchar.h>
#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;
struct crypt_storage;
int crypt_backend_init(void);
int crypt_backend_init(bool fips);
void crypt_backend_destroy(void);
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
#define CRYPT_BACKEND_PBKDF2_INT (1 << 1) /* Iteration in PBKDF2 is signed int and can overflow */
#define CRYPT_BACKEND_ARGON2 (1 << 2) /* Backend provides native Argon2 implementation */
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
uint32_t crypt_backend_flags(void);
const char *crypt_backend_version(void);
const char *crypt_argon2_version(void);
/* HASH */
int crypt_hash_size(const char *name);
@@ -84,16 +82,6 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
/* CRC32 */
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
uint32_t crypt_crc32c(uint32_t seed, const unsigned char *buf, size_t len);
/* Base64 */
int crypt_base64_encode(char **out, size_t *out_length, const char *in, size_t in_length);
int crypt_base64_decode(char **out, size_t *out_length, const char *in, size_t in_length);
/* 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);
@@ -137,22 +125,14 @@ 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) */
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);
/* crypto backend running in FIPS mode */
bool crypt_fips_mode(void);
/* kernel running in FIPS mode */
bool crypt_fips_mode_kernel(void);
# ifdef __cplusplus
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
}
# endif
#endif /* _CRYPTO_BACKEND_H */

View File

@@ -1,17 +1,29 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* crypto backend implementation
*
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRYPTO_BACKEND_INTERNAL_H
#define _CRYPTO_BACKEND_INTERNAL_H
#include "crypto_backend.h"
/* Internal PBKDF2 implementation */
/* internal PBKDF2 implementation */
int pkcs5_pbkdf2(const char *hash,
const char *P, size_t Plen,
const char *S, size_t Slen,
@@ -46,7 +58,4 @@ int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length);
/* Internal implementation for constant time memory comparison */
int crypt_internal_memeq(const void *m1, const void *m2, size_t n);
#endif /* _CRYPTO_BACKEND_INTERNAL_H */

View File

@@ -1,20 +1,35 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Linux kernel userspace API crypto backend implementation (skcipher)
*
* Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2025 Milan Broz
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include "crypto_backend_internal.h"
#if ENABLE_AF_ALG
#ifdef ENABLE_AF_ALG
#include <linux/if_alg.h>
@@ -40,8 +55,6 @@ 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;
@@ -62,7 +75,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, &optval, tag_length) < 0) {
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, tag_length) < 0) {
crypt_cipher_destroy_kernel(ctx);
return -EINVAL;
}
@@ -88,33 +101,14 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
if (!strcmp(name, "cipher_null"))
key_length = 0;
if (!strncmp(name, "capi:", 5))
strncpy((char *)sa.salg_name, &name[5], sizeof(sa.salg_name) - 1);
else {
r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
if (r < 0 || (size_t)r >= sizeof(sa.salg_name))
return -EINVAL;
}
r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
if (r < 0 || (size_t)r >= sizeof(sa.salg_name))
return -EINVAL;
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,
const char *in, size_t in_length,
char *out, size_t out_length,
@@ -160,7 +154,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;
@@ -169,7 +163,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;
crypt_backend_memcpy(alg_iv->iv, iv, iv_length);
memcpy(alg_iv->iv, iv, iv_length);
}
len = sendmsg(ctx->opfd, &msg, 0);
@@ -216,8 +210,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], *cipher_iv = NULL, *key;
const char *salg_type, *real_mode;
char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
const char *salg_type;
bool aead;
int r;
struct sockaddr_alg sa = {
@@ -225,7 +219,6 @@ 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) {
@@ -246,22 +239,14 @@ 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) {
/* 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 (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 (r < 0 || (size_t)r >= sizeof(tmp_salg_name))
return -EINVAL;
@@ -327,8 +312,6 @@ int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
}
#else /* ENABLE_AF_ALG */
#pragma GCC diagnostic ignored "-Wunused-parameter"
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
const char *mode, const void *key, size_t key_length)
{

View File

@@ -1,16 +1,29 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* GCRYPT crypto backend implementation
*
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <strings.h>
#include <assert.h>
#include <gcrypt.h>
#include <pthread.h>
#include "crypto_backend_internal.h"
static int crypto_backend_initialised = 0;
@@ -51,6 +64,7 @@ static void crypt_hash_test_whirlpool_bug(void)
{
struct crypt_hash *h;
char buf[2] = "\0\0", hash_out1[64], hash_out2[64];
int r;
if (crypto_backend_whirlpool_bug >= 0)
return;
@@ -60,16 +74,16 @@ static void crypt_hash_test_whirlpool_bug(void)
return;
/* One shot */
if (crypt_hash_write(h, &buf[0], 2) ||
crypt_hash_final(h, hash_out1, 64)) {
if ((r = crypt_hash_write(h, &buf[0], 2)) ||
(r = crypt_hash_final(h, hash_out1, 64))) {
crypt_hash_destroy(h);
return;
}
/* Split buf (crypt_hash_final resets hash state) */
if (crypt_hash_write(h, &buf[0], 1) ||
crypt_hash_write(h, &buf[1], 1) ||
crypt_hash_final(h, hash_out2, 64)) {
if ((r = crypt_hash_write(h, &buf[0], 1)) ||
(r = crypt_hash_write(h, &buf[1], 1)) ||
(r = crypt_hash_final(h, hash_out2, 64))) {
crypt_hash_destroy(h);
return;
}
@@ -80,7 +94,7 @@ static void crypt_hash_test_whirlpool_bug(void)
crypto_backend_whirlpool_bug = 1;
}
int crypt_backend_init(void)
int crypt_backend_init(bool fips __attribute__((unused)))
{
int r;
@@ -113,11 +127,10 @@ int crypt_backend_init(void)
crypto_backend_initialised = 1;
crypt_hash_test_whirlpool_bug();
r = snprintf(version, sizeof(version), "gcrypt %s%s%s%s",
r = snprintf(version, sizeof(version), "gcrypt %s%s%s",
gcry_check_version(NULL),
crypto_backend_secmem ? "" : ", secmem disabled",
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "",
crypt_backend_flags() & CRYPT_BACKEND_ARGON2 ? ", argon2" : "");
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "");
if (r < 0 || (size_t)r >= sizeof(version))
return -EINVAL;
@@ -139,11 +152,7 @@ const char *crypt_backend_version(void)
uint32_t crypt_backend_flags(void)
{
uint32_t flags = 0;
#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2
flags |= CRYPT_BACKEND_ARGON2;
#endif
return flags;
return 0;
}
static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
@@ -249,7 +258,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
if (!hash)
return -EINVAL;
crypt_backend_memcpy(buffer, hash, length);
memcpy(buffer, hash, length);
crypt_hash_restart(ctx);
return 0;
@@ -258,6 +267,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
void crypt_hash_destroy(struct crypt_hash *ctx)
{
gcry_md_close(ctx->hd);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
}
@@ -323,7 +333,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
if (!hash)
return -EINVAL;
crypt_backend_memcpy(buffer, hash, length);
memcpy(buffer, hash, length);
crypt_hmac_restart(ctx);
return 0;
@@ -332,6 +342,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
void crypt_hmac_destroy(struct crypt_hmac *ctx)
{
gcry_md_close(ctx->hd);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
}
@@ -376,130 +387,6 @@ static int pbkdf2(const char *hash,
#endif /* USE_INTERNAL_PBKDF2 */
}
#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2
struct gcrypt_thread_job
{
pthread_t thread;
struct job_thread_param {
gcry_kdf_job_fn_t job;
void *p;
} work;
};
struct gcrypt_threads
{
pthread_attr_t attr;
unsigned int num_threads;
unsigned int max_threads;
struct gcrypt_thread_job *jobs_ctx;
};
static void *gcrypt_job_thread(void *p)
{
struct job_thread_param *param = p;
param->job(param->p);
pthread_exit(NULL);
}
static int gcrypt_wait_all_jobs(void *ctx)
{
unsigned int i;
struct gcrypt_threads *threads = ctx;
for (i = 0; i < threads->num_threads; i++) {
pthread_join(threads->jobs_ctx[i].thread, NULL);
threads->jobs_ctx[i].thread = 0;
}
threads->num_threads = 0;
return 0;
}
static int gcrypt_dispatch_job(void *ctx, gcry_kdf_job_fn_t job, void *p)
{
struct gcrypt_threads *threads = ctx;
if (threads->num_threads >= threads->max_threads)
return -1;
threads->jobs_ctx[threads->num_threads].work.job = job;
threads->jobs_ctx[threads->num_threads].work.p = p;
if (pthread_create(&threads->jobs_ctx[threads->num_threads].thread, &threads->attr,
gcrypt_job_thread, &threads->jobs_ctx[threads->num_threads].work))
return -1;
threads->num_threads++;
return 0;
}
static int gcrypt_argon2(const char *type,
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)
{
gcry_kdf_hd_t hd;
int atype, r = -EINVAL;
unsigned long param[4];
struct gcrypt_threads threads = {
.max_threads = parallel,
.num_threads = 0
};
const gcry_kdf_thread_ops_t ops = {
.jobs_context = &threads,
.dispatch_job = gcrypt_dispatch_job,
.wait_all_jobs = gcrypt_wait_all_jobs
};
gpg_error_t err;
if (!strcmp(type, "argon2i"))
atype = GCRY_KDF_ARGON2I;
else if (!strcmp(type, "argon2id"))
atype = GCRY_KDF_ARGON2ID;
else
return -EINVAL;
param[0] = key_length;
param[1] = iterations;
param[2] = memory;
param[3] = parallel;
err = gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4,
password, password_length, salt, salt_length,
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 */
if (gcry_kdf_compute(hd, NULL))
goto out;
} else {
threads.jobs_ctx = calloc(threads.max_threads,
sizeof(struct gcrypt_thread_job));
if (!threads.jobs_ctx)
goto out;
if (pthread_attr_init(&threads.attr))
goto out;
if (gcry_kdf_compute(hd, &ops))
goto out;
}
if (gcry_kdf_final(hd, key_length, key))
goto out;
r = 0;
out:
gcry_kdf_close(hd);
pthread_attr_destroy(&threads.attr);
free(threads.jobs_ctx);
return r;
}
#endif
/* PBKDF */
int crypt_pbkdf(const char *kdf, const char *hash,
const char *password, size_t password_length,
@@ -514,13 +401,8 @@ int crypt_pbkdf(const char *kdf, const char *hash,
return pbkdf2(hash, password, password_length, salt, salt_length,
key, key_length, iterations);
else if (!strncmp(kdf, "argon2", 6))
#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2
return gcrypt_argon2(kdf, password, password_length, salt, salt_length,
key, key_length, iterations, memory, parallel);
#else
return argon2(kdf, password, password_length, salt, salt_length,
key, key_length, iterations, memory, parallel);
#endif
return -EINVAL;
}
@@ -668,28 +550,3 @@ out:
return -ENOTSUP;
#endif
}
int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
{
return crypt_internal_memeq(m1, m2, n);
}
#if !ENABLE_FIPS
bool crypt_fips_mode(void) { return false; }
#else
bool crypt_fips_mode(void)
{
static bool fips_mode = false, fips_checked = false;
if (fips_checked)
return fips_mode;
if (crypt_backend_init())
return false;
fips_mode = gcry_fips_mode_active();
fips_checked = true;
return fips_mode;
}
#endif /* ENABLE FIPS */

View File

@@ -1,11 +1,25 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Linux kernel userspace API crypto backend implementation
*
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
@@ -103,7 +117,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
return 0;
}
int crypt_backend_init(void)
int crypt_backend_init(bool fips __attribute__((unused)))
{
struct utsname uts;
struct sockaddr_alg sa = {
@@ -231,6 +245,7 @@ void crypt_hash_destroy(struct crypt_hash *ctx)
close(ctx->tfmfd);
if (ctx->opfd >= 0)
close(ctx->opfd);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
}
@@ -309,6 +324,7 @@ void crypt_hmac_destroy(struct crypt_hmac *ctx)
close(ctx->tfmfd);
if (ctx->opfd >= 0)
close(ctx->opfd);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
}
@@ -400,13 +416,3 @@ int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}
int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
{
return crypt_internal_memeq(m1, m2, n);
}
bool crypt_fips_mode(void)
{
return crypt_fips_mode_kernel();
}

Some files were not shown because too many files have changed in this diff Show More