nvme format: INVALID_OPCODE(2001)
I (author of this blog) am not the author of the post below, however I want to share it with wider audience as it is pretty well hidden within numerous Github issues I read to solve my issue with the one of Samsung drives I was trying to reformat from 512 byte to 4096 byte sectors. Original post: https://github.com/linux-nvme/nvme-cli/issues/84#issuecomment-2183511051
I recently had to revisit this issue on a PC where the suspend workaround didn’t work, and now have a pretty full understanding of what the real issue is, why the workaround sometimes works, and what can be done when it doesn’t.
Quick Summary
* The issue has nothing to do with `nvme-cli` (as expected)
* The issue is caused by storage devices which behave incorrectly when security operations are blocked
* motherboards generally block storage device security operations on drives at boot
* The suspend/resume workaround often works because many motherboards fail to block storage device security operations on resume
* But some motherboards do block these on resume; on such boards, the workaround is ineffective
* If you encounter the issue and the suspend/resume workaround is ineffective, you motherboard likely has an option to disable the storage device security operations block on next boot (on my board, it is `Disable Block SID` under `Security>Trusted Computing`), and this will let you `nvme format`, etc during the next boot
Full Explanation
Most modern PCs, on boot, will use a Trusted Computing Group (TCG) feature called Block SID Authentication on storage devices that support it. For storage devices that support it, this feature will check to see if the storage device’s security identifier (SID) password is still set to the default. If it is, the feature will be enabled, and the storage device will block attempts to authenticate until a subsequent device power cycle occurs. This functionality is similar to the ATA FreezeLock command. The goal of this feature is to prevent malware from being able to easily set the password on a disk that has not yet had a password set.
In general, an NVMe device can still be formatted even when SID Authentication is blocked. However, some devices like the WD SN750 (with certain firmware versions) mistakenly block nvme format
when SID Authentication is blocked. I imagine the other drives mentioned here behave similarly.
Suspending and resuming the system is an effective workaround in many cases because many systems fail to block SID Authentication when resuming from a suspend. As such, doing a suspend and resume disables the block and avoids the arguably buggy behavior of the SN750 and other drives.
If your motherboard blocks SID Authentication when resuming, the workaround is not effective. What can you do? Most boards have a mechanism to allow you to disable the block on next boot - on mine it is Disable Block SID
under Security>Trusted Computing
, and only shows up if a drive with blocked SID Authentication is present; You enable Disable Block SID
, save and exit BIOS, and the system reboots. It then requires confirmation via specific keyboard button press on the next boot that you really want to boot without blocking SID Authentication. Then you can perform the format, or you can set the SID password to a non-default value, which will prevent the SID Authentication block from ever being set again on the storage device.
Examining the Block SID Authentication state of a drive and changing its password is pretty awkward. The SN750 seems to implement TCG Pyrite, or something like it, and the tools for working with such drives are limited. There is a tool called sedutil-cli
, but the official version of it on Github does not support Pyrite, and no version appears to be available via apt
in Ubuntu. Fortunately, there are a couple forks that have added support for Pyrite, including one for BSD and one from the owners of sedutil.com. The latter is available on Github with source and precompiled linux/windows binaries: https://github.com/ChubbyAnt/sedutil/releases
After building or copying the prebuilt sedutil-cli, one can examine the state of their drives from within the OS:
:~$ sudo ./sedutil-cli --scan
Scanning for Opal compliant disks
/dev/nvme0 p WDS100T3X0C-00SJG0 102000WD
No more disks present ending scan
The p
tells us the drive supports pyrite. We can then query the drive:
~$ sudo ./sedutil-cli --query /dev/nvme0
/dev/nvme0 NVMe WDS100T3X0C-00SJG0 102000WD <serial_number>
TPer function (0x0001)
ACKNAK = N, ASYNC = N. BufferManagement = N, comIDManagement = N, Streaming = Y, SYNC = Y
Locking function (0x0002)
Locked = N, LockingEnabled = N, LockingSupported = Y, MBRDone = N, MBREnabled = N, MBRAbsent = Y, MediaEncrypt = N
Block SID Authentication function (0x0402)
SID Blocked State = Y, SID Value State = N, Hardware Reset = Y
Pyrite 1.0 function (0x0302)
Base comID = 0x7ffe, comIDs = 1, Initial PIN = 0x0, Reverted PIN = 0x0
Notice the SID Blocked State
is Y
. After disabling the block (either by using the option in the BIOS or the suspend/resume workaround (if it works)), we see this:
~$ sudo ./sedutil-cli --query /dev/nvme0
/dev/nvme0 NVMe WDS100T3X0C-00SJG0 102000WD <serial_number>
TPer function (0x0001)
ACKNAK = N, ASYNC = N. BufferManagement = N, comIDManagement = N, Streaming = Y, SYNC = Y
Locking function (0x0002)
Locked = N, LockingEnabled = N, LockingSupported = Y, MBRDone = N, MBREnabled = N, MBRAbsent = Y, MediaEncrypt = N
Block SID Authentication function (0x0402)
SID Blocked State = N, SID Value State = N, Hardware Reset = N
Pyrite 1.0 function (0x0302)
Base comID = 0x7ffe, comIDs = 1, Initial PIN = 0x0, Reverted PIN = 0x0
Notice the SID Blocked State
is N
. We can now format the drive, or set its password to prevent it from ever being blocked again. To do the latter, we run:
~$ sudo ./sedutil-cli --initialSetup my_secret_password /dev/nvme0
SID password changed
takeOwnership complete
Locking SP Activate Complete
LockingRange0 disabled
LockingRange0 set to RW
Initial setup of TPer complete on /dev/nvme0
You’ll want to make sure you do not lose that password, as options for being able to perform certain operations on the drive may be limited or nonexistant without it.
Update: If your device supports Opal, doing --initialSetup
may also output MBREnable set on
. You can run --query
again to confirm that MBREnabled = Y
. In this case, if you do not want the first 128MB of your drive to be read-only courtesy of the “shadow MBR feature”, you can run ~$ sudo ./sedutil-cli --setMBREnable off my_secret_password /dev/nvme0
After all of this, you should be able to format the storage device without any workaround in any machine.
The TCG Storage Opal Integration Guidelines have even more details on all of this.
Finally, the suspend/resume workaround is a common mechanism to be able to bypass a similar “FreezeLock” on ATA devices. Interestingly, that mechanism works just fine on the motherboard I’m using, even though the motherboard stops it from working on NVMe devices.