.. _espsecure:

espsecure.py
============

``espsecure.py`` is a tool for manipulating data that relates to the secure boot and flash encryption features of ESP32 and later Espressif chips.

For more details, see the ESP-IDF documentation which explains this tool and how to use it to enable the relevant features:

*  `Secure Boot <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v2.html>`_
*  `Flash Encryption <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/flash-encryption.html>`_

.. _hsm_signing:

Remote Signing using an external HSM
------------------------------------

An external Hardware Security Module (HSM) can be used for remote signing of images in secure boot v2 scheme.

You must install ``esptool.py`` package with the ``hsm`` extra using the command ``pip install 'esptool[hsm]'`` to use this feature. ``esp_hsm_sign`` provides a PKCS #11 interface to communicate with the external HSM and is integrated in ``espsecure.py``.

The following command should be used to get an image signed using an external HSM. ::

    python espsecure.py sign_data --version 2 --hsm --hsm-config <hsm_config_file> --output <signed_image> <datafile>

The above command first extracts the public key from the HSM, generates a signature for an image using the HSM, and then creates a signature block and appends it to the image to generate a signed image.

If the public key is not stored in the external HSM, you can specify the ``--pub-key`` argument to supply the public key. ::

    python espsecure.py sign_data --version 2 --hsm --hsm-config <hsm_config_file> --pub-key <public_key> --output <signed_image> <datafile>

.. note::
    In case you are using ESP-IDF, then an unsigned application can be generated by disabling ``CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES`` configuration option in the project settings.

Verifying the Signed Image
~~~~~~~~~~~~~~~~~~~~~~~~~~

Once the signed image is generated, we can verify it using the following command: ::

    python espsecure.py verify_signature --version 2 --hsm --hsm-config <hsm_config_file> <signed_image>

If the public key is not stored in the external HSM, you can specify the ``--keyfile`` argument to supply the public key. ::

    python espsecure.py verify_signature --version 2 --keyfile <public_key> <signed_image>


HSM config file
~~~~~~~~~~~~~~~

An HSM config file is required with the fields (``pkcs11_lib``, ``credentials``, ``slot``, ``label``, ``label_pubkey``)
populated corresponding to the HSM used.

To access an HSM token of a selected slot, you will also need to pass in the token User PIN and thus you will be prompted to type in the User PIN.
Alternatively, you could also add a ``credentials`` field in the HSM config file to store the (plaintext) User PIN to automate the signing workflow.

Below is a sample HSM config file (``hsm_config.ini``) for using `SoftHSMv2 <https://github.com/opendnssec/SoftHSMv2>`_ as an external HSM: ::

    # hsm_config.ini

    # Config file for the external Hardware Security Module
    # to be used to generate signature.

    [hsm_config]

    # PKCS11 shared object/library module of the HSM vendor
    pkcs11_lib = /usr/local/lib/softhsm/libsofthsm2.so

    # HSM login credentials
    credentials = 1234

    # Slot number to be used
    slot = 1108821954

    # Label of the object used to store the private key
    label = Private Key for Digital Signature

    # Label of the object used to store corresponding public key
    # label_pubkey is the same as label if the label for public key
    # is not explicitly specified while key-pair generation.
    label_pubkey = Public Key for Digital Signature
