1Non-volatile storage library 2============================ 3 4:link_to_translation:`zh_CN:[中文]` 5 6Introduction 7------------ 8 9Non-volatile storage (NVS) library is designed to store key-value pairs in flash. This section introduces some concepts used by NVS. 10 11 12Underlying storage 13^^^^^^^^^^^^^^^^^^ 14 15Currently, NVS uses a portion of main flash memory through ``spi_flash_{read|write|erase}`` APIs. The library uses all the partitions with ``data`` type and ``nvs`` subtype. The application can choose to use the partition with the label ``nvs`` through the ``nvs_open`` API function or any other partition by specifying its name using the ``nvs_open_from_part`` API function. 16 17Future versions of this library may have other storage backends to keep data in another flash chip (SPI or I2C), RTC, FRAM, etc. 18 19.. note:: if an NVS partition is truncated (for example, when the partition table layout is changed), its contents should be erased. ESP-IDF build system provides a ``idf.py erase_flash`` target to erase all contents of the flash chip. 20 21.. note:: NVS works best for storing many small values, rather than a few large values of the type 'string' and 'blob'. If you need to store large blobs or strings, consider using the facilities provided by the FAT filesystem on top of the wear levelling library. 22 23 24Keys and values 25^^^^^^^^^^^^^^^ 26 27NVS operates on key-value pairs. Keys are ASCII strings; the maximum key length is currently 15 characters. Values can have one of the following types: 28 29- integer types: ``uint8_t``, ``int8_t``, ``uint16_t``, ``int16_t``, ``uint32_t``, ``int32_t``, ``uint64_t``, ``int64_t`` 30- zero-terminated string 31- variable length binary data (blob) 32 33.. note:: 34 35 String values are currently limited to 4000 bytes. This includes the null terminator. Blob values are limited to 508000 bytes or 97.6% of the partition size - 4000 bytes, whichever is lower. 36 37Additional types, such as ``float`` and ``double`` might be added later. 38 39Keys are required to be unique. Assigning a new value to an existing key works as follows: 40 41- if the new value is of the same type as the old one, value is updated 42- if the new value has a different data type, an error is returned 43 44Data type check is also performed when reading a value. An error is returned if the data type of the read operation does not match the data type of the value. 45 46 47Namespaces 48^^^^^^^^^^ 49 50To mitigate potential conflicts in key names between different components, NVS assigns each key-value pair to one of namespaces. Namespace names follow the same rules as key names, i.e., the maximum length is 15 characters. Namespace name is specified in the ``nvs_open`` or ``nvs_open_from_part`` call. This call returns an opaque handle, which is used in subsequent calls to the ``nvs_get_*``, ``nvs_set_*``, and ``nvs_commit`` functions. This way, a handle is associated with a namespace, and key names will not collide with same names in other namespaces. 51Please note that the namespaces with the same name in different NVS partitions are considered as separate namespaces. 52 53 54Security, tampering, and robustness 55^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 56 57NVS is not directly compatible with the ESP32 flash encryption system. However, data can still be stored in encrypted form if NVS encryption is used together with ESP32 flash encryption. Please refer to :ref:`nvs_encryption` for more details. 58 59If NVS encryption is not used, it is possible for anyone with physical access to the flash chip to alter, erase, or add key-value pairs. With NVS encryption enabled, it is not possible to alter or add a key-value pair and get recognized as a valid pair without knowing corresponding NVS encryption keys. However, there is no tamper-resistance against the erase operation. 60 61The library does try to recover from conditions when flash memory is in an inconsistent state. In particular, one should be able to power off the device at any point and time and then power it back on. This should not result in loss of data, except for the new key-value pair if it was being written at the moment of powering off. The library should also be able to initialize properly with any random data present in flash memory. 62 63 64Internals 65--------- 66 67Log of key-value pairs 68^^^^^^^^^^^^^^^^^^^^^^ 69 70NVS stores key-value pairs sequentially, with new key-value pairs being added at the end. When a value of any given key has to be updated, a new key-value pair is added at the end of the log and the old key-value pair is marked as erased. 71 72Pages and entries 73^^^^^^^^^^^^^^^^^ 74 75NVS library uses two main entities in its operation: pages and entries. Page is a logical structure which stores a portion of the overall log. Logical page corresponds to one physical sector of flash memory. Pages which are in use have a *sequence number* associated with them. Sequence numbers impose an ordering on pages. Higher sequence numbers correspond to pages which were created later. Each page can be in one of the following states: 76 77Empty/uninitialized 78 Flash storage for the page is empty (all bytes are ``0xff``). Page is not used to store any data at this point and does not have a sequence number. 79 80Active 81 Flash storage is initialized, page header has been written to flash, page has a valid sequence number. Page has some empty entries and data can be written there. No more than one page can be in this state at any given moment. 82 83Full 84 Flash storage is in a consistent state and is filled with key-value pairs. 85 Writing new key-value pairs into this page is not possible. It is still possible to mark some key-value pairs as erased. 86 87Erasing 88 Non-erased key-value pairs are being moved into another page so that the current page can be erased. This is a transient state, i.e., page should never stay in this state at the time when any API call returns. In case of a sudden power off, the move-and-erase process will be completed upon the next power-on. 89 90Corrupted 91 Page header contains invalid data, and further parsing of page data was canceled. Any items previously written into this page will not be accessible. The corresponding flash sector will not be erased immediately and will be kept along with sectors in *uninitialized* state for later use. This may be useful for debugging. 92 93Mapping from flash sectors to logical pages does not have any particular order. The library will inspect sequence numbers of pages found in each flash sector and organize pages in a list based on these numbers. 94 95:: 96 97 +--------+ +--------+ +--------+ +--------+ 98 | Page 1 | | Page 2 | | Page 3 | | Page 4 | 99 | Full +---> | Full +---> | Active | | Empty | <- states 100 | #11 | | #12 | | #14 | | | <- sequence numbers 101 +---+----+ +----+---+ +----+---+ +---+----+ 102 | | | | 103 | | | | 104 | | | | 105 +---v------+ +-----v----+ +------v---+ +------v---+ 106 | Sector 3 | | Sector 0 | | Sector 2 | | Sector 1 | <- physical sectors 107 +----------+ +----------+ +----------+ +----------+ 108 109Structure of a page 110^^^^^^^^^^^^^^^^^^^ 111 112For now, we assume that flash sector size is 4096 bytes and that ESP32 flash encryption hardware operates on 32-byte blocks. It is possible to introduce some settings configurable at compile-time (e.g., via menuconfig) to accommodate flash chips with different sector sizes (although it is not clear if other components in the system, e.g., SPI flash driver and SPI flash cache can support these other sizes). 113 114Page consists of three parts: header, entry state bitmap, and entries themselves. To be compatible with ESP32 flash encryption, entry size is 32 bytes. For integer types, entry holds one key-value pair. For strings and blobs, an entry holds part of key-value pair (more on that in the entry structure description). 115 116The following diagram illustrates the page structure. Numbers in parentheses indicate the size of each part in bytes. :: 117 118 +-----------+--------------+-------------+-------------------------+ 119 | State (4) | Seq. no. (4) | version (1) | Unused (19) | CRC32 (4) | Header (32) 120 +-----------+--------------+-------------+-------------------------+ 121 | Entry state bitmap (32) | 122 +------------------------------------------------------------------+ 123 | Entry 0 (32) | 124 +------------------------------------------------------------------+ 125 | Entry 1 (32) | 126 +------------------------------------------------------------------+ 127 / / 128 / / 129 +------------------------------------------------------------------+ 130 | Entry 125 (32) | 131 +------------------------------------------------------------------+ 132 133Page header and entry state bitmap are always written to flash unencrypted. Entries are encrypted if flash encryption feature of ESP32 is used. 134 135Page state values are defined in such a way that changing state is possible by writing 0 into some of the bits. Therefore it is not necessary to erase the page to change its state unless that is a change to the *erased* state. 136 137The version field in the header reflects the NVS format version used. For backward compatibility reasons, it is decremented for every version upgrade starting at 0xff (i.e., 0xff for version-1, 0xfe for version-2 and so on). 138 139CRC32 value in the header is calculated over the part which does not include a state value (bytes 4 to 28). The unused part is currently filled with ``0xff`` bytes. 140 141The following sections describe the structure of entry state bitmap and entry itself. 142 143Entry and entry state bitmap 144^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 145 146Each entry can be in one of the following three states represented with two bits in the entry state bitmap. The final four bits in the bitmap (256 - 2 * 126) are not used. 147 148Empty (2'b11) 149 Nothing is written into the specific entry yet. It is in an uninitialized state (all bytes are ``0xff``). 150 151Written (2'b10) 152 A key-value pair (or part of key-value pair which spans multiple entries) has been written into the entry. 153 154Erased (2'b00) 155 A key-value pair in this entry has been discarded. Contents of this entry will not be parsed anymore. 156 157 158.. _structure_of_entry: 159 160Structure of entry 161^^^^^^^^^^^^^^^^^^ 162 163For values of primitive types (currently integers from 1 to 8 bytes long), entry holds one key-value pair. For string and blob types, entry holds part of the whole key-value pair. For strings, in case when a key-value pair spans multiple entries, all entries are stored in the same page. Blobs are allowed to span over multiple pages by dividing them into smaller chunks. For tracking these chunks, an additional fixed length metadata entry is stored called "blob index". Earlier formats of blobs are still supported (can be read and modified). However, once the blobs are modified, they are stored using the new format. 164 165:: 166 167 +--------+----------+----------+----------------+-----------+---------------+----------+ 168 | NS (1) | Type (1) | Span (1) | ChunkIndex (1) | CRC32 (4) | Key (16) | Data (8) | 169 +--------+----------+----------+----------------+-----------+---------------+----------+ 170 171 Primitive +--------------------------------+ 172 +--------> | Data (8) | 173 | Types +--------------------------------+ 174 +-> Fixed length -- 175 | | +---------+--------------+---------------+-------+ 176 | +--------> | Size(4) | ChunkCount(1)| ChunkStart(1) | Rsv(2)| 177 Data format ---+ Blob Index +---------+--------------+---------------+-------+ 178 | 179 | +----------+---------+-----------+ 180 +-> Variable length --> | Size (2) | Rsv (2) | CRC32 (4) | 181 (Strings, Blob Data) +----------+---------+-----------+ 182 183 184Individual fields in entry structure have the following meanings: 185 186NS 187 Namespace index for this entry. For more information on this value, see the section on namespaces implementation. 188 189Type 190 One byte indicating the value data type. See the ``ItemType`` enumeration in ``nvs_types.h`` for possible values. 191 192Span 193 Number of entries used by this key-value pair. For integer types, this is equal to 1. For strings and blobs, this depends on value length. 194 195ChunkIndex 196 Used to store the index of a blob-data chunk for blob types. For other types, this should be ``0xff``. 197 198CRC32 199 Checksum calculated over all the bytes in this entry, except for the CRC32 field itself. 200 201Key 202 Zero-terminated ASCII string containing a key name. Maximum string length is 15 bytes, excluding a zero terminator. 203 204Data 205 For integer types, this field contains the value itself. If the value itself is shorter than 8 bytes, it is padded to the right, with unused bytes filled with ``0xff``. 206 207 For "blob index" entry, these 8 bytes hold the following information about data-chunks: 208 209 - Size 210 (Only for blob index.) Size, in bytes, of complete blob data. 211 212 - ChunkCount 213 (Only for blob index.) Total number of blob-data chunks into which the blob was divided during storage. 214 215 - ChunkStart 216 (Only for blob index.) ChunkIndex of the first blob-data chunk of this blob. Subsequent chunks have chunkIndex incrementally allocated (step of 1). 217 218 For string and blob data chunks, these 8 bytes hold additional data about the value, which are described below: 219 220 - Size 221 (Only for strings and blobs.) Size, in bytes, of actual data. For strings, this includes zero terminators. 222 223 - CRC32 224 (Only for strings and blobs.) Checksum calculated over all bytes of data. 225 226Variable length values (strings and blobs) are written into subsequent entries, 32 bytes per entry. The `Span` field of the first entry indicates how many entries are used. 227 228 229Namespaces 230^^^^^^^^^^ 231 232As mentioned above, each key-value pair belongs to one of the namespaces. Namespace identifiers (strings) are stored as keys of key-value pairs in namespace with index 0. Values corresponding to these keys are indexes of these namespaces. 233 234:: 235 236 +-------------------------------------------+ 237 | NS=0 Type=uint8_t Key="wifi" Value=1 | Entry describing namespace "wifi" 238 +-------------------------------------------+ 239 | NS=1 Type=uint32_t Key="channel" Value=6 | Key "channel" in namespace "wifi" 240 +-------------------------------------------+ 241 | NS=0 Type=uint8_t Key="pwm" Value=2 | Entry describing namespace "pwm" 242 +-------------------------------------------+ 243 | NS=2 Type=uint16_t Key="channel" Value=20 | Key "channel" in namespace "pwm" 244 +-------------------------------------------+ 245 246 247Item hash list 248^^^^^^^^^^^^^^ 249 250To reduce the number of reads from flash memory, each member of the Page class maintains a list of pairs: item index; item hash. This list makes searches much quicker. Instead of iterating over all entries, reading them from flash one at a time, ``Page::findItem`` first performs a search for the item hash in the hash list. This gives the item index within the page if such an item exists. Due to a hash collision, it is possible that a different item will be found. This is handled by falling back to iteration over items in flash. 251 252Each node in the hash list contains a 24-bit hash and 8-bit item index. Hash is calculated based on item namespace, key name, and ChunkIndex. CRC32 is used for calculation; the result is truncated to 24 bits. To reduce the overhead for storing 32-bit entries in a linked list, the list is implemented as a double-linked list of arrays. Each array holds 29 entries, for the total size of 128 bytes, together with linked list pointers and a 32-bit count field. The minimum amount of extra RAM usage per page is therefore 128 bytes; maximum is 640 bytes. 253 254.. _nvs_encryption: 255 256NVS Encryption 257-------------- 258 259Data stored in NVS partitions can be encrypted using AES-XTS in the manner similar to the one mentioned in disk encryption standard IEEE P1619. For the purpose of encryption, each entry is treated as one `sector` and relative address of the entry (w.r.t. partition-start) is fed to the encryption algorithm as `sector-number`. The NVS Encryption can be enabled by enabling :ref:`CONFIG_NVS_ENCRYPTION`. The keys required for NVS encryption are stored in yet another partition, which is protected using :doc:`Flash Encryption <../../security/flash-encryption>`. Therefore, enabling :doc:`Flash Encryption <../../security/flash-encryption>` is a prerequisite for NVS encryption. 260 261The NVS Encryption is enabled by default when :doc:`Flash Encryption <../../security/flash-encryption>` is enabled. This is done because WiFi driver stores credentials (like SSID and passphrase) in the default NVS partition. It is important to encrypt them as default choice if platform level encryption is already enabled. 262 263For using NVS encryption, the partition table must contain the :ref:`nvs_key_partition`. Two partition tables containing the :ref:`nvs_key_partition` are provided for NVS encryption under the partition table option (menuconfig->Partition Table). They can be selected with the project configuration menu (``idf.py menuconfig``). Please refer to the example :example:`security/flash_encryption` for how to configure and use NVS encryption feature. 264 265.. _nvs_key_partition: 266 267NVS key partition 268^^^^^^^^^^^^^^^^^ 269 270 An application requiring NVS encryption support needs to be compiled with a key-partition of the type `data` and subtype `key`. This partition should be marked as `encrypted`. Refer to :doc:`Partition Tables <../../api-guides/partition-tables>` for more details. Two additional partition tables which contain the :ref:`nvs_key_partition` are provided under the partition table option (menuconfig->Partition Table). They can be directly used for :ref:`nvs_encryption`. The structure of these partitions is depicted below. 271 272:: 273 274 +-----------+--------------+-------------+----+ 275 | XTS encryption key(32) | 276 +---------------------------------------------+ 277 | XTS tweak key (32) | 278 +---------------------------------------------+ 279 | CRC32(4) | 280 +---------------------------------------------+ 281 282The XTS encryption keys in the :ref:`nvs_key_partition` can be generated with one of the following two ways. 283 2841. Generate the keys on the ESP chip: 285 286 When NVS encryption is enabled the :cpp:func:`nvs_flash_init` API function can be used to initialize the encrypted default NVS partition. The API function internally generates the XTS encryption keys on the ESP chip. The API function finds the first :ref:`nvs_key_partition`. 287 Then the API function automatically generates and stores the nvs keys in that partition by making use of the :cpp:func:`nvs_flash_generate_keys` API function provided by ``nvs_flash.h``. New keys are generated and stored only when the respective key partiton is empty. The same key partition can then be used to read the security configurations for initializing a custom encrypted NVS partition with help of :cpp:func:`nvs_flash_secure_init_partition`. 288 289 The API functions :cpp:func:`nvs_flash_secure_init` and :cpp:func:`nvs_flash_secure_init_partition` do not generate the keys internally. When these API functions are used for initializing encrypted NVS partitions, the keys can be generated after startup using the :cpp:func:`nvs_flash_generate_keys` API function provided by ``nvs_flash.h``. The API function will then write those keys onto the key-partition in encrypted form. 290 2912. Use pre-generated key partition: 292 293 This option will be required by the user when keys in the :ref:`nvs_key_partition` are not generated by the application. The :ref:`nvs_key_partition` containing the XTS encryption keys can be generated with the help of :doc:`NVS Partition Generator Utility</api-reference/storage/nvs_partition_gen>`. Then the user can store the pre generated key partition on the flash with help of the following two commands: 294 295 i) Build and flash the partition table 296 :: 297 298 idf.py partition_table partition_table-flash 299 300 ii) Store the keys in the :ref:`nvs_key_partition` (on the flash) with the help of :component_file:`parttool.py<partition_table/parttool.py>` (see Partition Tool section in :doc:`partition-tables </api-guides/partition-tables>` for more details) 301 :: 302 303 parttool.py --port /dev/ttyUSB0 --partition-table-offset "nvs_key partition offset" write_partition --partition-name="name of nvs_key partition" --input "nvs_key partition" 304 305Since the key partition is marked as `encrypted` and :doc:`Flash Encryption <../../security/flash-encryption>` is enabled, the bootloader will encrypt this partition using flash encryption key on the first boot. 306 307It is possible for an application to use different keys for different NVS partitions and thereby have multiple key-partitions. However, it is a responsibility of the application to provide correct key-partition/keys for the purpose of encryption/decryption. 308 309Encrypted Read/Write 310^^^^^^^^^^^^^^^^^^^^ 311 312The same NVS API functions ``nvs_get_*`` or ``nvs_set_*`` can be used for reading of, and writing to an encrypted nvs partition as well. 313 314**Encrypt the default NVS partition:** 315To enable encryption for the default NVS partition no additional steps are necessary. When :ref:`CONFIG_NVS_ENCRYPTION` is enabled, the :cpp:func:`nvs_flash_init` API function internally performs some additional steps using the first :ref:`nvs_key_partition` found to enable encryption for the default NVS partition (refer to the API documentation for more details). Alternatively, :cpp:func:`nvs_flash_secure_init` API function can also be used to enable encryption for the default NVS partition. 316 317**Encrypt a custom NVS partition:** 318To enable encryption for a custom NVS partition, :cpp:func:`nvs_flash_secure_init_partition` API function is used instead of :cpp:func:`nvs_flash_init_partition`. 319 320When :cpp:func:`nvs_flash_secure_init` and :cpp:func:`nvs_flash_secure_init_partition` API functions are used, the applications are expected to follow the steps below in order to perform NVS read/write operations with encryption enabled. 321 322 1. Find key partition and NVS data partition using ``esp_partition_find*`` API functions. 323 2. Populate the ``nvs_sec_cfg_t`` struct using the ``nvs_flash_read_security_cfg`` or ``nvs_flash_generate_keys`` API functions. 324 3. Initialise NVS flash partition using the ``nvs_flash_secure_init`` or ``nvs_flash_secure_init_partition`` API functions. 325 4. Open a namespace using the ``nvs_open`` or ``nvs_open_from_part`` API functions. 326 5. Perform NVS read/write operations using ``nvs_get_*`` or ``nvs_set_*``. 327 6. Deinitialise an NVS partition using ``nvs_flash_deinit``. 328 329NVS iterators 330^^^^^^^^^^^^^ 331 332Iterators allow to list key-value pairs stored in NVS, based on specified partition name, namespace, and data type. 333 334There are the following functions available: 335 336- ``nvs_entry_find`` returns an opaque handle, which is used in subsequent calls to the ``nvs_entry_next`` and ``nvs_entry_info`` functions. 337- ``nvs_entry_next`` returns iterator to the next key-value pair. 338- ``nvs_entry_info`` returns information about each key-value pair 339 340If none or no other key-value pair was found for given criteria, ``nvs_entry_find`` and ``nvs_entry_next`` return NULL. In that case, the iterator does not have to be released. If the iterator is no longer needed, you can release it by using the function ``nvs_release_iterator``. 341