The HMAC (Hash-based Message Authentication Code) module provides hardware acceleration for SHA256-HMAC generation using a key burned into an eFuse block.
HMACs work with pre-shared secret keys and provide authenticity and integrity to a message.
For 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>`__].
Six physical eFuse blocks can be used as keys for the HMAC module: block 4 up to block 9.
The enum :cpp:enum:`hmac_key_id_t` in the API maps them to `HMAC_KEY0 ... HMAC_KEY5`.
Each key has a corresponding eFuse parameter *key purpose* determining for which of the three HMAC application scenarios (see below) the key may be used:
..list-table::
:widths:15 70
:header-rows:1
* - Key Purpose
- Application Scenario
* - 8
- HMAC generated for software use
* - 7
- HMAC used as a key for the Digital Signature (DS) module
* - 6
- HMAC used for enabling the soft-disabled JTAG interface
* - 5
- HMAC both as a key for the DS module and for enabling JTAG
This is to prevent the usage of a key for a different function than originally intended.
To 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>`__]).
The input arguments for the function are the message, message length and the eFuse key block ID which contains the secret and has efuse key purpose set to Upstream mode.
The HMAC can be used as a key derivation function to decrypt private key parameters which are used by the Digital Signature module.
A standard message is used by the hardware in that case.
The 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).
Neither the key nor the actual HMAC are ever exposed to outside the HMAC module and DS component.
The calculation of the HMAC and its hand-over to the DS component happen internally.
1. Generate a 256-bit HMAC secret key to use for JTAG re-enable.
2. 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.
3. Configure the eFuse key block to be read protected using the esp_efuse_set_read_protect(), so that software cannot read back the value.
4. Burn the "soft JTAG disable" bit/bits on {IDF_TARGET_NAME}. This will permanently disable JTAG unless the correct key value is provided by software.
..only:: esp32s2
..note:: The API *esp_efuse_write_field_bit(ESP_EFUSE_SOFT_DIS_JTAG)* can be used to burn "soft JTAG disable" bit on {IDF_TARGET_NAME}.
..note:: The API *esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count)* can be used to burn "soft JTAG disable" bits on {IDF_TARGET_NAME}.