We Ran NIST's Software Write Block Test on Our Rust Kernel Driver

Sherlock Forensics USB Write Blocker 2.0 uses sherlockwb.sys, a Rust kernel filter driver signed by Microsoft through attestation signing. It was tested in-house using NIST CFTT's published software write block test method, the method behind NIST's last software write blocker reports in January 2008. The first run let 5 write commands and 8 injected write requests through and over-blocked 61 harmless commands. After the fixes every write, vendor-specific and undefined command is blocked and every harmless command is allowed except opcodes 0x42 and 0x48, which are UNMAP and SANITIZE on modern disks and are blocked on purpose.

We built a kernel write blocker for Windows in Rust, had Microsoft sign it and then ran the public NIST CFTT software write block test against it. It did not pass the first time. This is the engineering record: what the signing pipeline demands, what the test caught, what we changed and the two places where we chose to disagree with a 2008 test on purpose.

Why we ran a test nobody asked us to run

A write blocker makes one promise: nothing you do while examining a disk will change it. Every other feature is secondary. The trouble with that promise is that you cannot see it working. A blocked write looks exactly like a write that was never attempted. The only way to know a blocker keeps its promise is to throw every kind of disk command at it and record which ones reach the disk.

That is what the Computer Forensics Tool Testing program at NIST built. CFTT published a specification for software write block tools, a test plan and a test harness, then tested a handful of products against them. The most recent software write block reports on the NIST CFTT software page date from January 2008. They cover two versions of a tool called Writeblocker, for Windows XP and Windows 2000. No software write blocker has had a NIST CFTT report since.

The method is still public. Anyone can run it. So we did, against the exact driver we ship in Sherlock Forensics USB Write Blocker 2.0. We are publishing the full results, including the run that failed.

To be precise about what this is: Sherlock Forensics USB Write Blocker was tested in-house using NIST CFTT's published software write block test method. It is not a NIST report and NIST has not reviewed it.

What changed in 2.0: from asking Windows to refusing at the disk

Earlier versions of our blocker worked the way most Windows software blockers work. When a USB disk arrived, the app asked Windows to mark it read-only. That works, but it has a gap. The disk exists for a moment before the app reacts and Windows can write to it in that moment. We measured and published that gap. We never liked it.

Version 2.0 replaces that approach with a kernel driver, sherlockwb.sys. It is a filter that sits directly above the Windows USB storage driver for each disk. Every command headed for the disk passes through it, from the very first command the disk receives. Commands that cannot change the disk go through. Everything else is refused at that layer and never reaches the hardware.

The kernel blocker is part of the Pro edition. The free edition keeps the older Windows read-only attribute blocking. It starts switched off at every launch, it applies only after Windows has detected a disk and it never installs the driver. That mode is not kernel-level and the results below do not apply to it.

Building a kernel driver in Rust

sherlockwb.sys is written in Rust using windows-drivers-rs, Microsoft's open-source Rust bindings for the Windows Driver Kit, on the Kernel-Mode Driver Framework (KMDF) version 1.31. Rust kernel drivers are still rare on Windows. We chose it for one reason. Memory-safety bugs are what crash or compromise kernel drivers. In 2019 the Microsoft Security Response Center reported that about 70 percent of the vulnerabilities Microsoft assigns a CVE each year were memory-safety issues. Rust rules out most of that class at compile time. In a component whose only job is to be trustworthy, that matters more than anything else about the language.

What it takes to get a kernel driver signed by Microsoft

A kernel driver that Microsoft has not signed does not load on a normal Windows 11 machine. Getting that signature is a pipeline with real constraints and every one of them shaped how we work.

1. Microsoft only accepts EV-signed submissions

Microsoft offers two ways to sign a kernel driver. The full route is Windows certification, which requires passing Microsoft's Hardware Lab Kit (HLK) tests and is what Microsoft recommends for drivers distributed through Windows Update. The other is attestation signing, which Microsoft's documentation describes as intended for testing. An attestation-signed driver is trusted by Windows 10 and Windows 11 but is not Windows Certified and cannot be published to Windows Update for retail audiences. Ours is attestation-signed and installs from our own app. Microsoft accepts a driver package for attestation only if the submitter has already signed it with an Extended Validation code signing certificate. Industry rules have required the private key for code signing certificates to live in a hardware crypto module since June 2023. Ours lives on a YubiKey and the key never leaves it. Every signing run stops at a PIN prompt and a person has to be there to enter it. No build machine can sign a driver on its own, which is exactly the point.

2. Microsoft re-signs it, not us

We upload a CAB file containing the driver, its INF install file and its debug symbols. Partner Center checks the package and signs it as "Microsoft Windows Hardware Compatibility Publisher." Microsoft also generates its own catalog file and replaces any catalog a submitter includes, so we leave ours out. Each round trip took under an hour.

3. The INF has to be minimal

Our INF is an extension INF. It only adds our filter to USB disks that Windows has already set up and it writes nothing outside its own device keys. It has to pass infverif, Microsoft's INF checker, in three strictness modes: signature requirements, universal and declarative.

4. Sign for the versions it can actually run on

Partner Center offers about 30 signature targets, going back to Windows 10 version 1507. We picked six, from Windows 10 version 2004 through Windows 11 26H1. The reason is the framework: KMDF 1.31 first shipped with Windows 10 version 2004, so a signature for anything older would cover a driver that cannot load there. Windows 10 22H2, the final Windows 10 release, is covered by the 2004 signature.

5. The rules are tightening mid-stream

Partner Center now warns that driver packages containing files the INF does not reference will be affected by a policy change. We checked ours. Debug symbol files are exempt and nothing else in our package is unreferenced.

6. Every behaviour change means signing again

The fixes described below changed what the driver blocks. That sent it back through the whole cycle: release build, EV signature, Partner Center, Microsoft signature and then re-testing the Microsoft-signed file itself. We did not test a debug build and ship a different one. We published the tested file's SHA-256 so the results are tied to the exact bytes customers run.

7. Microsoft's signature is what makes it a normal install

Because Microsoft signed it, the driver loads on a standard Windows 11 machine with Secure Boot on and test mode off. Customers never have to switch off a security feature to install a security tool. The signed driver ships inside the app and installs itself for Pro users. Windows re-checks Microsoft's signature at install time, so a tampered copy is refused rather than installed.

Keeping that signing pipeline alive is a standing cost: the EV certificate, the hardware key, the Partner Center account and a full re-sign and re-test for every change to what the driver blocks. It is the main reason kernel blocking sits in the paid edition.

How the NIST CFTT test works, in plain English

The test harness has two halves. One half sends commands at the disk from above the blocker, the way an application or Windows itself would. The other half sits below the blocker and records which commands actually arrive. NIST calls them the pitcher and the catcher. For every command, the test knows what a correct write blocker should do:

  • Blocked: anything that writes, anything vendor-specific and anything undefined. A blocker cannot know what an undocumented command does, so it must refuse it.
  • Allowed: reads and the "other" commands that only ask the disk about itself.

Getting this wrong in either direction is a failure. Letting a write through breaks the promise. Blocking a harmless read breaks the examination, because imaging tools and Windows need those commands to work.

We used the ACES software write block test support package NIST used for its 2008 reports. It was written for 32-bit Windows. Porting it to 64-bit Windows took 24 documented changes, credited in the kit as NIST's terms require.

Our first run was not clean

We ran the test exactly as published. It failed in three ways.

  • 5 write commands got through. SYNCHRONIZE CACHE in both of its forms, which our original allowlist had treated as harmless. Opcode 0x51. Two ATA pass-through commands.
  • 8 file-system write requests got through. The harness injects these directly below the disk driver. Normal Windows never sends them at that level, but a write blocker should refuse them anyway. We had only ever tested what Windows actually sends. The test was right to go further.
  • 61 harmless commands were over-blocked: 16 read commands and 45 "other" commands. NIST counts blocking a harmless command as a failure too. It should.

That is what independent methods are for. Each of these passed our own testing because our own testing asked the questions we already knew to ask.

The fixes that taught us something

SYNCHRONIZE CACHE: answer it, don't forward it

SYNCHRONIZE CACHE tells a disk to write anything sitting in its cache to the media. On a disk under a write blocker there should be nothing new in that cache, but the command still asks the disk to write. Refusing it outright causes problems of its own, because Windows sends routine flushes and treats a refusal as an error. The driver now answers "done" itself and never sends the command to the disk. Windows is satisfied and the disk is untouched.

ATA pass-through: read the protocol field

ATA pass-through wraps an ATA command inside a SCSI command. NIST's all-zero test command turned out to be a drive hardware reset. The driver now reads the protocol field inside the pass-through command and refuses resets and anything that sends data to the drive. Health (SMART) reads and identify reads still work, because examiners need them.

Opening the disk cannot simply be refused

Some of the injected file-system requests were opens. Refusing every open would be easy and wrong: imaging tools must open the disk to read it. The driver refuses only opens that did not come through Windows' normal I/O path. Imaging works. Injected requests do not.

"Allow other commands" needed care

NIST expects every command in its "other" category to pass. Some of those commands can change settings stored on the drive. Our first assumption was that a command with no parameter data is harmless. It is not. MAINTENANCE OUT with the SET IDENTIFYING INFORMATION service action and a zero length clears the drive's identifying information. So the rule became stricter: those commands pass only when every field is zero. In that form each one is either a defined no-op or a request the drive must reject.

Where a 2008 test meets a 2026 disk

Two results differ from what the test expects and they differ on purpose. NIST's 2008 test lists opcodes 0x42 and 0x48 as read commands. On a CD or DVD drive they are. The current SCSI standards for disks reuse both codes. 0x42 is UNMAP, which tells a drive to discard data. 0x48 is SANITIZE, which erases the entire drive. A blocker that passed the test exactly as written would pass an erase command through to an evidence disk. We block both and we publish the deviation instead of hiding it.

Final results

Run on Windows 10 x64 against the Microsoft-signed driver we ship: sherlockwb.sys 3.1, SHA-256 FCE3B147DCF790B4B42C7C5C670BBE7A71D0FDA64803A9949077397B1061307C. Both runs below used that exact file.

CategoryNIST expectsWrite blocking ONWrite blocking OFF
Write commands (34)blocked34/34 blocked34/34 allowed
Write requests (8)blocked8/8 blocked8/8 allowed
Vendor-specific commands (80)blocked80/80 blocked80/80 allowed
Undefined commands (53)blocked53/53 blocked53/53 allowed
Read commands (27)allowed25/27 allowed *27/27 allowed
Read requests (4)allowed4/4 allowed4/4 allowed
Other commands (62)allowed62/62 allowed62/62 allowed
Other requests (15)allowed15/15 allowed15/15 allowed

* Two deliberate blocks. NIST's 2008 test lists opcodes 0x42 and 0x48 as read commands. On CD and DVD drives that is what they are: READ SUB-CHANNEL and PLAY AUDIO TRACK INDEX. Since then, the SCSI standard for disks (SBC-3) has reused both codes. On a hard drive, SSD or USB stick, 0x42 is UNMAP, which tells the drive to discard data, and 0x48 is SANITIZE, which erases the entire drive. Sherlock USB Write Blocker protects disks, so it refuses both. Allowing them would mean letting a command through that can destroy evidence. Every other result matches the test's expected outcome.

Some commands in NIST's "other" category can change settings stored on a drive (for example MODE SELECT with its save option). Sherlock passes these only in their empty form, with no data and no save or reset option, so they cannot change anything. NIST's test sends exactly that form, so they show as allowed. A real attempt to change a stored drive setting is refused and logged.

In short: every write, vendor-specific and undefined command is blocked. Every harmless command is allowed except the two deliberate blocks. With blocking off, nothing is blocked, which shows the harness and the disk path are working and the blocks come from the driver.

Design rules we ended up with

Decide once, when the disk arrives

The driver decides whether to attach to a disk at the moment Windows sets that disk up. Turning the write blocking switch on never touches a disk that is already connected. Forcing a mounted read-write disk into read-only is how other tools cause Windows "Delayed Write Failed" errors and file-system corruption. The operating rule follows directly: turn write blocking on (or block the disk individually) before you connect evidence.

Default deny

Only commands known not to modify media pass. Anything unknown is refused, including commands that have not been invented yet. The 0x42 and 0x48 story is the reason: the meaning of a command code can change under you.

Tell Windows the truth

The driver reports the disk as write-protected, so Windows mounts it read-only and never tries to write in the first place. Fewer refused writes means fewer errors and a cleaner log.

Log every refusal in plain English

Every refused command is recorded with what it was trying to do, such as "Write to the disk," "Format the disk" or "Change the drive's settings." An examiner can show what was attempted and that it never reached the evidence.

Test rigs fight back

Porting a 32-bit test harness from 2008 to 64-bit Windows was its own project. VirtualBox needed an upgrade before Windows 11 would boot in it. USB sticks got stuck "busy" between the host and the virtual machine. Windows kept the old driver loaded until a reboot, which is an easy way to test yesterday's code by accident. Each of those is why we re-tested the Microsoft-signed file itself rather than trusting the build that went into it.

Limits

  • In-house test. This uses NIST's published method. It is not a NIST report and no software write blocker has had a NIST CFTT report since 2008.
  • USB Attached SCSI is not covered yet. The driver currently covers USB mass storage disks that use the Bulk-Only Transport. Many fast USB-C NVMe enclosures use UAS instead. UAS support is next.
  • Memory Integrity (HVCI) on Windows 11 has not been tested yet.
  • Not for Windows Server. Windows Server 2016 and later load only drivers that have passed HLK testing, so the attestation-signed driver does not load there.
  • x64 only. Windows 10 version 2004 or later and Windows 11. No ARM64 build yet.
  • The driver runs inside the operating system it protects. That is a structural limit of every software write blocker. A software blocker is not a substitute for a hardware write blocker in every workflow. Labs with procedures built around hardware blockers should keep them. Our practitioner's guide to USB write blockers covers when each kind fits.

Check it yourself

The tested driver's SHA-256 is above. It ships inside the Sherlock Forensics USB Write Blocker 2.0 installer, available from the USB Write Blocker product page with the installer's own SHA-256. The free edition includes the Windows attribute blocking (switched on per session), USB topology view, device history and a hash-chained audit log. The Pro edition adds the Microsoft-signed kernel write blocker tested above, per-disk kernel block and allow, signed audit logs and forensic reports. If you run the CFTT method against it yourself and see something different, we want to hear about it.

If you need a disk acquired or examined rather than a tool, our computer forensics team does that work.

Frequently asked questions

Did NIST test Sherlock Forensics USB Write Blocker?

No. Sherlock Forensics USB Write Blocker was tested in-house using NIST CFTT's published software write block test method. It is not a NIST report. NIST's most recent software write block reports date from January 2008.

Why does the blocker refuse opcodes 0x42 and 0x48 when NIST's test expects them to pass?

NIST's 2008 test lists 0x42 and 0x48 as CD and DVD read commands. On a hard drive, SSD or USB stick the current SCSI disk standard uses 0x42 for UNMAP, which discards data. It uses 0x48 for SANITIZE, which erases the whole drive. Passing them would let a command through that can destroy evidence, so the driver blocks both and the deviation is published.

Does turning on write blocking protect a disk that is already plugged in?

No. The driver decides whether to attach to a disk when Windows first sets that disk up and the switch never touches a disk that is already connected. Turn write blocking on (or block the disk individually) before you connect evidence.

Do I need to disable Secure Boot or enable test mode to install the driver?

No. The driver is signed by Microsoft as Windows Hardware Compatibility Publisher, so it loads on a standard Windows 11 machine with Secure Boot on and test mode off.

Does it work with USB-C NVMe enclosures?

Not yet if the enclosure uses USB Attached SCSI (UAS), which many fast USB-C NVMe enclosures do. The driver currently covers USB mass storage disks that use the Bulk-Only Transport. UAS support is next.

Is the kernel write blocker included in the free edition?

No. The Microsoft-signed kernel write blocker is part of the Pro edition. The free edition keeps Windows read-only attribute blocking, which applies after a disk is detected, is not kernel-level and is not covered by these test results.

Sources