Remove MD dependency from pkcs12 module

Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
diff --git a/library/pkcs12.c b/library/pkcs12.c
index e725a97..8dd5f74 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -39,6 +39,9 @@
 #include "mbedtls/des.h"
 #endif
 
+#include "hash_info.h"
+#include "mbedtls/psa_util.h"
+
 #if defined(MBEDTLS_ASN1_PARSE_C)
 
 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
@@ -209,6 +212,108 @@
     }
 }
 
+
+static int calculate_hashes( mbedtls_md_type_t md_type, int iterations,
+    unsigned char *diversifier, unsigned char *salt_block,
+    unsigned char *pwd_block, unsigned char *hash_output, int use_salt,
+    int use_password, size_t hlen, size_t v )
+{
+#if defined(MBEDTLS_MD_C)
+    int ret = -1;
+    size_t i;
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+    md_info = mbedtls_md_info_from_type( md_type );
+    if( md_info == NULL )
+        return ( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+
+    mbedtls_md_init( &md_ctx );
+
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        return ( ret );
+    // Calculate hash( diversifier || salt_block || pwd_block )
+    if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
+        goto exit;
+
+    if( use_salt != 0 )
+    {
+        if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 )
+            goto exit;
+    }
+
+    if( use_password != 0 )
+    {
+        if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 )
+            goto exit;
+    }
+
+    if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
+        goto exit;
+
+    // Perform remaining ( iterations - 1 ) recursive hash calculations
+    for( i = 1; i < (size_t) iterations; i++ )
+    {
+        if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) )
+            != 0 )
+            goto exit;
+    }
+
+exit:
+    mbedtls_md_free( &md_ctx );
+    return ret;
+#else
+    psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
+    psa_algorithm_t alg = mbedtls_psa_translate_md( md_type );
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t status_abort = PSA_ERROR_CORRUPTION_DETECTED;
+    size_t i, out_len, out_size = PSA_HASH_LENGTH( alg );
+
+    if( alg == PSA_ALG_NONE )
+        return ( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+
+    if( ( status = psa_hash_setup( &op, alg ) ) != PSA_SUCCESS )
+        goto exit;
+
+    // Calculate hash( diversifier || salt_block || pwd_block )
+    if( ( status = psa_hash_update( &op, diversifier, v ) ) != PSA_SUCCESS )
+        goto exit;
+
+    if( use_salt != 0 )
+    {
+        if( ( status = psa_hash_update( &op, salt_block, v ) ) != PSA_SUCCESS )
+            goto exit;
+    }
+
+    if( use_password != 0 )
+    {
+        if( ( status = psa_hash_update( &op, pwd_block, v ) ) != PSA_SUCCESS )
+            goto exit;
+    }
+
+    if( ( status = psa_hash_finish( &op, hash_output, out_size, &out_len ) )
+        != PSA_SUCCESS )
+        goto exit;
+
+    // Perform remaining ( iterations - 1 ) recursive hash calculations
+    for( i = 1; i < (size_t) iterations; i++ )
+    {
+        if( ( status = psa_hash_compute( alg, hash_output, hlen, hash_output,
+            out_size, &out_len ) ) != PSA_SUCCESS )
+            goto exit;
+    }
+
+exit:
+    status_abort = psa_hash_abort( &op );
+    if( status == PSA_SUCCESS )
+        status = status_abort;
+    return ( mbedtls_md_error_from_psa( status ) );
+#endif /* !MBEDTLS_MD_C */
+}
+
+
 int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
                        const unsigned char *pwd, size_t pwdlen,
                        const unsigned char *salt, size_t saltlen,
@@ -227,9 +332,6 @@
 
     size_t hlen, use_len, v, i;
 
-    const mbedtls_md_info_t *md_info;
-    mbedtls_md_context_t md_ctx;
-
     // This version only allows max of 64 bytes of password or salt
     if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
         return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
@@ -243,15 +345,7 @@
     use_password = ( pwd && pwdlen != 0 );
     use_salt = ( salt && saltlen != 0 );
 
-    md_info = mbedtls_md_info_from_type( md_type );
-    if( md_info == NULL )
-        return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
-
-    mbedtls_md_init( &md_ctx );
-
-    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
-        return( ret );
-    hlen = mbedtls_md_get_size( md_info );
+    hlen = mbedtls_hash_info_get_size( md_type );
 
     if( hlen <= 32 )
         v = 64;
@@ -273,33 +367,11 @@
     p = data;
     while( datalen > 0 )
     {
-        // Calculate hash( diversifier || salt_block || pwd_block )
-        if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
-            goto exit;
-
-        if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
-            goto exit;
-
-        if( use_salt != 0 )
+        if( calculate_hashes( md_type, iterations, diversifier, salt_block,
+            pwd_block, hash_output, use_salt, use_password, hlen,
+            v ) != 0 )
         {
-            if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v )) != 0 )
-                goto exit;
-        }
-
-        if( use_password != 0)
-        {
-            if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v )) != 0 )
-                goto exit;
-        }
-
-        if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
             goto exit;
-
-        // Perform remaining ( iterations - 1 ) recursive hash calculations
-        for( i = 1; i < (size_t) iterations; i++ )
-        {
-            if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 )
-                goto exit;
         }
 
         use_len = ( datalen > hlen ) ? hlen : datalen;
@@ -351,8 +423,6 @@
     mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) );
     mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) );
 
-    mbedtls_md_free( &md_ctx );
-
     return( ret );
 }