Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate ECP light #7357

Closed
wants to merge 9 commits into from
2 changes: 2 additions & 0 deletions include/mbedtls/ecp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,7 @@ int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp,
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
* on failure.
*/
#if defined(ECP_FULL)
int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d,
mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
Expand All @@ -1235,6 +1236,7 @@ int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d,
int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
#endif

/**
* \brief This function reads an elliptic curve private key.
Expand Down
25 changes: 23 additions & 2 deletions library/ecp.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@
* Counts of point addition and doubling, and field multiplications.
* Used to test resistance of point multiplication to simple timing attacks.
*/
static unsigned long add_count, dbl_count, mul_count;
#if defined(ECP_FULL)
static unsigned long add_count, dbl_count;
#endif /* ECP_FULL */
static unsigned long mul_count;
#endif

#if defined(MBEDTLS_ECP_RESTARTABLE)
Expand Down Expand Up @@ -320,6 +323,7 @@ int mbedtls_ecp_check_budget(const mbedtls_ecp_group *grp,

#endif /* MBEDTLS_ECP_RESTARTABLE */

#if defined(ECP_FULL)
static void mpi_init_many(mbedtls_mpi *arr, size_t size)
{
while (size--) {
Expand All @@ -333,6 +337,7 @@ static void mpi_free_many(mbedtls_mpi *arr, size_t size)
mbedtls_mpi_free(arr++);
}
}
#endif /* ECP_FULL */

/*
* List of supported curves:
Expand Down Expand Up @@ -1306,7 +1311,10 @@ static int mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group *grp,
mbedtls_mpi_free(&exp);
return ret;
}
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */

#if defined(ECP_FULL)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* For curves in short Weierstrass form, we do all the internal operations in
* Jacobian coordinates.
Expand Down Expand Up @@ -2723,6 +2731,7 @@ int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
{
return mbedtls_ecp_mul_restartable(grp, R, m, P, f_rng, p_rng, NULL);
}
#endif /* ECP_FULL */

#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
Expand Down Expand Up @@ -2763,6 +2772,7 @@ static int ecp_check_pubkey_sw(const mbedtls_ecp_group *grp, const mbedtls_ecp_p
}
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */

#if defined(ECP_FULL)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* R = m * P with shortcuts for m == 0, m == 1 and m == -1
Expand Down Expand Up @@ -2914,6 +2924,7 @@ int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return mbedtls_ecp_muladd_restartable(grp, R, m, P, n, Q, NULL);
}
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
#endif /* ECP_FULL */

#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Expand Down Expand Up @@ -3159,6 +3170,7 @@ int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp,
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}

#if defined(ECP_FULL)
/*
* Generate a keypair with configurable base point
*/
Expand Down Expand Up @@ -3200,6 +3212,7 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,

return mbedtls_ecp_gen_keypair(&key->grp, &key->d, &key->Q, f_rng, p_rng);
}
#endif /* ECP_FULL */

#define ECP_CURVE25519_KEY_SIZE 32
#define ECP_CURVE448_KEY_SIZE 56
Expand Down Expand Up @@ -3316,7 +3329,7 @@ int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
return ret;
}


#if defined(ECP_FULL)
/*
* Check a public-private key pair
*/
Expand Down Expand Up @@ -3357,6 +3370,7 @@ int mbedtls_ecp_check_pub_priv(

return ret;
}
#endif /* ECP_FULL */

/*
* Export generic key-pair parameters.
Expand All @@ -3383,6 +3397,7 @@ int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp,

#if defined(MBEDTLS_SELF_TEST)

#if defined(ECP_FULL)
/*
* PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
*
Expand Down Expand Up @@ -3490,12 +3505,14 @@ static int self_test_point(int verbose,
}
return ret;
}
#endif /* ECP_FULL */

/*
* Checkup routine
*/
int mbedtls_ecp_self_test(int verbose)
{
#if defined(ECP_FULL)
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group grp;
mbedtls_ecp_point R, P;
Expand Down Expand Up @@ -3609,6 +3626,10 @@ int mbedtls_ecp_self_test(int verbose)
}

return ret;
#else /* ECP_FULL */
(void) verbose;
return 0;
#endif /* ECP_FULL */
}

#endif /* MBEDTLS_SELF_TEST */
Expand Down
81 changes: 81 additions & 0 deletions library/pk_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1095,13 +1095,94 @@ static int eckey_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
}
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */

#if !defined(ECP_FULL)
/*
* Alternative function used to verify that the EC private/public key pair
* is valid using PSA functions instead of ECP ones.
* The flow is:
* - import the private key "prv" to PSA and export its public part
* - write the raw content of public key "pub" to a local buffer
* - compare the two buffers
*/
static int eckey_alt_check_pair(const void *pub, const void *prv,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
(void)f_rng;
(void)p_rng;
psa_status_t status;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_ecp_keypair *prv_ctx = (mbedtls_ecp_keypair *) prv;
mbedtls_ecp_keypair *pub_ctx = (mbedtls_ecp_keypair *) pub;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
size_t prv_key_len;
uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
size_t pub_key_len;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
size_t curve_bits;
psa_ecc_family_t curve =
mbedtls_ecc_group_to_psa(prv_ctx->grp.id, &curve_bits);
size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);

psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);

ret = mbedtls_mpi_write_binary(&prv_ctx->d, prv_key_buf, curve_bytes);
if (ret != 0) {
return ret;
}

status = psa_import_key(&key_attr, prv_key_buf, curve_bytes, &key_id);
if (status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
return ret;
}

mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));

status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
&prv_key_len);
if (status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
status = psa_destroy_key(key_id);
return (status != PSA_SUCCESS) ? PSA_PK_TO_MBEDTLS_ERR(status) : ret;
}

status = psa_destroy_key(key_id);
if (status != PSA_SUCCESS) {
return PSA_PK_TO_MBEDTLS_ERR(status);
}

ret = mbedtls_ecp_point_write_binary(&pub_ctx->grp, &pub_ctx->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&pub_key_len, pub_key_buf, sizeof(pub_key_buf));
if (ret != 0) {
return ret;
}

if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}

return 0;
}
#endif /* ECP_FULL */

static int eckey_check_pair(const void *pub, const void *prv,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
#if defined(ECP_FULL)
return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub,
(const mbedtls_ecp_keypair *) prv,
f_rng, p_rng);
#else /* ECP_FULL */
return eckey_alt_check_pair((const mbedtls_ecp_keypair *) pub,
(const mbedtls_ecp_keypair *) prv,
f_rng, p_rng);
#endif /* ECP_FULL */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
}

static void *eckey_alloc_wrap(void)
Expand Down
74 changes: 69 additions & 5 deletions library/pkparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@
#include "mbedtls/pkcs12.h"
#endif

#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h"
#endif

#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif

#include "mbedtls/platform.h"

#if defined(MBEDTLS_FS_IO)
Expand Down Expand Up @@ -868,6 +876,52 @@ static int pk_parse_key_pkcs1_der(mbedtls_rsa_context *rsa,
}
#endif /* MBEDTLS_RSA_C */

#if !defined(MBEDTLS_ECP_FULL)
static int pk_derive_public_key(mbedtls_ecp_group *grp, mbedtls_ecp_point *Q,
const mbedtls_mpi *d)
{
psa_status_t status;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
size_t curve_bits;
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(grp->id, &curve_bits);
unsigned char key_buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
size_t key_len = PSA_BITS_TO_BYTES(curve_bits);
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
int ret;

psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);

ret = mbedtls_mpi_write_binary(d, key_buf, key_len);
if (ret != 0) {
return ret;
}

status = psa_import_key(&key_attr, key_buf, key_len, &key_id);
if (status != PSA_SUCCESS) {
ret = psa_pk_status_to_mbedtls(status);
return ret;
}

mbedtls_platform_zeroize(key_buf, sizeof(key_buf));
status = psa_export_public_key(key_id, key_buf, sizeof(key_buf), &key_len);
if (status != PSA_SUCCESS) {
ret = psa_pk_status_to_mbedtls(status);
status = psa_destroy_key(key_id);
return (status != PSA_SUCCESS) ? psa_pk_status_to_mbedtls(status) : ret;
}

ret = mbedtls_ecp_point_read_binary(grp, Q, key_buf, key_len);

status = psa_destroy_key(key_id);
if (status != PSA_SUCCESS) {
return psa_pk_status_to_mbedtls(status);
}

return ret;
}
#endif /* MBEDTLS_ECP_FULL */

#if defined(MBEDTLS_ECP_C)
/*
* Parse a SEC1 encoded private EC key
Expand Down Expand Up @@ -975,11 +1029,21 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
}
}

if (!pubkey_done &&
(ret = mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G,
f_rng, p_rng)) != 0) {
mbedtls_ecp_keypair_free(eck);
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
if (!pubkey_done) {
#if defined(ECP_FULL)
if ((ret = mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G,
f_rng, p_rng)) != 0) {
mbedtls_ecp_keypair_free(eck);
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
#else /* ECP_FULL */
(void)f_rng;
(void)p_rng;
if ((ret = pk_derive_public_key(&eck->grp, &eck->Q, &eck->d)) != 0) {
mbedtls_ecp_keypair_free(eck);
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
#endif /* ECP_FULL */
}

if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
Expand Down
2 changes: 2 additions & 0 deletions library/psa_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ int psa_pk_status_to_mbedtls(psa_status_t status)
return MBEDTLS_ERR_PK_ALLOC_FAILED;
case PSA_ERROR_BAD_STATE:
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
case PSA_ERROR_INVALID_SIGNATURE:
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
case PSA_ERROR_DATA_CORRUPT:
case PSA_ERROR_DATA_INVALID:
case PSA_ERROR_STORAGE_FAILURE:
Expand Down
10 changes: 6 additions & 4 deletions tests/scripts/all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2239,17 +2239,19 @@ component_test_psa_crypto_config_accel_all_ec_algs_use_psa () {
# SHA-1 and all SHA-2 variants, as they are used by ECDSA deterministic.
loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512"
loc_accel_flags=$( echo "$loc_accel_list $loc_extra_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' )
make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS"
# Setting ECP_FULL in order to have full ECP support (including math) on
# the driver side
make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags -DECP_FULL" LDFLAGS="$ASAN_CFLAGS"

# Configure and build the main libraries with drivers enabled
# -----------------------------------------------------------

# Use the same config as reference, only without built-in EC algs
config_psa_crypto_config_all_ec_algs_use_psa 1

# Build the library
# Build the library (without ECP_FULL)
loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS"
make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" -C tests

# Make sure any built-in EC alg was not re-enabled by accident (additive config)
not grep mbedtls_ecdsa_ library/ecdsa.o
Expand All @@ -2263,7 +2265,7 @@ component_test_psa_crypto_config_accel_all_ec_algs_use_psa () {
make test

msg "ssl-opt: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated EC algs + USE_PSA"
tests/ssl-opt.sh
#tests/ssl-opt.sh
}

# Keep in sync with component_test_psa_crypto_config_accel_all_ec_algs_use_psa
Expand Down
2 changes: 1 addition & 1 deletion tests/suites/test_suite_ecp.function
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
/* END_HEADER */

/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_ECP_C
* depends_on:MBEDTLS_ECP_C:ECP_FULL
* END_DEPENDENCIES
*/

Expand Down
2 changes: 1 addition & 1 deletion tests/suites/test_suite_pk.data
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ mbedtls_pk_check_pair:"data_files/ec_256_pub.pem":"data_files/ec_256_prv.pem":0

Check pair #2 (EC, bad)
depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_PEM_PARSE_C
mbedtls_pk_check_pair:"data_files/ec_256_pub.pem":"data_files/server5.key":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
mbedtls_pk_check_pair:"data_files/ec_256_pub.pem":"data_files/server5.key":MBEDTLS_ERR_PK_BAD_INPUT_DATA

Check pair #3 (RSA, OK)
depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_PEM_PARSE_C
Expand Down
Loading