PSA PAKE: reintroduce psa_pake_primitive_t

If PSA_PAKE_OUTPUT_SIZE takes cipher_suite as a parameter and it is a
structure it can't be a compile-time constant anymore.

Reintroducing psa_pake_primitive_t, because it can be constructed as an
integral type and holds enough information to allow PSA_PAKE_OUTPUT_SIZE
calculating accurate estimates on the output size in compile time.

Signed-off-by: Janos Follath <janos.follath@arm.com>
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index a2f34ca..ec5c16c 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -4145,107 +4145,30 @@
  * This function may be provided as a function-like macro, but in this case it
  * must evaluate its argument exactly once.
  *
- * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
- * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
- * for more information.
- *
  * \param[in] cipher_suite     The cipher suite structure to query.
  *
- * \return The primitive type stored in the cipher suite structure.
+ * \return The primitive stored in the cipher suite structure.
  */
-static psa_pake_primitive_type_t psa_pake_cs_get_type(
+static psa_pake_primitive_t psa_pake_cs_get_primitive(
                            const psa_pake_cipher_suite_t* cipher_suite
                            );
 
 /** Declare the primitive type for a PAKE cipher suite.
  *
- * This function overwrites any primitive type
- * previously set in \p cipher_suite.
+ * This function overwrites any primitive previously set in \p cipher_suite.
  *
  * This function may be declared as `static` (i.e. without external
  * linkage). This function may be provided as a function-like macro,
  * but in this case it must evaluate each of its arguments exactly once.
  *
  * \param[out] cipher_suite    The cipher suite structure to write to.
- * \param type                 The primitive type to write.
- *                             If this is 0, the primitive type in
- *                             \p cipher_suite becomes unspecified.
+ * \param primitive            The primitive to write. If this is 0, the
+ *                             primitive type in \p cipher_suite becomes
+ *                             unspecified.
  */
-static void psa_pake_cs_set_type(
+static void psa_pake_cs_set_primitive(
                            psa_pake_cipher_suite_t* cipher_suite,
-                           psa_pake_primitive_type_t type
-                           );
-
-/** Retrieve the primitive family from a PAKE cipher suite.
- *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate its argument exactly once.
- *
- * \param[in] cipher_suite      The cipher suite structure to query.
- *
- * \return The primitive family stored in the cipher suite structure.
- */
-static psa_pake_family_t psa_pake_cs_get_family(
-                           const psa_pake_cipher_suite_t* cipher_suite
-                           );
-
-/** Declare the primitive family for a PAKE cipher suite.
- *
- * This function overwrites any primitive family
- * previously set in \p cipher_suite.
- *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate each of its arguments exactly once.
- *
- * \param[out] cipher_suite     The cipher suite structure to write to.
- * \param family                The primitive family to write.
- *                              If this is 0, the primitive family in
- *                              \p cipher_suite becomes unspecified. The
- *                              interpretation of this parameter depends on
- *                              the primitive type. For more information
- *                              consult the documentation of individual
- *                              ::psa_pake_primitive_type_t constants).
- */
-static void psa_pake_cs_set_family(
-                           psa_pake_cipher_suite_t* cipher_suite,
-                           psa_pake_family_t family
-                           );
-
-/** Retrieve the size associated with the primitive from a PAKE cipher suite.
- *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate its argument exactly once.
- *
- * \param[in] cipher_suite      The cipher suite structure to query.
- *
- * \return The primitive bits stored in the cipher suite structure.
- */
-static size_t psa_pake_cs_get_bits(const psa_pake_cipher_suite_t* cipher_suite);
-
-/** Declare the primitive bits for a PAKE cipher suite.
- *
- * This function overwrites any primitive bits
- * previously set in \p cipher_suite.
- *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate each of its arguments exactly once.
- *
- * \param[out] cipher_suite     The cipher suite structure to write to.
- * \param bits                  The primitive bits to write.
- *                              If this is 0, the primitive bits in
- *                              \p cipher_suite becomes unspecified. The
- *                              interpretation of this parameter depends on
- *                              the family, for more information consult the
- *                              documentation of individual
- *                              ::psa_pake_primitive_type_t constants).
- */
-static void psa_pake_cs_set_bits(
-                           psa_pake_cipher_suite_t* cipher_suite,
-                           size_t bits
+                           psa_pake_primitive_t primitive
                            );
 
 /** Retrieve the hash algorithm from a PAKE cipher suite.
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index 9d2f6c4..d8fc997 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -1143,7 +1143,7 @@
  *
  * \param alg           A PAKE algorithm (PSA_ALG_XXX value such that
  *                      #PSA_ALG_IS_PAKE(\p alg) is true).
- * \param cipher_suite  A cipher suite that is compatible with algorithm \p alg.
+ * \param primitive     A primitive that is compatible with algorithm \p alg.
  * \param output_step   A value of type ::psa_pake_step_t that is valid for the
  *                      algorithm \p alg.
  * \return              A sufficient output buffer size for the specified
@@ -1151,7 +1151,7 @@
  *                      the output type or PAKE algorithm is not recognized, or
  *                      the parameters are incompatible, return 0.
  */
-#define PSA_PAKE_OUTPUT_SIZE(alg, cipher_suite, output_step)
+#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step)
 
 /** Output buffer size for psa_pake_output() for any of the supported cipher
  * suites and PAKE algorithms.
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 97d5d2b..a5f35cb 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -466,10 +466,16 @@
     psa_algorithm_t algorithm;
     psa_pake_primitive_type_t type;
     psa_pake_family_t family;
-    size_t  bits;
+    uint16_t  bits;
     psa_algorithm_t hash;
 };
 
+static inline psa_algorithm_t psa_pake_cs_get_algorithm(
+    const psa_pake_cipher_suite_t *cipher_suite)
+{
+    return( cipher_suite->algorithm );
+}
+
 static inline void psa_pake_cs_set_algorithm(
     psa_pake_cipher_suite_t *cipher_suite,
     psa_algorithm_t algorithm)
@@ -480,49 +486,20 @@
         cipher_suite->algorithm = algorithm;
 }
 
-static inline psa_algorithm_t psa_pake_cs_get_algorithm(
+static inline psa_pake_primitive_t psa_pake_cs_get_primitive(
     const psa_pake_cipher_suite_t *cipher_suite)
 {
-    return( cipher_suite->algorithm );
+    return( PSA_PAKE_PRIMITIVE( cipher_suite->type, cipher_suite->family,
+                cipher_suite->bits) );
 }
 
-static inline psa_pake_primitive_type_t psa_pake_cs_get_type(
-    const psa_pake_cipher_suite_t *cipher_suite)
-{
-    return( cipher_suite->type );
-}
-
-static inline void psa_pake_cs_set_type(
+static inline void psa_pake_cs_set_primitive(
     psa_pake_cipher_suite_t *cipher_suite,
-    psa_pake_primitive_type_t type)
+    psa_pake_primitive_t primitive)
 {
-    cipher_suite->type = type;
-}
-
-static inline psa_pake_family_t psa_pake_cs_get_family(
-    const psa_pake_cipher_suite_t *cipher_suite)
-{
-    return( cipher_suite->family );
-}
-
-static inline void psa_pake_cs_set_family(
-    psa_pake_cipher_suite_t *cipher_suite,
-    psa_pake_family_t family)
-{
-    cipher_suite->family = family;
-}
-
-static inline size_t psa_pake_cs_get_bits(
-    const psa_pake_cipher_suite_t *cipher_suite)
-{
-    return( cipher_suite->bits );
-}
-
-static inline void psa_pake_cs_set_bits(
-    psa_pake_cipher_suite_t *cipher_suite,
-    size_t bits)
-{
-    cipher_suite->bits = bits;
+    cipher_suite->type = (psa_pake_primitive_type_t) primitive >> 24;
+    cipher_suite->family = (psa_pake_family_t) ( 0xFF & (primitive >> 16) );
+    cipher_suite->bits = (uint16_t) ( 0xFFFF & primitive );
 }
 
 static inline psa_algorithm_t psa_pake_cs_get_hash(
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index bf8ab15..5418bd7 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -415,5 +415,11 @@
  * PSA_PAKE_PRIMITIVE_TYPE_XXX constants.
  */
 typedef uint8_t psa_pake_family_t;
+
+/** \brief Encoding of the primitive associated with the PAKE.
+ *
+ * For more information see the documentation of the #PSA_PAKE_PRIMITIVE macro.
+ */
+typedef uint32_t psa_pake_primitive_t;
 /**@}*/
 #endif /* PSA_CRYPTO_TYPES_H */
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index a920023..cb4c604 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -2546,6 +2546,30 @@
  */
 #define PSA_PAKE_PRIMITIVE_TYPE_DH       ((psa_pake_primitive_type_t)0x02)
 
+/** Construct a PAKE primitive from type, family and bitsize.
+ *
+ * \param pake_type     The type of the primitive
+ *                      (value of type ::psa_pake_primitive_type_t).
+ * \param pake_family   The family of the primitive
+ *                      (the type and interpretation of this parameter depends
+ *                      on \p type, for more information consult the
+ *                      documentation of individual ::psa_pake_primitive_type_t
+ *                      constants).
+ * \param pake_bits     The bitsize of the primitive
+ *                      (Value of type \c size_t. The interpretation
+ *                      of this parameter depends on \p family, for more
+ *                      information consult the documentation of individual
+ *                      ::psa_pake_primitive_type_t constants).
+ *
+ * \return The constructed primitive value of type ::psa_pake_primitive_t.
+ *         Return 0 if the requested primitive can't be encoded as
+ *         ::psa_pake_primitive_t.
+ */
+#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \
+    (pake_bits > 0xFFFF) ? 0 :                                \
+    ((psa_pake_primitive_t) (((pake_type) << 24 |             \
+            (pake_family) << 16) | (pake_bits)))
+
 /** The key share being sent to or received from the peer.
  *
  * Unless the documentation of the PAKE algorithm says otherwise this is a