Dispatch sign/verify funtions through the driver interface

Signed-off-by: gabor-mezei-arm <gabor.mezei@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 4cb6ff3..00558e1 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -2917,20 +2917,9 @@
 
     if( operation == PSA_SIGN_MESSAGE )
     {
-        size_t hash_length;
-        uint8_t hash[PSA_HASH_MAX_SIZE];
-
-        status = psa_driver_wrapper_hash_compute( PSA_ALG_SIGN_GET_HASH( alg ),
-                                                  input, input_length,
-                                                  hash, sizeof( hash ),
-                                                  &hash_length );
-
-        if( status != PSA_SUCCESS )
-            goto exit;
-
-        status = psa_driver_wrapper_sign_hash(
+        status = psa_driver_wrapper_sign_message(
             &attributes, slot->key.data, slot->key.bytes,
-            alg, hash, hash_length,
+            alg, input, input_length,
             signature, signature_size, signature_length );
     }
     else if( operation == PSA_SIGN_HASH )
@@ -3006,20 +2995,9 @@
 
     if( operation == PSA_VERIFY_MESSAGE )
     {
-        size_t hash_length;
-        uint8_t hash[PSA_HASH_MAX_SIZE];
-
-        status = psa_driver_wrapper_hash_compute( PSA_ALG_SIGN_GET_HASH( alg ),
-                                                  input, input_length,
-                                                  hash, sizeof( hash ),
-                                                  &hash_length );
-
-        if( status != PSA_SUCCESS )
-            goto exit;
-
-        status = psa_driver_wrapper_verify_hash(
+        status = psa_driver_wrapper_verify_message(
             &attributes, slot->key.data, slot->key.bytes,
-            alg, hash, hash_length,
+            alg, input, input_length,
             signature, signature_length );
     }
     else if( operation == PSA_VERIFY_HASH )
@@ -3030,13 +3008,41 @@
             signature, signature_length );
     }
 
-exit:
     unlock_status = psa_unlock_key_slot( slot );
 
     return( ( status == PSA_SUCCESS ) ? unlock_status : status );
 
 }
 
+psa_status_t psa_sign_message_internal(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *signature,
+    size_t signature_size,
+    size_t *signature_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    size_t hash_length;
+    uint8_t hash[PSA_HASH_MAX_SIZE];
+
+    status = psa_driver_wrapper_hash_compute( PSA_ALG_SIGN_GET_HASH( alg ),
+                                              input, input_length,
+                                              hash, sizeof( hash ),
+                                              &hash_length );
+
+    if( status != PSA_SUCCESS )
+        return status;
+
+    return psa_sign_hash_internal(
+                attributes, key_buffer, key_buffer_size,
+                alg, hash, hash_length,
+                signature, signature_size, signature_length );
+}
+
 psa_status_t psa_sign_message( mbedtls_svc_key_id_t key,
                                psa_algorithm_t alg,
                                const uint8_t * input,
@@ -3050,6 +3056,34 @@
         signature, signature_size, signature_length );
 }
 
+psa_status_t psa_verify_message_internal(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    const uint8_t *signature,
+    size_t signature_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    size_t hash_length;
+    uint8_t hash[PSA_HASH_MAX_SIZE];
+
+    status = psa_driver_wrapper_hash_compute( PSA_ALG_SIGN_GET_HASH( alg ),
+                                              input, input_length,
+                                              hash, sizeof( hash ),
+                                              &hash_length );
+
+    if( status != PSA_SUCCESS )
+        return status;
+
+    return psa_verify_hash_internal(
+                attributes, key_buffer, key_buffer_size,
+                alg, hash, hash_length,
+                signature, signature_length );
+}
+
 psa_status_t psa_verify_message( mbedtls_svc_key_id_t key,
                                  psa_algorithm_t alg,
                                  const uint8_t * input,
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index d51d226..2ca5abd 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -357,6 +357,79 @@
                                         uint8_t *key_buffer,
                                         size_t key_buffer_size,
                                         size_t *key_buffer_length );
+/** Sign a message with a private key. For hash-and-sign algorithms,
+ *  this includes the hashing step.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       sign_message entry point. This function behaves as a sign_message
+ *       entry point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * \param[in]  attributes       The attributes of the key to use for the
+ *                              operation.
+ * \param[in]  key_buffer       The buffer containing the key context.
+ * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
+ * \param[in]  alg              A signature algorithm that is compatible with
+ *                              the type of the key.
+ * \param[in]  input            The input message to sign.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[out] signature        Buffer where the signature is to be written.
+ * \param[in]  signature_size   Size of the \p signature buffer in bytes.
+ * \param[out] signature_length On success, the number of bytes
+ *                              that make up the returned signature value.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p signature buffer is too small. You can
+ *         determine a sufficient buffer size by calling
+ *         #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ *         where \c key_type and \c key_bits are the type and bit-size
+ *         respectively of the key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ */
+psa_status_t psa_sign_message_internal(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg, const uint8_t *input, size_t input_length,
+    uint8_t *signature, size_t signature_size, size_t *signature_length );
+
+/** Verify the signature of a message with a public key, using
+ *  a hash-and-sign verification algorithm.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       verify_message entry point. This function behaves as a verify_message
+ *       entry point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * \param[in]  attributes       The attributes of the key to use for the
+ *                              operation.
+ * \param[in]  key_buffer       The buffer containing the key context.
+ * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
+ * \param[in]  alg              A signature algorithm that is compatible with
+ *                              the type of the key.
+ * \param[in]  input            The message whose signature is to be verified.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[in]  signature        Buffer containing the signature to verify.
+ * \param[in]  signature_length Size of the \p signature buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         The signature is valid.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ *         The calculation was performed successfully, but the passed
+ *         signature is not a valid signature.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ */
+psa_status_t psa_verify_message_internal(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg, const uint8_t *input, size_t input_length,
+    const uint8_t *signature, size_t signature_length );
 
 /** Sign an already-calculated hash with a private key.
  *
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 9bef02c..db0d0f7 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -64,6 +64,210 @@
 #endif
 
 /* Start delegation functions */
+psa_status_t psa_driver_wrapper_sign_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *signature,
+    size_t signature_size,
+    size_t *signature_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    /* Try dynamically-registered SE interface first */
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+    const psa_drv_se_t *drv;
+    psa_drv_se_context_t *drv_context;
+
+    if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+    {
+        if( drv->asymmetric == NULL ||
+            drv->asymmetric->p_sign == NULL )
+        {
+            /* Key is defined in SE, but we have no way to exercise it */
+            return( PSA_ERROR_NOT_SUPPORTED );
+        }
+
+        size_t hash_length;
+        uint8_t hash[PSA_HASH_MAX_SIZE];
+
+        status = psa_driver_wrapper_hash_compute( PSA_ALG_SIGN_GET_HASH( alg ),
+                                                  input, input_length,
+                                                  hash, sizeof( hash ),
+                                                  &hash_length );
+
+        if( status != PSA_ERROR_NOT_SUPPORTED )
+            return( status );
+
+        return( drv->asymmetric->p_sign(
+                    drv_context, *( (psa_key_slot_number_t *)key_buffer ),
+                    alg, hash, hash_length,
+                    signature, signature_size, signature_length ) );
+    }
+#endif /* PSA_CRYPTO_SE_C */
+
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+
+    switch( location )
+    {
+        case PSA_KEY_LOCATION_LOCAL_STORAGE:
+            /* Key is stored in the slot in export representation, so
+             * cycle through all known transparent accelerators */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+            status = mbedtls_test_transparent_signature_sign_message(
+                        attributes,
+                        key_buffer,
+                        key_buffer_size,
+                        alg,
+                        input,
+                        input_length,
+                        signature,
+                        signature_size,
+                        signature_length );
+            /* Declared with fallback == true */
+            if( status != PSA_ERROR_NOT_SUPPORTED )
+                return( status );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+            /* Fell through, meaning no accelerator supports this operation */
+            return( psa_sign_message_internal( attributes,
+                                               key_buffer,
+                                               key_buffer_size,
+                                               alg,
+                                               input,
+                                               input_length,
+                                               signature,
+                                               signature_size,
+                                               signature_length ) );
+
+        /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
+            return( mbedtls_test_opaque_signature_sign_message(
+                        attributes,
+                        key_buffer,
+                        key_buffer_size,
+                        alg,
+                        input,
+                        input_length,
+                        signature,
+                        signature_size,
+                        signature_length ) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+        default:
+            /* Key is declared with a lifetime not known to us */
+            (void)status;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
+psa_status_t psa_driver_wrapper_verify_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    const uint8_t *signature,
+    size_t signature_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    /* Try dynamically-registered SE interface first */
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+    const psa_drv_se_t *drv;
+    psa_drv_se_context_t *drv_context;
+
+    if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+    {
+        if( drv->asymmetric == NULL ||
+            drv->asymmetric->p_verify == NULL )
+        {
+            /* Key is defined in SE, but we have no way to exercise it */
+            return( PSA_ERROR_NOT_SUPPORTED );
+        }
+
+        size_t hash_length;
+        uint8_t hash[PSA_HASH_MAX_SIZE];
+
+        status = psa_driver_wrapper_hash_compute( PSA_ALG_SIGN_GET_HASH( alg ),
+                                                  input, input_length,
+                                                  hash, sizeof( hash ),
+                                                  &hash_length );
+
+        if( status != PSA_ERROR_NOT_SUPPORTED )
+            return( status );
+
+        return( drv->asymmetric->p_verify(
+                    drv_context, *( (psa_key_slot_number_t *)key_buffer ),
+                    alg, hash, hash_length,
+                    signature, signature_length ) );
+    }
+#endif /* PSA_CRYPTO_SE_C */
+
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+
+    switch( location )
+    {
+        case PSA_KEY_LOCATION_LOCAL_STORAGE:
+            /* Key is stored in the slot in export representation, so
+             * cycle through all known transparent accelerators */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+            status = mbedtls_test_transparent_signature_verify_message(
+                        attributes,
+                        key_buffer,
+                        key_buffer_size,
+                        alg,
+                        input,
+                        input_length,
+                        signature,
+                        signature_length );
+            /* Declared with fallback == true */
+            if( status != PSA_ERROR_NOT_SUPPORTED )
+                return( status );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+            return( psa_verify_message_internal( attributes,
+                                                 key_buffer,
+                                                 key_buffer_size,
+                                                 alg,
+                                                 input,
+                                                 input_length,
+                                                 signature,
+                                                 signature_length ) );
+
+        /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
+            return( mbedtls_test_opaque_signature_verify_message(
+                        attributes,
+                        key_buffer,
+                        key_buffer_size,
+                        alg,
+                        input,
+                        input_length,
+                        signature,
+                        signature_length ) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+        default:
+            /* Key is declared with a lifetime not known to us */
+            (void)status;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
 psa_status_t psa_driver_wrapper_sign_hash(
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer, size_t key_buffer_size,
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index e82d093..956b648 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -28,6 +28,27 @@
 /*
  * Signature functions
  */
+psa_status_t psa_driver_wrapper_sign_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *signature,
+    size_t signature_size,
+    size_t *signature_length );
+
+psa_status_t psa_driver_wrapper_verify_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    const uint8_t *signature,
+    size_t signature_length );
+
 psa_status_t psa_driver_wrapper_sign_hash(
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer, size_t key_buffer_size,