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.
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index e7aef55..70ea4b6 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 c4f9acd..03180c6 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -70,78 +70,16 @@
  * 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 a86a323..87ad15f 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 79db686..1120c83 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -427,7 +427,8 @@
 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 0205eea..8f89ea3 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -2594,7 +2594,9 @@
 
 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