esp-idf/examples/protocols/mqtt/ssl_ds
Angus Gratton 66fb5a29bb Whitespace: Automated whitespace fixes (large commit)
Apply the pre-commit hook whitespace fixes to all files in the repo.

(Line endings, blank lines at end of file, trailing whitespace)
2020-11-11 07:36:35 +00:00
..
main Whitespace: Automated whitespace fixes (large commit) 2020-11-11 07:36:35 +00:00
CMakeLists.txt cmake: Apply cmakelint fixes 2020-11-11 07:36:35 +00:00
configure_ds.py esp32s2-ssl_ds: Use CLI interface for espefuse in configure_ds.py 2020-10-22 17:25:23 +05:30
partitions.csv Whitespace: Automated whitespace fixes (large commit) 2020-11-11 07:36:35 +00:00
README.md esp32s2-ssl_ds: Use CLI interface for espefuse in configure_ds.py 2020-10-22 17:25:23 +05:30
sdkconfig.defaults Whitespace: Automated whitespace fixes (large commit) 2020-11-11 07:36:35 +00:00

| Supported Targets | ESP32-S2 |

ESP-MQTT SSL Mutual Authentication with Digital Signature

(See the README.md file in the upper level 'examples' directory for more information about examples.)

Espressif's ESP32-S2 MCU has a built-in Digital Signature (DS) Peripheral, which provides hardware acceleration for RSA signature. More details can be found at Digital Signature with ESP-TLS.

This example connects to the broker test.mosquitto.org using ssl transport with client certificate(RSA) and as a demonstration subscribes/unsubscribes and sends a message on certain topic.The RSA signature operation required in the ssl connection is performed with help of the Digital Signature (DS) peripheral. (Please note that the public broker is maintained by the community so may not be always available, for details please visit http://test.mosquitto.org)

It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker.

How to use example

Hardware Required

This example can be executed on any ESP32-S2 board (which has a built-in DS peripheral), the only required interface is WiFi and connection to internet.

Configure the project

1) Selecting the target

As the project is to be built for the target ESP32-S2, it should be selected with the following command

idf.py set-target esp32s2

More detials can be found at Selecting the target.

2) Generate your client key and certificate

Navigate to the main directory

cd main

Generate a client key and a CSR. When you are generating the CSR, do not use the default values. At a minimum, the CSR must include the Country, Organisation and Common Name fields.

openssl genrsa -out client.key
openssl req -out client.csr -key client.key -new

Paste the generated CSR in the Mosquitto test certificate signer, click Submit and copy the downloaded client.crt in the main directory.

Please note, that the supplied file client.crt in the main directory is only a placeholder for your client certificate (i.e. the example "as is" would compile but would not connect to the broker)

3) Configure the DS peripheral

  • The DS peripheral can be configured with the python script configure_ds.py by executing the following command
    python configure_ds.py --port /* USB COM port */ --private_key /* RSA priv key */

In the command USB COM port is nothing but the serial port to which the ESP32-S2 chip is connected. see check serial port for more details. RSA private key is nothing but the client private key ( RSA ) generated in Step 2.

4) Connection cofiguration

  • Open the project configuration menu (idf.py menuconfig)
  • Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in examples/protocols/README.md for more details.
  • When using Make build system, set Default serial port under Serial flasher config.

Build and Flash

Build the project and flash it to the board, then run monitor tool to view serial output:

idf.py -p PORT flash monitor

(To exit the serial monitor, type Ctrl-].)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

Example Output

I (3714) event: sta ip: 192.168.0.139, mask: 255.255.255.0, gw: 192.168.0.2
I (3714) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (3964) MQTT_CLIENT: Sending MQTT CONNECT message, type: 1, id: 0000
I (4164) MQTTS_EXAMPLE: MQTT_EVENT_CONNECTED
I (4174) MQTTS_EXAMPLE: sent publish successful, msg_id=41464
I (4174) MQTTS_EXAMPLE: sent subscribe successful, msg_id=17886
I (4174) MQTTS_EXAMPLE: sent subscribe successful, msg_id=42970
I (4184) MQTTS_EXAMPLE: sent unsubscribe successful, msg_id=50241
I (4314) MQTTS_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=41464
I (4484) MQTTS_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=17886
I (4484) MQTTS_EXAMPLE: sent publish successful, msg_id=0
I (4684) MQTTS_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=42970
I (4684) MQTTS_EXAMPLE: sent publish successful, msg_id=0
I (4884) MQTT_CLIENT: deliver_publish, message_length_read=19, message_length=19
I (4884) MQTTS_EXAMPLE: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA=data
I (5194) MQTT_CLIENT: deliver_publish, message_length_read=19, message_length=19
I (5194) MQTTS_EXAMPLE: MQTT_EVENT_DATA
TOPIC=/topic/qos0
DATA=data

configure_ds.py

The script configure_ds.py is used for configuring the DS peripheral on the ESP32-S2 SoC. The steps in the script are based on technical details of certain operations in the Digital Signature calculation, which can be found at Digital Signature Section of ESP32-S2 TRM

The configuration script performs the following steps -

  1. Take the client private key ( RSA key ) as input. (*required parameter for the script) can be provided with
    python configure_ds.py --private-key /* path to client (rsa) prv key */
  1. Randomly Calculate the HMAC_KEY and the initialization vector(IV).Then calculate the encrypted private key parameters from client private key (step i) and newly generated parameters. These encrypted private key parameters are required for the DS peripheral to perform the Digital Signature operation.

  2. Store HMAC_KEY in one of the efuse key blocks (in the hardware). The ID of the efuse key block ( should be in range 1-5) can be provided with the following option. ( default value of 1 is used if not provided),

    python configure_ds.py --efuse_key_id /* key id in range 1-5 */

Currently for development purposes, the HMAC_KEY is stored in the efuse key block without read protection so that read operation can be performed on the same key block.

You can burn (write) a key on an efuse key block only once.Please use a different block ID, if you want to use a different HMAC_KEY for the DS operation.

  1. Create an NVS partition of the name pre_prov.csv (in esp_ds_data folder) which contains the required encrypted private key parameters. A bin file of the nvs partition (pre_prov.bin) is also created and is flashed on the device. As we have added a custom partition, the example is set to use the custom partition table by adding the required option in sdkconfig.defaults.

  2. (optional) The script can be made to print the summary of the efuse on the chip by providing the following option.When this option is enabled, no other operations in the script are performed.

    python configure_ds.py --summary

A list of all the supported options in the script can be obtained by executing python configure_ds.py --help.