Drive Firmware Security - Overview

Hardware

Storage drives are one of the more complex components you can find in a standard personal computer, it is essentially a computer in its own right, a mini computer inside a computer. As a computer they contain the typical fundamental components you would expect, a processor, volatile memory, and non-volatile storage. They even run their own form of operating system, typically a minimal Real Time Operating System (RTOS) sometimes derived from common RTOS implementations such as ThreadX. All storage drives also have some type of storage medium they're built around, such as NAND flash for SSDs or magnetic disks for HDDs, and will have a bus to interface with an attached computer such as SATA or NVMe. This bus will use a standardised command set, such as ATA for SATA drives, for a computer to both read and write data to the drive and also access various other drive functionality.

Example diagrams showing these components on a Phison PS3111 SATA SSD are included below, the first shows components on the PCB, the second shows elements within the controller.

Product diagram

Controller diagram

Boot Process

The Phison PS3111 is a simple design that is instructive for demonstrating the concepts SSD design is built on. When the drive is powered on, the CPU boots and executes code from a mask ROM internal to the controller, this initial code is a bootloader with the main task of loading and executing the main firmware code from attached flash chips. The bootloader does a search reading the first page of each block of connected flash to find a specific signature, if found it will parse this page as a firmware header and load the firmware code in the pages that follow, executing it and handing over control. If the bootloader is unable to locate the main firmware on flash, it will instead begin its own minimal firmware implementation commonly known as safe mode.

This safe mode is a version of firmware that implements only a very basic set of standard functionality, such as returning drive identification data, but without for example features to read or write data to storage, most functionality available is vendor-specific undocumented features that allow software tools to load and execute firmware code in controller memory through the SATA interface, without the controller needing to load it from flash. This functionality for the bootloader to execute firmware in-memory has two main purposes. First for factory initialisation of the drive during the manufacturing process, when the drive PCB has been assembled but before the firmware code has been installed the drive executes in-memory a special firmware type known as a burner, this burner firmware implements the functionality needed to then initialise the drive and install the regular firmware to flash. The second use-case is for drive diagnostics or recovery, if firmware on flash becomes corrupted or otherwise unavailable, firmware code can then be loaded in memory to investigate the drive further, this is commonly used for example during data recovery or the RMA process.

Although safe mode can be entered automatically on drive failure as detailed above, drives will usually provide some hardware feature allowing it to be entered manually on-demand too, usually with a jumper on the PCB. A video below shows safe mode in use with the PC3000 data recovery product, using it to diagnose and recover data from a malfunctioning drive.

Video thumbnail

Initialisation and Operation

At the lowest level, a drive accesses its storage medium through a system of physical addressing, reading and writing data by its physical location. For SSDs this physical addressing system is standardised to use values of the die, plane, block, and page within a flash chip. For HDDs, it uses values of Cylinder, Head, and Sector (CHS) for a position on the magnetic disks.

NAND flash diagram

CHS diagram

However when a computer reads and writes data to the drive, it doesn't use a physical location, but a Logical Block Address (LBA). Rather than an array of physical flash chips or platters, a drive presents its storage to a computer as a single continuous area of data, indexed by a sector offset within that data. Once the main firmware has been loaded by the bootloader and executes, the firmware must then setup the subsystem handling access based on that logical addressing, converting those LBAs to physical locations on the storage medium. This subsystem is called the Translator, or Flash Translation Layer (FTL) in SSD-specific terminology. The FTL maintains a Logical To Physical (L2P) mapping table for converting a given LBA to its physical address on flash, the FTL stores this table on flash and updates it as data is written or erased.

This raises a chicken-and-egg type problem though, if the SSD requires an L2P table to locate data on flash, and that table itself is stored in that same flash, when the drive initialises how does it locate that table? The answer is simple, critical internal data such as the FTL L2P table can simply be stored anywhere on flash (or within some broad block range), and the firmware will find it by searching for a specific identifying signature.

For the Phison 3111, critical firmware data such as code, configuration, and FTL tables are stored as separate blocks anywhere within a designated range (for FTL data the first 100 blocks), and marked with a specific 32-bit magic value in the spare Error Correction Code (ECC) area of each page, the firmware header for example uses 0x31113111 for this magic value. The firmware locates the data by reading the first page of every block in that range searching for the appropriate magic value.

One type of data loaded from flash this way is a bitmap of every block on flash and its designated purpose if any, this includes blocks of System Unit data (firmware, configuration), FTL data, and Product History data. All other blocks not marked in that bitmap are considered free for allocation by the FTL.

System Area

This introduces a concept known as the System Area (SA). For any storage drive, the data it stores is divided into two distinct types, User Area data which is all regular external data written to it as storage, and SA data which is all other data used internally by the firmware. Although the SA is at least always partially designated by physical locations on the storage medium for critical data such as the L2P table as detailed earlier, many drives also maintain an additional logical SA managed by the Translator. In the Phison 3111 for example while critical system data is stored and located by physical address without logical translation, there's an additional logical SA accessed through the FTL for some non-critical data such as SMART logs.

Command Sets

When a drive is attached to a computer, the computer communicates with it through a standard command set, examples of these are ATA for SATA drives and NVM for NVMe drives. These commands can have various functionality, not only reading and writing data but also configuring drive parameters or accessing diagnostics. Command sets do not uniquely map to a drive bus type one-to-one, as some command sets can be used for multiple, for example SCSI is used for both SAS and USB drives. This is further complicated by the fact that some command sets can be encapsulated within others, such as SCSI ATA Translation (SAT) which allows sending ATA commands through SCSI commands, this is commonly used for example with USB-SATA adaptors, where ATA commands can be sent to the drive through SAT over the USB Attached SCSI (UAS) protocol.

ATA

ATA is the command set of the SATA protocol, as used by most hard drives and many solid state drives. ATA commands are based on a set of 7 register values, each of 8 or 16 bits depending on the mode (LBA28/LBA48).

Number Name Bits LBA28 Bits LBA48
1 Features 8 16
2 Sector Count 8 16
3 LBA Low 8 16
4 LBA Mid 8 16
5 LBA High 8 16
6 Device 8 8
7 Command 8 8

The command register is used for the actual command opcode ranging from 0 to 0xFF, while the other registers are parameter values with behaviors depending on the specific command.

ATA commands
Opcode Name
0x00 NOP
0x01 to 0x02
0x03 CFA REQUEST EXTENDED ERROR CODE
0x04 to 0x05
0x06 DATA SET MANAGEMENT
0x07 DATA SET MANAGEMENT XL
0x08 DEVICE RESET
0x09 to 0x0A
0x0B REQUEST SENSE DATA EXT
0x0C to 0x0F
0x10 to 0x1F RECALIBRATE
0x20 READ SECTOR(S)
0x21 READ SECTOR(S) (without retry)
0x22 READ LONG
0x23 READ LONG (without retry)
0x24 READ SECTOR(S) EXT
0x25 READ DMA EXT
0x26 READ DMA QUEUED EXT
0x27 READ NATIVE MAX ADDRESS EXT
0x28
0x29 READ MULTIPLE EXT
0x2A READ STREAM DMA EXT
0x2B READ STREAM EXT
0x2C to 0x2E
0x2F READ LOG EXT
0x30 WRITE SECTOR(S)
0x31 WRITE SECTOR(S) (without retry)
0x32 WRITE LONG
0x33 WRITE LONG (without retry)
0x34 WRITE SECTOR(S) EXT
0x35 WRITE DMA EXT
0x36 WRITE DMA QUEUED EXT
0x37 SET MAX ADDRESS EXT
0x38 CFA WRITE SECTORS WITHOUT ERASE
0x39 WRITE MULTIPLE EXT
0x3A WRITE STREAM DMA EXT
0x3B WRITE STREAM EXT
0x3C WRITE VERIFY
0x3D WRITE DMA FUA EXT
0x3E WRITE DMA QUEUED FUA EXT
0x3F WRITE LOG EXT
0x40 READ VERIFY SECTOR(S)
0x41 READ VERIFY SECTOR(S) (without retry)
0x42 READ VERIFY SECTOR(S) EXT
0x43
0x44 ZERO EXT
0x45 WRITE UNCORRECTABLE EXT
0x46
0x47 READ LOG DMA EXT
0x48 to 0x49
0x4A ZAC Management In
0x4B to 0x4F
0x50 FORMAT TRACK
0x51 CONFIGURE STREAM
0x52 to 0x56
0x57 WRITE LOG DMA EXT
0x58 to 0x5A
0x5B TRUSTED NON-DATA
0x5C TRUSTED RECEIVE
0x5D TRUSTED RECEIVE DMA
0x5E TRUSTED SEND
0x5F TRUSTED SEND DMA
0x60 READ FPDMA QUEUED
0x61 WRITE FPDMA QUEUED
0x62
0x63 NCQ NON-DATA
0x64 SEND FPDMA QUEUED
0x65 RECEIVE FPDMA QUEUED
0x66 to 0x6F
0x70 to 0x76 SEEK
0x77 SET DATE & TIME EXT / SEEK
0x78 ACCESSIBLE MAX ADDRESS CONFIGURATION / SEEK
0x79 to 0x7B SEEK
0x7C REMOVE ELEMENT AND TRUNCATE / SEEK
0x7D RESTORE ELEMENTS AND REBUILD / SEEK
0x7E REMOVE ELEMENT AND MODIFY ZONES / SEEK
0x7F SEEK
0x80 to 0x86 Vendor Specific
0x87 CFA TRANSLATE SECTOR
0x88 to 0x8F Vendor Specific
0x90 EXECUTE DEVICE DIAGNOSTIC
0x91 INITIALIZE DEVICE PARAMETERS
0x92 DOWNLOAD MICROCODE
0x93 DOWNLOAD MICROCODE DMA
0x94 STANDBY IMMEDIATE
0x95 IDLE IMMEDIATE
0x96 MUTATE EXT / STANDBY
0x97 IDLE
0x98 CHECK POWER MODE
0x99 SLEEP
0x9A Vendor Specific
0x9B to 0x9E
0x9F ZAC Management Out
0xA0 PACKET
0xA1 IDENTIFY PACKET DEVICE
0xA2 SERVICE
0xA3 to 0xAF
0xB0 SMART
0xB1 Device Configuration Overlay
0xB2 SET SECTOR CONFIGURATION EXT
0xB3
0xB4 Sanitize Device
0xB5
0xB6 NV Cache
0xB7 to 0xBB Reserved for CFA
0xBC to 0xBF
0xC0 CFA ERASE SECTORS
0xC1 to 0xC3 Vendor Specific
0xC4 READ MULTIPLE
0xC5 WRITE MULTIPLE
0xC6 SET MULTIPLE MODE
0xC7 READ DMA QUEUED
0xC8 READ DMA
0xC9 READ DMA (without retry)
0xCA WRITE DMA
0xCB WRITE DMA (without retry)
0xCC WRITE DMA QUEUED
0xCD CFA WRITE MULTIPLE WITHOUT ERASE
0xCE WRITE MULTIPLE FUA EXT
0xCF to 0xD0
0xD1 CHECK MEDIA CARD TYPE
0xD2 to 0xD9
0xDA GET MEDIA STATUS
0xDB ACKNOWLEDGE MEDIA CHANGE
0xDC BOOT - POST-BOOT
0xDD BOOT - PRE-BOOT
0xDE MEDIA LOCK
0xDF MEDIA UNLOCK
0xE0 STANDBY IMMEDIATE
0xE1 IDLE IMMEDIATE
0xE2 STANDBY
0xE3 IDLE
0xE4 READ BUFFER
0xE5 CHECK POWER MODE
0xE6 SLEEP
0xE7 FLUSH CACHE
0xE8 WRITE BUFFER
0xE9 READ BUFFER DMA / WRITE SAME
0xEA FLUSH CACHE EXT
0xEB WRITE BUFFER DMA
0xEC IDENTIFY DEVICE
0xED MEDIA EJECT
0xEE IDENTIFY DEVICE DMA
0xEF SET FEATURES
0xF0 Vendor Specific
0xF1 SECURITY SET PASSWORD
0xF2 SECURITY UNLOCK
0xF3 SECURITY ERASE PREPARE
0xF4 SECURITY ERASE UNIT
0xF5 SECURITY FREEZE LOCK
0xF6 SECURITY DISABLE PASSWORD
0xF7 Vendor Specific
0xF8 READ NATIVE MAX ADDRESS
0xF9 SET MAX ADDRESS
0xFA to 0xFF Vendor Specific

NVM

NVM is the primary command set for the NVMe protocol, as used by most modern SSDs. Commands are 64 bytes in size, although the exact fields within those 64 bytes vary based on the command, there is a Common Command Format defining a general format applicable to all:

Bytes Field Description
00-03 CDW0 Command Dword 0 (Opcode, FUSE, PSDT, CID)
04-07 NSID Namespace Identifier
08-11 CDW2 Command-specific
12-15 CDW3 Command-specific
16-23 MPTR Metadata Pointer
24-39 DPTR Data Pointer
40-43 CDW10 Command-specific
44-47 CDW11 Command-specific
48-51 CDW12 Command-specific
52-55 CDW13 Command-specific
56-59 CDW14 Command-specific
60-63 CDW15 Command-specific

NVM commands are separated into two main types, I/O commands, and Admin commands. I/O commands are what you would expect from the name, handling regular data reading and writing. Admin commands are the more interesting type for this topic's security focus, as they handle management of the drive itself, including managing drive configuration, firmware, and various other internal functionality. NVM Admin command opcodes are organised in three distinct ranges, each serving a specific purpose:

Range Purpose
0x00-0x7F Standard
0x80-0xBF I/O Command Set Specific
0xC0-0xFF Vendor Specific
NVM Admin commands
Opcode Command Name
0x00 Delete I/O Submission Queue
0x01 Create I/O Submission Queue
0x02 Get Log Page
0x04 Delete I/O Completion Queue
0x05 Create I/O Completion Queue
0x06 Identify
0x08 Abort
0x09 Set Features
0x0A Get Features
0x0C Asynchronous Event Request
0x0D Namespace Management
0x10 Firmware Commit
0x11 Firmware Image Download
0x14 Device Self-Test
0x15 Namespace Attachment
0x18 Keep Alive
0x19 Directive Send
0x1A Directive Receive
0x1C Virtualization Management
0x1D NVMe-MI Send
0x1E NVMe-MI Receive
0x20 Capacity Management
0x24 Lockdown
0x7C Doorbell Buffer Config
0x7F Fabrics Commands
0x80 Format NVM
0x81 Security Send
0x82 Security Receive
0x84 Sanitize
0x86 Get LBA Status
0xC0–0xFF Vendor Specific

Vendor Unique Commands

So as mentioned in section Boot Process in safe mode software tools can use vendor-specific features to load firmware into memory, but how do those features work? They use something called Vendor Unique Commands (VUCs), also known as Vendor Specific Commands (VSCs). In any command set used by drives some subset of commands are reserved as vendor specific, these commands are available for drive vendors to use for whatever functionality they like. Some forms of VUCs can be more complicated, and instead of using those reserved command codes implement special features within the standard command set, such as magic parameters to activate some alternate functionality, others can use sub-protocols transported within the standard command set such as ATA SMART Command Transport (SCT).

VUCs are not something unique to a drive's safe mode, but are something vendors also implement in standard firmware versions too, providing commands available during normal drive operation. These commands can allow access to low-level engineering features and firmware internals, including reading/writing controller memory, direct access to physical flash, and configuring internal drive parameters. VUCs are usually undocumented and intended for internal use by the vendor, however through leaked information or reverse engineering can sometimes be discovered and used. All modern storage drives have some form of VUCs implemented, across all drive types including SATA and NVMe, as vendors consider them an essential tool for drive manufacturing and diagnostics.

Security

Over the years drive manufacturers have introduced many security features to protect their products, these security features generally focus on protecting two main areas, firmware confidentiality and integrity, and authorised Vendor Unique Command (VUC) access.

Modern storage drives generally secure their firmware with encryption, and often cryptographic signing too for validating authenticity. Firmware is usually secured with these protections not only through the standard update process (e.g. firmware sent through the ATA DOWNLOAD MICROCODE command), but also at rest when stored in the drive. When the bootloader loads firmware as detailed in section Boot Process, the bootloader will first decrypt the firmware and verify some type of signature or checksum before executing it, providing protection intended to be analogous to UEFI Secure Boot found in personal computers.

Additionally VUCs for accessing sensitive drive functionality will generally be locked by default during normal drive operation, drive firmware will usually implement some type of authentication flow to gain access to these commands. This authentication is usually implemented as a challenge-response scheme using cryptography, some subset of unrestricted VUCs are first used to read challenge data from the drive, which is then encrypted or signed with a specific hardcoded key, and then sent back to the drive. If the drive validates the encryption or signature is valid, those restricted VUCs are then unlocked.

Both types of security protections detailed above are often built on asymmetric cryptography using an algorithm such as RSA, the drive will contain a public key to verify the signature of firmware images or VUC unlock challenge responses. However the private key necessary to create those signatures is not contained in the drive at all, and is kept private by the vendor for their internal use.