crates/veilvoice-crypto/src/shred.rs
veilvoice-crypto · 417 lines · read the source here · or on GitHub
Secure erasure, the self-destruct.
Read this before relying on it
Overwriting a file does not reliably destroy it on modern storage, and any tool that tells you otherwise is selling something. This module does the best that software can do from userspace, reports honestly what that is worth on your storage, and points at the thing that actually works.
On a spinning disk, overwriting is genuinely effective. The write goes to the same physical sectors, and the belief that a scanning-microscope recovery of overwritten magnetic media is practical does not survive contact with the literature. Gutmann's 1996 paper, whose 35-pass pattern is still cited, says so himself in its own epilogue about modern drives.
On an SSD, or any flash media, it is not reliable and cannot be made so. Wear levelling means the controller writes your "overwrite" to different physical cells and marks the old ones free. The original data still exists in flash, out of reach of every write you can issue. The same applies to SD cards, USB sticks, eMMC and NVMe. It also applies through copy-on-write filesystems (Btrfs, ZFS, APFS), snapshots, journals and any backup that has already run.
The answer that does work is full-disk encryption. If the volume is encrypted, destroying the key destroys everything on it at once, wherever the controller chose to put the blocks. LUKS, BitLocker and FileVault all do this. Use it, and treat this module as a second line rather than a first.
Why not 35 passes
Because passes stopped being the interesting variable decades ago. Against a drive that honours writes, one pass is enough; against one that does not, no number of passes reaches the retained cells. The default here is three, random then complement then random, which satisfies the common three-pass expectation without pretending that thirty-five would be stronger. Time is better spent enabling disk encryption than on passes 4 through 35.
In plain words
This is meant to destroy a file, and the first thing it does is tell you how much that is worth.
On the drives most computers now have, overwriting a file does not reliably remove it. The drive puts the new data somewhere else and leaves the original sitting in a place no ordinary program can reach, until it is cleaned up later, which may be never.
So this does what it can and refuses to promise more. If you need something to be genuinely unrecoverable, encrypt it from the start and never write it unencrypted anywhere.
WHAT THIS FILE CONTAINS
417 lines defining 3 functions (1 public), 2 types and 1 constant. Everything below is read out of the source, so it cannot disagree with the code.
The types it owns.
enum Passesline 64 · How thoroughly to overwrite before unlinking.struct ShredReportline 88 · What actually happened, so the caller can tell the user the truth.
What happens when it runs. These are the ways in: public, and nothing else in this file calls them, so they are what an outside caller reaches first.
shred_fileline 107 · Overwrite a file's contents, then delete it.
reachescaveats
WHAT CALLS WHAT
The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.
The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
n_count["Passes::count<br/>line 77"]
n_shred_file(["shred_file<br/>line 107"])
n_caveats["caveats<br/>line 192"]
n_shred_file --> n_caveats
click n_count href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/shred.rs#L77" "open the source"
click n_shred_file href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/shred.rs#L107" "open the source"
click n_caveats href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/shred.rs#L192" "open the source"
classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
class n_shred_file entry
classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
class n_count,n_caveats helper
This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.
ITEMS
| Item | Line | Documentation |
|---|---|---|
CHUNK const | 60 | Bytes written per chunk. |
Passes pub enum | 64 | How thoroughly to overwrite before unlinking. |
Passes::count fn | 77 | How many overwriting passes this setting means, with a custom count held between 1 and 32. |
ShredReport pub struct | 88 | What actually happened, so the caller can tell the user the truth. |
shred_file pub fn | 107 | Overwrite a file's contents, then delete it. |
caveats fn | 192 | The honest limits, phrased for a user rather than a security engineer. |