Merge branch 'bugfix/ds_mpi_lock' into 'master'

crypto: DS uses RSA peripheral, added shared lock

See merge request espressif/esp-idf!8274
This commit is contained in:
Angus Gratton 2020-04-15 15:15:25 +08:00
commit 433c1c9ee1
12 changed files with 76 additions and 59 deletions

View File

@ -16,17 +16,29 @@
#include "esp_crypto_lock.h"
/* Single lock for SHA engine
*/
static _lock_t s_crypto_lock;
/* Single lock for SHA and AES engine which both use the crypto DMA */
void esp_crypto_lock_acquire(void)
static _lock_t s_crypto_dma_lock;
/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */
static _lock_t s_crypto_mpi_lock;
void esp_crypto_dma_lock_acquire(void)
{
_lock_acquire(&s_crypto_lock);
_lock_acquire(&s_crypto_dma_lock);
}
void esp_crypto_lock_release(void)
void esp_crypto_dma_lock_release(void)
{
_lock_release(&s_crypto_lock);
_lock_release(&s_crypto_dma_lock);
}
void esp_crypto_mpi_lock_acquire(void)
{
_lock_acquire(&s_crypto_mpi_lock);
}
void esp_crypto_mpi_lock_release(void)
{
_lock_release(&s_crypto_mpi_lock);
}

View File

@ -55,7 +55,9 @@ _Static_assert(sizeof(esp_digital_signature_length_t) == sizeof(unsigned),
"The size of esp_digital_signature_length_t and unsigned has to be the same");
static void ds_acquire_enable(void) {
esp_crypto_lock_acquire();
/* Lock AES, SHA and RSA peripheral */
esp_crypto_dma_lock_acquire();
esp_crypto_mpi_lock_acquire();
ets_hmac_enable();
ets_ds_enable();
}
@ -63,7 +65,8 @@ static void ds_acquire_enable(void) {
static void ds_disable_release(void) {
ets_ds_disable();
ets_hmac_disable();
esp_crypto_lock_release();
esp_crypto_mpi_lock_release();
esp_crypto_dma_lock_release();
}
esp_err_t esp_ds_sign(const void *message,
@ -177,7 +180,7 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
esp_err_t result = ESP_OK;
esp_crypto_lock_acquire();
esp_crypto_dma_lock_acquire();
ets_aes_enable();
ets_sha_enable();
@ -190,7 +193,7 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
ets_sha_disable();
ets_aes_disable();
esp_crypto_lock_release();
esp_crypto_dma_lock_release();
return result;
}

View File

@ -30,13 +30,13 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
if (!message || !hmac) return ESP_ERR_INVALID_ARG;
if (key_id >= HMAC_KEY_MAX) return ESP_ERR_INVALID_ARG;
esp_crypto_lock_acquire();
esp_crypto_dma_lock_acquire();
ets_hmac_enable();
hmac_ret = ets_hmac_calculate_message(convert_key_type(key_id), message, message_len, hmac);
ets_hmac_disable();
esp_crypto_lock_release();
esp_crypto_dma_lock_release();
if (hmac_ret != ETS_OK) {
return ESP_FAIL;

View File

@ -27,14 +27,24 @@ extern "C" {
*/
/**
* Acquire lock for the ESP cryptography peripheral.
* Acquire lock for the AES and SHA cryptography peripherals, which both use the crypto DMA.
*/
void esp_crypto_lock_acquire(void);
void esp_crypto_dma_lock_acquire(void);
/**
* Release the lock for the ESP cryptography peripheral.
* Release lock for the AES and SHA cryptography peripherals, which both use the crypto DMA.
*/
void esp_crypto_lock_release(void);
void esp_crypto_dma_lock_release(void);
/**
* Acquire lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_acquire(void);
/**
* Release lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_release(void);
#ifdef __cplusplus
}

View File

@ -97,7 +97,7 @@ typedef struct {
* in parallel.
* It blocks until the signing is finished and then returns the signature.
*
* @note This function locks the HMAC, SHA and AES components during its entire execution time.
* @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time.
*
* @param message the message to be signed; its length is determined by data->rsa_length
* @param data the encrypted signing key data (AES encrypted RSA key + IV)
@ -126,7 +126,7 @@ esp_err_t esp_ds_sign(const void *message,
* This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing
* process.
*
* @note This function locks the HMAC, SHA and AES components, so the user has to ensure to call
* @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call
* \c esp_ds_finish_sign() in a timely manner.
*
* @param message the message to be signed; its length is determined by data->rsa_length

View File

@ -26,6 +26,9 @@
#include <mbedtls/bignum.h>
#include "bignum_impl.h"
#include <sys/param.h>
#include <sys/lock.h>
static _lock_t mpi_lock;
/* Round up number of words to nearest
512 bit (16 word) block count.
@ -37,6 +40,9 @@ size_t esp_mpi_hardware_words(size_t words)
void esp_mpi_enable_hardware_hw_op( void )
{
/* newlib locks lazy initialize on ESP-IDF */
_lock_acquire(&mpi_lock);
/* Enable RSA hardware */
periph_module_enable(PERIPH_RSA_MODULE);
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
@ -52,6 +58,8 @@ void esp_mpi_disable_hardware_hw_op( void )
/* Disable RSA hardware */
periph_module_disable(PERIPH_RSA_MODULE);
_lock_release(&mpi_lock);
}

View File

@ -100,7 +100,7 @@ static inline bool valid_key_length(const esp_aes_context *ctx)
void esp_aes_acquire_hardware( void )
{
/* Need to lock DMA since it is shared with SHA block */
esp_crypto_lock_acquire();
esp_crypto_dma_lock_acquire();
/* Enable AES hardware */
periph_module_enable(PERIPH_AES_DMA_MODULE);
@ -112,7 +112,7 @@ void esp_aes_release_hardware( void )
/* Disable AES hardware */
periph_module_disable(PERIPH_AES_DMA_MODULE);
esp_crypto_lock_release();
esp_crypto_dma_lock_release();
}

View File

@ -27,6 +27,7 @@
#include "soc/dport_reg.h"
#include "soc/periph_defs.h"
#include <sys/param.h>
#include "esp_crypto_lock.h"
size_t esp_mpi_hardware_words(size_t words)
{
@ -35,6 +36,8 @@ size_t esp_mpi_hardware_words(size_t words)
void esp_mpi_enable_hardware_hw_op( void )
{
esp_crypto_mpi_lock_acquire();
/* Enable RSA hardware */
periph_module_enable(PERIPH_RSA_MODULE);
@ -51,6 +54,8 @@ void esp_mpi_disable_hardware_hw_op( void )
/* Disable RSA hardware */
periph_module_disable(PERIPH_RSA_MODULE);
esp_crypto_mpi_lock_release();
}

View File

@ -98,7 +98,7 @@ inline static size_t state_length(esp_sha_type type)
/* Enable SHA peripheral and then lock it */
void esp_sha_acquire_hardware()
{
esp_crypto_lock_acquire();
esp_crypto_dma_lock_acquire();
/* Enable SHA and DMA hardware */
periph_module_enable(PERIPH_SHA_DMA_MODULE);
@ -113,7 +113,7 @@ void esp_sha_release_hardware()
/* Disable SHA and DMA hardware */
periph_module_disable(PERIPH_SHA_DMA_MODULE);
esp_crypto_lock_release();
esp_crypto_dma_lock_release();
}
/* Busy wait until SHA is idle */

View File

@ -56,8 +56,6 @@ static const __attribute__((unused)) char *TAG = "bignum";
#define biL (ciL << 3) /* bits in limb */
static _lock_t mpi_lock;
/* Convert bit count to word count
*/
static inline size_t bits_to_words(size_t bits)
@ -81,25 +79,6 @@ static size_t mpi_words(const mbedtls_mpi *mpi)
#endif //MBEDTLS_MPI_EXP_MOD_ALT
void esp_mpi_acquire_hardware( void )
{
/* newlib locks lazy initialize on ESP-IDF */
_lock_acquire(&mpi_lock);
/* Enable RSA hardware */
esp_mpi_enable_hardware_hw_op();
}
void esp_mpi_release_hardware( void )
{
esp_mpi_disable_hardware_hw_op();
_lock_release(&mpi_lock);
}
/**
*
* There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1,
@ -137,7 +116,7 @@ static mbedtls_mpi_uint modular_inverse(const mbedtls_mpi *M)
* This calculation is computationally expensive (mbedtls_mpi_mod_mpi)
* so caller should cache the result where possible.
*
* DO NOT call this function while holding esp_mpi_acquire_hardware().
* DO NOT call this function while holding esp_mpi_enable_hardware_hw_op().
*
*/
static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words)
@ -185,7 +164,7 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, hw_words));
Mprime = modular_inverse(M);
esp_mpi_acquire_hardware();
esp_mpi_enable_hardware_hw_op();
/* Load and start a (X * Y) mod M calculation */
esp_mpi_mul_mpi_mod_hw_op(X, Y, M, &Rinv, Mprime, hw_words);
@ -196,7 +175,7 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
cleanup:
mbedtls_mpi_free(&Rinv);
esp_mpi_release_hardware();
esp_mpi_disable_hardware_hw_op();
return ret;
}
@ -247,7 +226,7 @@ static int mpi_montgomery_exp_calc( mbedtls_mpi *Z, const mbedtls_mpi *X, const
// 0 determine t (highest bit set in y)
int t = mbedtls_mpi_msb(Y);
esp_mpi_acquire_hardware();
esp_mpi_enable_hardware_hw_op();
// 1.1 x_ = mont(x, R^2 mod m)
// = mont(x, rb)
@ -275,7 +254,7 @@ static int mpi_montgomery_exp_calc( mbedtls_mpi *Z, const mbedtls_mpi *X, const
}
cleanup:
esp_mpi_release_hardware();
esp_mpi_disable_hardware_hw_op();
cleanup2:
mbedtls_mpi_free(&X_);
@ -345,16 +324,16 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
ret = mpi_montgomery_exp_calc(Z, X, Y, M, Rinv, num_words, Mprime) ;
MBEDTLS_MPI_CHK(ret);
#else
esp_mpi_acquire_hardware();
esp_mpi_enable_hardware_hw_op();
esp_mpi_exp_mpi_mod_hw_op(X, Y, M, Rinv, Mprime, num_words);
ret = mbedtls_mpi_grow(Z, m_words);
if (ret != 0) {
esp_mpi_release_hardware();
esp_mpi_disable_hardware_hw_op();
goto cleanup;
}
esp_mpi_read_result_hw_op(Z, m_words);
esp_mpi_release_hardware();
esp_mpi_disable_hardware_hw_op();
#endif
// Compensate for negative X
@ -442,12 +421,12 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
}
/* Otherwise, we can use the (faster) multiply hardware unit */
esp_mpi_acquire_hardware();
esp_mpi_enable_hardware_hw_op();
esp_mpi_mul_mpi_hw_op(X, Y, hw_words);
esp_mpi_read_result_hw_op(Z, z_words);
esp_mpi_release_hardware();
esp_mpi_disable_hardware_hw_op();
Z->s = X->s * Y->s;
@ -535,7 +514,7 @@ static int mpi_mult_mpi_failover_mod_mult( mbedtls_mpi *Z, const mbedtls_mpi *X,
int ret;
size_t hw_words = esp_mpi_hardware_words(z_words);
esp_mpi_acquire_hardware();
esp_mpi_enable_hardware_hw_op();
esp_mpi_mult_mpi_failover_mod_mult_hw_op(X, Y, hw_words );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, hw_words) );
@ -543,7 +522,7 @@ static int mpi_mult_mpi_failover_mod_mult( mbedtls_mpi *Z, const mbedtls_mpi *X,
Z->s = X->s * Y->s;
cleanup:
esp_mpi_release_hardware();
esp_mpi_disable_hardware_hw_op();
return ret;
}

View File

@ -14,13 +14,13 @@
#endif
/**
* @brief Enable the MPI hardware
* @brief Enable the MPI hardware and acquire the lock
*
*/
void esp_mpi_enable_hardware_hw_op( void );
/**
* @brief Disable the MPI hardware
* @brief Disable the MPI hardware and release the lock
*
*/
void esp_mpi_disable_hardware_hw_op( void );

View File

@ -12,7 +12,7 @@
#include "test_utils.h"
#include "ccomp_timer.h"
TEST_CASE("mbedtls AES performance", "[aes]")
TEST_CASE("mbedtls AES performance", "[aes][timeout=60]")
{
const unsigned CALLS = 256;
const unsigned CALL_SZ = 32 * 1024;