Use PSA MAC API in mbedtls_ssl_encrypt/decrypt_buf()

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 8a71a19..7445cb5 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -673,11 +673,35 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         unsigned char mac[MBEDTLS_SSL_MAC_ADD];
         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+        size_t sign_mac_length = 0;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
         ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
                                           transform->minor_ver,
                                           transform->taglen );
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        status = psa_mac_sign_setup( &operation, transform->psa_mac_enc,
+                                     transform->psa_mac_alg );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+
+        status = psa_mac_update( &operation, add_data, add_data_len );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+
+        status = psa_mac_update( &operation, data, rec->data_len );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+
+        status = psa_mac_sign_finish( &operation, mac, MBEDTLS_SSL_MAC_ADD,
+                                      &sign_mac_length );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+#else
         ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
                                       add_data_len );
         if( ret != 0 )
@@ -691,6 +715,7 @@
         ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
         if( ret != 0 )
             goto hmac_failed_etm_disabled;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
         memcpy( data + rec->data_len, mac, transform->maclen );
 #endif
@@ -704,8 +729,15 @@
 
     hmac_failed_etm_disabled:
         mbedtls_platform_zeroize( mac, transform->maclen );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        psa_mac_abort( &operation );
+        if( status != PSA_SUCCESS )
+        {
+            ret = psa_ssl_status_to_mbedtls( status );
+#else
         if( ret != 0 )
         {
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
             return( ret );
         }
@@ -998,6 +1030,10 @@
         if( auth_done == 0 )
         {
             unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+            psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+            size_t sign_mac_length = 0;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
             /*
              * MAC(MAC_write_key, seq_num +
@@ -1021,6 +1057,25 @@
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
                                    add_data_len );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+            status = psa_mac_sign_setup( &operation, transform->psa_mac_enc,
+                                         transform->psa_mac_alg );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+
+            status = psa_mac_update( &operation, add_data, add_data_len );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+
+            status = psa_mac_update( &operation, data, rec->data_len );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+
+            status = psa_mac_sign_finish( &operation, mac, MBEDTLS_SSL_MAC_ADD,
+                                          &sign_mac_length );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+#else
 
             ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
                                           add_data_len );
@@ -1036,6 +1091,7 @@
             ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
             if( ret != 0 )
                 goto hmac_failed_etm_enabled;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
             memcpy( data + rec->data_len, mac, transform->maclen );
 
@@ -1045,8 +1101,15 @@
 
         hmac_failed_etm_enabled:
             mbedtls_platform_zeroize( mac, transform->maclen );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+            psa_mac_abort( &operation );
+            if( status != PSA_SUCCESS )
+            {
+                ret = psa_ssl_status_to_mbedtls( status );
+#else
             if( ret != 0 )
             {
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
                 MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
                 return( ret );
             }
@@ -1331,7 +1394,11 @@
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
         if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
         {
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+            psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+#else
             unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
 
@@ -1353,6 +1420,26 @@
             /* Calculate expected MAC. */
             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
                                    add_data_len );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+            status = psa_mac_verify_setup( &operation, transform->psa_mac_dec,
+                                           transform->psa_mac_alg );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+
+            status = psa_mac_update( &operation, add_data, add_data_len );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+
+            status = psa_mac_update( &operation, data, rec->data_len );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+
+            /* Compare expected MAC with MAC at the end of the record. */
+            status = psa_mac_verify_finish( &operation, data + rec->data_len,
+                                            transform->maclen );
+            if( status != PSA_SUCCESS )
+                goto hmac_failed_etm_enabled;
+#else
             ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
                                           add_data_len );
             if( ret != 0 )
@@ -1381,12 +1468,20 @@
                 ret = MBEDTLS_ERR_SSL_INVALID_MAC;
                 goto hmac_failed_etm_enabled;
             }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
             auth_done++;
 
         hmac_failed_etm_enabled:
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+            psa_mac_abort( &operation );
+            if( status != PSA_SUCCESS )
+            {
+                ret = psa_ssl_status_to_mbedtls( status );
+#else
             mbedtls_platform_zeroize( mac_expect, transform->maclen );
             if( ret != 0 )
             {
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
                 if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
                     MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
                 return( ret );
@@ -1586,8 +1681,13 @@
 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
     if( auth_done == 0 )
     {
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+#else
         unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
         unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
         /* If the initial value of padlen was such that
          * data_len < maclen + padlen + 1, then padlen
@@ -1608,6 +1708,29 @@
                                           transform->taglen );
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        status = psa_mac_verify_setup( &operation, transform->psa_mac_dec,
+                                       transform->psa_mac_alg );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+
+        status = psa_mac_update( &operation, add_data, add_data_len );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+
+        status = psa_mac_update( &operation, data, rec->data_len );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+
+        /* PSA psa_mac_verify_finish() is expected to make the best effort
+         * to ensure that the comparison between the actual MAC and the
+         * expected MAC is performed in constant time.
+         */
+        status = psa_mac_verify_finish( &operation, data + rec->data_len,
+                                        transform->maclen );
+        if( status != PSA_SUCCESS )
+            goto hmac_failed_etm_disabled;
+#else
         /*
             * The next two sizes are the minimum and maximum values of
             * data_len over all padlen values.
@@ -1635,8 +1758,10 @@
                                   rec->data_len,
                                   min_len, max_len,
                                   transform->maclen );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
         MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen );
         MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", mac_peer, transform->maclen );
@@ -1650,13 +1775,29 @@
 #endif
             correct = 0;
         }
+#endif /* !MBEDTLS_USE_PSA_CRYPTO */
         auth_done++;
 
     hmac_failed_etm_disabled:
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        psa_mac_abort( &operation );
+        if( status == PSA_ERROR_INVALID_SIGNATURE )
+        {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+#endif
+            correct = 0;
+        }
+        else if( status != PSA_SUCCESS )
+        {
+            return psa_ssl_status_to_mbedtls( status );
+        }
+#else
         mbedtls_platform_zeroize( mac_peer, transform->maclen );
         mbedtls_platform_zeroize( mac_expect, transform->maclen );
         if( ret != 0 )
             return( ret );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
     }
 
     /*