crypto: DS uses RSA peripheral, added shared lock

This commit is contained in:
Marius Vikhammer 2020-04-07 12:30:00 +08:00 committed by bot
parent a521921788
commit a2a204c2b9
11 changed files with 75 additions and 58 deletions

View file

@ -16,17 +16,29 @@
#include "esp_crypto_lock.h" #include "esp_crypto_lock.h"
/* Single lock for SHA engine /* Single lock for SHA and AES engine which both use the crypto DMA */
*/
static _lock_t s_crypto_lock;
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"); "The size of esp_digital_signature_length_t and unsigned has to be the same");
static void ds_acquire_enable(void) { 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_hmac_enable();
ets_ds_enable(); ets_ds_enable();
} }
@ -63,7 +65,8 @@ static void ds_acquire_enable(void) {
static void ds_disable_release(void) { static void ds_disable_release(void) {
ets_ds_disable(); ets_ds_disable();
ets_hmac_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, 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_err_t result = ESP_OK;
esp_crypto_lock_acquire(); esp_crypto_dma_lock_acquire();
ets_aes_enable(); ets_aes_enable();
ets_sha_enable(); ets_sha_enable();
@ -190,7 +193,7 @@ esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
ets_sha_disable(); ets_sha_disable();
ets_aes_disable(); ets_aes_disable();
esp_crypto_lock_release(); esp_crypto_dma_lock_release();
return result; 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 (!message || !hmac) return ESP_ERR_INVALID_ARG;
if (key_id >= HMAC_KEY_MAX) 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(); ets_hmac_enable();
hmac_ret = ets_hmac_calculate_message(convert_key_type(key_id), message, message_len, hmac); hmac_ret = ets_hmac_calculate_message(convert_key_type(key_id), message, message_len, hmac);
ets_hmac_disable(); ets_hmac_disable();
esp_crypto_lock_release(); esp_crypto_dma_lock_release();
if (hmac_ret != ETS_OK) { if (hmac_ret != ETS_OK) {
return ESP_FAIL; 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 #ifdef __cplusplus
} }

View file

@ -97,7 +97,7 @@ typedef struct {
* in parallel. * in parallel.
* It blocks until the signing is finished and then returns the signature. * 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 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) * @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 * This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing
* process. * 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. * \c esp_ds_finish_sign() in a timely manner.
* *
* @param message the message to be signed; its length is determined by data->rsa_length * @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 <mbedtls/bignum.h>
#include "bignum_impl.h" #include "bignum_impl.h"
#include <sys/param.h> #include <sys/param.h>
#include <sys/lock.h>
static _lock_t mpi_lock;
/* Round up number of words to nearest /* Round up number of words to nearest
512 bit (16 word) block count. 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 ) void esp_mpi_enable_hardware_hw_op( void )
{ {
/* newlib locks lazy initialize on ESP-IDF */
_lock_acquire(&mpi_lock);
/* Enable RSA hardware */ /* Enable RSA hardware */
periph_module_enable(PERIPH_RSA_MODULE); periph_module_enable(PERIPH_RSA_MODULE);
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); 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 */ /* Disable RSA hardware */
periph_module_disable(PERIPH_RSA_MODULE); 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 ) void esp_aes_acquire_hardware( void )
{ {
/* Need to lock DMA since it is shared with SHA block */ /* Need to lock DMA since it is shared with SHA block */
esp_crypto_lock_acquire(); esp_crypto_dma_lock_acquire();
/* Enable AES hardware */ /* Enable AES hardware */
periph_module_enable(PERIPH_AES_DMA_MODULE); periph_module_enable(PERIPH_AES_DMA_MODULE);
@ -112,7 +112,7 @@ void esp_aes_release_hardware( void )
/* Disable AES hardware */ /* Disable AES hardware */
periph_module_disable(PERIPH_AES_DMA_MODULE); 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/dport_reg.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include <sys/param.h> #include <sys/param.h>
#include "esp_crypto_lock.h"
size_t esp_mpi_hardware_words(size_t words) 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 ) void esp_mpi_enable_hardware_hw_op( void )
{ {
esp_crypto_mpi_lock_acquire();
/* Enable RSA hardware */ /* Enable RSA hardware */
periph_module_enable(PERIPH_RSA_MODULE); periph_module_enable(PERIPH_RSA_MODULE);
@ -51,6 +54,8 @@ void esp_mpi_disable_hardware_hw_op( void )
/* Disable RSA hardware */ /* Disable RSA hardware */
periph_module_disable(PERIPH_RSA_MODULE); 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 */ /* Enable SHA peripheral and then lock it */
void esp_sha_acquire_hardware() void esp_sha_acquire_hardware()
{ {
esp_crypto_lock_acquire(); esp_crypto_dma_lock_acquire();
/* Enable SHA and DMA hardware */ /* Enable SHA and DMA hardware */
periph_module_enable(PERIPH_SHA_DMA_MODULE); periph_module_enable(PERIPH_SHA_DMA_MODULE);
@ -113,7 +113,7 @@ void esp_sha_release_hardware()
/* Disable SHA and DMA hardware */ /* Disable SHA and DMA hardware */
periph_module_disable(PERIPH_SHA_DMA_MODULE); periph_module_disable(PERIPH_SHA_DMA_MODULE);
esp_crypto_lock_release(); esp_crypto_dma_lock_release();
} }
/* Busy wait until SHA is idle */ /* 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 */ #define biL (ciL << 3) /* bits in limb */
static _lock_t mpi_lock;
/* Convert bit count to word count /* Convert bit count to word count
*/ */
static inline size_t bits_to_words(size_t bits) 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 #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, * 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) * This calculation is computationally expensive (mbedtls_mpi_mod_mpi)
* so caller should cache the result where possible. * 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) 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)); MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, hw_words));
Mprime = modular_inverse(M); Mprime = modular_inverse(M);
esp_mpi_acquire_hardware(); esp_mpi_enable_hardware_hw_op();
/* Load and start a (X * Y) mod M calculation */ /* Load and start a (X * Y) mod M calculation */
esp_mpi_mul_mpi_mod_hw_op(X, Y, M, &Rinv, Mprime, hw_words); 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: cleanup:
mbedtls_mpi_free(&Rinv); mbedtls_mpi_free(&Rinv);
esp_mpi_release_hardware(); esp_mpi_disable_hardware_hw_op();
return ret; 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) // 0 determine t (highest bit set in y)
int t = mbedtls_mpi_msb(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) // 1.1 x_ = mont(x, R^2 mod m)
// = mont(x, rb) // = mont(x, rb)
@ -275,7 +254,7 @@ static int mpi_montgomery_exp_calc( mbedtls_mpi *Z, const mbedtls_mpi *X, const
} }
cleanup: cleanup:
esp_mpi_release_hardware(); esp_mpi_disable_hardware_hw_op();
cleanup2: cleanup2:
mbedtls_mpi_free(&X_); 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) ; ret = mpi_montgomery_exp_calc(Z, X, Y, M, Rinv, num_words, Mprime) ;
MBEDTLS_MPI_CHK(ret); MBEDTLS_MPI_CHK(ret);
#else #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); esp_mpi_exp_mpi_mod_hw_op(X, Y, M, Rinv, Mprime, num_words);
ret = mbedtls_mpi_grow(Z, m_words); ret = mbedtls_mpi_grow(Z, m_words);
if (ret != 0) { if (ret != 0) {
esp_mpi_release_hardware(); esp_mpi_disable_hardware_hw_op();
goto cleanup; goto cleanup;
} }
esp_mpi_read_result_hw_op(Z, m_words); esp_mpi_read_result_hw_op(Z, m_words);
esp_mpi_release_hardware(); esp_mpi_disable_hardware_hw_op();
#endif #endif
// Compensate for negative X // 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 */ /* 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_mul_mpi_hw_op(X, Y, hw_words);
esp_mpi_read_result_hw_op(Z, z_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; 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; int ret;
size_t hw_words = esp_mpi_hardware_words(z_words); 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 ); esp_mpi_mult_mpi_failover_mod_mult_hw_op(X, Y, hw_words );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, 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; Z->s = X->s * Y->s;
cleanup: cleanup:
esp_mpi_release_hardware(); esp_mpi_disable_hardware_hw_op();
return ret; return ret;
} }

View file

@ -14,13 +14,13 @@
#endif #endif
/** /**
* @brief Enable the MPI hardware * @brief Enable the MPI hardware and acquire the lock
* *
*/ */
void esp_mpi_enable_hardware_hw_op( void ); 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 ); void esp_mpi_disable_hardware_hw_op( void );