Commit Graph
3003 Commits
Author SHA1 Message Date
Bernard LadenthinandGitHub e9992cf778 Tests: verify that CRYPTOPP_ALIGN_DATA delivers the requested alignment (#1844)
The macro expands to nothing for compilers that are neither MSVC nor
GCC/Clang, and the SIMD backends issue aligned loads against buffers declared
with it, so a silent expansion to nothing would fault at run time. Nothing
verified this so far.

Add TC_IS_ALIGNED next to the existing alignment constants and check both of
them from the platform self-test suites. The probe buffers stay below the
alignment under test because the ABI already aligns larger objects by itself,
which would make the check pass vacuously.

The check is skipped in the Windows driver: a failing self-test there reaches
TC_BUG_CHECK and would bugcheck the machine.
2026-10-13 17:09:34 +09:00
Mounir IDRASSI 24c7449c69 docs: describe volume files on user-only FUSE mounts on Linux
Add a Troubleshooting entry for volume files that root cannot open on a
file system mounted by the user, such as a GVfs share: what VeraCrypt
now does, why the share and the session must stay available, when
keyfiles stored there can be used, and the alternatives of a kernel CIFS
mount or allow_root. Add release notes for the requester access and its
effect on NFS with root_squash.
2026-10-13 14:36:46 +09:00
Mounir IDRASSI 632963cf85 Tests: add a root test for the requester helper
The test compiles the requester helper code into a small harness and runs
it as root on an ordinary file owned by an unprivileged user. It checks
that the helper runs in a freshly executed process with a reduced
environment, descriptors 0-2 on /dev/null and no other inherited
descriptor, with and without close_range, including when a library is
found only through LD_LIBRARY_PATH, as in the AppImage. It also checks
that a failed or incomplete start is reported as a startup failure and
never falls back to read-only access, and that invalid requests and a
request socket whose peer is not root are refused.
2026-10-13 14:36:46 +09:00
Mounir IDRASSI e21ab81231 Tests: add a root test for volume files on user-only FUSE mounts
As an unprivileged user, the test mounts a passthrough FUSE fixture
without allow_other, so that root is denied as with a GVfs share. It then
runs VeraCrypt as root with the sudo attribution of that user. It covers
writable and read-only mounting, the read-only fallbacks, missing or
invalid attribution, wrong passwords, special files, hidden volume
protection, slow servers, timestamp restoration and the mount warning.
2026-10-13 14:36:45 +09:00
Mounir IDRASSI 3e1c3f6490 Linux: warn when a mounted volume depends on the requester's session
A volume file opened with the credentials of the requesting user is
served by a file system that belongs to that user's session. Ejecting
the share or logging out while the volume is mounted can lose data, and
GVfs does not refuse to eject a share whose file is in use. Warn after
each such mount that the share must stay mounted and the session active
until the volume is unmounted. Append the English message to all
language files as a fallback.

The indicator reaches the UI with the mount result, through a new
MountVolumeRequestV2/ResponseV2 pair: a service that predates it rejects
the new request before mounting, and legacy requests keep their legacy
response, so that an older UI still works with a newer service. The
control file format is unchanged.
2026-10-13 14:36:45 +09:00
Mounir IDRASSI eb9d10f430 Linux: mount volume files that only the requesting user can access
A FUSE file system mounted without allow_other, such as a GVfs share,
denies root access to files that its owner can open. Mounting a volume
stored there, or formatting a new one with a non-FAT file system, failed
with "Permission denied".

When root is denied opening an existing volume file, re-execute
VeraCrypt with the internal option --requester-helper. The helper
permanently takes the credentials of the user who requested elevation
through sudo or doas, opens the file and passes the descriptor back.
Root does all I/O through that descriptor and mounts the volume through
the FUSE volume image. Another helper restores the timestamps when the
FUSE service closes the file.

This also lets volumes on NFS with root_squash mount read-write instead
of falling back to read-only.

Fixes #23
2026-10-13 14:36:40 +09:00
a835875912 Fix build with NOSSE2 (#1891)
* Fix build with NOSSE2

Disable AESNI and SHANI code that depends on SSE2 availability if NOSSE2
is enabled.

* Fix NOSSE2 builds while preserving runtime AES acceleration

Keep AES/Camellia acceleration enabled and honor NOSSE2 with NOAESNI.
Include stddef.h outside UEFI to provide wchar_t for Camellia.
Match the SHA probe guard to its implementation, keeping NOASM and
UEFI exclusions.

---------

Co-authored-by: Mounir IDRASSI <mounir.idrassi@amcrypto.jp>
2026-10-12 00:01:39 +09:00
Mounir IDRASSI 62253154cb Wipe token keyfile buffers on failure and release
Use a size_t counter in burn so large erasures retain their full length.
Install cleanup guards before token verification and keyfile application,
including the Windows token export path.

Reserve the complete EMV keyfile output before copying its components,
and wipe temporary components on every exit. Erase cached card data before
clearing or replacing it, including when copying a card fails.

Validation: Linux console and GUI builds with algorithm tests; cleanup
checks with GCC and Clang UBSan. PR 1816 still applies cleanly.
2026-10-11 23:10:55 +09:00
Mounir IDRASSI b2b28d5793 Linux: release only the volume's own loop and device-mapper devices
Unmounting released the loop device and device-mapper devices recorded
at mount time, by name. After a dismount that failed partway, for
example on a busy auxiliary FUSE mount, these names could be reused by
unrelated objects, which the listing then showed as the volume's and a
retry, emergency cleanup, filesystem check or auto-dismount released.
Without kernel cryptography, the loop device, which carries the
decrypted volume, was also released while the filesystem was mounted
elsewhere or the device was held open. A failed mount could remove a
pre-existing device-mapper device of the same name, and a failed
cascade mount could leave its layers and loop device behind.

Each destructive step now acts only on a device verified to belong to
the volume. A loop device must be bound to the container or volume
image (LOOP_GET_STATUS64). Device-mapper devices get the UUID
VERACRYPT-<serial>-<name> and are removed by UUID; those of earlier
versions, which have none, are verified through their sysfs slaves,
and the dismount fails, saying why, if that is not possible. Emergency
cleanup is not offered then, as it would hide the volume but leave its
devices. While the filesystem is mounted elsewhere, the dismount fails
and keeps the volume's devices. With kernel cryptography, the loop
device is marked for autoclear as soon as it is attached and verified,
so the kernel detaches it once device-mapper releases it; a process
holding it open sees only ciphertext and does not fail the dismount.
Without kernel cryptography, the dismount also fails while the loop
device is held open. Dismount, emergency cleanup, filesystem check and
the listing re-read the volume's devices from its auxiliary mount, and
the English emergency warning mentions these causes.

Add Tests/test_linux_loop_identity.py, covering these cases with and
without kernel cryptography, and with --legacy-binary, volumes mounted
by an earlier version. All 89 checks pass, as do the 11 added by
--legacy-binary 1.26.29; 1.26.29 itself fails 21 of the 89.
2026-10-11 22:33:20 +09:00
Jonatan NybergandGitHub 4b3d38eed4 Update Swedish translation (#1826) 2026-10-11 22:27:09 +09:00
Mounir IDRASSI 3eaa6fc4c7 Windows: handle window placement repair failure
Return the SetWindowPlacement result so SC_RESTORE falls back to
normal handling on failure.

Describe the observed window state without assuming its cause.
2026-10-11 22:18:03 +09:00
amail80andGitHub 689507c41c Windows: bring the main window back on screen when its restore position is off screen (#1858)
* Windows: bring the main window back on screen when its restore position is off screen

A minimized window is parked by Windows at (-32000,-32000). When the display
topology changes while it is minimized - which happens on every session lock
that powers off a monitor - Windows can copy that parking position into the
window's restore rectangle and clear WS_MINIMIZE. The window then is, by every
API, a normal visible window living 32000 pixels off screen: IsIconic returns
FALSE, IsWindowVisible returns TRUE, and ShowWindow (SW_RESTORE) is a no-op
because the restore rectangle is exactly where the window already is.

The user is left with an application that answers its notification area icon
but whose main window cannot be shown by any means, and only restarting
VeraCrypt recovers it.

Validate the restore rectangle and re-center it on the primary monitor when it
intersects none. The repair runs from the three paths that show the window and,
because clicking the taskbar button of an already visible window runs no
application code at all, also on WM_DISPLAYCHANGE. showCmd is left as
GetWindowPlacement returned it, so a legitimately minimized window stays
minimized and only its future restore position is corrected.

The window size is captured once after the dialog has been laid out: a parked
window carries the parking size, so it cannot serve as a source for the normal
dimensions.

Verified on Windows 11 26200.8875 with two monitors at different scale factors,
the primary one being powered off by the session lock: GetWindowPlacement
returned rcNormalPosition = (-32000,-32000)-(-31840,-31972), and neither a
notification area click nor an explicit minimize/restore cycle brought the
window back.

* Windows: fix the size, offset and trigger of the main window repair

The size used by RepairMainWindowPlacement was measured on the window at
the end of InitMainDialog whenever the window was not minimized. In the
state the repair handles, the window is not minimized but has the
parking dimensions, and InitMainDialog can run on it, for example when
the language is changed from Preferences opened from the notification
area. The font compensation then grows the height and keeps the parking
width, so the kept size became 160x456. The size is now taken once from
the newly created window, whose width never changes, and follows the
font compensation only while the window has that width: in a window as
narrow as a parked one the menu bar wraps and moves the controls down,
so the compensation height is meaningless there too.

A restore rectangle that is no larger than a minimized window in either
dimension is now repaired. Before, both dimensions had to be that small,
so a 160x456 rectangle was left as it was.

The repaired position was converted with the work area origin of the
primary monitor, and the visibility test passed rcNormalPosition to
MonitorFromRect unconverted. Workspace coordinates are offset by the
position of the work area within the monitor associated with the
window, so the offset of that monitor is now used, both to convert a
copy of the rectangle to screen coordinates for the visibility test and
to express the repaired position. With an appbar on the left, a window
just beyond the right edge was taken as visible; with an appbar on top
of the primary monitor only, a window repaired on another monitor was
placed too high.

The repair also runs on WM_ACTIVATE. The session notification that
triggers it after an unlock is registered only while the background task
is enabled, and activating a window that is not minimized, from its
taskbar button or with Alt+Tab, runs none of the other repair paths.
Two comments that said a taskbar click runs none of our code are
corrected.
2026-10-11 22:13:35 +09:00
amail80andGitHub 83b4fc23cb Show Secure Desktop dialogs on the monitor of their parent window (#1912)
* Show Secure Desktop dialogs on the monitor of their parent window

Dialogs shown through SecureDesktopDialogBoxParam (the password prompt,
mount options and the security token PIN prompt) are created on the
Secure Desktop without an owner, because their parent window stays on
the original desktop. Without an owner, DS_CENTER puts them on the
primary monitor even when the main window is on another one, so the
password is typed on one monitor and the wait dialog then appears on
the other.

Before switching desktops, take the middle of the work area of the
monitor that Windows associates with the parent window, and create a
hidden owner window at that point on the Secure Desktop. The DS_CENTER
dialog is then centered on the same monitor as without Secure Desktop,
and the dialogs opened from it follow it. If the parent window is hidden
or minimized, or the owner can't be created, the dialog has no owner as
before.

The monitor lookup added to ShowWaitDialogEx in #1865 moves into a
helper used by both.

* Windows: read signed coordinates in the Keyfiles context menu handlers

The WM_CONTEXTMENU handlers of the password dialog, the mount options
dialog and the VeraCrypt Expander password dialog took the click
position with LOWORD and HIWORD and compared it with the signed
rectangle from GetWindowRect. On a monitor to the left of or above the
primary one the screen coordinates are negative, LOWORD and HIWORD
return them as large positive values, and a right click on the
Keyfiles button was ignored. Use GET_X_LPARAM and GET_Y_LPARAM, as the
other WM_CONTEXTMENU handlers in Mount.c already do.

Now that the Secure Desktop prompt opens on the monitor of its parent
window, this case is easier to reach.
2026-10-11 20:44:22 +09:00
MatthaiksandGitHub f939c3f639 Update Polish translation (#1918) 2026-10-11 20:21:38 +09:00
Mounir IDRASSI 89cd591abb Tests: cover uneven reads with 32 workers
Add a 33 sector range to the volume read test and correct the header compatibility check description in the big endian workflow.
2026-10-11 20:15:46 +09:00
Ville TakioandGitHub df2e9dcd30 Tests: read known data from the test volumes without mounting (#1907)
The Linux workflow checks the content of the Tests/*.hc volumes by
mounting them, which needs root, FUSE and the installed package, and so
only runs on x86_64. Add a test that recovers the same data through the
volume layer instead, so it also runs on other architectures, e.g. on the
big-endian cross build under qemu-user.

Tests/volume_read_test.cpp opens a volume read-only and reads its data
area with Volume::ReadSectors: in one call, as multi-sector ranges at
nonzero offsets with odd sector counts, again with the encryption thread
pool running, and one sector at a time; every read must match the first.
CPU features are detected as in the application, and the character set
is taken from the environment (LC_CTYPE) so that paths with non-ASCII
characters work; if that locale is unavailable, the test continues in the
C locale and says so.

Tests/test_volume_read.py builds it against Volume.a and Platform.a of a
finished standard Linux build (CXX and NM can be set for a cross build)
and checks the plaintext of every Tests/test.*.hc volume: the FAT boot
sector, DUMMY.TXT with the content "Dummy" at the cluster given by the
root directory, and a known SHA-256 digest of the whole data area. A
volume without a digest, or a digest without a volume, is an error.

It runs in the Linux workflow after the .deb build and in the build job
of the big-endian workflow (test.sha512.hc only in the automatic check,
all volumes in the full run), and requires the thread pool there.

Signed-off-by: Ville Takio <ville+git@takio.fi>
2026-10-11 18:50:22 +09:00
Mounir IDRASSI 3f04c42db9 Increment version to 1.26.30 2026-10-11 15:56:54 +09:00
Mounir IDRASSI 6e63041962 Linux: secure NixOS helper lookup and report blocked elevation
Look up NixOS helpers only when trusted system metadata identifies NixOS
and each path component passes ownership and permission checks. Keep the
existing helper search on other distributions.

Detect NoNewPrivs before prompting for administrator credentials, with a
clear error for restricted launchers. Add regression coverage to Linux CI
and append the English fallback message to all language files.

Refs #1911
2026-10-10 22:25:42 +09:00
Mounir IDRASSI 3e3a271e52 Unix: fix SystemLog include cycle in debug builds
With DEBUG enabled, including StringConverter.h reaches SystemLog.h through
PlatformBase.h before StringConverter is declared. The inline
WriteException implementation then fails to compile.

Move WriteException into Unix/SystemLog.cpp and include StringConverter.h
there, keeping the logging behavior unchanged while removing the header
dependency cycle.
2026-10-10 20:33:18 +09:00
Mounir IDRASSI ac842e8d04 Tests: cover wxWidgets job sharing and OpenWrt serial builds 2026-10-10 12:26:38 +09:00
Mounir IDRASSI dc74edfd5b Build: clarify wxWidgets job selection limitations 2026-10-10 12:26:21 +09:00
Ville TakioandGitHub 98ef739cd8 Build: let a parent make control the wxWidgets build jobs (#1903)
* Build: let a parent make control the wxWidgets build jobs

The wxbuild target always runs the wxWidgets sub-make with -j 4. When
VeraCrypt is built from a parent "make -jN" (for example by a
distribution or embedded build system), the explicit -j 4 overrides the
parent's job count and jobserver: the wx build ignores -j1 and the
configured parallelism and can oversubscribe the machine.

Keep -j 4 as the default for a standalone build, but leave the job count
to the parent make when it was started with -j: MFLAGS then contains -j,
-jN or the jobserver option (-j1 since GNU make 4.2; older makes treat a
-j1 parent like a serial one without -j). MFLAGS is used rather than
MAKEFLAGS because it holds only options, not command-line variable
definitions, so a variable value containing "-j" cannot match.

See also #717, which proposed dropping -j 4 for the same reason.

Signed-off-by: Ville Takio <ville+git@takio.fi>

* Build: also detect grouped -j flags; pass OpenWrt jobs to wxbuild

Address review:

- GNU make 3.81 can group single-letter options in MFLAGS, e.g. "-sj"
  for the -s this Makefile adds plus a bare -j, which the previous
  pattern missed. Look for "j" in every single-dash option word instead,
  skipping the options that take an argument (-C, -E, -I, -O, -W, -f,
  -o). An option argument containing a space followed by "-j" can still
  be mistaken for a job option; this is documented next to the variable.
- The OpenWrt recipe built wxWidgets without the package's job settings,
  so it still ran 4 jobs. Pass $(PKG_JOBS) and an empty WX_MAKE_JOBS, so
  the wxWidgets build follows OpenWrt's settings, including serial
  builds.

Signed-off-by: Ville Takio <ville+git@takio.fi>

---------

Signed-off-by: Ville Takio <ville+git@takio.fi>
2026-10-10 12:10:26 +09:00
Mounir IDRASSI 37ce73775f Tests: verify rejected passwords leave volumes unchanged
Compare volume contents before and after a rejected password change.
Check before reopening, which rewrites both headers and could hide damage.
2026-10-09 21:16:17 +09:00
Ville TakioandGitHub 277e236968 CI: build and test on big-endian (s390x) and across byte orders (#1905)
* CI: build and test on big-endian (s390x) and across byte orders

The Linux workflow only builds and tests on x86_64, so code that assumes
a little-endian host (see #1899) is not caught. Add a workflow that
cross-builds the console version for s390x and runs it under qemu-user:

- the algorithm self-tests (--test),
- the Tests/test.*.hc volumes, created on little-endian, must open and
  accept a password change,
- volumes created on s390x open on a native amd64 build and the other
  way round, for every encryption algorithm and cascade, with every PRF
  (new Tests/test_byte_order_interop.py, also usable on its own).

The wxWidgets console build is cached per architecture, like in the
existing Linux workflow.

Signed-off-by: Ville Takio <ville+git@takio.fi>

* CI: quick big-endian check on pull requests, full suite on request

Address review:

- Pull requests and pushes run only the s390x build, the algorithm
  self-tests and the Tests/*.hc volumes. The full suite (amd64 build,
  volumes on both builds, interoperability in both directions) runs
  when started manually, with the volume and interoperability tests in
  separate jobs that run concurrently.
- Pass the KDF with --hash; one interoperability case per direction
  still uses autodetection.
- Use separate current and new PIM values: the Tests/*.hc volumes are
  opened with PIM 0, but the new headers use PIM 1, so only the first
  key derivation is expensive.
- Open each Tests/*.hc volume again with the new password before
  removing it.
- Run VeraCrypt with LANG and LC_ALL set to C and an empty
  XDG_CONFIG_HOME, so the "Incorrect password" check does not depend on
  the user's language settings.
- Fail instead of reporting success when nothing would be tested:
  --skip-official without a second binary, or no (or a missing
  requested) Tests/*.hc volume. Add --fixture to select volumes.
- Print how long each check takes.

* CI: keep the automatic big-endian check short

- Open only Tests/test.sha512.hc in the automatic check (all five
  volumes took 154 s of the 327 s s390x job); the full suite still
  opens all of them.
- Cover KDF autodetection in the automatic check too: the first volume
  is opened with the new password (PIM 1) without --hash. The
  interoperability case without --hash now uses sha256, since sha512
  is tried first anyway.
- Include the event name in the concurrency group, so a push does not
  cancel a manual full run.
- Print the elapsed time for failed checks too.

(The previous commit message should say that XDG_CONFIG_HOME points to
an empty temporary directory.)

* CI: use actions/cache@v5 in the big-endian workflow

Match build-linux.yml, which moved to the Node 24 runtime in 9d9fda20.

---------

Signed-off-by: Ville Takio <ville+git@takio.fi>
2026-10-09 21:11:38 +09:00
amail80andGitHub f8e397cd5d Show mount/wait dialog on the monitor of the main window (#1865)
* Show mount/wait dialog on the monitor of the main window

* Place the wait dialog owner on the monitor chosen by MonitorFromWindow

Instead of the centre of the creator window, put the temporary owner in the
middle of the work area of the monitor returned by MonitorFromWindow
(MONITOR_DEFAULTTONEAREST). The centre point can lie on a different monitor
than most of the window when displays are offset, and Windows may make the
owner larger than the requested 1x1, so an owner close to a monitor edge
could spill onto the neighbouring monitor and take the wait dialog with it.
2026-10-09 20:41:11 +09:00
Ville TakioandGitHub 7c06e03ec3 Crypto: use alignment-safe loads and stores where unaligned access faults (#1909)
* Crypto: use alignment-safe loads and stores on all hosts

SHA-2, BLAKE2s, Twofish and Kuznyechik read and write words in caller
buffers directly on little-endian hosts, Streebog's stage2() reads 64-bit
words from the input, and the Unix XTS code XORs whitening values through
uint64 pointers. On strict-alignment CPUs (ARMv5-v7 for LDRD/LDM, MIPS,
mips64) this raises SIGBUS when a caller passes an unaligned buffer; real
volume operations use aligned buffers, but test vectors and future
callers need not.

- SHA-2, BLAKE2s, Twofish and Kuznyechik use the VcLoad*/VcStore* helpers
  on all hosts, not only on big-endian ones.
- On GCC/Clang little-endian targets the helpers copy with memcpy, which
  compiles to single loads and stores where unaligned access is allowed,
  so the C paths keep their speed. MSVC targets keep native accesses, as
  before.
- Streebog takes the direct path only for 8-byte-aligned input; other
  input goes through the existing copy into CTX->buffer.
- XTS (Unix, without the x64 SSE path) XORs the whitening values through
  memcpy.

Output is unchanged: known-answer comparisons for every offset from 0 to
15 match on x86_64, armv7, mips, mipsel and mips64, and an
alignment-checking (UBSan) build is clean.

Signed-off-by: Ville Takio <ville+git@takio.fi>

* Crypto: keep direct word accesses where unaligned access is safe

Address review: limit the alignment fix to the targets that need it.

VC_UNALIGNED_ACCESS_OK (config.h) is 1 on x86, x64, ARMv8 (including
MSVC ARM64) and PowerPC, where unaligned 32- and 64-bit accesses are
safe; there SHA-2, BLAKE2s, Twofish, Kuznyechik, Streebog and XTS
compile exactly as before. On other targets (32-bit ARM, whose
unaligned support does not cover LDRD/LDM, MIPS, ...), they load and
store through the VcLoad*/VcStore* helpers; SHA-2 keeps its byte swaps
and only the input load changes.

The object code of the changed files is identical to master with GCC
and Clang on x86_64 and with GCC on AArch64. On armv7, mips, mipsel and
mips64 (qemu-user), the known-answer outputs at buffer offsets 0..15
match x86_64.

Signed-off-by: Ville Takio <ville+git@takio.fi>

---------

Signed-off-by: Ville Takio <ville+git@takio.fi>
2026-10-09 20:39:21 +09:00
Ville TakioandGitHub cb1d9a4c3b Crypto: no unaligned 64-bit accesses on 32-bit ARM (#1908)
CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS was defined whenever
__ARM_FEATURE_UNALIGNED is set, which includes 32-bit ARMv6/ARMv7. There
the hardware handles unaligned single-word loads and stores, but not
LDRD/STRD/LDM, which the compiler uses for 64-bit words. Camellia
(camellia_load64/camellia_store64) and Whirlpool (HashMultipleBlocks on
unaligned input) then access 64-bit words through unaligned pointers.

camellia_set_key() raised SIGBUS in the XTS self-test on an ARMv7
(cortex-a15) build whose test key happened to be only 2-byte aligned.

Define the macro for AArch64 only among the ARM targets; on 32-bit ARM
the memcpy and aligned-copy paths are used instead.

Signed-off-by: Ville Takio <ville+git@takio.fi>
2026-10-09 06:28:13 +09:00
Marius KjærstadandGitHub ed6613a001 Update Norwegian Bokmål translation (#1904)
* Update Norwegian Bokmål translation

* Accelerator collisions and some other fixes
2026-10-09 06:12:26 +09:00
felixandGitHub 4edad72bcc Unix: require confirmation before overwriting containers (#1861) 2026-10-06 00:09:52 +09:00
Mounir IDRASSI 9d9fda208d CI: test Ubuntu 24.04 and 26.04
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
2026-10-05 10:23:32 +09:00
Mounir IDRASSI ff355d111f Argon2: fail self tests on context errors
Count argon2_ctx errors as test failures. Previously, failed calls skipped the hash comparison without increasing the failure count.
2026-10-05 09:27:21 +09:00
Ville TakioandGitHub 4f76ff7132 Argon2: fix build with -march=x86-64-v3/v4 and XOP targets (#1906)
* 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
2026-10-05 09:22:45 +09:00
MatthaiksandGitHub 5d4127d9a7 Update Polish translation (#1902)
* Update Polish translation
2026-10-04 18:40:25 +09:00
Mounir IDRASSI dbe3a72de4 Translations: restore key coverage and fix XML validation
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.
2026-10-04 11:18:54 +09:00
Thomas De RockerandGitHub 2db949b271 Update Language.nl.xml (#1893) 2026-10-04 11:07:27 +09:00
Mounir IDRASSI a1dfce108d Linux: don't detach the host device of a device-hosted volume
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.
2026-10-04 10:35:30 +09:00
Ville TakioandGitHub 425cea6c9c Crypto: fix portable C code on big-endian CPUs (#1899)
* 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>
2026-10-04 09:51:59 +09:00
Mounir IDRASSI ce72be65bb Unix: avoid unaligned FAT field accesses
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.
2026-10-03 23:51:36 +09:00
Mounir IDRASSI 58344c204e Linux: forward FUSE volume fsync to the backing storage
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.
2026-10-03 20:33:03 +09:00
Ville TakioandGitHub d24b82102a Linux: fall back to FUSE when dmsetup is not installed (#1898)
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>
2026-10-03 11:00:48 +09:00
Ville TakioandGitHub 5c7f60dfcf Crypto: use VC_INLINE for the ARM CPU_Query helpers (#1886)
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>
2026-09-30 20:52:30 +09:00
fb9d96c52d Merge commit from fork
* Harden serializer deserialization bounds

* Finalize Unix serializer hardening

Validate object types before parsing and release owned objects on failure.
Enforce nesting limits through shared serialization entry points.

Mirror read/write size limits and reject embedded NULs while preserving
the wire format. Add regression tests for bounds, types, and cleanup.

Validated Linux self-tests, C++03 platform tests, and ASan/UBSan with leak
detection.

Co-authored-by: Damian Rickard <damian@rickard.us>

---------

Co-authored-by: Damian Rickard <damian@rickard.us>
Co-authored-by: Mounir IDRASSI <mounir.idrassi@amcrypto.jp>
2026-09-30 20:12:20 +09:00
Mounir IDRASSIandGitHub dea8fb0dc0 Merge commit from fork
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)
2026-09-30 18:05:22 +09:00
Ville TakioandGitHub a15c996f4f Crypto: fix NOASM link failures on x86 (#1896)
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>
2026-09-30 15:49:18 +09:00
Ville TakioandGitHub 81cd94f18f Linux: rewrite mount.veracrypt in POSIX sh (#1895)
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>
2026-09-30 15:06:28 +09:00
Mounir IDRASSI 41bc8e5f6a macOS: isolate FUSE-T auxiliary mount paths
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.
2026-09-29 10:01:37 +02:00
Mounir IDRASSI c91f386f00 Unix: preserve automatic backup-header errors
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.
2026-09-28 15:23:50 +02:00
Mounir IDRASSI 83cb2471bb Unix: avoid false unmount success reports on retries
Skip success reporting after a failed first-pass unmount is queued for
retry. Cover successful, failed, and unconfirmed retries.
2026-09-28 11:45:42 +02:00
Mounir IDRASSI 596beb82a1 macOS: harden volume discovery and FUSE-T teardown
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.
2026-09-28 03:17:28 +02:00
Mounir IDRASSI aedb2ef863 macOS: harden FUSE-T dismount ownership and teardown
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.
2026-09-27 09:28:37 +02:00