docs: Update nvs_flash docs for the HMAC-based NVS encr-keys protection scheme

- Also updated the `nvs_partition_generator` and `mass_mfg` tools
  documentation
This commit is contained in:
Laukik Hase 2023-04-18 18:09:38 +05:30
parent 9ac87fcc8b
commit a06118012e
No known key found for this signature in database
GPG Key ID: 11C571361F51A199
10 changed files with 506 additions and 275 deletions

View File

@ -6,20 +6,22 @@ NVS Partition Generator Utility
Introduction
------------
The utility :component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py` creates a binary file based on key-value pairs provided in a CSV file. The binary file is compatible with NVS architecture defined in :doc:`Non-Volatile Storage </api-reference/storage/nvs_flash>`. This utility is ideally suited for generating a binary blob, containing data specific to ODM/OEM, which can be flashed externally at the time of device manufacturing. This allows manufacturers to generate many instances of the same application firmware with customized parameters for each device, such as a serial number.
The utility :component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py` creates a binary file, compatible with the NVS architecture defined in :doc:`Non-Volatile Storage </api-reference/storage/nvs_flash>`, based on the key-value pairs provided in a CSV file.
This utility is ideally suited for generating a binary blob, containing data specific to ODM/OEM, which can be flashed externally at the time of device manufacturing. This allows manufacturers to generate many instances of the same application firmware with customized parameters for each device, such as a serial number.
Prerequisites
-------------
To use this utility in encryption mode, install the following packages:
- cryptography package
- ``cryptography``
All the required packages are included in `requirements.txt` in the root of the esp-idf directory.
All the required packages are included in `requirements.txt` in the root of the ESP-IDF directory.
CSV File Format
---------------
~~~~~~~~~~~~~~~
Each line of a CSV file should contain 4 parameters, separated by a comma. The table below provides the description for each of these parameters.
Each line of a CSV file should contain 4 parameters, separated by a comma. The table below describes each of these parameters.
.. list-table::
:widths: 10 20 35 35
@ -73,19 +75,15 @@ When a namespace entry is encountered in a CSV file, each following entry will b
Multipage Blob Support
----------------------
By default, binary blobs are allowed to span over multiple pages and are written in the format mentioned in Section :ref:`structure_of_entry`. If you intend to use an older format, the utility provides an option to disable this feature.
By default, binary blobs are allowed to span over multiple pages and are written in the format mentioned in Section :ref:`structure_of_entry`. If you intend to use the older format, the utility provides an option to disable this feature.
Encryption Support
-------------------
Encryption-Decryption Support
-----------------------------
The NVS Partition Generator utility also allows you to create an encrypted binary file. The utility uses the XTS-AES encryption. Please refer to :ref:`nvs_encryption` for more details.
The NVS Partition Generator utility also allows you to create an encrypted binary file and decrypt an encrypted one. The utility uses the XTS-AES encryption. Please refer to :doc:`NVS Encryption <nvs_encryption>` for more details.
Decryption Support
-------------------
This utility allows you to decrypt an encrypted NVS binary file. The utility uses an NVS binary file encrypted using XTS-AES encryption. Please refer to :ref:`nvs_encryption` for more details.
Running the Utility
-------------------
@ -95,141 +93,173 @@ Running the Utility
**Optional Arguments**:
+-----+------------+----------------------------------------------------------------------+
+-----+------------------------+---------------------------------------------------------------+
| No. | Parameter | Description |
+=====+============+======================================================================+
| 1 | -h, --help | Show this help message and exit |
+-----+------------+----------------------------------------------------------------------+
+=====+========================+===============================================================+
| 1 | ``-h`` \ ``--help`` | Show the help message and exit |
+-----+------------------------+---------------------------------------------------------------+
**Commands**::
Run nvs_partition_gen.py {command} -h for additional help
+-----+--------------+--------------------------------------------------------------------+
+-----+---------------------+---------------------------------------------------------------+
| No. | Parameter | Description |
+=====+==============+====================================================================+
| 1 | generate | Generate NVS partition |
+-----+--------------+--------------------------------------------------------------------+
| 2 | generate-key | Generate keys for encryption |
+-----+--------------+--------------------------------------------------------------------+
| 3 | encrypt | Generate NVS encrypted partition |
+-----+--------------+--------------------------------------------------------------------+
| 4 | decrypt | Decrypt NVS encrypted partition |
+-----+--------------+--------------------------------------------------------------------+
+=====+=====================+===============================================================+
| 1 | ``generate`` | Generate NVS partition |
+-----+---------------------+---------------------------------------------------------------+
| 2 | ``generate-key`` | Generate keys for encryption |
+-----+---------------------+---------------------------------------------------------------+
| 3 | ``encrypt`` | Generate NVS encrypted partition |
+-----+---------------------+---------------------------------------------------------------+
| 4 | ``decrypt`` | Decrypt NVS encrypted partition |
+-----+---------------------+---------------------------------------------------------------+
To Generate NVS Partition (Default):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generate NVS Partition (Default)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Usage**::
python nvs_partition_gen.py generate [-h] [--version {1,2}] [--outdir OUTDIR]
input output size
python nvs_partition_gen.py generate [-h] [--version {1,2}] [--outdir OUTDIR] input output size
**Positional Arguments**:
+--------------+----------------------------------------------------------------------+
+--------------+---------------------------------------------------------------+
| Parameter | Description |
+==============+======================================================================+
| input | Path to CSV file to parse |
+--------------+----------------------------------------------------------------------+
| output | Path to output NVS binary file |
+--------------+----------------------------------------------------------------------+
| size | Size of NVS partition in bytes (must be multiple of 4096) |
+--------------+----------------------------------------------------------------------+
+==============+===============================================================+
| ``input`` | Path to CSV file to parse |
+--------------+---------------------------------------------------------------+
| ``output`` | Path to output NVS binary file |
+--------------+---------------------------------------------------------------+
| ``size`` | Size of NVS partition in bytes (must be multiple of 4096) |
+--------------+---------------------------------------------------------------+
**Optional Arguments**:
+-----------------+--------------------------------------------------------------------+
+------------------------+----------------------------------------------------------------------+
| Parameter | Description |
+=================+====================================================================+
| -h, --help | Show this help message and exit |
+-----------------+--------------------------------------------------------------------+
| --version {1,2} | Set multipage blob version |
| | Version 1 - Multipage blob support disabled |
| | Version 2 - Multipage blob support enabled |
| | Default: Version 2 |
+========================+======================================================================+
| ``-h`` \ ``--help`` | Show the help message and exit |
+------------------------+----------------------------------------------------------------------+
| ``--version {1,2}`` | Set multipage blob version (Default: Version 2) |
| | |
+-----------------+--------------------------------------------------------------------+
| --outdir OUTDIR | Output directory to store files created |
| | (Default: current directory) |
+-----------------+--------------------------------------------------------------------+
| | Version 1 - Multipage blob support disabled |
| | |
| | Version 2 - Multipage blob support enabled |
+------------------------+----------------------------------------------------------------------+
| ``--outdir OUTDIR`` | Output directory to store file created (Default: current directory) |
+------------------------+----------------------------------------------------------------------+
You can run the utility to generate NVS partition using the command below. A sample CSV file is provided with the utility::
python nvs_partition_gen.py generate sample_singlepage_blob.csv sample.bin 0x3000
To Generate Only Encryption Key Partition:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generate Encryption Keys Partition
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Usage**::
python nvs_partition_gen.py generate-key [-h] [--keyfile KEYFILE]
[--outdir OUTDIR]
python nvs_partition_gen.py generate-key [-h] [--key_protect_hmac] [--kp_hmac_keygen]
[--kp_hmac_keyfile KP_HMAC_KEYFILE] [--kp_hmac_inputkey KP_HMAC_INPUTKEY]
[--keyfile KEYFILE] [--outdir OUTDIR]
**Optional Arguments**:
.. list-table::
:widths: 30 70
:header-rows: 1
* - Parameter
- Description
* - -h, --help
- Show this help message and exit
* - --keyfile KEYFILE
- Path to output encryption key partition file
* - --outdir OUTDIR
- Output directory to store file created (Default: current directory)
+---------------------------------------------+-----------------------------------------------------------------------------------+
| Parameter | Description |
+=============================================+===================================================================================+
| ``-h`` \ ``--help`` | Show the help message and exit |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC |
| | peripheral is used; else the default scheme based on Flash Encryption |
| | is used |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--keyfile KEYFILE`` | Path to output encryption keys file |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--outdir OUTDIR`` | Output directory to store files created. (Default: current directory) |
+---------------------------------------------+-----------------------------------------------------------------------------------+
You can run the utility to generate only the encryption key partition using the command below::
python nvs_partition_gen.py generate-key
To Generate Encrypted NVS Partition:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For generating encryption key for the HMAC-based scheme, the following commands can be used:
- Generate the HMAC key and the NVS encryption keys::
python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_keygen
.. note:: Encryption key of the format ``<outdir>/keys/keys-<timestamp>.bin`` and HMAC key of the format ``<outdir>/keys/hmac-keys-<timestamp>.bin`` are created.
- Generate the NVS encryption keys, given the HMAC-key::
python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin
.. note:: You can provide the custom filename for the HMAC key as well as the encryption key as a parameter.
Generate Encrypted NVS Partition
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Usage**::
python nvs_partition_gen.py encrypt [-h] [--version {1,2}] [--keygen]
[--keyfile KEYFILE] [--inputkey INPUTKEY]
[--outdir OUTDIR]
[--keyfile KEYFILE] [--inputkey INPUTKEY] [--outdir OUTDIR]
[--key_protect_hmac] [--kp_hmac_keygen]
[--kp_hmac_keyfile KP_HMAC_KEYFILE] [--kp_hmac_inputkey KP_HMAC_INPUTKEY]
input output size
**Positional Arguments**:
+--------------+----------------------------------------------------------------------+
+--------------+---------------------------------------------------------------+
| Parameter | Description |
+==============+======================================================================+
| input | Path to CSV file to parse |
+--------------+----------------------------------------------------------------------+
| output | Path to output NVS binary file |
+--------------+----------------------------------------------------------------------+
| size | Size of NVS partition in bytes (must be multiple of 4096) |
+--------------+----------------------------------------------------------------------+
+==============+===============================================================+
| ``input`` | Path to CSV file to parse |
+--------------+---------------------------------------------------------------+
| ``output`` | Path to output NVS binary file |
+--------------+---------------------------------------------------------------+
| ``size`` | Size of NVS partition in bytes (must be multiple of 4096) |
+--------------+---------------------------------------------------------------+
**Optional Arguments**:
+---------------------+--------------------------------------------------------------------+
+---------------------------------------------+-------------------------------------------------------------------------------+
| Parameter | Description |
+=====================+====================================================================+
| -h, --help | Show this help message and exit |
+=============================================+===============================================================================+
| ``-h`` \ ``--help`` | Show the help message and exit |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--version {1,2}`` | Set multipage blob version (Default: Version 2) |
| | |
+---------------------+--------------------------------------------------------------------+
| --version {1,2} | Set multipage blob version |
| | Version 1 - Multipage blob support disabled |
| | |
| | Version 2 - Multipage blob support enabled |
| | Default: Version 2 |
+---------------------+--------------------------------------------------------------------+
| --keygen | Generates key for encrypting NVS partition |
+---------------------+--------------------------------------------------------------------+
| --keyfile KEYFILE | Path to output encryption keys file |
+---------------------+--------------------------------------------------------------------+
| --inputkey INPUTKEY | File having key for encrypting NVS partition |
+---------------------+--------------------------------------------------------------------+
| --outdir OUTDIR | Output directory to store files created |
| | (Default: current directory) |
+---------------------+--------------------------------------------------------------------+
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--keygen`` | Generates key for encrypting NVS partition |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--keyfile KEYFILE`` | Path to output encryption keys file |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--inputkey INPUTKEY`` | File having key for encrypting NVS partition |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--outdir OUTDIR`` | Output directory to store file created (Default: current directory) |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC |
| | peripheral is used; else the default scheme based on Flash Encryption |
| | is used |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys |
+---------------------------------------------+-------------------------------------------------------------------------------+
You can run the utility to encrypt NVS partition using the command below. A sample CSV file is provided with the utility:
@ -237,21 +267,38 @@ You can run the utility to encrypt NVS partition using the command below. A samp
python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen
.. note:: Encryption key of the following format ``<outdir>/keys/keys-<timestamp>.bin`` is created.
.. note:: Encryption key of the format ``<outdir>/keys/keys-<timestamp>.bin`` is created.
- To generate an encrypted partition using the HMAC-based scheme, the above command can be used alongwith some additional parameters.
- Encrypt by allowing the utility to generate encryption keys and the HMAC-key::
python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --key_protect_hmac --kp_hmac_keygen
.. note:: Encryption key of the format ``<outdir>/keys/keys-<timestamp>.bin`` and HMAC key of the format ``<outdir>/keys/hmac-keys-<timestamp>.bin`` are created.
- Encrypt by allowing the utility to generate encryption keys with user-provided HMAC-key::
python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin
.. note:: You can provide the custom filename for the HMAC key as well as the encryption key as a parameter.
- Encrypt by allowing the utility to generate encryption keys and store it in provided custom filename::
python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --keyfile sample_keys.bin
.. note:: Encryption key of the following format ``<outdir>/keys/sample_keys.bin`` is created.
.. note:: This newly created file having encryption keys in ``keys/`` directory is compatible with NVS key-partition structure. Refer to :ref:`nvs_key_partition` for more details.
.. note::
- Encryption key of the format ``<outdir>/keys/sample_keys.bin`` is created.
- This newly created file having encryption keys in ``keys/`` directory is compatible with NVS key-partition structure. Refer to :ref:`nvs_encr_key_partition` for more details.
- Encrypt by providing the encryption keys as input binary file::
python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --inputkey sample_keys.bin
To Decrypt Encrypted NVS Partition:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Decrypt Encrypted NVS Partition
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Usage**::
@ -259,26 +306,25 @@ To Decrypt Encrypted NVS Partition:
**Positional Arguments**:
+--------------+----------------------------------------------------------------------+
+--------------+---------------------------------------------------------------+
| Parameter | Description |
+==============+======================================================================+
| input | Path to encrypted NVS partition file to parse |
+--------------+----------------------------------------------------------------------+
| key | Path to file having keys for decryption |
+--------------+----------------------------------------------------------------------+
| output | Path to output decrypted binary file |
+--------------+----------------------------------------------------------------------+
+==============+===============================================================+
| ``input`` | Path to encrypted NVS partition file to parse |
+--------------+---------------------------------------------------------------+
| ``key`` | Path to file having keys for decryption |
+--------------+---------------------------------------------------------------+
| ``output`` | Path to output decrypted binary file |
+--------------+---------------------------------------------------------------+
**Optional Arguments**:
+---------------------+--------------------------------------------------------------------+
+------------------------+----------------------------------------------------------------------+
| Parameter | Description |
+=====================+====================================================================+
| -h, --help | Show this help message and exit |
+---------------------+--------------------------------------------------------------------+
| --outdir OUTDIR | Output directory to store files created |
| | (Default: current directory) |
+---------------------+--------------------------------------------------------------------+
+========================+======================================================================+
| ``-h`` / ``--help`` | Show the help message and exit |
+------------------------+----------------------------------------------------------------------+
| ``--outdir OUTDIR`` | Output directory to store file created (Default: current directory) |
+------------------------+----------------------------------------------------------------------+
You can run the utility to decrypt encrypted NVS partition using the command below::
@ -289,24 +335,26 @@ You can also provide the format version number:
- Multipage Blob Support Enabled (Version 2)
Multipage Blob Support Disabled (Version 1):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Multipage Blob Support Disabled (Version 1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can run the utility in this format by setting the version parameter to 1, as shown below. A sample CSV file is provided with the utility::
You can run the utility in this format by setting the version parameter to 1, as shown below. A sample CSV file for the same is provided with the utility::
python nvs_partition_gen.py generate sample_singlepage_blob.csv sample.bin 0x3000 --version 1
Multipage Blob Support Enabled (Version 2):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Multipage Blob Support Enabled (Version 2)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can run the utility in this format by setting the version parameter to 2, as shown below. A sample CSV file is provided with the utility::
You can run the utility in this format by setting the version parameter to 2, as shown below. A sample CSV file for the same is provided with the utility::
python nvs_partition_gen.py generate sample_multipage_blob.csv sample.bin 0x4000 --version 2
.. note:: *Minimum NVS Partition Size needed is 0x3000 bytes.*
.. note::
.. note:: *When flashing the binary onto the device, make sure it is consistent with the application's sdkconfig.*
- Minimum NVS Partition Size needed is 0x3000 bytes.
- When flashing the binary onto the device, make sure it is consistent with the application's sdkconfig.
Caveats

View File

@ -235,6 +235,7 @@ INPUT = \
$(PROJECT_PATH)/components/mqtt/esp-mqtt/include/mqtt_client.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs.h \
$(PROJECT_PATH)/components/nvs_sec_provider/include/nvs_sec_provider.h \
$(PROJECT_PATH)/components/openthread/include/esp_openthread_border_router.h \
$(PROJECT_PATH)/components/openthread/include/esp_openthread_lock.h \
$(PROJECT_PATH)/components/openthread/include/esp_openthread_netif_glue.h \

View File

@ -23,6 +23,7 @@ This section contains reference of the high-level storage APIs. They are based o
fatfs
mass_mfg.rst
nvs_flash
nvs_encryption
nvs_partition_gen.rst
nvs_partition_parse.rst
sdmmc

View File

@ -0,0 +1,199 @@
NVS Encryption
==============
Overview
--------
This guide provides an overview of the NVS Encryption feature. NVS encryption helps to achieve secure storage on the device flash memory.
Data stored in NVS partitions can be encrypted using XTS-AES 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`.
.. only:: SOC_HMAC_SUPPORTED
NVS Encryption can be facilitated by enabling :ref:`CONFIG_NVS_ENCRYPTION` and :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> ``CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC`` or ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` depending on the scheme to be used.
NVS Encryption: Flash Encryption-based Scheme
---------------------------------------------
In this scheme, 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>` becomes a prerequisite for NVS encryption here.
The NVS Encryption is enabled by default when :doc:`Flash Encryption <../../security/flash-encryption>` is enabled. This is done because Wi-Fi 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.
For using NVS encryption using this scheme, the partition table must contain the :ref:`nvs_encr_key_partition`. Two partition tables containing the :ref:`nvs_encr_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 the NVS encryption feature.
.. _nvs_encr_key_partition:
NVS Key Partition
^^^^^^^^^^^^^^^^^
An application requiring NVS encryption support (using the Flash Encryption-based scheme) needs to be compiled with a key-partition of the type `data` and subtype `key`. This partition should be marked as `encrypted` and its size should be the minimum partition size (4KB). Refer to :doc:`Partition Tables <../../api-guides/partition-tables>` for more details. Two additional partition tables which contain the :ref:`nvs_encr_key_partition` are provided under the partition table option (``menuconfig`` > ``Partition Table``). They can be directly used for NVS encryption. The structure of these partitions is depicted below.
.. highlight:: none
::
+-----------+--------------+-------------+----+
| XTS encryption key (32) |
+---------------------------------------------+
| XTS tweak key (32) |
+---------------------------------------------+
| CRC32 (4) |
+---------------------------------------------+
The XTS encryption keys in the :ref:`nvs_encr_key_partition` can be generated in one of the following two ways.
**Generate the keys on {IDF_TARGET_NAME} chip itself**
* 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_encr_key_partition`.
* 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 :component_file:`nvs_flash/include/nvs_flash.h`. New keys are generated and stored only when the respective key partition 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`.
* 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.
.. note:: Please note that ``nvs_keys`` partition must be completely erased before you start the application in this approach. Otherwise the application may generate :c:macro:`ESP_ERR_NVS_CORRUPT_KEY_PART` error code assuming that ``nvs_keys`` partition is not empty and contains malformatted data. You can use the following command for this:
::
parttool.py --port PORT --partition-table-file=PARTITION_TABLE_FILE --partition-table-offset PARTITION_TABLE_OFFSET erase_partition --partition-type=data --partition-subtype=nvs_keys
**Use a pre-generated NVS key partition**
This option will be required by the user when keys in the :ref:`nvs_encr_key_partition` are not generated by the application. The :ref:`nvs_encr_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:
1. Build and flash the partition table
::
idf.py partition-table partition-table-flash
2. Store the keys in the :ref:`nvs_encr_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)
::
parttool.py --port PORT --partition-table-offset PARTITION_TABLE_OFFSET write_partition --partition-name="name of nvs_key partition" --input NVS_KEY_PARTITION_FILE
.. note:: If the device is encrypted in flash encryption development mode and you want to renew the NVS key partition, you need to tell :component_file:`parttool.py <partition_table/parttool.py>` to encrypt the NVS key partition and you also need to give it a pointer to the unencrypted partition table in your build directory (build/partition_table) since the partition table on the device is encrypted, too. You can use the following command:
::
parttool.py --esptool-write-args encrypt --port PORT --partition-table-file=PARTITION_TABLE_FILE --partition-table-offset PARTITION_TABLE_OFFSET write_partition --partition-name="name of nvs_key partition" --input NVS_KEY_PARTITION_FILE
Since 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.
It 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.
.. only:: SOC_HMAC_SUPPORTED
NVS Encryption: HMAC peripheral-based Scheme
--------------------------------------------
In this scheme, the XTS keys required for NVS encryption are derived from an HMAC key programmed in eFuse with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`. Since the encryption keys are derived at runtime, they are not stored anywhere in the flash. Thus, this feature does not require a separate :ref:`nvs_encr_key_partition`.
.. note::
This scheme enables us to achieve secure storage on {IDF_TARGET_NAME} **without enabling flash encryption**.
.. important::
Please take note that this scheme will use one eFuse block for storing the HMAC key required for deriving the encryption keys.
- 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 first checks whether an HMAC key is present at :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`.
.. note::
The valid range for the config :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` is from ``0`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY0`) to ``5`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY5`). By default, the config is set to ``6`` (:cpp:enumerator:`hmac_key_id_t::HMAC_KEY_MAX`), which will have to configured before building the user application.
- If no key is found, a key is generated internally and stored at the eFuse block specified at :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`.
- If a key is found with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`, the same is used for the derivation of the XTS encryption keys.
- If the specified eFuse block is found to be occupied with a key with a purpose other than :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`, an error is thrown.
- The API :cpp:func:`nvs_flash_init` then automatically generates the NVS keys on demand by using the :cpp:func:`nvs_flash_generate_keys_v2` API function provided by the :component_file:`nvs_flash/include/nvs_flash.h`. The same keys can also be used to read the security configurations (see :cpp:func:`nvs_flash_read_security_cfg_v2`) for initializing a custom encrypted NVS partition with help of :cpp:func:`nvs_flash_secure_init_partition`.
- 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_v2` API function or take and populate the NVS security configuration structure :cpp:type:`nvs_sec_cfg_t` with :cpp:func:`nvs_flash_read_security_cfg_v2` and feed them into the above APIs.
.. note:: Users can program their own HMAC key in eFuse block beforehand by using the following command -
::
espefuse.py -p PORT burn_key <BLOCK_KEYN> <hmac_key_file.bin> HMAC_UP
Encrypted Read/Write
--------------------
The same NVS API functions ``nvs_get_*`` or ``nvs_set_*`` can be used for reading of, and writing to an encrypted nvs partition as well.
**Encrypt the default NVS partition**
- To 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 to enable encryption for the default NVS partition depending on the scheme being used (set by :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME`).
- For the flash encryption-based scheme, the first :ref:`nvs_encr_key_partition` found is used to generate the encryption keys while for the HMAC one, keys are generated using the HMAC key burnt in eFuse at :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` (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.
**Encrypt a custom NVS partition**
- To 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`.
- When :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.
1. Populate the NVS security configuration structure :cpp:type:`nvs_sec_cfg_t`
* For the Flash Encryption-based scheme -
- Find key partition and NVS data partition using ``esp_partition_find*`` API functions.
- Populate the :cpp:type:`nvs_sec_cfg_t` struct using the :cpp:func:`nvs_flash_read_security_cfg` or :cpp:func:`nvs_flash_generate_keys` API functions.
.. only:: SOC_HMAC_SUPPORTED
* For the HMAC-based scheme -
- Set the scheme (see :cpp:enum:`nvs_sec_scheme_id_t`) and the scheme-specific data (to :cpp:enum:`hmac_key_id_t`) with the :cpp:type:`nvs_sec_scheme_t` struct and register the HMAC-based scheme with the API :cpp:func:`nvs_sec_provider_register_hmac`.
- Populate the :cpp:type:`nvs_sec_cfg_t` struct using the :cpp:func:`nvs_flash_read_security_cfg_v2` or :cpp:func:`nvs_flash_generate_keys_v2` API functions.
.. code-block:: c
nvs_sec_cfg_t cfg = {};
nvs_sec_scheme_t *sec_scheme_handle = NULL;
nvs_sec_config_hmac_t sec_scheme_cfg = {};
hmac_key_id_t hmac_key = HMAC_KEY0;
sec_scheme_cfg.hmac_key_id = hmac_key;
ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle);
if (ret != ESP_OK) {
return ret;
}
ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg);
if (ret != ESP_OK) {
if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) {
ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate NVS encr-keys!");
return ret;
}
}
ESP_LOGE(TAG, "Failed to read NVS security cfg!");
return ret;
}
2. Initialise NVS flash partition using the :cpp:func:`nvs_flash_secure_init` or :cpp:func:`nvs_flash_secure_init_partition` API functions.
3. Open a namespace using the :cpp:func:`nvs_open` or :cpp:func:`nvs_open_from_partition` API functions.
4. Perform NVS read/write operations using ``nvs_get_*`` or ``nvs_set_*``.
5. Deinitialise an NVS partition using :cpp:func:`nvs_flash_deinit`.
.. only:: SOC_HMAC_SUPPORTED
.. note:: While using the HMAC-based scheme, the above workflow can be used without enabling any of the config options for NVS Encryption - :ref:`CONFIG_NVS_ENCRYPTION`, :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` and :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` to encrypt the default as well as custom NVS partitions with :cpp:func:`nvs_flash_secure_init` API.
NVS Security Provider
---------------------
The component :component:`nvs_sec_provider` stores all the implementation-specific code for the NVS encryption schemes and would also accomodate any future schemes. This component acts as an interface to the :component:`nvs_flash` component for the handling of encryption keys. :component:`nvs_sec_provider` has a configuration menu of its own, based on which the selected security scheme and the corresponding settings are registered for the :component:`nvs_flash` component.
.. only:: SOC_HMAC_SUPPORTED
This component offers factory functions with which a particular security scheme can be registered without having to worry about the APIs to generate and read the encryption keys (e.g. :cpp:func:`nvs_sec_provider_register_hmac`). Refer to the :example:`security/nvs_encryption_hmac` example for API usage.
API Reference
-------------
.. include-build-file:: inc/nvs_sec_provider.inc

View File

@ -66,7 +66,13 @@ In general, all iterators obtained via :cpp:func:`nvs_entry_find` have to be rel
Security, Tampering, and Robustness
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
NVS is not directly compatible with the {IDF_TARGET_NAME} flash encryption system. However, data can still be stored in encrypted form if NVS encryption is used together with {IDF_TARGET_NAME} flash encryption. Please refer to :ref:`nvs_encryption` for more details.
.. only:: not SOC_HMAC_SUPPORTED
NVS is not directly compatible with the {IDF_TARGET_NAME} flash encryption system. However, data can still be stored in encrypted form if NVS encryption is used together with {IDF_TARGET_NAME} flash encryption. Please refer to :doc:`NVS Encryption <nvs_encryption>` for more details.
.. only:: SOC_HMAC_SUPPORTED
NVS is not directly compatible with the {IDF_TARGET_NAME} flash encryption system. However, data can still be stored in encrypted form if NVS encryption is used together with {IDF_TARGET_NAME} flash encryption or with the help of the HMAC peripheral. Please refer to :doc:`NVS Encryption <nvs_encryption>` for more details.
If 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.
@ -78,86 +84,7 @@ The library does try to recover from conditions when flash memory is in an incon
NVS Encryption
--------------
Data stored in NVS partitions can be encrypted using XTS-AES 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.
The NVS Encryption is enabled by default when :doc:`Flash Encryption <../../security/flash-encryption>` is enabled. This is done because Wi-Fi 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.
For 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.
.. _nvs_key_partition:
NVS Key Partition
^^^^^^^^^^^^^^^^^
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` and its size should be the minimum partition size (4KB). 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.
.. highlight:: none
::
+-----------+--------------+-------------+----+
| XTS encryption key (32) |
+---------------------------------------------+
| XTS tweak key (32) |
+---------------------------------------------+
| CRC32 (4) |
+---------------------------------------------+
The XTS encryption keys in the :ref:`nvs_key_partition` can be generated in one of the following two ways.
1. Generate the keys on the ESP chip:
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`. 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 :component_file:`nvs_flash/include/nvs_flash.h`. New keys are generated and stored only when the respective key partition 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`.
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.
.. note:: Please note that `nvs_keys` partition must be completely erased before you start the application in this approach. Otherwise the application may generate :c:macro:`ESP_ERR_NVS_CORRUPT_KEY_PART` error code assuming that `nvs_keys` partition is not empty and contains malformatted data. You can use the following command for this:
::
parttool.py --port PORT --partition-table-file=PARTITION_TABLE_FILE --partition-table-offset PARTITION_TABLE_OFFSET erase_partition --partition-type=data --partition-subtype=nvs_keys
2. Use pre-generated key partition:
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:
i) Build and flash the partition table
::
idf.py partition-table partition-table-flash
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)
::
parttool.py --port PORT --partition-table-offset PARTITION_TABLE_OFFSET write_partition --partition-name="name of nvs_key partition" --input NVS_KEY_PARTITION_FILE
.. note:: If the device is encrypted in flash encryption development mode and you want to renew the NVS key partition, you need to tell :component_file:`parttool.py <partition_table/parttool.py>` to encrypt the NVS key partition and you also need to give it a pointer to the unencrypted partition table in your build directory (build/partition_table) since the partition table on the device is encrypted, too. You can use the following command:
::
parttool.py --esptool-write-args encrypt --port PORT --partition-table-file=PARTITION_TABLE_FILE --partition-table-offset PARTITION_TABLE_OFFSET write_partition --partition-name="name of nvs_key partition" --input NVS_KEY_PARTITION_FILE
Since 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.
It 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.
Encrypted Read/Write
^^^^^^^^^^^^^^^^^^^^
The same NVS API functions ``nvs_get_*`` or ``nvs_set_*`` can be used for reading of, and writing to an encrypted nvs partition as well.
**Encrypt the default NVS partition:**
To 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.
**Encrypt a custom NVS partition:**
To 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`.
When :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.
1. Find key partition and NVS data partition using ``esp_partition_find*`` API functions.
2. Populate the :cpp:type:`nvs_sec_cfg_t` struct using the :cpp:func:`nvs_flash_read_security_cfg` or :cpp:func:`nvs_flash_generate_keys` API functions.
3. Initialise NVS flash partition using the :cpp:func:`nvs_flash_secure_init` or :cpp:func:`nvs_flash_secure_init_partition` API functions.
4. Open a namespace using the :cpp:func:`nvs_open` or :cpp:func:`nvs_open_from_partition` API functions.
5. Perform NVS read/write operations using ``nvs_get_*`` or ``nvs_set_*``.
6. Deinitialise an NVS partition using :cpp:func:`nvs_flash_deinit`.
Please refer to the :doc:`NVS Encryption <nvs_encryption>` guide for more details.
NVS Partition Generator Utility
-------------------------------

View File

@ -721,7 +721,7 @@ You can also use the following SPI flash API functions:
- :cpp:func:`esp_flash_read` to read raw (encrypted) data which will not be decrypted
- :cpp:func:`esp_flash_read_encrypted` to read and decrypt data
Data stored using the Non-Volatile Storage (NVS) API is always stored and read decrypted from the perspective of flash encryption. It is up to the library to provide encryption feature if required. Refer to :ref:`NVS Encryption <nvs_encryption>` for more details.
Data stored using the Non-Volatile Storage (NVS) API is always stored and read decrypted from the perspective of flash encryption. It is up to the library to provide encryption feature if required. Refer to :doc:`NVS Encryption <../api-reference/storage/nvs_encryption>` for more details.
Writing to Encrypted Flash
@ -809,7 +809,7 @@ Key Points About Flash Encryption
- Flash access is transparent via the flash cache mapping feature of {IDF_TARGET_NAME} - any flash regions which are mapped to the address space will be transparently decrypted when read.
Some data partitions might need to remain unencrypted for ease of access or might require the use of flash-friendly update algorithms which are ineffective if the data is encrypted. NVS partitions for non-volatile storage cannot be encrypted since the NVS library is not directly compatible with flash encryption. For details, refer to :ref:`NVS Encryption <nvs_encryption>`.
Some data partitions might need to remain unencrypted for ease of access or might require the use of flash-friendly update algorithms which are ineffective if the data is encrypted. NVS partitions for non-volatile storage cannot be encrypted since the NVS library is not directly compatible with flash encryption. For details, refer to :doc:`NVS Encryption <../api-reference/storage/nvs_encryption>`.
- If flash encryption might be used in future, the programmer must keep it in mind and take certain precautions when writing code that :ref:`uses encrypted flash <reading-writing-content>`.
@ -834,7 +834,7 @@ Flash encryption protects firmware against unauthorised readout and modification
- Flash encryption is only as strong as the key. For this reason, we recommend keys are generated on the device during first boot (default behaviour). If generating keys off-device, ensure proper procedure is followed and don't share the same key between all production devices.
- Not all data is stored encrypted. If storing data on flash, check if the method you are using (library, API, etc.) supports flash encryption.
- Flash encryption does not prevent an attacker from understanding the high-level layout of the flash. This is because the same AES key is used for every pair of adjacent 16 byte AES blocks. When these adjacent 16 byte blocks contain identical content (such as empty or padding areas), these blocks will encrypt to produce matching pairs of encrypted blocks. This may allow an attacker to make high-level comparisons between encrypted devices (i.e. to tell if two devices are probably running the same firmware version).
:esp32: - For the same reason, an attacker can always tell when a pair of adjacent 16 byte blocks (32 byte aligned) contain two identical 16 byte sequences. Keep this in mind if storing sensitive data on the flash, design your flash storage so this doesn't happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). :ref:`NVS Encryption <nvs_encryption>` deals with this and is suitable for many uses.
:esp32: - For the same reason, an attacker can always tell when a pair of adjacent 16 byte blocks (32 byte aligned) contain two identical 16 byte sequences. Keep this in mind if storing sensitive data on the flash, design your flash storage so this doesn't happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). :doc:`NVS Encryption <../api-reference/storage/nvs_encryption>` deals with this and is suitable for many uses.
- Flash encryption alone may not prevent an attacker from modifying the firmware of the device. To prevent unauthorised firmware from running on the device, use flash encryption in combination with :doc:`Secure Boot <secure-boot-v2>`.
.. _flash-encryption-and-secure-boot:

View File

@ -205,7 +205,12 @@ Secure storage refers to the application specific data that can be stored in a s
ESP-IDF provides "NVS (Non-volatile Storage)" management component which allows encrypted data partitions. This feature is tied with the platform :ref:`flash_enc-guide` feature described earlier.
Please refer to the :ref:`NVS Encryption <nvs_encryption>` for detailed documentation on the working and instructions to enable this feature.
.. only:: SOC_HMAC_SUPPORTED
This feature can also be used independent of the platform :ref:`flash_enc-guide` feature with the help of the {IDF_TARGET_NAME} HMAC peripheral.
Please refer to the :doc:`NVS Encryption <../api-reference/storage/nvs_encryption>` for detailed documentation on the working and instructions to enable this feature.
.. important::

View File

@ -23,6 +23,7 @@
fatfs
mass_mfg.rst
nvs_flash
nvs_encryption
nvs_partition_gen.rst
nvs_partition_parse.rst
sdmmc

View File

@ -0,0 +1 @@
.. include:: ../../../en/api-reference/storage/nvs_encryption.rst

View File

@ -11,14 +11,15 @@ This utility is designed to create instances of factory NVS partition images on
Please note that this utility only creates manufacturing binary images which then need to be flashed onto your devices using:
- `esptool.py`_
- `Flash Download tool <https://www.espressif.com/en/support/download/other-tools?keys=flash+download+tools>`_ (available on Windows only).Just download it, unzip, and follow the instructions inside the *doc* folder.
- `Flash Download tool <https://www.espressif.com/en/support/download/other-tools?keys=flash+download+tools>`_ (available on Windows only)
- Download and unzip it, and follow the instructions inside the *doc* folder.
- Direct flash programming using custom production tools.
Prerequisites
-------------
**This utility is dependent on esp-idf's NVS partition utility.**
**This utility is dependent on ESP-IDF's NVS Partition Generator Utility.**
* Operating System requirements:
- Linux / MacOS / Windows (standard distributions)
@ -30,7 +31,7 @@ Prerequisites
Before using this utility, please make sure that:
- The path to Python is added to the PATH environment variable.
- You have installed the packages from `requirement.txt`, the file in the root of the esp-idf directory.
- You have installed the packages from `requirement.txt`, the file in the root of the ESP-IDF directory.
Workflow
@ -66,7 +67,7 @@ The data in the configuration file has the following format (the `REPEAT` tag is
Each line should have three parameters: ``key,type,encoding``, separated by a comma.
If the ``REPEAT`` tag is present, the value corresponding to this key in the master value CSV file will be the same for all devices.
*Please refer to README of the NVS Partition Generator utility for detailed description of each parameter.*
*Please refer to README of the NVS Partition Generator Utility for detailed description of each parameter.*
Below is a sample example of such a configuration file::
@ -134,31 +135,32 @@ Running the utility
**Optional Arguments**:
+-----+------------+----------------------------------------------------------------------+
+-----+------------------------+----------------------------------------------------------------------+
| No. | Parameter | Description |
+=====+============+======================================================================+
| 1 | -h, --help | show this help message and exit |
+-----+------------+----------------------------------------------------------------------+
+=====+========================+======================================================================+
| 1 | ``-h`` / ``--help`` | Show the help message and exit |
+-----+------------------------+----------------------------------------------------------------------+
**Commands**:
Run mfg_gen.py {command} -h for additional help
+-----+--------------+--------------------------------------------------------------------+
+-----+------------------+--------------------------------------------------------------------+
| No. | Parameter | Description |
+=====+==============+====================================================================+
| 1 | generate | Generate NVS partition |
+-----+--------------+--------------------------------------------------------------------+
| 2 | generate-key | Generate keys for encryption |
+-----+--------------+--------------------------------------------------------------------+
+=====+==================+====================================================================+
| 1 | ``generate`` | Generate NVS partition |
+-----+------------------+--------------------------------------------------------------------+
| 2 | ``generate-key`` | Generate keys for encryption |
+-----+------------------+--------------------------------------------------------------------+
**To generate factory images for each device (Default):**
**Usage**::
python mfg_gen.py generate [-h] [--fileid FILEID] [--version {1,2}] [--keygen]
[--keyfile KEYFILE] [--inputkey INPUTKEY]
[--outdir OUTDIR]
[--inputkey INPUTKEY] [--outdir OUTDIR]
[--key_protect_hmac] [--kp_hmac_keygen]
[--kp_hmac_keyfile KP_HMAC_KEYFILE] [--kp_hmac_inputkey KP_HMAC_INPUTKEY]
conf values prefix size
**Positional Arguments**:
@ -166,38 +168,47 @@ Running the utility
+--------------+----------------------------------------------------------------------+
| Parameter | Description |
+==============+======================================================================+
| conf | Path to configuration csv file to parse |
| ``conf`` | Path to configuration csv file to parse |
+--------------+----------------------------------------------------------------------+
| values | Path to values csv file to parse |
| ``values`` | Path to values csv file to parse |
+--------------+----------------------------------------------------------------------+
| prefix | Unique name for each output filename prefix |
+-----+--------------+----------------------------------------------------------------+
| size | Size of NVS partition in bytes |
| | (must be multiple of 4096) |
| ``prefix`` | Unique name for each output filename prefix |
+--------------+----------------------------------------------------------------------+
| ``size`` | Size of NVS partition in bytes (must be multiple of 4096) |
+--------------+----------------------------------------------------------------------+
**Optional Arguments**:
+---------------------+--------------------------------------------------------------------+
+---------------------------------------------+-------------------------------------------------------------------------------+
| Parameter | Description |
+=====================+====================================================================+
| -h, --help | show this help message and exit |
+---------------------+--------------------------------------------------------------------+
| --fileid FILEID | Unique file identifier(any key in values file) |
| | for each filename suffix (Default: numeric value(1,2,3...) |
+---------------------+--------------------------------------------------------------------+
| --version {1,2} | Set multipage blob version. |
+=============================================+===============================================================================+
| ``-h`` / ``--help`` | Show the help message and exit |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--fileid FILEID`` | Unique file identifier (any key in values file) |
| | for each filename suffix (Default: numeric value(1,2,3...)) |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--version {1,2}`` | Set multipage blob version. (Default: Version 2) |
| | |
| | Version 1 - Multipage blob support disabled. |
| | |
| | Version 2 - Multipage blob support enabled. |
| | Default: Version 2 |
+---------------------+--------------------------------------------------------------------+
| --keygen | Generates key for encrypting NVS partition |
+---------------------+--------------------------------------------------------------------+
| --inputkey INPUTKEY | File having key for encrypting NVS partition |
+---------------------+--------------------------------------------------------------------+
| --outdir OUTDIR | Output directory to store files created |
| | (Default: current directory) |
+---------------------+--------------------------------------------------------------------+
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--keygen`` | Generates key for encrypting NVS partition |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--inputkey INPUTKEY`` | File having key for encrypting NVS partition |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--outdir OUTDIR`` | Output directory to store files created (Default: current directory) |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC |
| | peripheral is used; else the default scheme based on Flash Encryption |
| | is used |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file |
+---------------------------------------------+-------------------------------------------------------------------------------+
| ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys |
+---------------------------------------------+-------------------------------------------------------------------------------+
You can run the utility to generate factory images for each device using the command below. A sample CSV file is provided with the utility::
@ -213,7 +224,21 @@ You can run the utility to encrypt factory images for each device using the comm
python mfg_gen.py generate samples/sample_config.csv samples/sample_values_singlepage_blob.csv Sample 0x3000 --keygen
.. note:: Encryption key of the following format ``<outdir>/keys/keys-<prefix>-<fileid>.bin`` is created. This newly created file having encryption keys in ``keys/`` directory is compatible with NVS key-partition structure. Refer to :ref:`nvs_key_partition` for more details.
.. note:: Encryption key of the following format ``<outdir>/keys/keys-<prefix>-<fileid>.bin`` is created. This newly created file having encryption keys in ``keys/`` directory is compatible with NVS key-partition structure. Refer to :ref:`nvs_encr_key_partition` for more details.
- To generate an encrypted image using the HMAC-based scheme, the above command can be used alongwith some additional parameters.
- Encrypt by allowing the utility to generate encryption keys and the HMAC-key::
python mfg_gen.py generate samples/sample_config.csv samples/sample_values_singlepage_blob.csv Sample 0x3000 --keygen --key_protect_hmac --kp_hmac_keygen
.. note:: Encryption key of the format ``<outdir>/keys/keys-<timestamp>.bin`` and HMAC key of the format ``<outdir>/keys/hmac-keys-<timestamp>.bin`` are created.
- Encrypt by allowing the utility to generate encryption keys with user-provided HMAC-key::
python mfg_gen.py generate samples/sample_config.csv samples/sample_values_singlepage_blob.csv Sample 0x3000 --keygen --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin
.. note:: You can provide the custom filename for the HMAC key as well as the encryption key as a parameter.
- Encrypt by providing the encryption keys as input binary file::
@ -225,16 +250,25 @@ You can run the utility to encrypt factory images for each device using the comm
python mfg_gen.py generate-key [-h] [--keyfile KEYFILE] [--outdir OUTDIR]
**Optional Arguments**:
+--------------------+----------------------------------------------------------------------+
+---------------------------------------------+-----------------------------------------------------------------------------------+
| Parameter | Description |
+====================+======================================================================+
| -h, --help | show this help message and exit |
+--------------------+----------------------------------------------------------------------+
| --keyfile KEYFILE | Path to output encryption keys file |
+--------------------+----------------------------------------------------------------------+
| --outdir OUTDIR | Output directory to store files created. |
| | (Default: current directory) |
+--------------------+----------------------------------------------------------------------+
+=============================================+===================================================================================+
| ``-h`` / ``--help`` | Show the help message and exit |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--keyfile KEYFILE`` | Path to output encryption keys file |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--outdir OUTDIR`` | Output directory to store files created. (Default: current directory) |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC |
| | peripheral is used; else the default scheme based on Flash Encryption |
| | is used |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file |
+---------------------------------------------+-----------------------------------------------------------------------------------+
| ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys |
+---------------------------------------------+-----------------------------------------------------------------------------------+
You can run the utility to generate only encryption keys using the command below::
@ -242,6 +276,20 @@ You can run the utility to generate only encryption keys using the command below
.. note:: Encryption key of the following format ``<outdir>/keys/keys-<timestamp>.bin`` is created. Timestamp format is: ``%m-%d_%H-%M``. To provide custom target filename use the --keyfile argument.
For generating encryption key for the HMAC-based scheme, the following commands can be used:
- Generate the HMAC key and the NVS encryption keys::
python mfg_gen.py generate-key --key_protect_hmac --kp_hmac_keygen
.. note:: Encryption key of the format ``<outdir>/keys/keys-<timestamp>.bin`` and HMAC key of the format ``<outdir>/keys/hmac-keys-<timestamp>.bin`` are created.
- Generate the NVS encryption keys, given the HMAC-key::
python mfg_gen.py generate-key --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin
.. note:: You can provide the custom filename for the HMAC key as well as the encryption key as a parameter.
Generated encryption key binary file can further be used to encrypt factory images created on the per device basis.
The default numeric value: 1,2,3... of the ``fileid`` argument corresponds to each line bearing device instance values in the master value CSV file.