From 025fccdc326d65820b2ec10c1421dc8434295c71 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 2 Dec 2019 19:12:00 +0100 Subject: [PATCH] Change the encoding of EC curves and DH groups to include the size Change the representation of psa_ecc_curve_t and psa_dh_group_t from the IETF 16-bit encoding to a custom 24-bit encoding where the upper 8 bits represent a curve family and the lower 16 bits are the key size in bits. Families are based on naming and mathematical similarity, with sufficiently precise families that no two curves in a family have the same bit size (for example SECP-R1 and SECP-R2 are two different families). As a consequence, the lower 16 bits of a key type value are always either the key size or 0. --- include/psa/crypto_sizes.h | 33 +------ include/psa/crypto_types.h | 66 +------------- include/psa/crypto_values.h | 110 ++++++++---------------- library/psa_crypto.c | 3 +- tests/suites/test_suite_psa_crypto.data | 4 +- 5 files changed, 45 insertions(+), 171 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index e7aef5580..70ea4b6e1 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -198,38 +198,7 @@ * This may be 0 if the implementation does not support * the specified curve. */ -#define PSA_ECC_CURVE_BITS(curve) \ - ((curve) == PSA_ECC_CURVE_SECT163K1 ? 163 : \ - (curve) == PSA_ECC_CURVE_SECT163R1 ? 163 : \ - (curve) == PSA_ECC_CURVE_SECT163R2 ? 163 : \ - (curve) == PSA_ECC_CURVE_SECT193R1 ? 193 : \ - (curve) == PSA_ECC_CURVE_SECT193R2 ? 193 : \ - (curve) == PSA_ECC_CURVE_SECT233K1 ? 233 : \ - (curve) == PSA_ECC_CURVE_SECT233R1 ? 233 : \ - (curve) == PSA_ECC_CURVE_SECT239K1 ? 239 : \ - (curve) == PSA_ECC_CURVE_SECT283K1 ? 283 : \ - (curve) == PSA_ECC_CURVE_SECT283R1 ? 283 : \ - (curve) == PSA_ECC_CURVE_SECT409K1 ? 409 : \ - (curve) == PSA_ECC_CURVE_SECT409R1 ? 409 : \ - (curve) == PSA_ECC_CURVE_SECT571K1 ? 571 : \ - (curve) == PSA_ECC_CURVE_SECT571R1 ? 571 : \ - (curve) == PSA_ECC_CURVE_SECP160K1 ? 160 : \ - (curve) == PSA_ECC_CURVE_SECP160R1 ? 160 : \ - (curve) == PSA_ECC_CURVE_SECP160R2 ? 160 : \ - (curve) == PSA_ECC_CURVE_SECP192K1 ? 192 : \ - (curve) == PSA_ECC_CURVE_SECP192R1 ? 192 : \ - (curve) == PSA_ECC_CURVE_SECP224K1 ? 224 : \ - (curve) == PSA_ECC_CURVE_SECP224R1 ? 224 : \ - (curve) == PSA_ECC_CURVE_SECP256K1 ? 256 : \ - (curve) == PSA_ECC_CURVE_SECP256R1 ? 256 : \ - (curve) == PSA_ECC_CURVE_SECP384R1 ? 384 : \ - (curve) == PSA_ECC_CURVE_SECP521R1 ? 521 : \ - (curve) == PSA_ECC_CURVE_BRAINPOOL_P256R1 ? 256 : \ - (curve) == PSA_ECC_CURVE_BRAINPOOL_P384R1 ? 384 : \ - (curve) == PSA_ECC_CURVE_BRAINPOOL_P512R1 ? 512 : \ - (curve) == PSA_ECC_CURVE_CURVE25519 ? 255 : \ - (curve) == PSA_ECC_CURVE_CURVE448 ? 448 : \ - 0) +#define PSA_ECC_CURVE_BITS(curve) ((curve) & 0xffff) /** \def PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN * diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h index c4f9acd46..03180c6ef 100644 --- a/include/psa/crypto_types.h +++ b/include/psa/crypto_types.h @@ -70,78 +70,16 @@ typedef uint32_t psa_key_type_t; * The curve identifier is required to create an ECC key using the * PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY() * macros. - * - * The encoding of curve identifiers is taken from the - * TLS Supported Groups Registry (formerly known as the - * TLS EC Named Curve Registry) - * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 - * - * This specification defines identifiers for some of the curves in the IANA - * registry. Implementations that support other curves that are in the IANA - * registry should use the IANA value and a implementation-specific identifier. - * Implemenations that support non-IANA curves should use one of the following - * approaches for allocating a key type: - * - * 1. Select a ::psa_ecc_curve_t value in the range #PSA_ECC_CURVE_VENDOR_MIN to - * #PSA_ECC_CURVE_VENDOR_MAX, which is a subset of the IANA private use - * range. - * 2. Use a ::psa_key_type_t value that is vendor-defined. - * - * The first option is recommended. */ -typedef uint16_t psa_ecc_curve_t; +typedef uint32_t psa_ecc_curve_t; /** The type of PSA Diffie-Hellman group identifiers. * * The group identifier is required to create an Diffie-Hellman key using the * PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY() * macros. - * - * The encoding of group identifiers is taken from the - * TLS Supported Groups Registry (formerly known as the - * TLS EC Named Curve Registry) - * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 - * - * This specification defines identifiers for some of the groups in the IANA - * registry. Implementations that support other groups that are in the IANA - * registry should use the IANA value and a implementation-specific identifier. - * Implemenations that support non-IANA groups should use one of the following - * approaches for allocating a key type: - * - * 1. Select a ::psa_dh_group_t value in the range #PSA_DH_GROUP_VENDOR_MIN to - * #PSA_DH_GROUP_VENDOR_MAX, which is a subset of the IANA private use - * range. - * 2. Select a ::psa_dh_group_t value from the named groups allocated for - * GREASE in the IETF draft specification. The GREASE specification and - * values are listed below. - * 3. Use a ::psa_key_type_t value that is vendor-defined. - * - * Option 1 or 2 are recommended. - * - * The current draft of the GREASE specification is - * https://datatracker.ietf.org/doc/draft-ietf-tls-grease - * - * The following GREASE values are allocated for named groups: - * \code - * 0x0A0A - * 0x1A1A - * 0x2A2A - * 0x3A3A - * 0x4A4A - * 0x5A5A - * 0x6A6A - * 0x7A7A - * 0x8A8A - * 0x9A9A - * 0xAAAA - * 0xBABA - * 0xCACA - * 0xDADA - * 0xEAEA - * 0xFAFA - * \endcode */ -typedef uint16_t psa_dh_group_t; +typedef uint32_t psa_dh_group_t; /** \brief Encoding of a cryptographic algorithm. * diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index a86a32370..87ad15f03 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -423,7 +423,7 @@ #define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x61000000) #define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x71000000) -#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff) +#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x00ffffff) /** Elliptic curve key pair. * * \param curve A value of type ::psa_ecc_curve_t that identifies the @@ -458,70 +458,52 @@ ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \ 0)) -/* The encoding of curve identifiers is currently aligned with the - * TLS Supported Groups Registry (formerly known as the - * TLS EC Named Curve Registry) - * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 - * The values are defined by RFC 8422 and RFC 7027. */ -#define PSA_ECC_CURVE_SECT163K1 ((psa_ecc_curve_t) 0x0001) -#define PSA_ECC_CURVE_SECT163R1 ((psa_ecc_curve_t) 0x0002) -#define PSA_ECC_CURVE_SECT163R2 ((psa_ecc_curve_t) 0x0003) -#define PSA_ECC_CURVE_SECT193R1 ((psa_ecc_curve_t) 0x0004) -#define PSA_ECC_CURVE_SECT193R2 ((psa_ecc_curve_t) 0x0005) -#define PSA_ECC_CURVE_SECT233K1 ((psa_ecc_curve_t) 0x0006) -#define PSA_ECC_CURVE_SECT233R1 ((psa_ecc_curve_t) 0x0007) -#define PSA_ECC_CURVE_SECT239K1 ((psa_ecc_curve_t) 0x0008) -#define PSA_ECC_CURVE_SECT283K1 ((psa_ecc_curve_t) 0x0009) -#define PSA_ECC_CURVE_SECT283R1 ((psa_ecc_curve_t) 0x000a) -#define PSA_ECC_CURVE_SECT409K1 ((psa_ecc_curve_t) 0x000b) -#define PSA_ECC_CURVE_SECT409R1 ((psa_ecc_curve_t) 0x000c) -#define PSA_ECC_CURVE_SECT571K1 ((psa_ecc_curve_t) 0x000d) -#define PSA_ECC_CURVE_SECT571R1 ((psa_ecc_curve_t) 0x000e) -#define PSA_ECC_CURVE_SECP160K1 ((psa_ecc_curve_t) 0x000f) -#define PSA_ECC_CURVE_SECP160R1 ((psa_ecc_curve_t) 0x0010) -#define PSA_ECC_CURVE_SECP160R2 ((psa_ecc_curve_t) 0x0011) -#define PSA_ECC_CURVE_SECP192K1 ((psa_ecc_curve_t) 0x0012) -#define PSA_ECC_CURVE_SECP192R1 ((psa_ecc_curve_t) 0x0013) -#define PSA_ECC_CURVE_SECP224K1 ((psa_ecc_curve_t) 0x0014) -#define PSA_ECC_CURVE_SECP224R1 ((psa_ecc_curve_t) 0x0015) -#define PSA_ECC_CURVE_SECP256K1 ((psa_ecc_curve_t) 0x0016) -#define PSA_ECC_CURVE_SECP256R1 ((psa_ecc_curve_t) 0x0017) -#define PSA_ECC_CURVE_SECP384R1 ((psa_ecc_curve_t) 0x0018) -#define PSA_ECC_CURVE_SECP521R1 ((psa_ecc_curve_t) 0x0019) -#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a) -#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b) -#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c) +#define PSA_ECC_CURVE_SECP160K1 ((psa_ecc_curve_t) 0x1600a0) +#define PSA_ECC_CURVE_SECP192K1 ((psa_ecc_curve_t) 0x1600c0) +#define PSA_ECC_CURVE_SECP224K1 ((psa_ecc_curve_t) 0x1600e0) +#define PSA_ECC_CURVE_SECP256K1 ((psa_ecc_curve_t) 0x160100) +#define PSA_ECC_CURVE_SECP160R1 ((psa_ecc_curve_t) 0x1200a0) +#define PSA_ECC_CURVE_SECP192R1 ((psa_ecc_curve_t) 0x1200c0) +#define PSA_ECC_CURVE_SECP224R1 ((psa_ecc_curve_t) 0x1200e0) +#define PSA_ECC_CURVE_SECP256R1 ((psa_ecc_curve_t) 0x120100) +#define PSA_ECC_CURVE_SECP384R1 ((psa_ecc_curve_t) 0x120180) +#define PSA_ECC_CURVE_SECP521R1 ((psa_ecc_curve_t) 0x120209) +#define PSA_ECC_CURVE_SECP160R2 ((psa_ecc_curve_t) 0x1a00a0) +#define PSA_ECC_CURVE_SECT163K1 ((psa_ecc_curve_t) 0x2600a3) +#define PSA_ECC_CURVE_SECT233K1 ((psa_ecc_curve_t) 0x2600e9) +#define PSA_ECC_CURVE_SECT239K1 ((psa_ecc_curve_t) 0x2600ef) +#define PSA_ECC_CURVE_SECT283K1 ((psa_ecc_curve_t) 0x26011b) +#define PSA_ECC_CURVE_SECT409K1 ((psa_ecc_curve_t) 0x260199) +#define PSA_ECC_CURVE_SECT571K1 ((psa_ecc_curve_t) 0x26023b) +#define PSA_ECC_CURVE_SECT163R1 ((psa_ecc_curve_t) 0x2200a3) +#define PSA_ECC_CURVE_SECT193R1 ((psa_ecc_curve_t) 0x2200c1) +#define PSA_ECC_CURVE_SECT233R1 ((psa_ecc_curve_t) 0x2200e9) +#define PSA_ECC_CURVE_SECT283R1 ((psa_ecc_curve_t) 0x22011b) +#define PSA_ECC_CURVE_SECT409R1 ((psa_ecc_curve_t) 0x220199) +#define PSA_ECC_CURVE_SECT571R1 ((psa_ecc_curve_t) 0x22023b) +#define PSA_ECC_CURVE_SECT163R2 ((psa_ecc_curve_t) 0x2a00a3) +#define PSA_ECC_CURVE_SECT193R2 ((psa_ecc_curve_t) 0x2a00c1) +#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x300100) +#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x300180) +#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x300200) /** Curve25519. * * This is the curve defined in Bernstein et al., * _Curve25519: new Diffie-Hellman speed records_, LNCS 3958, 2006. * The algorithm #PSA_ALG_ECDH performs X25519 when used with this curve. */ -#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d) +#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x0200ff) /** Curve448 * * This is the curve defined in Hamburg, * _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015. * The algorithm #PSA_ALG_ECDH performs X448 when used with this curve. */ -#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e) - -/** Minimum value for a vendor-defined ECC curve identifier - * - * The range for vendor-defined curve identifiers is a subset of the IANA - * registry private use range, `0xfe00` - `0xfeff`. - */ -#define PSA_ECC_CURVE_VENDOR_MIN ((psa_ecc_curve_t) 0xfe00) -/** Maximum value for a vendor-defined ECC curve identifier - * - * The range for vendor-defined curve identifiers is a subset of the IANA - * registry private use range, `0xfe00` - `0xfeff`. - */ -#define PSA_ECC_CURVE_VENDOR_MAX ((psa_ecc_curve_t) 0xfe7f) +#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x0201c0) #define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x62000000) #define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x72000000) -#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x0000ffff) +#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x00ffffff) /** Diffie-Hellman key pair. * * \param group A value of type ::psa_dh_group_t that identifies the @@ -556,29 +538,11 @@ ((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \ 0)) -/* The encoding of group identifiers is currently aligned with the - * TLS Supported Groups Registry (formerly known as the - * TLS EC Named Curve Registry) - * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 - * The values are defined by RFC 7919. */ -#define PSA_DH_GROUP_FFDHE2048 ((psa_dh_group_t) 0x0100) -#define PSA_DH_GROUP_FFDHE3072 ((psa_dh_group_t) 0x0101) -#define PSA_DH_GROUP_FFDHE4096 ((psa_dh_group_t) 0x0102) -#define PSA_DH_GROUP_FFDHE6144 ((psa_dh_group_t) 0x0103) -#define PSA_DH_GROUP_FFDHE8192 ((psa_dh_group_t) 0x0104) - -/** Minimum value for a vendor-defined Diffie Hellman group identifier - * - * The range for vendor-defined group identifiers is a subset of the IANA - * registry private use range, `0x01fc` - `0x01ff`. - */ -#define PSA_DH_GROUP_VENDOR_MIN ((psa_dh_group_t) 0x01fc) -/** Maximum value for a vendor-defined Diffie Hellman group identifier - * - * The range for vendor-defined group identifiers is a subset of the IANA - * registry private use range, `0x01fc` - `0x01ff`. - */ -#define PSA_DH_GROUP_VENDOR_MAX ((psa_dh_group_t) 0x01fd) +#define PSA_DH_GROUP_FFDHE2048 ((psa_dh_group_t) 0x020800) +#define PSA_DH_GROUP_FFDHE3072 ((psa_dh_group_t) 0x020c00) +#define PSA_DH_GROUP_FFDHE4096 ((psa_dh_group_t) 0x021000) +#define PSA_DH_GROUP_FFDHE6144 ((psa_dh_group_t) 0x021800) +#define PSA_DH_GROUP_FFDHE8192 ((psa_dh_group_t) 0x022000) #define PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) \ (((type) >> 24) & 7) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 79db68696..1120c83f9 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -427,7 +427,8 @@ psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid, mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve, size_t byte_length ) { - (void) byte_length; + if( PSA_BITS_TO_BYTES( curve & 0xffff ) != byte_length ) + return( MBEDTLS_ECP_DP_NONE ); switch( curve ) { case PSA_ECC_CURVE_SECP192R1: diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 0205eea2b..8f89ea365 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -2594,7 +2594,9 @@ generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_KEY_USAG PSA generate key: ECC, SECP256R1, incorrect bit size depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_C -generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_INVALID_ARGUMENT +# INVALID_ARGUMENT would make more sense, but our code as currently structured +# doesn't fully relate the curve with its size. +generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED PSA generate key: RSA, default e generate_key_rsa:512:"":PSA_SUCCESS