esp-idf/components/mbedtls/port/ecc/ecc_alt.c
Sachin Parekh 32a6550e87 mbedtls: Added ECC hardware accelerator support on ESP32C2
ESP32C2 has a ECC hardware accelerator capable of performing point
multiplication and point verification with a significant performance
boost
2022-03-08 14:05:23 +00:00

130 lines
3.9 KiB
C

/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "soc/hwcrypto_periph.h"
#include "ecc_impl.h"
/* TBD: Remove this and use proper getter/setter methods to access
* private members of EC data structures once they are available
* in mbedTLS stack */
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
#include "mbedtls/ecp.h"
#include "mbedtls/platform_util.h"
#define ECP_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
#define ECP_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
#if defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK)
#define MAX_SIZE 32 // 256 bits
static int esp_mbedtls_ecp_point_multiply(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P)
{
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
uint8_t x_tmp[MAX_SIZE];
uint8_t y_tmp[MAX_SIZE];
ecc_point_t p_pt = {0};
ecc_point_t r_pt = {0};
p_pt.len = grp->pbits / 8;
memcpy(&p_pt.x, P->X.p, mbedtls_mpi_size(&P->X));
memcpy(&p_pt.y, P->Y.p, mbedtls_mpi_size(&P->Y));
ret = esp_ecc_point_multiply(&p_pt, (uint8_t *)m->p, &r_pt, false);
for (int i = 0; i < MAX_SIZE; i++) {
x_tmp[MAX_SIZE - i - 1] = r_pt.x[i];
y_tmp[MAX_SIZE - i - 1] = r_pt.y[i];
}
mbedtls_mpi_read_binary(&R->X, x_tmp, MAX_SIZE);
mbedtls_mpi_read_binary(&R->Y, y_tmp, MAX_SIZE);
mbedtls_mpi_lset(&R->Z, 1);
return ret;
}
/*
* Restartable multiplication R = m * P
*/
int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) {
#if defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK)
return mbedtls_ecp_mul_restartable_soft(grp, R, m, P, f_rng, p_rng, rs_ctx);
#else
return ret;
#endif
}
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( R != NULL );
ECP_VALIDATE_RET( m != NULL );
ECP_VALIDATE_RET( P != NULL );
/* Common sanity checks */
MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) );
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
/* MBEDTLS_MPI_CHK macro assigns the return value of the function to
* `ret` variable
*/
MBEDTLS_MPI_CHK( esp_mbedtls_ecp_point_multiply(grp, R, m, P) );
cleanup:
return( ret );
}
#endif /* defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) */
#if defined(MBEDTLS_ECP_VERIFY_ALT) || defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK)
int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *pt )
{
int res;
ecc_point_t point;
if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) {
#if defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK)
return mbedtls_ecp_check_pubkey_soft(grp, pt);
#else
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
#endif
}
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( pt != NULL );
/* Must use affine coordinates */
if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
mbedtls_platform_zeroize((void *)&point, sizeof(ecc_point_t));
memcpy(&point.x, pt->X.p, mbedtls_mpi_size(&pt->X));
memcpy(&point.y, pt->Y.p, mbedtls_mpi_size(&pt->Y));
point.len = grp->pbits / 8;
res = esp_ecc_point_verify(&point);
if (res == 1) {
return 0;
} else {
return MBEDTLS_ERR_ECP_INVALID_KEY;
}
}
#endif /* defined(MBEDTLS_ECP_VERIFY_ALT) || defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK) */