Reject key agreement chained with PSA_ALG_TLS12_ECJPAKE_TO_PMS

The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
used on a shared secret from a key agreement since its input must be
an ECC public key. Reject this properly.

This is tested by test_suite_psa_crypto_op_fail.generated.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt b/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt
new file mode 100644
index 0000000..cfea661
--- /dev/null
+++ b/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
+     used on a shared secret from a key agreement since its input must be
+     an ECC public key. Reject this properly.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index cb5791f..145054f 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -5176,6 +5176,17 @@
     (void) alg;
     return( PSA_ERROR_NOT_SUPPORTED );
 }
+
+static int psa_key_derivation_allows_free_form_secret_input(
+    psa_algorithm_t kdf_alg )
+{
+#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
+    if( kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS )
+        return( 0 );
+#endif
+    (void) kdf_alg;
+    return( 1 );
+}
 #endif /* AT_LEAST_ONE_BUILTIN_KDF */
 
 psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation,
@@ -5196,6 +5207,8 @@
         status = psa_key_agreement_try_support( ka_alg );
         if( status != PSA_SUCCESS )
             return( status );
+        if( ! psa_key_derivation_allows_free_form_secret_input( kdf_alg ) )
+            return( PSA_ERROR_INVALID_ARGUMENT );
         status = psa_key_derivation_setup_kdf( operation, kdf_alg );
 #else
         return( PSA_ERROR_NOT_SUPPORTED );