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

Driver-only ECC: auto-enable ECP_LIGHT when needed #7717

Merged
merged 11 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions include/mbedtls/build_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,39 @@
#define MBEDTLS_MD_LIGHT
#endif

/* MBEDTLS_ECP_C now consists of MBEDTLS_ECP_LIGHT plus functions for curve
* arithmetic. As a consequence if MBEDTLS_ECP_C is required for some reason,
* then MBEDTLS_ECP_LIGHT should be enabled as well. */
#if defined(MBEDTLS_ECP_C)
/* MBEDTLS_ECP_LIGHT is auto-enabled by the following symbols:
* - MBEDTLS_ECP_C because now it consists of MBEDTLS_ECP_LIGHT plus functions
* for curve arithmetic. As a consequence if MBEDTLS_ECP_C is required for
* some reason, then MBEDTLS_ECP_LIGHT should be enabled as well.
* - MBEDTLS_PK_PARSE_EC_EXTENDED and MBEDTLS_PK_PARSE_EC_COMPRESSED because
* these features are not supported in PSA so the only way to have them is
* to enable the built-in solution.
* Both of them are temporary dependencies:
* - PK_PARSE_EC_EXTENDED will be removed after #7779 and #7789
* - support for compressed points should also be added to PSA, but in this
* case there is no associated issue to track it yet.
* - PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE because Weierstrass key derivation
* still depends on ECP_LIGHT.
* - PK_C + USE_PSA + PSA_WANT_ALG_ECDSA is a temporary dependency which will
* be fixed by #7453.
*/
#if defined(MBEDTLS_ECP_C) || \
defined(MBEDTLS_PK_PARSE_EC_EXTENDED) || \
defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \
(defined(MBEDTLS_PK_C) && defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDSA))
#define MBEDTLS_ECP_LIGHT
#endif

/* MBEDTLS_PK_PARSE_EC_COMPRESSED is introduced in MbedTLS version 3.5, while
* in previous version compressed points were automatically supported as long
* as PK_PARSE_C and ECP_C were enabled. As a consequence, for backward
* compatibility, we auto-enable PK_PARSE_EC_COMPRESSED when these conditions
* are met. */
#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_ECP_C)
#define MBEDTLS_PK_PARSE_EC_COMPRESSED
#endif

/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
* is defined as well to include all PSA code.
*/
Expand Down
13 changes: 13 additions & 0 deletions include/mbedtls/mbedtls_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,19 @@
*/
#define MBEDTLS_PK_PARSE_EC_EXTENDED

/**
* \def MBEDTLS_PK_PARSE_EC_COMPRESSED
*
* Enable the support for parsing public keys of type Short Weierstrass
* (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX) which are using the
* compressed point format. This parsing is done through ECP module's functions.
*
* \note As explained in the description of MBEDTLS_ECP_PF_COMPRESSED (in ecp.h)
* the only unsupported curves are MBEDTLS_ECP_DP_SECP224R1 and
* MBEDTLS_ECP_DP_SECP224K1.
*/
#define MBEDTLS_PK_PARSE_EC_COMPRESSED
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: in 3.4 this was not a separate option, support was automatically present in PK when ECP_C was defined. So, I think in order to preserve backward compatibility for people using a custom config we need to also auto-enable MBEDTLS_PK_PARSE_EC_COMPRESSED when PK_PARSE_C && ECP_C in build_info.h.


/**
* \def MBEDTLS_ERROR_STRERROR_DUMMY
*
Expand Down
8 changes: 6 additions & 2 deletions library/pkparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
}
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */

#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) && defined(MBEDTLS_PK_PARSE_EC_COMPRESSED)
/*
* Create a temporary ecp_keypair for converting an EC point in compressed
* format to an uncompressed one
Expand Down Expand Up @@ -717,7 +717,7 @@ static int pk_convert_compressed_ec(mbedtls_pk_context *pk,
mbedtls_ecp_keypair_free(&ecp_key);
return ret;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA && MBEDTLS_PK_PARSE_EC_COMPRESSED */

/*
* EC public key is an EC point
Expand All @@ -744,12 +744,16 @@ static int pk_get_ecpubkey(unsigned char **p, const unsigned char *end,
* consequence ecp functions are used to "convert" the point to
* uncompressed format */
if ((**p == 0x02) || (**p == 0x03)) {
#if defined(MBEDTLS_PK_PARSE_EC_COMPRESSED)
ret = pk_convert_compressed_ec(pk, *p, len,
&(pk->pub_raw_len), pk->pub_raw,
PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
if (ret != 0) {
return ret;
}
#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
} else {
/* Uncompressed format */
if ((end - *p) > MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN) {
Expand Down
49 changes: 26 additions & 23 deletions tests/scripts/all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,9 @@ component_test_full_no_bignum () {
scripts/config.py unset MBEDTLS_ECDSA_C
scripts/config.py unset MBEDTLS_ECJPAKE_C
scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
# Disable what auto-enables ECP_LIGHT
scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
# Indirect dependencies of ECP
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
Expand Down Expand Up @@ -2323,10 +2326,10 @@ component_test_psa_crypto_config_accel_pake() {
#
# This is used by the two following components to ensure they always use the
# same config, except for the use of driver or built-in EC algorithms:
# - component_test_psa_crypto_config_accel_all_ec_algs_use_psa;
# - component_test_psa_crypto_config_reference_all_ec_algs_use_psa.
# - component_test_psa_crypto_config_accel_ecc_ecp_light_only;
# - component_test_psa_crypto_config_reference_ecc_ecp_light_only.
# This supports comparing their test coverage with analyze_outcomes.py.
config_psa_crypto_config_all_ec_algs_use_psa () {
config_psa_crypto_config_ecp_ligh_only () {
DRIVER_ONLY="$1"
# start with config full for maximum coverage (also enables USE_PSA)
helper_libtestdriver1_adjust_config "full"
Expand All @@ -2344,8 +2347,8 @@ config_psa_crypto_config_all_ec_algs_use_psa () {
scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
}

# Keep in sync with component_test_psa_crypto_config_reference_all_ec_algs_use_psa
component_test_psa_crypto_config_accel_all_ec_algs_use_psa () {
# Keep in sync with component_test_psa_crypto_config_reference_ecc_ecp_light_only
component_test_psa_crypto_config_accel_ecc_ecp_light_only () {
msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated EC algs + USE_PSA"

# Algorithms and key types to accelerate
Expand All @@ -2358,11 +2361,7 @@ component_test_psa_crypto_config_accel_all_ec_algs_use_psa () {
# ---------

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

# Temporary hack to enable MBEDTLS_ECP_LIGHT
# (will soon be auto-enabled in build_info.h)
echo '#define MBEDTLS_ECP_LIGHT' >> include/mbedtls/mbedtls_config.h
config_psa_crypto_config_ecp_ligh_only 1

# Build
# -----
Expand All @@ -2389,11 +2388,11 @@ component_test_psa_crypto_config_accel_all_ec_algs_use_psa () {
tests/ssl-opt.sh
}

# Keep in sync with component_test_psa_crypto_config_accel_all_ec_algs_use_psa
component_test_psa_crypto_config_reference_all_ec_algs_use_psa () {
# Keep in sync with component_test_psa_crypto_config_accel_ecc_ecp_light_only
component_test_psa_crypto_config_reference_ecc_ecp_light_only () {
msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with non-accelerated EC algs + USE_PSA"

config_psa_crypto_config_all_ec_algs_use_psa 0
config_psa_crypto_config_ecp_ligh_only 0

make

Expand All @@ -2405,8 +2404,8 @@ component_test_psa_crypto_config_reference_all_ec_algs_use_psa () {
}

# This helper function is used by:
# - component_test_psa_crypto_full_accel_all_ec_algs_no_ecp_use_psa()
# - component_test_psa_crypto_full_reference_all_ec_algs_no_ecp_use_psa()
# - component_test_psa_crypto_config_accel_ecc_no_ecp_at_all()
# - component_test_psa_crypto_config_reference_ecc_no_ecp_at_all()
# to ensure that both tests use the same underlying configuration when testing
# driver's coverage with analyze_outcomes.py.
#
Expand All @@ -2417,7 +2416,7 @@ component_test_psa_crypto_config_reference_all_ec_algs_use_psa () {
#
# PK_C and RSA_C are always disabled to ensure there is no remaining dependency
# on the ECP module.
config_psa_crypto_full_all_ec_algs_no_ecp_use_psa () {
config_psa_crypto_no_ecp_at_all () {
DRIVER_ONLY="$1"
# start with crypto_full config for maximum coverage (also enables USE_PSA),
# but excluding X509, TLS and key exchanges
Expand All @@ -2432,7 +2431,6 @@ config_psa_crypto_full_all_ec_algs_no_ecp_use_psa () {
scripts/config.py unset MBEDTLS_ECJPAKE_C
# Disable ECP module (entirely)
scripts/config.py unset MBEDTLS_ECP_C
scripts/config.py unset MBEDTLS_ECP_LIGHT
fi

# Disable PK module since it depends on ECP
Expand All @@ -2451,6 +2449,11 @@ config_psa_crypto_full_all_ec_algs_no_ecp_use_psa () {
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED

# Disable all the features that auto-enable ECP_LIGHT (see build_info.h)
scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE

# Restartable feature is not yet supported by PSA. Once it will in
# the future, the following line could be removed (see issues
# 6061, 6332 and following ones)
Expand All @@ -2471,8 +2474,8 @@ config_psa_crypto_full_all_ec_algs_no_ecp_use_psa () {
# all support and dependencies from ECP and ECP_LIGHT are removed on the library
# side.
#
# Keep in sync with component_test_psa_crypto_full_reference_all_ec_algs_no_ecp_use_psa()
component_test_psa_crypto_full_accel_all_ec_algs_no_ecp_use_psa () {
# Keep in sync with component_test_psa_crypto_config_reference_ecc_no_ecp_at_all()
component_test_psa_crypto_config_accel_ecc_no_ecp_at_all () {
msg "build: crypto_full + accelerated EC algs + USE_PSA - ECP"

# Algorithms and key types to accelerate
Expand All @@ -2485,7 +2488,7 @@ component_test_psa_crypto_full_accel_all_ec_algs_no_ecp_use_psa () {
# ---------

# Set common configurations between library's and driver's builds
config_psa_crypto_full_all_ec_algs_no_ecp_use_psa 1
config_psa_crypto_no_ecp_at_all 1

# Build
# -----
Expand Down Expand Up @@ -2514,12 +2517,12 @@ component_test_psa_crypto_full_accel_all_ec_algs_no_ecp_use_psa () {
}

# Reference function used for driver's coverage analysis in analyze_outcomes.py
# in conjunction with component_test_psa_crypto_full_accel_all_ec_algs_no_ecp_use_psa().
# in conjunction with component_test_psa_crypto_config_accel_ecc_no_ecp_at_all().
# Keep in sync with its accelerated counterpart.
component_test_psa_crypto_full_reference_all_ec_algs_no_ecp_use_psa () {
component_test_psa_crypto_config_reference_ecc_no_ecp_at_all () {
msg "build: crypto_full + non accelerated EC algs + USE_PSA"

config_psa_crypto_full_all_ec_algs_no_ecp_use_psa 0
config_psa_crypto_no_ecp_at_all 0

make

Expand Down
20 changes: 13 additions & 7 deletions tests/scripts/analyze_outcomes.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,11 @@ def do_analyze_driver_vs_reference(outcome_file, args):
}
}
},
'analyze_driver_vs_reference_all_ec_algs': {
'analyze_driver_vs_reference_ecp_light_only': {
'test_function': do_analyze_driver_vs_reference,
'args': {
'component_ref': 'test_psa_crypto_config_reference_all_ec_algs_use_psa',
'component_driver': 'test_psa_crypto_config_accel_all_ec_algs_use_psa',
'component_ref': 'test_psa_crypto_config_reference_ecc_ecp_light_only',
'component_driver': 'test_psa_crypto_config_accel_ecc_ecp_light_only',
'ignored_suites': [
'ecdsa',
'ecdh',
Expand Down Expand Up @@ -265,11 +265,11 @@ def do_analyze_driver_vs_reference(outcome_file, args):
}
}
},
'analyze_driver_vs_reference_all_ec_algs_no_ecp': {
'analyze_driver_vs_reference_no_ecp_at_all': {
'test_function': do_analyze_driver_vs_reference,
'args': {
'component_ref': 'test_psa_crypto_full_reference_all_ec_algs_no_ecp_use_psa',
'component_driver': 'test_psa_crypto_full_accel_all_ec_algs_no_ecp_use_psa',
'component_ref': 'test_psa_crypto_config_reference_ecc_no_ecp_at_all',
'component_driver': 'test_psa_crypto_config_accel_ecc_no_ecp_at_all',
'ignored_suites': [
# Ignore test suites for the modules that are disabled in the
# accelerated test case.
Expand All @@ -296,7 +296,13 @@ def do_analyze_driver_vs_reference(outcome_file, args):
'PSA key derivation: bits=7 invalid for ECC SECT_K1 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECT_R1 (ECC enabled)',
'PSA key derivation: bits=7 invalid for ECC SECT_R2 (ECC enabled)',
]
],
'test_suite_pkparse': [
# See description provided for the analyze_driver_vs_reference_all_ec_algs
# case above.
('Key ASN1 (OneAsymmetricKey X25519, doesn\'t match masking '
'requirements, from RFC8410 Appendix A but made into version 0)'),
],
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions tests/scripts/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ def test(self, options):
'MBEDTLS_ECDH_C',
'MBEDTLS_ECJPAKE_C',
'MBEDTLS_ECP_RESTARTABLE',
'MBEDTLS_PK_PARSE_EC_EXTENDED',
'MBEDTLS_PK_PARSE_EC_COMPRESSED',
'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED',
Expand Down
Loading