Commit Graph

1052 Commits

Author SHA1 Message Date
Fabian Druschke
c13f2477b1 Update README and manpage for v0.40: document AES-CTR, large I/O buffers, new I/O modes, BMB21 method, and improved device exclusion
This commit updates both README.md and the nwipe(8) manpage to reflect the
features and behaviour introduced in the upcoming v0.40 release. Changes include:

- Added documentation for the new AES-256-CTR PRNG and its hardware-accelerated
  implementation.
- Updated erasure method list to include the BMB21-2019 State Secrets Bureau
  sanitisation standard.
- Added full documentation for large, aligned I/O buffers and their impact on
  performance.
- Documented the new I/O mode system (`--io-mode=auto|direct|cached`,
  `--directio`, `--cachedio`) and the interaction with O_DIRECT fallback logic.
- Updated sync behaviour description to match the new byte-accurate scaling for
  cached I/O.
- Updated PRNG section to remove the “future release” note for AES-CTR.
- Documented improved device exclusion with `/dev/disk/by-id/*` support.
- Updated seeding description to reflect the use of `getrandom()` instead of
  `/dev/urandom`.
- Refreshed dependency lists and provided concise installation instructions for
  multiple Linux distributions.
- Minor stylistic cleanup, clarification of SSD limitations, and improved README
  structure for readability and accuracy.
2025-11-27 16:23:22 +01:00
PartialVolume
dcfa8f4ea2 Merge pull request #660 from Knogle/kernel-aes-ni
Implement high-performance AES-256-CTR PRNG via Linux kernel AF_ALG socket
2025-11-26 21:15:17 +00:00
PartialVolume
ccf8eed4ed Merge branch 'master' into kernel-aes-ni 2025-11-26 21:14:23 +00:00
PartialVolume
375f8b3f87 Merge pull request #686 from Knogle/persistent-device-paths
Enhances the --exclude option to match devices by their underlying block
2025-11-26 20:43:10 +00:00
Fabian Druschke
c51a8e9846 Enhances the --exclude option to match devices by their underlying block
device ID (major/minor), allowing persistent identifiers in /dev/disk/by-id/
and /dev/disk/by-path/ to be used safely. Legacy string-based matching is
preserved.
2025-11-26 17:15:35 +01:00
PartialVolume
a0339c3bb1 Merge pull request #684 from PartialVolume/add_hostid_option_to_pdf
Add user selectable host information to the PDF
2025-11-18 18:59:18 +00:00
PartialVolume
0801ca7ae8 Add user selectable host information
You can now specify --pdftag to enable the
display of system UUID and system serial
number information on the PDF report.

Nwipe defaults to not displaying system IDs
but some users like to record the system UUID
or serial number on the Erasure Report along
with the disk information.
2025-11-18 18:44:41 +00:00
PartialVolume
96127687cd Merge pull request #682 from desertwitch/upstr
fix: respect no-blanking methods in --nogui mode also
2025-11-14 23:32:26 +00:00
desertwitch
24dcbaa40c fix: outdated documentation for zero/one-fill rounds
The zero and one fill methods are no longer bound to just a single round.

Signed-off-by: desertwitch <24509509+desertwitch@users.noreply.github.com>
2025-11-15 00:12:27 +01:00
desertwitch
0d043a3745 fix: respect no-blanking methods in --nogui mode also
This fixes an issue where a default blanking pass was added to methods which do not support it when in --nogui mode.

Existing GUI code overriding the option is never called in --nogui mode, so needs handling as part of option parsing.

Signed-off-by: desertwitch <24509509+desertwitch@users.noreply.github.com>
2025-11-14 23:35:13 +01:00
PartialVolume
3e79c46f45 Merge pull request #680 from Knogle/no-fd-urandom
rng: use getrandom(2) for PRNG seeding instead of /dev/urandom fd
2025-11-14 21:29:16 +00:00
PartialVolume
ae3a8a51d1 Merge pull request #681 from PartialVolume/Reinstate_pdf_page_1_label
Reinstate page 1 label on PDF
2025-11-14 17:12:57 +00:00
PartialVolume
67df917378 Reinstate page 1 label on PDF 2025-11-14 17:08:40 +00:00
Fabian Druschke
04b79bc746 rng: use getrandom(2) for PRNG seeding instead of /dev/urandom fd
The internal PRNGs are now seeded via getrandom(2) rather than through a
long-lived file descriptor to /dev/urandom.

Previously, nwipe opened /dev/urandom once at startup, stored the file
descriptor in the nwipe_context_t (entropy_fd) and used read() on that fd
whenever seed material was required (e.g. DoD, Gutmann, OPS-II and generic
random passes). The path to the entropy source was hard-coded via
NWIPE_KNOB_ENTROPY ("/dev/urandom").

This change introduces a small helper in method.c:

  - nwipe_read_entropy(buf, len)

which calls the getrandom(2) syscall in a loop until the requested number
of bytes has been filled, handling short reads and EINTR/EAGAIN. All
former uses of read(ctx->entropy_fd, ...) for seeding have been switched
to nwipe_read_entropy(), and the error messages in those places now
correctly report "getrandom" instead of "read" as the failing operation.

The nwipe_context_t no longer carries an entropy_fd and nwipe.c no longer
opens /dev/urandom at startup nor assigns that fd to each context. The
NWIPE_KNOB_ENTROPY macro and its only use site were removed. At runtime,
nwipe now directly consumes entropy via getrandom(2), with an optional
log notice stating that getrandom(2) is used as the entropy source.

Debug behaviour is preserved: any existing code that logs or dumps the
PRNG seed or pattern values after they have been obtained continues to
work unchanged, it simply sees data that originated from getrandom(2)
instead of /dev/urandom.

Rationale for preferring getrandom(2) over /dev/urandom via fd:

  - getrandom(2) is a dedicated kernel API for CSPRNG output; it does not
    depend on any device node or path existing in /dev. This avoids a
    whole class of "weird environment" failures where /dev/urandom might
    be missing, replaced, or mounted in a surprising way inside chroots,
    containers, or minimal live systems.

  - getrandom(2) guarantees that it will block until the kernel CRNG has
    been properly initialized. Historically, /dev/urandom on very old
    kernels could be read before the CRNG was fully seeded if the caller
    did not implement extra checks; using getrandom(2) pushes that logic
    into the kernel and makes the seeding semantics explicit.

  - We no longer need to manage a process-wide entropy file descriptor:
    there is no open(), no global fd to propagate into every context, and
    nothing to close on shutdown. This simplifies the lifetime rules for
    entropy, especially in the presence of multiple worker threads or any
    future changes that might involve fork/exec.

  - By avoiding a persistent fd, we also remove the (admittedly low but
    non-zero) risk of that descriptor being accidentally clobbered,
    reused, or inherited in unexpected ways in future code changes. Each
    seed request is now an independent syscall that either succeeds or
    fails cleanly with an errno.

  - From a security perspective, /dev/urandom and getrandom(2) are backed
    by the same kernel CSPRNG on modern Linux, so we do not weaken the
    entropy source. Instead, we get stricter initialization guarantees
    and a smaller attack surface (no device node, no path resolution, no
    reliance on a specific /dev layout) while keeping performance and
    quality where they should be for a disk wiping tool.

In short, this patch keeps all existing wipe patterns and debug output in
place, but replaces the plumbing underneath so that PRNG seeding is
simpler, more robust against odd environments, and aligned with the
modern Linux API for secure random numbers.
2025-11-14 14:35:53 +01:00
PartialVolume
f83f229a6a Merge pull request #678 from PartialVolume/create_function_from_duplicated_code
Combine duplicated code into function
2025-11-13 21:49:37 +00:00
PartialVolume
30015d1be4 Combine duplicated code into function
The fifteen lines of code that creates the header
and footer text in the PDF appear in two separate
places. The first occurrence  in the create_pdf(..)
function and once in the create_header_and_footer(..)
function.

This duplicated code was combined into a third
function pdf_header_footer_text(..) and is now called
from the other functions.

This was done as I need to add some user selectable
changes to the header text that will include host
identification such as system tag, UUID, hostname
without creating further duplicated code.
2025-11-13 21:43:55 +00:00
PartialVolume
071487e4bc Merge pull request #677 from PartialVolume/Update_BMB21-2019_info
Updated UK HMG IA/IS 5 and Chinese BMB21-2019 Info
2025-11-11 20:21:13 +00:00
PartialVolume
7fdf6b379a Updated UK HMG IA/IS 5 and Chinese BMB21-2019 Info 2025-11-11 20:14:09 +00:00
PartialVolume
0e78efeb40 Merge pull request #676 from PartialVolume/Add_uuid_to_pdf_filename
Add device name, e.g sda, sdb etc to PDF filename

Closes #664
2025-11-10 23:30:52 +00:00
PartialVolume
e8c07bddc5 Add device name, e.g sda, SD etc to PDF filename
The purpose of this commit is to add an additional
identifying piece of information to the pdf filename.

This was found to be necessary in the case of a user
wiping partitions as opposed to the whole disc. Currently
when wiping a partition the model name and serial number
is missing from the pdf content and pdf filename so by adding
the device name, it make it less likely that an existing pdf
will get overwritten. This is a stop gap fix as preferably
the disk model and serial no needs to be retrieved even
wiping just one partition.

Additional functions were added including retrieval of UUID,
however UUID was found to not be available for some USB
devices when wiping partitions. The UUID function remains
in the code and the UUID if available is output to the log
but is not used anywhere else at the moment.
2025-11-10 23:21:15 +00:00
Fabian Druschke
b1dfea30d6 aes_ctr_prng: replace linear stash with lock-free ring buffer for thread-local prefetch
Replaced the old memmove-based stash buffer with a true circular (ring) buffer
for the thread-local AES-CTR PRNG prefetch mechanism Increased Buffers to 1M stash and 128 KiB block.

Key improvements:
 - Eliminates O(n) memmove() calls on buffer wrap → constant-time refill
 - Avoids redundant memory copies and improves cache locality
 - Supports larger prefetch capacities (256 KiB–1 MiB) without performance penalty
 - Adds fast-path for large reads (direct 16 KiB chunks to user buffer)
 - Aligns stash to 64 B for better cacheline performance
 - Increased prefetch size to 1M. Increased block size to 128 KiB
 - Reduced syscall overhead by increasing buffers
Result: measurable +5–20 % throughput gain on small-read workloads,
lower memory bandwidth usage, and more consistent latency across threads.
2025-11-10 20:55:22 +01:00
PartialVolume
86cf634ab6 Merge pull request #668 from xicaixiaokeke/apply-patch
Add BMB21-2019 wipe function
2025-11-09 16:42:29 +00:00
PartialVolume
1a27e0ac7e Merge branch 'master' into apply-patch 2025-11-09 16:42:08 +00:00
PartialVolume
ed74492a1d Merge pull request #672 from Extloga/master
Fixes for English text in several files
2025-09-30 21:11:49 +01:00
Extloga
b8f9307256 Fixes for consistency in nwipe.8 2025-09-30 12:38:29 +02:00
Extloga
d9ff3e8f8e Fixes for consistency in gui.c 2025-09-30 12:14:49 +02:00
Extloga
76c7820002 Update README.md for version 0.39 2025-09-30 12:08:43 +02:00
Extloga
bc1bc190b5 Update version number in version.c 2025-09-19 07:29:33 +02:00
Extloga
8fc559774d Fixes for consistency in nwipe.8 2025-09-19 07:27:35 +02:00
Extloga
f48fac0e5b Fixes for consistency in options.c 2025-09-19 07:26:02 +02:00
Extloga
a76046ed37 Fixes for formatting and consistency in options.c 2025-09-19 07:19:15 +02:00
Extloga
ae6c839e3a Fixes for consistency in gui.c 2025-09-19 07:11:39 +02:00
Extloga
34e42b3c5e Fix for orthography in prng.c 2025-09-19 07:08:47 +02:00
Extloga
2f2c0a5153 Fixes for formatting and consistency in gui.c 2025-09-19 07:06:39 +02:00
Extloga
342fb03c1d Include the algorithm of Bruce Schneier in nwipe.8 2025-09-19 06:29:19 +02:00
Extloga
8bc22175ac Update version number to 0.39 in nwipe.8 2025-09-19 06:20:06 +02:00
Extloga
39ee8cfc91 Update version number to 0.39 in configure.ac 2025-09-19 06:18:13 +02:00
Martijn van Brummelen
316b707308 release 0.39 v0.39 2025-09-10 11:10:15 +02:00
Martijn van Brummelen
ae6cd21019 add tag v038.1 2025-09-10 10:21:08 +02:00
Martijn van Brummelen
a01ec958e4 Merge pull request #652 from Knogle/remove-exp-flag
Removed EXPERIMENTAL! comments for ALFG and Xoroshiro due to their ma…
2025-09-09 21:45:27 +02:00
Martijn van Brummelen
ad25e08997 Merge pull request #663 from Knogle/gcc-15-forward-declarations
fix: some declaration changes to satisfy gcc 15
2025-09-09 21:42:21 +02:00
kobe_memba
59fbac30a8 add bmb21-2019 wipe function 2025-07-27 17:45:11 +08:00
Fabian Druschke
436aa12227 fix: some declaration changes to satisfy gcc 15 2025-06-09 20:05:05 +02:00
Fabian Druschke
628e514058 Fixed has_aes_ni() as it didn't build on systems different other than x86. Now the check returns 0 if the system is other than x86. Fixed missing focus for AES-CTR prng, in certain conditions AES-CTR PRNG was not selectable through p menu. 2025-05-31 20:57:06 +02:00
Fabian Druschke
5af773eaac Implement high-performance AES-256-CTR PRNG via Linux kernel AF_ALG socket
Problem
=======
The OpenSSL-based prelimininary, not yet committed userspace PRNG in nwipe
plateaued at ~250 MB/s, becoming the primary bottleneck when wiping modern
NVMe or RAID volumes that sustain gigabytes per second.

Solution
========
Replace the OpenSSL path with a kernel-accelerated AES-256-CTR generator that
streams 16 KiB keystream blocks through the AF_ALG “ctr(aes)” skcipher:

* Added aes_ctr_prng.cpp/.h
  • Opens a per-thread AF_ALG operation socket once (lazy init).
  • Builds a two-CMSG `sendmsg()` (ALG_SET_OP + ALG_SET_IV) and a single
    `read()` per chunk – minimal syscall overhead.
  • Public state (aes_ctr_state_t) intentionally remains 256 bit to preserve
    ABI compatibility; socket FD is kept thread-local.
  • Generates exactly 16 KiB per call, advancing an internal 128-bit counter.

* Comprehensive English comments explain every function, the ABI rationale and
  the kernel interaction pattern.

Performance
-----------
On a Ryzen 9 7950X (VAES):
  • Old OpenSSL path: ~260 MB/s
  • New AF_ALG path : ~6.2 GB/s  (≈ 24× faster, CPU-bound at ~7 % load)

Safety & Compatibility
----------------------
* Falls back automatically to the kernel’s software AES if AES-NI/VAES/SVE are
  absent – no code changes required.
* No external dependencies beyond standard linux-headers.
* Optional `aes_ctr_prng_shutdown()` closes the FD, though the kernel would
  reclaim it on exit anyway.

Testing
-------
* Added unit tests for counter wraparound and deterministic output with a
  fixed seed (compared to OpenSSL reference vectors).
* Verified multi-threaded wiping on a 4 × NVMe RAID-0 → sustained device speed,
  PRNG never starved the pipeline.

Future work
-----------
* Expose chunk size as a tunable CLI flag.
* Optionally copy keystream directly into the kernel’s page cache via `splice`.

Closes: #559 (Implement High-Quality Random Number Generation Using AES-CTR Mode with OpenSSL and AES-NI Support)
2025-05-28 22:32:18 -03:00
Fabian Druschke
764235fc7d Removed EXPERIMENTAL! comments for ALFG and Xoroshiro due to their matured state. Some clarification on ALFG PRNG header, which is actually more a SLFG 2025-03-14 11:06:32 +01:00
PartialVolume
f594d677a7 Merge pull request #651 from Knogle/cleanup
Some cleanup in options.c, added missing xoroshiro256_prng argument in help.
2025-03-13 21:46:35 +00:00
Fabian Druschke
536ead8f2b Some cleanup in options.c, added missing xoroshiro256_prng argument in --help 2025-03-13 12:51:04 +01:00
PartialVolume
c29a17d090 Update version.c
Bumped minor version
2025-03-12 22:58:05 +00:00
PartialVolume
d630e3bd3c Merge pull request #648 from Knogle/bruce-7
Implement Bruce Schneier 7-Pass wiping method
2025-03-12 22:44:32 +00:00