1Hash-based Message Authentication Code (HMAC) 2============================================= 3 4The HMAC (Hash-based Message Authentication Code) module provides hardware acceleration for SHA256-HMAC generation using a key burned into an eFuse block. 5HMACs work with pre-shared secret keys and provide authenticity and integrity to a message. 6 7For more detailed information on the application workflow and the HMAC calculation process, see *{IDF_TARGET_NAME} Technical Reference Manual* > *HMAC Accelerator (HMAC)* [`PDF <{IDF_TARGET_TRM_EN_URL}#hmac>`__]. 8 9Generalized Application Scheme 10------------------------------ 11Let there be two parties, A and B. They want to verify the authenticity and integrity of messages sent between each other. 12Before they can start sending messages, they need to exchange the secret key via a secure channel. 13To verify A's messages, B can do the following: 14 15- A calculates the HMAC of the message it wants to send. 16- A sends the message and the HMAC to B. 17- B calculates HMAC of the received message itself. 18- B checks wether the received and calculated HMACs match. 19 If they do match, the message is authentic. 20 21However, the HMAC itself isn't bound to this use case. 22It can also be used for challenge-response protocols supporting HMAC or as a key input for further security modules (see below), etc. 23 24HMAC on the {IDF_TARGET_NAME} 25----------------------------- 26On the {IDF_TARGET_NAME}, the HMAC module works with a secret key burnt into the eFuses. 27This eFuse key can be made completely inaccessible for any resources outside the cryptographic modules, thus avoiding key leakage. 28 29Furthermore, the {IDF_TARGET_NAME} has three different application scenarios for its HMAC module: 30 31#. HMAC is generated for software use 32#. HMAC is used as a key for the Digital Signature (DS) module 33#. HMAC is used for enabling the soft-disabled JTAG interface 34 35The first mode is also called *Upstream* mode, while the last two modes are also called *Downstream* modes. 36 37eFuse Keys for HMAC 38^^^^^^^^^^^^^^^^^^^ 39Six physical eFuse blocks can be used as keys for the HMAC module: block 4 up to block 9. 40The enum :cpp:enum:`hmac_key_id_t` in the API maps them to `HMAC_KEY0 ... HMAC_KEY5`. 41Each key has a corresponding eFuse parameter *key purpose* determining for which of the three HMAC application scenarios (see below) the key may be used: 42 43.. list-table:: 44 :widths: 15 70 45 :header-rows: 1 46 47 * - Key Purpose 48 - Application Scenario 49 * - 8 50 - HMAC generated for software use 51 * - 7 52 - HMAC used as a key for the Digital Signature (DS) module 53 * - 6 54 - HMAC used for enabling the soft-disabled JTAG interface 55 * - 5 56 - HMAC both as a key for the DS module and for enabling JTAG 57 58This is to prevent the usage of a key for a different function than originally intended. 59 60To calculate an HMAC, the software has to provide the ID of the key block containing the secret key as well as the *key purpose* (see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Controller (eFuse)* [`PDF <{IDF_TARGET_TRM_EN_URL}#efuse>`__]). 61Before the HMAC key calculation, the HMAC module looks up the purpose of the provided key block. 62The calculation only proceeds if the provided key purpose matches the purpose stored in the eFuses of the key block provided by the ID. 63 64HMAC Generation for Software 65^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 66Key Purpose value: 8 67 68In this case, the HMAC is given out to the software (e.g. to authenticate a message). 69 70The API to calculate the HMAC is :cpp:func:`esp_hmac_calculate`. 71Only the message, message length and the eFuse key block ID have to be provided to that function. 72The rest, like setting the key purpose, is done automatically. 73 74HMAC for Digital Signature 75^^^^^^^^^^^^^^^^^^^^^^^^^^ 76Key Purpose values: 7, 5 77 78The HMAC can be used as a key derivation function to decrypt private key parameters which are used by the Digital Signature module. 79A standard message is used by the hardware in that case. 80The user only needs to provide the eFuse key block and purpose on the HMAC side (additional parameters are required for the Digital Signature component in that case). 81Neither the key nor the actual HMAC are ever exposed to outside the HMAC module and DS component. 82The calculation of the HMAC and its hand-over to the DS component happen internally. 83 84For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. 85 86HMAC for Enabling JTAG 87^^^^^^^^^^^^^^^^^^^^^^ 88Key Purpose values: 6, 5 89 90The third application is using the HMAC as a key to enable JTAG if it was soft-disabled before. 91Following is the procedure to re-enable the JTAG 92 93Setup 94 951. Generate a 256-bit HMAC secret key to use for JTAG re-enable. 962. Write the key to an eFuse block with key purpose HMAC_DOWN_ALL (5) or HMAC_DOWN_JTAG (6). This can be done using the ets_efuse_write_key() function in the firmware or using espefuse.py from the host. 973. Configure the eFuse key block to be read protected using the esp_efuse_set_read_protect(), so that software cannot read back the value. 984. Burn the "soft JTAG disable" bit by esp_efuse_write_field_bit(ESP_EFUSE_SOFT_DIS_JTAG). This will permanently disable JTAG unless the correct key value is provided by software. 99 100JTAG enable 101 1021. The key to re-enable JTAG is the output of the HMAC-SHA256 function using the secret key in eFuse and 32 0x00 bytes as the message. 1032. Pass this key value when calling the :cpp:func:`esp_hmac_jtag_enable` function from the firmware. 1043. To re-disable JTAG in the firmware, reset the system or call :cpp:func:`esp_hmac_jtag_disable`. 105 106For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *HMAC Accelerator (HMAC)* [`PDF <{IDF_TARGET_TRM_EN_URL}#hmac>`__]. 107 108 109Application Outline 110------------------- 111 112Following code is an outline of how to set an eFuse key and then use it to calculate an HMAC for software usage. 113We use `ets_efuse_write_key` to set physical key block 4 in the eFuse for the HMAC module together with its purpose. 114`ETS_EFUSE_KEY_PURPOSE_HMAC_UP` (8) means that this key can only be used for HMAC generation for software usage: 115 116.. code-block:: c 117 118 #include "{IDF_TARGET_PATH_NAME}/rom/efuse.h" 119 120 const uint8_t key_data[32] = { ... }; 121 122 int ets_status = ets_efuse_write_key(ETS_EFUSE_BLOCK_KEY4, 123 ETS_EFUSE_KEY_PURPOSE_HMAC_UP, 124 key_data, sizeof(key_data)); 125 126 if (ets_status == ESP_OK) { 127 // written key 128 } else { 129 // writing key failed, maybe written already 130 } 131 132Now we can use the saved key to calculate an HMAC for software usage. 133 134.. code-block:: c 135 136 #include "esp_hmac.h" 137 138 uint8_t hmac[32]; 139 140 const char *message = "Hello, HMAC!"; 141 const size_t msg_len = 12; 142 143 esp_err_t result = esp_hmac_calculate(HMAC_KEY4, message, msg_len, hmac); 144 145 if (result == ESP_OK) { 146 // HMAC written to hmac now 147 } else { 148 // failure calculating HMAC 149 } 150 151API Reference 152------------- 153 154.. include-build-file:: inc/esp_hmac.inc 155