Disk encryption: wide-block modes, authentication tags aren’t silver bullets

Recently, IEEE released the P1619/D12 (October 2024) draft that changes the XTS mode of operation of the AES cipher. In particular, there is a new requirement:

The total number of 128-bit blocks in the key scope shall not exceed 2^44 (see D.6). For optimum security, the number of 128-bit blocks in the key scope should not exceed 2^36 (see D.4.3).

The current limit (IEEE Standard 1619-2018) is significantly higher:

The total number of 128-b blocks shall not exceed 2^64.

The proposed soft limit means that you are recommended not to encrypt more than 1 TiB of data without changing the keys, “for optimum security”. And the proposed hard limit means that you are not allowed to encrypt more than 256 TiB of data without changing the keys (the current limit is 268435456 TiB).

This requirement makes existing full-disk encryption implementations non-compliant, as mentioned by Milan Brož and Vladimı́r Sedláček in the “XTS mode revisited: high hopes for key scopes?” paper. The authors state that the proposed standard lacks a clear threat model, as well as rules defining how keys should be generated.

When exploring possible alternatives, the authors of this paper suggest the following:

From a long-term perspective, it might be more beneficial to switch to a different (wide) encryption mode ([…]) if length-preserving ciphertext is required. Or if the storage device provides space for authentication tags, authenticated encryption would be a strong candidate as well.

So, let’s explore the XTS mode in practice, then take a look on its alternatives…


Frankly speaking, the XTS mode is controversial, because it’s susceptible to:

  • Precise traffic analysis: an adversary capable of observing multiple versions of encrypted data can deduce what 16-byte blocks have changed between these versions.
  • Precise randomizing attacks: an adversary can turn a specific decrypted 16-byte block into random garbage by introducing a modification to the corresponding ciphertext.

These issues are well-known: e.g., see this Wikipedia article.

In practice, both flaws are crucial to the current full-disk encryption implementations (like BitLocker and LUKS). Here are examples for the traffic analysis attacks:

  • In the TPM-only mode of operation: a physically-present attacker can boot a target computer “seamlessly” up to the operating system’s login screen — thus, enabling traffic analysis attacks (new versions of encrypted data are produced due to background write activities of the operating system).
  • In the TPM plus network key mode of operation (which is used to implement secure unattended boot for servers): the same traffic analysis attacks are possible too (although a target computer is required to reside in a corporate network during the attack, otherwise a password is needed to unlock the TPM-bound encryption key).
  • In the TPM plus password mode of operation: if the password (i.e., one of two “factors”) is compromised, the same traffic analysis attacks are possible (the password alone isn’t enough to decrypt the data).
  • Sometimes full-disk encryption is used to protect data against legitimate unprivileged users (e.g., on a corporate laptop, it’s used to “enforce” existing file system access controls): such users have physical access to target computers, but no access to the corresponding encryption keys (even if an encryption password is set, it’s not enough to obtain the necessary key — i.e., the key is bound to the TPM), although they can boot the target computer and log in to its operating system — thus, enabling similar traffic analysis attacks.
  • In the dual-boot scenarios, a compromised operating system installation can be used to attack another, encrypted installation. Over time, a compromised operating system is likely to observe multiple states of the encrypted volume (of another operating system).
  • Finally, some authors suggest full-disk encryption as a measure against backdoors in the HDD/SSD firmware (along with other protections — against DMA and execution of untrusted code): obviously, traffic analysis attacks are possible to some extent (although there is no much space for such a backdoor to store old copies of encrypted data). A similar scenario is the “explicit” or “implicit” network boot (e.g., explicitly via the iSCSI protocol or implicitly via launching a virtual machine using a disk image stored on a network-based file system): an attacker can control the disk image storage (e.g., the iSCSI target), but not the virtualization host (which runs the virtual machine).

These scenarios are also relevant to randomizing attacks: attackers can turn some 16-byte blocks of their choice into random garbage and then observe runtime effects of this. The first two examples demonstrate that even one-time access to a target computer (and without any kind of prior knowledge of a secret) may expose multiple versions of some ciphertext blocks to unauthenticated attackers, and they can force the operating system to decrypt some modified ciphertext blocks.

It perfectly matches the following threat model from Microsoft:

The classic solution to this problem is to run a low-level disk encryption driver with the key provided by the user (passphrase), a token (smart card) or a combination of the two. The disadvantage of the classic solution is the additional user actions required each time the laptop is used. Most users are unwilling to go through these extra steps, and thus most laptops are unprotected.

BitLocker improves on the classic solution by allowing the user actions during boot or wake-up from hibernate to be eliminated. This is both a huge advantage and a limitation. Because of the ease of use, corporate IT administrators can enable BitLocker on the corporate laptops and deploy it without much user resistance. On the downside, this configuration of BitLocker can be defeated by hardware-based attacks.

[…]

In practice, we expect that many laptops will be used in the TPM-only mode and that scenario is the main driver for the disk cipher design.

[…]

In the BitLocker attack model we assume that the attacker has chosen some of the plaintext on the disk, and knows much of the rest of the plaintext. Furthermore, the attacker has access to all ciphertext, can modify the ciphertext, and can read some of the decrypted plaintext. (For example, the attacker can modify the ciphertext which stores the startup graphic, and read the corresponding plaintext off the screen during the boot process, though this would take a minute or so per attempt.) We also assume that the OS modifies some sectors in a predictable way during the boot sequence, and the attacker can observe the ciphertext changes.

However, the attacker cannot collect billions of plaintext/ciphertext pairs for a single sector. He cannot run chosen plaintext differences through the cipher. (He can choose many different plaintexts, but they are all for different sectors with different tweak values, so he cannot generate chosen plaintext differences on a single sector.) And finally, though this is not a cryptographic argument, to be useful the attack has to do more than just distinguish the cipher from a random permutation.

(Source.)

Continue reading “Disk encryption: wide-block modes, authentication tags aren’t silver bullets”

Symlink attacks without code execution

Background

Let’s take a look at the following piece of code:

if (is_infected_file(path)) {
  remove_file(path);
}

This is a oversimplified routine from a typical antivirus scanner — it takes a file path, checks data of that file using malware signatures, and removes the file if it’s “infected”.

However, if the remove_file() routine follows symlinks (i.e., it deletes a symlink target, not a symlink itself), security problems arise…

A malicious program can create a file, fill it with bytes that are detected by a specific antivirus engine (e.g., write the EICAR string), trigger the antivirus scan somehow (e.g., by trying to read that file, thus triggering on-access scans), and then quickly replace that file with a symlink to another file.

This leads to a well-known race condition: the is_infected_file() routine deals with one file, but, occasionally, the remove_file() routine deals with another file! The path is the same, but in these two routines it points to different files: one is a regular file that is detected as “infected”, another one is a symlink pointing somewhere.

If the attacker is lucky enough, the remove_file() routine deletes the symlink target (which is attacker-chosen).

This leads to many possible issues, including denial-of-service (when an important system file is deleted), privilege escalation (when a configuration file with security-related settings is deleted, forcing some software to use “less secure” defaults), or even information disclosure (when software creating a backup is forced to copy sensitive files to a world-readable location).

In general, symlink attacks allow low-privileged programs to do some unintended actions against files they can’t access directly.

More examples can be found in this Wikipedia article and in this research paper.

There is one limitation: symlink attacks require code execution. In particular, attackers must create a file, trigger a vulnerable application, and then quickly replace that file with a symlink.

Challenge

What if no code execution is needed to mount such an attack?

Continue reading “Symlink attacks without code execution”

CVE-2025-21210 aka CrashXTS: a practical randomization attack against BitLocker

Please, refer to this Wikipedia article if you need some theory… My paper is here.

Background: attacks on AES-CBC

Do you remember code execution attacks against full-disk encryption implementations using AES-CBC? Like that one described in the “Code Execution In Spite Of BitLocker” article or another one detailed in the “Practical malleability attack against CBC-Encrypted LUKS partitions” post.

In these attacks, physically-present adversaries manipulate ciphertext blocks to flip specific bits in the decrypted form, thus constructing code execution payloads to be executed on the next boot. This is not a direct payload injection, since the attackers don’t actually write their “raw” code into the encrypted volumes, but rather flip the bits belonging to existing executables in order to transform their code.

Such an attack consists of two stages:

  • finding the exact position of bits to flip;
  • flipping these bits (in a way that turns original code into attacker-chosen code).

The nature of AES-CBC makes it easy to flip bits in the decrypted form, because each block of plaintext is XORed with the previous ciphertext block before being encrypted:

In other words, the attacker can flip arbitrary bits in one block at the cost of randomizing the previous block.

(Source.)

The hardest part here is finding the exact blocks of ciphertext to manipulate. In order to inject custom code, the attacker must know what code to modify (i.e., its plaintext bytes) and its precise location on the disk. Otherwise, flipped bits won’t produce meaningful plaintext changes (since Attacker-chosen code = Original code XOR Delta, the attacker must know Original code and then produce Delta to obtain Attacker-chosen code).

Currently, the demonstrated bit-flipping attacks rely on predictable locations of executables. The attacker installs the same operating system version on similar media to learn the disk offsets required (this is based on one assumption: two operating system installations on similar media write at least some executables to the same disk offsets). According to the “Code Execution In Spite Of BitLocker” article:

In our testing, two installations of Windows 8 onto the same format of machine put the system DLLs in identical locations. This behavior is far from guarenteed, but if we do know where a file is expected to be, perhaps through educated guesswork and installing the OS on the same physical hardware, then we will know the location, the ciphertext, and the plaintext.

Obviously, this won’t work with operating system installations that are not “fresh”… Months (or even years) of operating system updates, their installation order, and many housekeeping activities are likely to move executables to unpredictable offsets, undermining the idea of predictable locations.

Thus, the most important part of the attack – finding the exact location of bits to flip – is extremely hard to complete in reality.

Concerns: attacks on AES-XTS

Bit flips through ciphertext manipulations are impossible with AES-XTS (and this is why this mode is preferred over AES-CBC when encrypting storage devices).

In this mode, any change to a ciphertext block will turn its decrypted form into garbage and won’t affect any preceding or subsequent blocks.

More than 15 years ago, Niels Ferguson and Vijay Bharadwaj argued that code execution payloads are still possible with AES-XTS:

The attacker now replaces the first few bytes of the ciphertext block and hopes that the randomized plaintext decrypts to a value such that the first instruction executed in the block is a jump instruction to the epilog code. On the x86 a relative jump instruction is 2 bytes long and can jump up to 128 bytes forward. The probability of getting the right plaintext is one in 2^16; high enough for a practical attack.

(Source.)

In other words, attackers can get specific byte values even through unpredictable (random) ciphertext manipulations.

Practical attack: CVE-2025-21210 vs. BitLocker & AES-XTS

The idea is to force the Windows operating system to write some sensitive data to the underlying drive without encrypting it first (i.e., to leak data in the plaintext form).

Continue reading “CVE-2025-21210 aka CrashXTS: a practical randomization attack against BitLocker”

Multiple vulnerabilities in AMI file system drivers

Background

The same malformed file system structures can cause problems in independently developed file system parsers…

For example, missing boundary checks when parsing the NTFS update sequence array resulted in two vulnerabilities disclosed before: one in the ntfsck tool (from the ntfs-3g package) – CVE-2021-46790, one in the 7-Zip archiver – CVE-2023-52168.

Now, there is a third item in that row: CVE-2022-29974.

This is a pool-based buffer overflow in the AMI NTFS driver, it has the same root cause as two other vulnerabilities mentioned above. And, interestingly, it took more than 2 years for the fix to reach downstream firmware updates…

This post is about 5 vulnerabilities discovered in EFI file system drivers from AMI.

Continue reading “Multiple vulnerabilities in AMI file system drivers”

Vulnerabilities in 7-Zip and ntfs3

As I demonstrated before, the same malformed file system structures can cause overflows/over-reads in independently developed software.

Here is a recent example: a buffer overflow vulnerability found in 7-Zip — CVE-2023-52168. This vulnerability is similar to one previously discovered by me in the ntfsck tool (from the NTFS-3G driver) — CVE-2021-46790.

And even more: a buffer over-read vulnerability in 7-Zip — CVE-2023-52169. It shares the same mechanics as a kernel memory disclosure vulnerability in the Linux ntfs3 driver — CVE-2023-45896.

Continue reading “Vulnerabilities in 7-Zip and ntfs3”

CVE-2023-4001: a vulnerability in the (downstream) GRUB boot manager

One can set a password to protect the boot menu entries and the command-line shell of the GRUB boot manager (see the official manual and the Red Hat manual). This is an additional security measure to be used along with a BIOS/UEFI password (e.g., to protect corporate computers from unprivileged users trying to leverage their physical access to boot another operating system or to escalate the privileges in an installed operating system).

Under the hood, this feature is implemented as two GRUB commands: “password” and “password_pbkdf2“. When one of these commands is issued with a proper set of arguments, a user with a specified password (or its hash) is created. And only those users listed in the “superusers” environment variable (when it’s set by issuing the “set” command) are allowed to edit boot menu entries and execute commands in the GRUB shell. (A physically-present user is required to authenticate as a superuser when trying to edit a menu entry or trying to enter the GRUB shell.)

In most cases, commands to set the “superusers” variable and to create corresponding users are stored in the GRUB configuration file, “grub.cfg” (which is more like a script, not a pure configuration file).

There were some vulnerabilities affecting the GRUB password protection feature, like weak permissions for the GRUB configuration file that allowed unprivileged users to obtain plain-text passwords and/or password hashes (for example: CVE-2012-2314, CVE-2013-4577, and CVE-2021-3981), an integer underflow (CVE-2015-8370), and even an improper string comparison (CVE-2009-4128).

Now, there is one more: CVE-2023-4001.

This vulnerability allows unprivileged users with physical access to a computer to bypass the password protection feature of the GRUB boot manager on many (but not all) UEFI-based computers. In some uncommon setups, no unprivileged access is required (so, physical access without an ability to log in into an operating system is enough).

Continue reading “CVE-2023-4001: a vulnerability in the (downstream) GRUB boot manager”

Bringing unallocated data back: the FAT12/16/32 case

Modern operating systems provide a way to increase the size of a given file without writing to it.

In Unix-like operating systems, this is achieved through the truncate() and ftruncate() system calls. These calls allow programs to decrease or increase the file size.

If the file size is decreased, data beyond the new end-of-file position is discarded (it can survive as deleted data, but there is no way to bring these bytes back by restoring the original file size).

If the file size is increased, extra data (data after the old end-of-file position) is filled with null bytes. Internally, many modern file systems don’t write those extra null bytes to the drive, they make a sparse data range instead (so, if a program increases the file size by several gigabytes, there is no need to actually write that amount of null bytes to the drive).

Some file systems may reserve sectors to hold that amount of extra data and attach those sectors to the file, but their contents are left intact. This is useful to quickly preallocate some space to avoid fragmentation: a file system driver reserves the requested amount of sectors, but it doesn’t clear them (and an attempt to read from that extra space returns null bytes, despite the fact that these extra sectors may contain something different).

Treating the extra space as containing null bytes is essential for security, there is a POSIX requirement for that:

If the file size is increased, the extended area shall appear as if it were zero-filled.

https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html

It’s a vulnerability if deleted (or uninitialized) data is returned when reading that extra area (for example, see CVE-2021-4155).

Surprisingly, such vulnerabilities are still discovered in file system drivers.

Continue reading “Bringing unallocated data back: the FAT12/16/32 case”

CVE-2023-45897: a vulnerability in the Linux exFAT userspace tools

Some vulnerabilities tend to appear in independently written code. And CVE-2023-4273 isn’t an exception here…

A very similar vulnerability, CVE-2023-45897, has been discovered in the exfatprogs package: in particular, in the fsck tool. This vulnerability has exactly the same mechanics (even the same proof-of-concept file system image would work), but the overflow occurs in the heap memory, not in the stack.

Continue reading “CVE-2023-45897: a vulnerability in the Linux exFAT userspace tools”

CVE-2023-4692, CVE-2023-4693: vulnerabilities in the GRUB boot manager

The GRUB boot manager is more an operating system than a boot loader. For example, it has more than 20 file system types supported!

This is a really wide attack surface… And, currently, GRUB is the default choice in the Secure Boot implementation using Microsoft-signed shims (but things are moving forward).

Some time ago, I discovered two vulnerabilities (or three vulnerabilities, if we count a security issue which is almost unexploitable) in the NTFS driver of the GRUB boot manager. And here are some technical details…

Continue reading “CVE-2023-4692, CVE-2023-4693: vulnerabilities in the GRUB boot manager”