# DF-4467 — software XTS: session-shared running tweak races across concurrent dm-crypt bios

## What
`cryptoapi`'s software XTS implementations (AES, Twofish, Serpent) keep the
running data-unit tweak **inside the session context**
(`struct aes_xts_ctx.tweak`, `twofish_xts_ctx.tweak`, `serpent_xts_ctx.tweak`)
and re-initialize it at the start of every `crypt()` call
(`aes_xts_reinit()` → `memcpy(ctx->tweak, iv, 8)` … `E_k2` in place), after
which `crypt_block_xts()` mutates it per block (GF(2^128) multiply).

`dm_target_crypt` calls `cryptoapi_cipher_crypt()` on **one shared session
per table config** from the strategy/completion context of every in-flight
bio — concurrently on any CPU (`dmtc_bio_encdec`,
sys/dev/disk/dm/crypt/dm_target_crypt.c:958-991, write encryption runs in
`dmstrategy` context on the dispatching CPU).

Two overlapping calls therefore interleave: CPU A's `aes_xts_reinit()`
overwrites `ctx->tweak` while CPU B is mid-chain, so B's remaining data
blocks are encrypted/decrypted with A's tweak value.

Consequences:
* **silent on-disk ciphertext corruption** — writes succeed, reads return
  garbage (reproduced: 1413/1536 verification rounds corrupted);
* **XTS tweak reuse across data units** — two different sectors encrypted
  under the same effective tweak, which is the classic XTS misuse
  (leaks `(P1^P2)` equality structure in GF(2^128) XOR domain).

The AESNI implementations are unaffected (the tweak is per-call); this is
the software path — the portable default and the only one on CPUs without
AESNI.

## Reproduce (root on the QEMU guest)
```
sh build.sh
sh run.sh
```
Creates `aes-xts-plain64` crypt on vn0, initializes 512 blocks
single-threaded, runs 8 concurrent writers on disjoint blocks for 25s,
then verifies every block 3×. Then a control run without concurrency.

## Expected result
```
race:    [result] corrupted blocks: 1413 / 512 (XTS TWEAK RACE REPRODUCED)
control: [result] corrupted blocks: 0 / 512 (no corruption detected)
```

## Fix
`fix.diff` (against `sys/crypto/cryptoapi/cryptoapi.c`) makes the tweak a
per-call stack buffer in all three software XTS implementations and drops
the shared `ctx->tweak` usage. Authored and `git apply --check`-verified;
kernel-module rebuild validation was not repeated for this Medium finding
within this run (the change is mechanical and local to the three `*_crypt`
functions).
