Replace the deprecated 22.04 runner with independent jobs for both releases.
Use system wxWidgets for the 26.04 GUI to match package dependencies;
keep static wxWidgets for 24.04 and both console builds.
Isolate caches, cleanup and artifacts by release. Update cache and cleanup
actions to Node 24 runtimes.
Fixes#1871
* Argon2: fix build with -march=x86-64-v3/v4 and XOP targets
blamka-round-opt.h picked its SSE2, AVX2 or AVX-512 definitions only from
the compiler flags. With global flags such as -march=x86-64-v3 or
-march=x86-64-v4, opt_sse2.c (and with v4 also opt_avx2.c) saw __AVX2__
or __AVX512F__ and got definitions that do not match its code, so the
build failed.
Let opt_sse2.c and opt_avx2.c select the variant they implement, and
fall back to the compiler flags for other includers. This needs no new
compiler options, so it also works with old compilers and with the
plain objects used by NOASM=1 builds.
With XOP targets (-march=bdver*), the header skipped its
_mm_roti_epi64 fallback but did not include the intrinsic; include
<x86intrin.h> for GCC and Clang there.
Hashes are identical through the AVX2, SSE2 and reference code paths,
and match an unmodified build.
Fixes#1867
Refs #1871
* Argon2: update branch comments in blamka-round-opt.h
The #else/#endif comments still named __AVX2__ and __AVX512F__, but the
branches are now selected by ARGON2_BLAMKA_USE_SSE2/AVX2.
Refs #1867
Add English fallbacks for 12 missing keys in 41 language files.
Report all missing keys and XML errors before failing validation.
Run four regression tests in CI. All tests and 43 XML files pass.
MountVolumeNative attaches a loop device only for a volume in a file,
but it recorded the volume path as the loop device in every case. For
a volume on a block device mounted with kernel cryptography, that is
the host device itself, so DismountVolume and EmergencyDismountVolume
ran losetup -d on it. A loop device that the user had attached, for
example to open a volume inside a disk image, was detached, or marked
for autoclear when emergency cleanup ran while the filesystem was
busy. On other devices, such as partitions, losetup failed and was
retried for about 1.2 seconds before the error was ignored. This code
comes from TrueCrypt 7.1a.
Record the loop device only when MountVolumeNative attached one, as
its error path already does. A volume mounted by an earlier version
keeps its FUSE service after an upgrade, and that service still
reports the host device, so the unmount functions also skip a loop
device that is the volume's own path. A loop device that VeraCrypt
attached is never the volume path.
Validated with console builds as root, for volumes on a loop device,
on a partition of a loop device attached with --partscan, and with
--emergency-unmount while the filesystem was busy: losetup no longer
runs, the loop device stays attached, and the partition case unmounts
in 0.18 s instead of 1.43 s. The same holds when these volumes are
mounted by 1.26.29 and unmounted by this build. Volumes in files and
nokernelcrypto mounts still detach the loop device that VeraCrypt
attached, also when mounting fails.
* Crypto: fix portable C code on big-endian CPUs
On big-endian CPUs (e.g. MIPS and PowerPC) the portable C code of
several algorithms assumes a little-endian host, so ciphertext, hashes
and derived keys are wrong and "veracrypt --text --test" fails:
- Twofish: the key-dependent S-box bytes are read back from 32-bit
words through a union, and blocks are loaded/stored as native words.
- Camellia: blocks and keys are always byte-swapped to big-endian.
- Kuznyechik: keys and blocks are loaded/stored as native 64-bit words
while the tables expect the little-endian interpretation.
- SHA-256/SHA-512: message words, length and digest are always
byte-swapped.
- BLAKE2s: the parameter block and message words are read as native
little-endian data. The parameter block is now built from its fields,
so it is right for any parameters, not only the ones VeraCrypt uses.
- Streebog: the existing big-endian code path is never enabled, and
BSWAP64 used by it is not defined (its buffer512 initializer also has
one pair of braces too many). Its add512() also differs from the
little-endian one, which drops a carry on purpose (existing volumes
depend on it); do the same limb arithmetic on big-endian.
- misc.h: the rotate-based bswap_32 (non-Linux, non-Apple, non-MSVC
builds) lacks outer parentheses, so "bswap_32(a) ^ b" is parsed
wrongly, and the fallback bswap_64 does not parenthesise its argument.
- PBKDF2: the block number is always byte-swapped.
Swap only where the host byte order differs from the data, and enable
the Streebog big-endian path. On big-endian hosts the message words,
keys and blocks of SHA-2, BLAKE2s, Twofish and Kuznyechik are read and
written byte-wise (new VcLoad*/VcStore* inline helpers in misc.h), so
these paths also work on misaligned buffers on strict-alignment CPUs.
On little-endian CPUs the code is unchanged: the object files of all
touched sources are byte-identical before and after this change
(checked on x86_64, aarch64 and mipsel). With it, all self-tests pass on
mips (big-endian) under qemu.
Signed-off-by: Ville Takio <ville+git@takio.fi>
* Volume: avoid unaligned 64-bit header and test vector accesses
The volume header (de)serialisation and TestXtsAES read and write 64-bit
fields through casted pointers into byte buffers at offsets that are
only 4-byte aligned (e.g. the header field at offset 12). CPUs that trap
on misaligned access without kernel fix-up (SPARC, MIPS64 on some
systems, qemu-user) then fail with SIGBUS in "veracrypt --test" and when
creating or opening any volume. Use memcpy instead, and have
DeserializeEntryAt check that the whole entry, not only its start, lies
inside the header.
The XTS code also accesses its local byte arrays (whitening values,
data unit number) through uint64 pointers; declare them 8-byte aligned
instead of relying on the compiler's stack layout.
Signed-off-by: Ville Takio <ville+git@takio.fi>
* Volume: test multi-block PBKDF2 output and the Streebog carry case
The PBKDF2 self-tests only check the first 4 bytes of each derivation,
so the block counter of the second and later output blocks is never
checked. Also compare the complete output of a 192-byte derivation for
every PRF, which covers the later blocks and how they are joined, and
hash a message whose block sum hits the carry case of Streebog's
add512(), which has to stay bit-compatible across CPUs. The message
buffer is 8-byte aligned, as the portable Streebog code reads it as
64-bit words. The expected values are those of the existing
little-endian code, and match independent implementations for all five
PRFs (Python hashlib/hmac, OpenSSL for Whirlpool, gostcrypto for
Streebog).
Signed-off-by: Ville Takio <ville+git@takio.fi>
---------
Signed-off-by: Ville Takio <ville+git@takio.fi>
The FAT formatter stored multi-byte boot sector and FSInfo fields by
casting positions in the sector buffer to integer pointers, and
GetMaxHiddenVolumeSize read the outer volume's boot sector the same
way. Several FAT fields start at odd offsets (bytes per sector at 11,
root directory entry count at 17, total sectors at 19, and the volume
ID at 39 or 67), so these accesses were misaligned. That is undefined
behavior whatever the byte order, and it can fault on targets that
require aligned accesses. An alignment-sanitized build reported the
stores in PutBoot and, for FAT12 and FAT16 outer volumes, the read of
the root directory entry count.
Copy each field between the buffer and a local integer with memcpy,
keeping the Endian::Little conversions, and copy the volume ID as its
four random bytes. Fields at even offsets use the same helpers: they
were aligned only because the sector buffer comes from malloc. The FAT
scan for the last used cluster is unchanged; it reads 32-bit words at
multiples of four in a malloc'd buffer and only tests them for zero.
Validated with x86_64 builds using -fsanitize=alignment and big-endian
s390x builds under qemu. With fixed volume ID bytes, the formatter
output for 18 FAT12, FAT16 and FAT32 layouts, including the FAT32
backup boot sector, is byte-identical before and after. The hidden
volume size of 16 volumes created and populated through the CLI is
unchanged and matches a separate implementation; the s390x checks used
the big-endian crypto fixes from #1899 to open the volumes. The
sanitizer and trap builds no longer report these accesses.
Volumes encrypted in user space are mounted through a loop device on the
FUSE volume image, and their writes end in buffered pwrite() calls to the
backing file or device. The FUSE service had no fsync callback, so libfuse
answered the fsync requests that the loop device issues for block-layer
flushes with ENOSYS, which Linux FUSE reports as success. Synced data
could therefore remain dirty in the host cache, and writeback errors were
not reported.
Register an fsync callback that syncs the backing storage for the volume
image and returns its errors through the existing mapping. Never return
ENOSYS, which would make Linux FUSE stop forwarding fsync for the whole
mount: report a backing ENOSYS as EIO, as the loop driver does, and
return success for the other files. Other Unix platforms are outside this
change.
Add regression coverage on device- and file-backed volumes: fsync must
flush the backing device, a backing failure must be reported as EIO, and
synced data must survive a simulated power cut. Without this change, the
synced data is lost. Validated with FUSE2 and FUSE3 builds.
Without dmsetup, MountVolumeNative fails with "dmsetup not found in
system directories" instead of using the FUSE path, so on systems that
do not ship device-mapper tools (for example OpenWrt) every mount and
the filesystem formatting step of --create need an explicit
--mount-options=nokernelcrypto. Treat a missing dmsetup like the other
cases where kernel crypto cannot be used.
Signed-off-by: Ville Takio <ville+git@takio.fi>
C99 inline without static does not emit a function body, so aarch64
builds at -O0/-Os fail to link DetectArmFeatures (undefined reference
to CPU_QueryAES / CPU_QuerySHA2). Use VC_INLINE like the other helpers
in cpu.c.
Signed-off-by: Ville Takio <ville+git@takio.fi>
Use the private file created by mktemp for embedded package data rather than reopening a predictable path. Quote the path and check failures when creating or placing the package.
Reported-by: curious-rabbit (https://github.com/curious-rabbit)
Fixed-by: curious-rabbit (https://github.com/curious-rabbit)
With NOASM=1 on x86/x64 the assembler module Aes_hw_cpu is not built,
but cpu.h still defines TC_AES_HW_CPU, so Cipher.cpp references
aes_hw_cpu_encrypt/decrypt. cpu.c also still declares and calls
TrySHA256, which Sha2Intel.c omits when CRYPTOPP_DISABLE_ASM is set
(NOASM passes CRYPTOPP_DISABLE_X86ASM, which implies it), and this
happens whenever __SHA__ is defined (-msha, -march=native) or
CRYPTOPP_SHANI_AVAILABLE is set.
- cpu.h: define TC_AES_HW_CPU on x86 only without CRYPTOPP_DISABLE_ASM
- cpu.c: declare and call TrySHA256 only under the same condition
Sha2Intel.c uses to build it (not _UEFI, not CRYPTOPP_DISABLE_ASM)
Both follow the compiler target, so cross builds need no ARCH override.
Signed-off-by: Ville Takio <ville+git@takio.fi>
Use POSIX sh and collect VeraCrypt arguments as quoted positional
parameters. Preserve whitespace in option values and keep wildcard
characters literal.
Handle calls without an option list and skip flags supplied between
the mountpoint and -o.
Collect system, nokernelcrypto, headerbak, and timestamp into one
--mount-options argument. Previously, only system had a mapping to
that argument; the remaining options went to the filesystem options.
Reject the obsolete truecrypt option before invoking VeraCrypt.
Validation: 32 cases passed under both Bash and dash using a stub
executable, with comparisons against the original helper.
Signed-off-by: Ville Takio <ville+git@takio.fi>
Create a fresh private parent for each FUSE-T auxiliary mount. Elevated
parents stay root-owned and grant only the original user read/search
access, restricting access through the auxiliary mount path and preventing
caller-controlled path replacement during elevated setup.
Clear inherited ACLs and reject temporary filesystems that ignore
ownership. Remove per-mount parents on setup failure and service teardown,
while preserving legacy temporary directories and discovery behavior.
Add regression coverage for permissions, unique parent creation, rollback,
and cleanup. FUSE-T transport authentication is outside this change.
Limit backup retry recovery to credential errors. Restore header selection
and rethrow other failures, including cancellation, in CLI and GUI.
Add regression coverage for fallback and credential recovery.
Run display discovery asynchronously and bound batched disk-image inventory
queries. Filter auxiliary mounts by basename, filesystem and owner, and
keep unresolved candidates separate from verified volumes. Allow targeted
dismounts despite incomplete discovery while requiring complete results
for slot allocation and empty-inventory decisions.
Use nonthrowing GUI snapshots with monotonic freshness, completion events
and safe window lifetimes. Suspend inactivity decisions while the snapshot
is stale, without restarting idle timers: activity counters are cumulative
per volume instance. Refresh logout targets and retry only failed ones.
Show a progress dialog for interactive unmounts, but keep automatic ones
synchronous, so a quit or logout request that arrives meanwhile is handled
afterwards rather than refused. Guard core operations against reentry and
route wait-dialog requests only from worker threads, so a main-thread
message cannot wait for itself.
Bind teardown to captured mount and service identities, including process
start time. Report a service exit that cannot be confirmed after auxiliary
mount removal as a distinct error that keeps the original details. Such
volumes are not retried, and a multi-volume unmount reports all of them
together with any other failure or a declined prompt. Warn about it after
automatic unmounts and at quit, and keep the background application until
the warning is acknowledged. Keep rollback responsive, and let services
remove their auxiliary directories without probing mounted paths. Preserve
released /control compatibility and perform best-effort cleanup for older
services.
Reap bounded subprocesses as soon as their output ends. A child that
survives SIGKILL is reaped by a later call, which starts no new child until
then. Keep subjects and subprocess command, status and error output when
formatting exceptions for wrapping and logs. Clarify discovery and rollback
diagnostics. Fix the localization-dependent busy-volume regression
assertion and extend discovery, snapshot, process identity, cleanup, GUI
lifecycle, inactivity and teardown coverage.
Keep FUSE serving until the auxiliary SMB filesystem is unmounted, then
join the shutdown worker before destroying the FUSE handle. Authenticate
socket peers and bind each request to the service and filesystem instance;
carry the force flag through to unmount and reply before teardown.
Resolve the current disk image before detach instead of trusting cached
BSD device numbers. Clear device and mount metadata when the image is gone,
and abort on inventory errors. Refresh ownership during enumeration and
before filesystem checks. Give each auxiliary mount a random path so an old
backend cannot target a subsequent VeraCrypt mount during cleanup.
Canonicalize the auxiliary path before service startup and hdiutil attach.
Resolve older clients' image paths through TMPDIR aliases without accessing
unrelated images. Treat candidate resolution failures as errors rather than
evidence that an attached image is gone.
Keep a new service provisional over a private inherited socketpair until
control-file readiness and public shutdown endpoint checks succeed. On
startup failure or caller exit, unmount while FUSE still serves and wait for
volume closure and service exit. Report incomplete cleanup explicitly and
keep retrying cleanup in the service if unmounting is temporarily blocked.
Restore dismounts of released services without /shutdown through a
validated legacy flow. Preserve incoming file-protocol notifications and
watch for external unmounts independently of those notifications. Legacy
unmount cannot guarantee termination of an already-running old service.
Use one fixed versioned socket frame and publish the random endpoint in
/shutdown-socket, preserving the three-field /shutdown identity. Remove
compatibility with unpublished socket protocols. Recover from transient
accept and mount-enumeration failures, bound partial-request lifetimes,
and report connection refusal as an availability error. Handle join failure
without unwinding the destructor or freeing a live worker's context.
Map auxiliary EBUSY to MountedVolumeInUse for the GUI force prompt. Return
failure for a single busy non-interactive dismount and log automatic-dismount
failures. Mark inherited descriptors close-on-exec before FUSE setup and
make File::SetCloseOnExec const.
Extend disposable-container tests for released clients and services,
reused device numbers, partial requests, identity validation, forced write
integrity, TMPDIR aliases, and injected startup and rollback failures.
Validated without sudo with a clean arm64 build, unchanged warnings,
algorithm self-tests, the compatibility matrix, descriptor audits, worker
fault-recovery checks, and 24 conditional compilation checks.
Set FD_CLOEXEC on the backing file and signal pipe write descriptor
before launching the backend.
This avoids retained volume handles and delayed signal handler exit.
Apply the change only to the macOS FUSE-T path.
Keep the shutdown worker joinable and wait for it before destroying the
FUSE handle.
Use explicit setup and cleanup so the channel is unmounted only once.
Generate the session serial before forking and reuse it in the service
and fallback mount metadata.
This keeps PR #1866's shutdown identity check consistent when control
metadata cannot be read.
Notify on direct favorite mount success using the returned protection mode.
Keep recovered mounts on their existing notification path, and use the
returned mode there as well so read-only overrides are reflected accurately.
Handle protection failures before outer-password retries, retain cached and
explicit outer credentials without adding default keyfiles, and focus the
hidden-protection controls. Initialize hidden PIM and KDF independently,
and retain an accepted backup header during protection recovery.
Retry embedded backup headers after repeated hidden-protection failures
without advancing the outer-password retry count. Restore the accepted
primary-header selection if backup authentication fails, and report
automatic backup use only when the selected header remains a backup.
Keep primary-header recovery available after an automatic backup attempt
fails with EIO, while reporting the error. Preserve cancellation and
other error handling.
Pass known protection failures from favorite mounts directly into GUI
recovery, including keyfile-only credentials with a null password. Skip
redundant authentication attempts and preserve the text interface's
existing retry path.
Initialize the backup-header checkbox with the other validated controls,
so an initial backup-header request survives the first password prompt.
Conceal the accepted outer password and PIM before disabling their
controls during protection recovery.
Add an authenticated shutdown endpoint to the auxiliary FUSE filesystem and wait for the matching service process to terminate before removing the mount point.
Reuse hidden-credential recovery for cached and backup-header attempts.
Keep the outer credential source and backup selection during correction.
Warn about automatic backup-header use only after mounting succeeds.
Handle protection-keyfile failures before general password failures.
Reset the hidden password, PIM, and keyfiles for correction while retaining
outer credentials and avoiding backup-header retries.
Check MissingArgument, NoItemSelected, and StringFormatterException before
UserInterfaceException in both rethrow helpers. This prevents slicing
and preserves their specific exception types and diagnostics.
Check PasswordIncorrect subclasses before the base class in both UI
exception handlers. This prevents slicing and preserves the specific
protection and keyfile error messages.
Reuse the prepared password to avoid rereading outer keyfiles after
mounting. This prevents post-mount read failures and ensures the cache
contains the credential that unlocked the volume.
Apply protection keyfiles once in the application, including cached-password
mounts. This keeps PC/SC out of the core service before FUSE forks.
Preserve protection errors and cache retries, and ignore protection
credentials when protection is disabled.
SCard::manager is a static object whose constructor called
SCardLoader::Initialize(), which establishes a PC/SC context before
main() in every VeraCrypt process. On macOS this opens an XPC
connection that starts a helper thread and marks libdispatch as
fork-unsafe.
As a result, CoreService::Start() forked a multithreaded process, and
the FUSE service (which libfuse runs after fork() without exec())
inherited armed Objective-C fork-safety checks and poisoned dispatch
queues. With macFUSE >= 5.3.3 this causes:
- a SIGABRT when mounting ("+[NSNumber initialize] may have been in
progress in another thread when fork() was called"), and
- a SIGSEGV in MFChannelClose/dispatch_channel_cancel at unmount.
Load the PC/SC library on first use instead: GetReaders() now calls
loader->Initialize() itself (GetReader() already did, and Initialize()
is idempotent). PC/SC is then only touched when EMV keyfiles are used,
and never in the core service or FUSE service processes.
Tested on macOS 27.0 (arm64) with macFUSE 5.4.0: 30/30 mount/write/
remount/verify/dismount cycles with no crash reports. Previously every
mount failed.
Refs #1884, #1863, macfuse/macfuse#1193
Assisted-by: Claude Opus 5.5
Restrict caller-supplied object-manager and disk paths used by metadata IOCTLs to the forms required by VeraCrypt. Also force symlink access checks, remove the unused legacy geometry handler, authorize real-drive probing before name resolution, and gate cache wiping on successful emergency key clearing.
Security advisory: https://github.com/veracrypt/VeraCrypt/security/advisories/GHSA-9mgv-w2fw-3m78/
A few menu item labels were passed as wxString instead of
.mb_str(), which doesn't compile against wxWidgets 3.2. One
label in the same function already did it right, the rest didn't.
Clone command-line auto-mount options before device and favorite batches, and clone the batch options again for each favorite before applying favorite-specific fields.
This prevents interactive credentials, PIM, KDF choices, and per-favorite filesystem settings from carrying over to later favorites.
Propagate EMVSupportEnabled through MountOptions serialization and mount setup so elevated core service requests use the same EMV setting as the caller.
Document the two Microsoft-signed loader sets and their firmware db requirements, the EfiBootLoader diagnostics registry key, and the BIOS third-party certificates option needed on machines that ship with a 2023-only Secure Boot configuration.
Explain why the Windows Secure Boot certificate rollout does not trigger automatically on system-encrypted machines, how to trigger it via the documented AvailableUpdates registry value, the precautions to take, and the recovery procedures when Secure Boot blocks the boot chain.
Link the page from the System Encryption documentation and the CHM table of contents.
Track Microsoft Windows Production PCA 2011 and Windows UEFI CA 2023 in the firmware db parser so the trust of the chainloaded Windows boot manager copy (bootmgfw_ms.vc) can be verified.
Add BootEncryption::GetEfiBootChainTrustStatus to check the installed VeraCrypt loader set and the bootmgfw_ms.vc signer against the active Secure Boot db, asserting nothing from malformed or partial firmware data.
Warn before reboot during Setup upgrade/repair and log a System Favorites service event when a boot chain component is no longer trusted, so Secure Boot certificate changes surface in Windows instead of as a pre-boot failure.
Refs #1655.
Expose FFS as the native OpenBSD filesystem option for volume creation and accept FFS/UFS on the command line, mapping mounts to the OpenBSD ffs filesystem type.
Run newfs through the elevated core service on vnd raw devices, then temporarily mount the new filesystem to transfer root directory ownership back to the invoking user.
Keep the non-interactive creation default as FAT on OpenBSD so existing unattended scripts do not start requiring elevation.
Reuse the OpenBSD doas PTY prompt flow on FreeBSD so opendoas receives the password through its controlling terminal.
Apply the same foreground process group validation on FreeBSD as on OpenBSD when attaching the private doas authentication PTY.
Detect the incompatible FreeBSD security/doas package by pkg origin and fail with explicit guidance.
Decrement ActiveWorkItems only after the completion work item has returned queue resources and released its pool item. EncryptedIoQueueStop now synchronizes with WorkItemLock after the active count drains, ensuring the last work item has stopped touching queue state before the work item pool and buffer pools are freed.