diff --git a/components/esp32s2/esp_hmac.c b/components/esp32s2/esp_hmac.c index ab5604dbe5..93f54a2a5c 100644 --- a/components/esp32s2/esp_hmac.c +++ b/components/esp32s2/esp_hmac.c @@ -12,9 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include "esp32s2/rom/hmac.h" #include "esp_hmac.h" #include "esp_crypto_lock.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "soc/hwcrypto_reg.h" +#include "soc/system_reg.h" +#include "esp_log.h" + +static const char *TAG = "esp_hmac"; static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) { return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id; @@ -44,3 +52,55 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id, } } + +esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) +{ + esp_err_t err; + + if ((!token) || (key_id >= HMAC_KEY_MAX)) + return ESP_ERR_INVALID_ARG; + + /* Check if JTAG is permanently disabled by HW Disable eFuse */ + if (esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG)) { + ESP_LOGE(TAG, "JTAG disabled permanently."); + return ESP_FAIL; + } + + esp_crypto_dma_lock_acquire(); + + ets_hmac_enable(); + + /* Token updating into HMAC module. */ + for (int i = 0; i < 32; i += 4) { + uint32_t key_word; + memcpy(&key_word, &token[i], 4); + REG_WRITE(DPORT_JTAG_CTRL_0_REG + i, __builtin_bswap32(key_word)); + } + + err = ets_hmac_calculate_downstream(convert_key_type(key_id), ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG); + if (err != ETS_OK) { + ESP_LOGE(TAG, "HMAC downstream JTAG enable mode setting failed."); + return ESP_FAIL; + } + + ESP_LOGD(TAG, "HMAC computation in downstream mode is completed."); + + ets_hmac_disable(); + + esp_crypto_dma_lock_release(); + + return ESP_OK; +} + +esp_err_t esp_hmac_jtag_disable() +{ + esp_crypto_dma_lock_acquire(); + + REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1); + + esp_crypto_dma_lock_release(); + + ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled."); + + return ESP_OK; +} diff --git a/components/esp32s2/include/esp_hmac.h b/components/esp32s2/include/esp_hmac.h index 6798ae8d1f..5fa836c47d 100644 --- a/components/esp32s2/include/esp_hmac.h +++ b/components/esp32s2/include/esp_hmac.h @@ -60,6 +60,38 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id, size_t message_len, uint8_t *hmac); +/** + * @brief + * Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disable by HW. + * In downstream mode HMAC calculations perfomred by peripheral used internally and not provided back to user. + * + * @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation. + * The corresponding purpose field of the key block in the efuse must be set to HMAC downstream purpose. + * + * @param token Pre calculated HMAC value of the 32-byte 0x00 using SHA-256 and the known private HMAC key. The key is already + * programmed to a eFuse key block. The key block number is provided as the first parameter to this function. + * + * @return + * * ESP_OK, if the calculation was successful, + * if the calculated HMAC value matches with provided token, + * JTAG will be re-enable otherwise JTAG will remain disabled. + * Return value does not indicate the JTAG status. + * * ESP_FAIL, if the hmac calculation failed or JTAG is permanently disabled by EFUSE_HARD_DIS_JTAG eFuse parameter. + * * ESP_ERR_INVALID_ARG, invalid input arguments + */ +esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, + const uint8_t *token); + +/** + * @brief + * Disable the JTAG which might be enable using the HMAC downstream mode. This function just clear the result generated by + * JTAG key by calling esp_hmac_jtag_enable() API. + * + * @return + * * ESP_OK return ESP_OK after writing the HMAC_SET_INVALIDATE_JTAG_REG with value 1. + */ +esp_err_t esp_hmac_jtag_disable(void); + #ifdef __cplusplus } #endif