global: bring up esp32s2(not beta)

This commit is contained in:
morris
2019-12-26 15:25:24 +08:00
parent a85b207d68
commit 1c2cc5430e
128 changed files with 17102 additions and 9733 deletions
File diff suppressed because it is too large Load Diff
@@ -56,15 +56,14 @@ void esp_mpi_acquire_hardware( void )
/* newlib locks lazy initialize on ESP-IDF */
_lock_acquire(&mpi_lock);
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_CLK_EN_RSA);
/* also clear reset on digital signature & secure boot, otherwise RSA is held in reset */
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_RST_EN_RSA
| DPORT_RST_EN_DIGITAL_SIGNATURE
| DPORT_RST_EN_SECURE_BOOT);
DPORT_REG_SET_BIT(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_RSA_CLK_EN);
/* also clear reset on digital signature, otherwise RSA is held in reset */
DPORT_REG_CLR_BIT(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_RSA_RST
| DPORT_CRYPTO_DS_RST);
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_MEM_PD);
while(DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) {
while (DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) {
}
// Note: from enabling RSA clock to here takes about 1.3us
}
@@ -74,8 +73,8 @@ void esp_mpi_release_hardware( void )
DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
/* don't reset digital signature unit, as this resets AES also */
DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA);
DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
DPORT_REG_SET_BIT(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_RSA_RST);
DPORT_REG_CLR_BIT(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_RSA_CLK_EN);
_lock_release(&mpi_lock);
}
@@ -141,12 +140,12 @@ static inline int mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_wo
esp_dport_access_read_buffer(x->p, mem_base, num_words);
/* Zero any remaining limbs in the bignum, if the buffer is bigger
than num_words */
for(size_t i = num_words; i < x->n; i++) {
for (size_t i = num_words; i < x->n; i++) {
x->p[i] = 0;
}
asm volatile ("memw");
cleanup:
cleanup:
return ret;
}
@@ -200,7 +199,7 @@ static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words
MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&RR, num_bits * 2, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(Rinv, &RR, M));
cleanup:
cleanup:
mbedtls_mpi_free(&RR);
return ret;
}
@@ -213,6 +212,7 @@ static inline void start_op(uint32_t op_reg)
{
/* Clear interrupt status */
DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1);
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
/* Note: above REG_WRITE includes a memw, so we know any writes
to the memory blocks are also complete. */
@@ -283,7 +283,7 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
esp_mpi_release_hardware();
cleanup:
cleanup:
mbedtls_mpi_free(&Rinv);
return ret;
}
@@ -298,7 +298,7 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
* (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv)
*
*/
int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi* Y, const mbedtls_mpi* M, mbedtls_mpi* _Rinv )
int mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv )
{
int ret = 0;
size_t y_bits = mbedtls_mpi_bitlen(Y);
@@ -379,7 +379,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi
Z->s = 1;
}
cleanup:
cleanup:
if (_Rinv == NULL) {
mbedtls_mpi_free(&Rinv_new);
}
@@ -509,13 +509,13 @@ static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X,
esp_mpi_acquire_hardware();
/* M = 2^num_words - 1, so block is entirely FF */
for(int i = 0; i < num_words; i++) {
for (int i = 0; i < num_words; i++) {
DPORT_REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX);
}
/* Mprime = 1 */
DPORT_REG_WRITE(RSA_M_DASH_REG, 1);
DPORT_REG_WRITE(RSA_LENGTH_REG, num_words -1);
DPORT_REG_WRITE(RSA_LENGTH_REG, num_words - 1);
/* Load X & Y */
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
@@ -523,7 +523,7 @@ static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X,
/* Rinv = 1 */
DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1);
for(int i = 1; i < num_words; i++) {
for (int i = 1; i < num_words; i++) {
DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0);
}
@@ -586,7 +586,7 @@ static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbe
/* Z += Ztemp */
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(Z, Z, &Ztemp) );
cleanup:
cleanup:
mbedtls_mpi_free(&Ztemp);
return ret;
+163 -61
View File
@@ -29,29 +29,47 @@
#include <stdio.h>
#include <sys/lock.h>
#include <assert.h>
#include "soc/soc.h"
#include "esp32s2beta/crypto_dma.h"
#include "esp32s2beta/sha.h"
#include "soc/crypto_dma_reg.h"
#include "esp32s2beta/rom/ets_sys.h"
#include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h"
#include "esp32s2beta/rom/lldesc.h"
#include "esp32s2beta/rom/cache.h"
#include "esp_intr_alloc.h"
#include "esp_log.h"
#include "soc/periph_defs.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
/* Single lock for SHA engine
*/
static _lock_t s_sha_lock;
/* This API was designed for ESP32, which has seperate
engines for SHA1,256,512. ESP32C has a single engine.
*/
/* Enable if want to use SHA interrupt */
//#define CONFIG_MBEDTLS_SHA_USE_INTERRUPT
#if defined(CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
static SemaphoreHandle_t op_complete_sem;
#endif
/* Return block size (in bytes) for a given SHA type */
inline static size_t block_length(esp_sha_type type) {
switch(type) {
inline static size_t block_length(esp_sha_type type)
{
switch (type) {
case SHA1:
case SHA2_224:
case SHA2_256:
return 64;
case SHA2_384:
case SHA2_512:
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
return 128;
default:
return 0;
@@ -59,50 +77,33 @@ inline static size_t block_length(esp_sha_type type) {
}
/* Return state size (in bytes) for a given SHA type */
inline static size_t state_length(esp_sha_type type) {
switch(type) {
inline static size_t state_length(esp_sha_type type)
{
switch (type) {
case SHA1:
return 160/8;
return 160 / 8;
case SHA2_224:
case SHA2_256:
return 256/8;
return 256 / 8;
case SHA2_384:
case SHA2_512:
return 512/8;
case SHA2_512224:
case SHA2_512256:
case SHA2_512T:
return 512 / 8;
default:
return 0;
}
}
/* Copy words in memory (to/from a memory block), byte swapping as we go. */
static void memcpy_endianswap(void *to, const void *from, size_t num_bytes)
{
uint32_t *to_words = (uint32_t *)to;
const uint32_t *from_words = (const uint32_t *)from;
assert(num_bytes % 4 == 0);
for (int i = 0; i < num_bytes / 4; i++) {
to_words[i] = __builtin_bswap32(from_words[i]);
}
asm volatile ("memw");
}
static void memcpy_swapwords(void *to, const void *from, size_t num_bytes)
{
uint32_t *to_words = (uint32_t *)to;
const uint32_t *from_words = (const uint32_t *)from;
assert(num_bytes % 8 == 0);
for (int i = 0; i < num_bytes / 4; i += 2) {
to_words[i] = from_words[i+1];
to_words[i+1] = from_words[i];
}
asm volatile ("memw");
}
/* This API was designed for ESP32, which has seperate
engines for SHA1,256,512. ESP32C has a single engine.
*/
static void esp_sha_lock_engine_inner(void);
bool esp_sha_try_lock_engine(esp_sha_type sha_type)
{
if(_lock_try_acquire(&s_sha_lock) != 0) {
if (_lock_try_acquire(&s_sha_lock) != 0) {
/* SHA engine is already in use */
return false;
} else {
@@ -117,55 +118,156 @@ void esp_sha_lock_engine(esp_sha_type sha_type)
esp_sha_lock_engine_inner();
}
/* Enable SHA block and then lock it */
static void esp_sha_lock_engine_inner(void)
{
ets_sha_enable();
/* Need to lock DMA since it is shared with AES block */
portENTER_CRITICAL(&crypto_dma_spinlock);
REG_SET_BIT(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_SHA_CLK_EN | DPORT_CRYPTO_DMA_CLK_EN);
REG_CLR_BIT(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_SHA_RST | DPORT_CRYPTO_HMAC_RST |
DPORT_CRYPTO_DMA_RST | DPORT_CRYPTO_DS_RST);
/* DMA for SHA */
REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, 1);
}
/* Disable SHA block and then unlock it */
void esp_sha_unlock_engine(esp_sha_type sha_type)
{
ets_sha_disable();
REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, 0);
REG_SET_BIT(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_SHA_RST | DPORT_CRYPTO_DMA_RST |
DPORT_CRYPTO_DS_RST);
REG_CLR_BIT(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_SHA_CLK_EN | DPORT_CRYPTO_DMA_CLK_EN);
portEXIT_CRITICAL(&crypto_dma_spinlock);
_lock_release(&s_sha_lock);
}
#if defined (CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
static IRAM_ATTR void esp_sha_dma_isr(void *arg)
{
BaseType_t higher_woken;
REG_WRITE(SHA_CLEAR_IRQ_REG, 1);
xSemaphoreGiveFromISR(op_complete_sem, &higher_woken);
if (higher_woken) {
portYIELD_FROM_ISR();
}
}
#endif
/* Check if SHA operation completed */
static int esp_sha_dma_complete(void)
{
#if defined (CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) {
ESP_LOGE("SHA", "Timed out waiting for completion of SHA Interrupt");
return -1;
}
#else
esp_sha_wait_idle();
#endif
return 0;
}
/* Wait until SHA is busy */
void esp_sha_wait_idle(void)
{
while(DPORT_REG_READ(SHA_BUSY_REG) != 0) { }
while (DPORT_REG_READ(SHA_BUSY_REG) != 0) { }
}
/* Read the SHA digest from hardware */
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
{
/* engine should be locked */
esp_sha_wait_idle();
if (sha_type != SHA2_512 && sha_type != SHA2_384) {
/* <SHA-512, read out directly */
memcpy(digest_state, (void *)SHA_H_BASE, state_length(sha_type));
} else {
/* SHA-512, read out with each pair of words swapped */
memcpy_swapwords(digest_state, (void *)SHA_H_BASE, state_length(sha_type));
}
memcpy(digest_state, (void *)SHA_H_BASE, state_length(sha_type));
}
/* Internally calls DMA API for single block */
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
{
/* engine should be locked */
esp_sha_dma(sha_type, data_block, block_length(sha_type), is_first_block);
}
REG_WRITE(SHA_MODE_REG, sha_type);
/* Performs SHA on multiple blocks at a time */
int esp_sha_dma(esp_sha_type sha_type, const void *data_block, uint32_t ilen, bool is_first_block)
{
size_t blk_len = 0;
const uint8_t *local_buf = data_block;
int ret = 0;
volatile lldesc_t dma_descr;
/* ESP32C SHA unit can be loaded while previous block is processing */
memcpy_endianswap((void *)SHA_M_BASE, data_block, block_length(sha_type));
esp_sha_wait_idle();
if (is_first_block) {
REG_WRITE(SHA_START_REG, 1);
} else {
REG_WRITE(SHA_CONTINUE_REG, 1);
if (ilen == 0) {
return ret;
}
/* Note: deliberately not waiting for this operation to complete,
as a performance tweak - delay waiting until the next time we need the SHA
unit, instead.
*/
blk_len = block_length(sha_type);
REG_WRITE(SHA_MODE_REG, sha_type);
if ((sha_type == SHA2_512T) && (is_first_block == true)) {
REG_WRITE(SHA_START_REG, 1);
}
REG_WRITE(SHA_BLOCK_NUM_REG, (ilen / blk_len));
if ((sha_type == SHA2_512T) && (is_first_block == true)) {
esp_sha_wait_idle();
is_first_block = false;
}
bzero( (void *)&dma_descr, sizeof( dma_descr ) );
/* DMA descriptor for Memory to DMA-AES transfer */
dma_descr.length = ilen;
dma_descr.size = ilen;
dma_descr.owner = 1;
dma_descr.eof = 1;
dma_descr.buf = local_buf;
dma_descr.sosf = 0;
dma_descr.empty = 0;
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
if ((unsigned int)data_block >= SOC_EXTRAM_DATA_LOW && (unsigned int)data_block <= SOC_EXTRAM_DATA_HIGH) {
Cache_WriteBack_All();
}
#endif
/* Reset DMA */
SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
/* Set descriptors */
CLEAR_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_ADDR);
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, ((uint32_t)(&dma_descr))&OUT_LINK_REG_OUTLINK_ADDR);
/* Start transfer */
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_START);
#if defined (CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
REG_WRITE(SHA_CLEAR_IRQ_REG, 1);
if (op_complete_sem == NULL) {
op_complete_sem = xSemaphoreCreateBinary();
esp_intr_alloc(ETS_SHA_INTR_SOURCE, 0, esp_sha_dma_isr, 0, 0);
}
REG_WRITE(SHA_INT_ENA_REG, 1);
#endif
if (is_first_block) {
REG_WRITE(SHA_DMA_START_REG, 1);
} else {
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
}
ret = esp_sha_dma_complete();
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
if ((unsigned int)data_block >= SOC_EXTRAM_DATA_LOW && (unsigned int)data_block <= SOC_EXTRAM_DATA_HIGH) {
Cache_Invalidate_DCache_All();
}
#endif
return ret;
}
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
@@ -0,0 +1,40 @@
/**
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
#ifndef ESP_CRYPTO_DMA_H
#define ESP_CRYPTO_DMA_H
#include <freertos/FreeRTOS.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Since crypto DMA is shared between DMA-AES and SHA blocks
* Needs to be taken by respective blocks before using Crypto DMA
*/
extern portMUX_TYPE crypto_dma_spinlock;
#ifdef __cplusplus
}
#endif
#endif /* crypto_dma.h */
@@ -0,0 +1,224 @@
/**
* \brief AES block cipher, ESP32C hardware accelerated version
* Based on mbedTLS FIPS-197 compliant version.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
#ifndef ESP_GCM_H
#define ESP_GCM_H
#include "aes.h"
#include "mbedtls/cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function.*/
/**
* \brief The GCM context structure.
*/
typedef struct {
uint8_t H[16]; /*!< H */
size_t iv_len; /*!< The length of IV. */
uint64_t aad_len; /*!< The total length of the additional data. */
const unsigned char *aad; /*!< The additional data. */
esp_aes_context aes_ctx;
}
esp_aes_gcm_context;
/**
* \brief This function initializes the specified GCM context
*
* \param ctx The GCM context to initialize.
*/
void esp_aes_gcm_init( esp_aes_gcm_context *ctx);
/**
* \brief This function associates a GCM context with a
* key.
*
* \param ctx The GCM context to initialize.
* \param cipher The 128-bit block cipher to use.
* \param key The encryption key.
* \param keybits The key size in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return A cipher-specific error code on failure.
*/
int esp_aes_gcm_setkey( esp_aes_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function starts a GCM encryption or decryption
* operation.
*
* \param ctx The GCM context.
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
* #MBEDTLS_GCM_DECRYPT.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data, or NULL
* if \p add_len is 0.
* \param add_len The length of the additional data. If 0,
* \p add is NULL.
*
* \return \c 0 on success.
*/
int esp_aes_gcm_starts( esp_aes_gcm_context *ctx,
int mode,
const unsigned char *iv,
size_t iv_len,
const unsigned char *aad,
size_t aad_len );
/**
* \brief This function feeds an input buffer into an ongoing GCM
* encryption or decryption operation.
*
* ` The function expects input to be a multiple of 16
* Bytes. Only the last call before calling
* mbedtls_gcm_finish() can be less than 16 Bytes.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context.
* \param length The length of the input data. This must be a multiple of
* 16 except in the last call before mbedtls_gcm_finish().
* \param input The buffer holding the input data.
* \param output The buffer for holding the output data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int esp_aes_gcm_update( esp_aes_gcm_context *ctx,
size_t length,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function finishes the GCM operation and generates
* the authentication tag.
*
* It wraps up the GCM stream, and generates the
* tag. The tag can have a maximum length of 16 Bytes.
*
* \param ctx The GCM context.
* \param tag The buffer for holding the tag.
* \param tag_len The length of the tag to generate. Must be at least four.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int esp_aes_gcm_finish( esp_aes_gcm_context *ctx,
unsigned char *tag,
size_t tag_len );
/**
* \brief This function clears a GCM context
*
* \param ctx The GCM context to clear.
*/
void esp_aes_gcm_free( esp_aes_gcm_context *ctx);
/**
* \brief This function performs GCM encryption or decryption of a buffer.
*
* \note For encryption, the output buffer can be the same as the
* input buffer. For decryption, the output buffer cannot be
* the same as input buffer. If the buffers overlap, the output
* buffer must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context to use for encryption or decryption.
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
* #MBEDTLS_GCM_DECRYPT.
* \param length The length of the input data. This must be a multiple of
* 16 except in the last call before mbedtls_gcm_finish().
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
* \param input The buffer holding the input data.
* \param output The buffer for holding the output data.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag.
*
* \return \c 0 on success.
*/
int esp_aes_gcm_crypt_and_tag( esp_aes_gcm_context *ctx,
int mode,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
unsigned char *tag );
/**
* \brief This function performs a GCM authenticated decryption of a
* buffer.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context.
* \param length The length of the input data. This must be a multiple
* of 16 except in the last call before mbedtls_gcm_finish().
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
* \param tag The buffer holding the tag.
* \param tag_len The length of the tag.
* \param input The buffer holding the input data.
* \param output The buffer for holding the output data.
*
* \return 0 if successful and authenticated.
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
*/
int esp_aes_gcm_auth_decrypt( esp_aes_gcm_context *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* gcm.h */
@@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_SHA_H_
#define _ESP_SHA_H_
@@ -101,6 +102,31 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
*/
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
/* @brief Begin to execute SHA block operation using DMA
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA
* algorithm.
*
* @note Call esp_sha_try_lock_engine() before calling this
* function. Do not call esp_sha_lock_memory_block() beforehand, this
* is done inside the function.
*
* @param sha_type SHA algorithm to use.
*
* @param data_block Pointer to block of data. Block size is
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
* SHA2_384/SHA2_512 = 128 bytes)
*
* @param ilen length of input data should be multiple of block length.
*
* @param is_first_block If this parameter is true, the SHA state will
* be initialised (with the initial state of the given SHA algorithm)
* before the block is calculated. If false, the existing state of the
* SHA engine will be used.
*
*/
int esp_sha_dma(esp_sha_type sha_type, const void *data_block, uint32_t ilen, bool is_first_block);
/** @brief Read out the current state of the SHA digest loaded in the engine.
*
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.