Merge branch 'gcm_through_cipher_api_tests' into psa_cipher_
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d25c9a6
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,4 @@
+[submodule "crypto"]
+	path = crypto
+	url = git@github.com:ARMmbed/mbedtls-psa.git
+	branch = feature-psa
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99bf31f..19ab4eb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,7 @@
 option(ENABLE_ZLIB_SUPPORT "Build mbed TLS with zlib library." OFF)
 
 option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
+option(USE_CRYPTO_SUBMODULE "Build and use libmbedcrypto from the crypto submodule." OFF)
 
 option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
 
@@ -167,8 +168,6 @@
     set(LIB_INSTALL_DIR lib)
 endif()
 
-include_directories(include/)
-
 if(ENABLE_ZLIB_SUPPORT)
     find_package(ZLIB)
 
@@ -179,6 +178,10 @@
 
 add_subdirectory(library)
 add_subdirectory(include)
+if(USE_CRYPTO_SUBMODULE)
+    add_subdirectory(crypto/library)
+    add_subdirectory(crypto/include)
+endif()
 
 if(ENABLE_PROGRAMS)
     add_subdirectory(programs)
diff --git a/ChangeLog b/ChangeLog
index f4bb416..2fb3300 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,13 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
-= mbed TLS 2.xx.x branch released xxxx-xx-xx
+= mbed TLS x.xx.x branch released xxxx-xx-xx
+
+Features
+   * Add an experimental build option, USE_CRYPTO_SUBMODULE, to enable use of
+     Mbed Crypto as the source of the cryptography implementation.
+   * Add an experimental configuration option, MBEDTLS_PSA_CRYPTO_C, to enable
+     the PSA Crypto API from Mbed Crypto when additionally used with the
+     USE_CRYPTO_SUBMODULE build option.
 
 Changes
    * Add unit tests for AES-GCM when called through mbedtls_cipher_auth_xxx()
diff --git a/Makefile b/Makefile
index f4c0a00..87b5a0c 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,13 @@
 	mkdir -p $(DESTDIR)/lib
 	cp -RP library/libmbedtls.*    $(DESTDIR)/lib
 	cp -RP library/libmbedx509.*   $(DESTDIR)/lib
+ifdef USE_CRYPTO_SUBMODULE
+	mkdir -p $(DESTDIR)/include/psa
+	cp -rp crypto/include/psa $(DESTDIR)/include
+	cp -RP crypto/library/libmbedcrypto.* $(DESTDIR)/lib
+else
 	cp -RP library/libmbedcrypto.* $(DESTDIR)/lib
+endif
 
 	mkdir -p $(DESTDIR)/bin
 	for p in programs/*/* ; do              \
@@ -44,6 +50,9 @@
 	rm -f $(DESTDIR)/lib/libmbedtls.*
 	rm -f $(DESTDIR)/lib/libmbedx509.*
 	rm -f $(DESTDIR)/lib/libmbedcrypto.*
+ifdef USE_CRYPTO_SUBMODULE
+	$(MAKE) -C crypto uninstall
+endif
 
 	for p in programs/*/* ; do              \
 	    if [ -x $$p ] && [ ! -d $$p ] ;     \
@@ -85,6 +94,9 @@
 	$(MAKE) -C library clean
 	$(MAKE) -C programs clean
 	$(MAKE) -C tests clean
+ifdef USE_CRYPTO_SUBMODULE
+	$(MAKE) -C crypto clean
+endif
 ifndef WINDOWS
 	find . \( -name \*.gcno -o -name \*.gcda -o -name \*.info \) -exec rm {} +
 endif
diff --git a/README.md b/README.md
index d7a0e9d..58e5273 100644
--- a/README.md
+++ b/README.md
@@ -158,6 +158,43 @@
 
 We provide some non-standard configurations focused on specific use cases in the `configs/` directory. You can read more about those in `configs/README.txt`
 
+Using Mbed Crypto as a submodule
+--------------------------------
+
+As an experimental feature, you can use Mbed Crypto as the source of the cryptography implementation, with Mbed TLS providing the X.509 and TLS parts of the library. Mbed Crypto is currently provided for evaluation only and should not be used in production. At this point, you should only use this option if you want to try out the experimental PSA Crypto API.
+
+To enable the use of Mbed Crypto as a submodule:
+
+1. Check out the `crypto` submodule and update it.
+
+        git submodule init crypto
+        git submodule update crypto
+
+2. (Optional) TO enable the PSA Crypto API, set the build configuration option `MBEDTLS_PSA_CRYPTO_C`. You can either edit `include/mbedtls/config.h` directly or use the configuration script:
+
+        scripts/config.pl set MBEDTLS_PSA_CRYPTO_C
+
+3. Activate the build option `USE_CRYPTO_SUBMODULE`. With GNU make, set `USE_CRYPTO_SUBMODULE=1` on each make invocation:
+
+        make USE_CRYPTO_SUBMODULE=1
+        make USE_CRYPTO_SUBMODULE=1 test
+        tests/ssl-opt.sh -f Default
+
+   Note that you need to pass `USE_CRYPTO_SUBMODULE=1` even to `make clean`. For example, if you change `config.h`, run this before rebuilding:
+
+        make USE_CRYPTO_SUBMODULE=1 clean
+
+   With CMake, create a build directory (recommended) and pass `-DUSE_CRYPTO_SUBMODULE=1` to `cmake`:
+
+        mkdir build
+        cd build
+        cmake -DUSE_CRYPTO_SUBMODULE=1 ..
+        make
+        make test
+        tests/ssl-opt.sh -f Default
+
+Note that this does not enable the PSA-specific tests and utility programs. To use these programs, use Mbed Crypto as a standalone project.
+
 Porting Mbed TLS
 ----------------
 
diff --git a/crypto b/crypto
new file mode 160000
index 0000000..dbb83ac
--- /dev/null
+++ b/crypto
@@ -0,0 +1 @@
+Subproject commit dbb83ac5f7b96077b21fc9fe72b2687986acf963
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 425e3ea..0a6f4bf 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -496,6 +496,12 @@
 #error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
 #endif
 
+#if defined(MBEDTLS_PSA_CRYPTO_C) &&            \
+    !( defined(MBEDTLS_CTR_DRBG_C) &&           \
+       defined(MBEDTLS_ENTROPY_C) )
+#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) ||         \
     !defined(MBEDTLS_OID_C) )
 #error "MBEDTLS_RSA_C defined, but not all prerequisites"
@@ -638,6 +644,10 @@
 #endif
 #undef MBEDTLS_THREADING_IMPL
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
 #error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
 #endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 16ed503..9751d26 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1583,6 +1583,24 @@
 //#define MBEDTLS_THREADING_PTHREAD
 
 /**
+ * \def MBEDTLS_USE_PSA_CRYPTO
+ *
+ * Make the X.509 and TLS library use PSA for cryptographic operations, see
+ * #MBEDTLS_PSA_CRYPTO_C.
+ *
+ * Note: this option is still in progress, the full X.509 and TLS modules are
+ * not covered yet, but parts that are not ported to PSA yet will still work
+ * as usual, so enabling this option should not break backwards compatibility.
+ *
+ * \warning  Support for PSA is still an experimental feature.
+ *           Any public API that depends on this option may change
+ *           at any time until this warning is removed.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C.
+ */
+//#define MBEDTLS_USE_PSA_CRYPTO
+
+/**
  * \def MBEDTLS_VERSION_FEATURES
  *
  * Allow run-time checking of compile-time enabled features. Thus allowing users
@@ -2591,6 +2609,25 @@
 #define MBEDTLS_POLY1305_C
 
 /**
+ * \def MBEDTLS_PSA_CRYPTO_C
+ *
+ * Enable the Platform Security Architecture cryptography API.
+ *
+ * \note This option only has an effect when the build option
+ * USE_CRYPTO_SUBMODULE is also in use.
+ *
+ * \warning This feature is experimental and available on an opt-in basis only.
+ * PSA APIs are subject to change at any time. The implementation comes with
+ * less assurance and support than the rest of Mbed TLS.
+ *
+ * Module:  crypto/library/psa_crypto.c
+ *
+ * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_C
+
+/**
  * \def MBEDTLS_RIPEMD160_C
  *
  * Enable the RIPEMD-160 hash algorithm.
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
new file mode 100644
index 0000000..5766133
--- /dev/null
+++ b/include/mbedtls/psa_util.h
@@ -0,0 +1,264 @@
+/**
+ * \file psa_util.h
+ *
+ * \brief Utility functions for the use of the PSA Crypto library.
+ *
+ * \warning This function is not part of the public API and may
+ *          change at any time.
+ */
+/*
+ *  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_PSA_UTIL_H
+#define MBEDTLS_PSA_UTIL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+#include "psa/crypto.h"
+
+#include "ecp.h"
+#include "md.h"
+#include "pk.h"
+
+/* Slot allocation */
+
+static inline psa_status_t mbedtls_psa_get_free_key_slot( psa_key_slot_t *key )
+{
+    for( psa_key_slot_t slot = 1; slot <= 32; slot++ )
+    {
+        if( psa_get_key_information( slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT )
+        {
+            *key = slot;
+            return( PSA_SUCCESS );
+        }
+    }
+    return( PSA_ERROR_INSUFFICIENT_MEMORY );
+}
+
+/* Translations for symmetric crypto. */
+
+static inline psa_key_type_t mbedtls_psa_translate_cipher_type(
+    mbedtls_cipher_type_t cipher )
+{
+    switch( cipher )
+    {
+        case MBEDTLS_CIPHER_AES_128_CCM:
+        case MBEDTLS_CIPHER_AES_192_CCM:
+        case MBEDTLS_CIPHER_AES_256_CCM:
+        case MBEDTLS_CIPHER_AES_128_GCM:
+        case MBEDTLS_CIPHER_AES_192_GCM:
+        case MBEDTLS_CIPHER_AES_256_GCM:
+        case MBEDTLS_CIPHER_AES_128_CBC:
+        case MBEDTLS_CIPHER_AES_192_CBC:
+        case MBEDTLS_CIPHER_AES_256_CBC:
+            return( PSA_KEY_TYPE_AES );
+
+        /* ARIA not yet supported in PSA. */
+        /* case MBEDTLS_CIPHER_ARIA_128_CCM:
+           case MBEDTLS_CIPHER_ARIA_192_CCM:
+           case MBEDTLS_CIPHER_ARIA_256_CCM:
+           case MBEDTLS_CIPHER_ARIA_128_GCM:
+           case MBEDTLS_CIPHER_ARIA_192_GCM:
+           case MBEDTLS_CIPHER_ARIA_256_GCM:
+           case MBEDTLS_CIPHER_ARIA_128_CBC:
+           case MBEDTLS_CIPHER_ARIA_192_CBC:
+           case MBEDTLS_CIPHER_ARIA_256_CBC:
+               return( PSA_KEY_TYPE_ARIA ); */
+
+        default:
+            return( 0 );
+    }
+}
+
+static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(
+    mbedtls_cipher_mode_t mode, size_t taglen )
+{
+    switch( mode )
+    {
+        case MBEDTLS_MODE_GCM:
+            return( PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, taglen ) );
+        case MBEDTLS_MODE_CCM:
+            return( PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, taglen ) );
+        case MBEDTLS_MODE_CBC:
+            if( taglen == 0 )
+                return( PSA_ALG_CBC_NO_PADDING );
+            /* Intentional fallthrough for taglen != 0 */
+        default:
+            return( 0 );
+    }
+}
+
+static inline psa_key_usage_t mbedtls_psa_translate_cipher_operation(
+    mbedtls_operation_t op )
+{
+    switch( op )
+    {
+        case MBEDTLS_ENCRYPT:
+            return( PSA_KEY_USAGE_ENCRYPT );
+        case MBEDTLS_DECRYPT:
+            return( PSA_KEY_USAGE_DECRYPT );
+        default:
+            return( 0 );
+    }
+}
+
+/* Translations for hashing. */
+
+static inline psa_algorithm_t mbedtls_psa_translate_md( mbedtls_md_type_t md_alg )
+{
+    switch( md_alg )
+    {
+#if defined(MBEDTLS_MD2_C)
+    case MBEDTLS_MD_MD2:
+        return( PSA_ALG_MD2 );
+#endif
+#if defined(MBEDTLS_MD4_C)
+    case MBEDTLS_MD_MD4:
+        return( PSA_ALG_MD4 );
+#endif
+#if defined(MBEDTLS_MD5_C)
+    case MBEDTLS_MD_MD5:
+        return( PSA_ALG_MD5 );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+    case MBEDTLS_MD_SHA1:
+        return( PSA_ALG_SHA_1 );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    case MBEDTLS_MD_SHA224:
+        return( PSA_ALG_SHA_224 );
+    case MBEDTLS_MD_SHA256:
+        return( PSA_ALG_SHA_256 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    case MBEDTLS_MD_SHA384:
+        return( PSA_ALG_SHA_384 );
+    case MBEDTLS_MD_SHA512:
+        return( PSA_ALG_SHA_512 );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+    case MBEDTLS_MD_RIPEMD160:
+        return( PSA_ALG_RIPEMD160 );
+#endif
+    case MBEDTLS_MD_NONE:  /* Intentional fallthrough */
+    default:
+        return( 0 );
+    }
+}
+
+/* Translations for ECC. */
+
+static inline psa_ecc_curve_t mbedtls_psa_translate_ecc_group( mbedtls_ecp_group_id grpid )
+{
+    switch( grpid )
+    {
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP192R1:
+            return( PSA_ECC_CURVE_SECP192R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP224R1:
+            return( PSA_ECC_CURVE_SECP224R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP256R1:
+            return( PSA_ECC_CURVE_SECP256R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP384R1:
+            return( PSA_ECC_CURVE_SECP384R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP521R1:
+            return( PSA_ECC_CURVE_SECP521R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+        case MBEDTLS_ECP_DP_BP256R1:
+            return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+        case MBEDTLS_ECP_DP_BP384R1:
+            return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+        case MBEDTLS_ECP_DP_BP512R1:
+            return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+        case MBEDTLS_ECP_DP_CURVE25519:
+            return( PSA_ECC_CURVE_CURVE25519 );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP192K1:
+            return( PSA_ECC_CURVE_SECP192K1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP224K1:
+            return( PSA_ECC_CURVE_SECP224K1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP256K1:
+            return( PSA_ECC_CURVE_SECP256K1 );
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+        case MBEDTLS_ECP_DP_CURVE448:
+            return( PSA_ECC_CURVE_CURVE448 );
+#endif
+        default:
+            return( 0 );
+    }
+}
+
+/* Translations for PK layer */
+
+static inline int mbedtls_psa_err_translate_pk( psa_status_t status )
+{
+    switch( status )
+    {
+        case PSA_SUCCESS:
+            return( 0 );
+        case PSA_ERROR_NOT_SUPPORTED:
+            return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+        case PSA_ERROR_INSUFFICIENT_MEMORY:
+            return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+        case PSA_ERROR_INSUFFICIENT_ENTROPY:
+            return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+        case PSA_ERROR_BAD_STATE:
+            return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+        /* All other failures */
+        case PSA_ERROR_COMMUNICATION_FAILURE:
+        case PSA_ERROR_HARDWARE_FAILURE:
+        case PSA_ERROR_TAMPERING_DETECTED:
+            return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+        default: /* We return the same as for the 'other failures',
+                  * but list them separately nonetheless to indicate
+                  * which failure conditions we have considered. */
+            return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+    }
+}
+
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#endif /* MBEDTLS_PSA_UTIL_H */
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index ea51363..cab8c27 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -140,42 +140,80 @@
 endif()
 
 if(USE_STATIC_MBEDTLS_LIBRARY)
-    add_library(${mbedcrypto_static_target} STATIC ${src_crypto})
-    set_target_properties(${mbedcrypto_static_target} PROPERTIES OUTPUT_NAME mbedcrypto)
-    target_link_libraries(${mbedcrypto_static_target} ${libs})
+    if(NOT USE_CRYPTO_SUBMODULE)
+        add_library(${mbedcrypto_static_target} STATIC ${src_crypto})
+        set_target_properties(${mbedcrypto_static_target} PROPERTIES OUTPUT_NAME mbedcrypto)
+        target_link_libraries(${mbedcrypto_static_target} ${libs})
+        target_include_directories(${mbedcrypto_static_target} PUBLIC ${CMAKE_SOURCE_DIR}/include/)
+    endif()
 
     add_library(${mbedx509_static_target} STATIC ${src_x509})
     set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509)
     target_link_libraries(${mbedx509_static_target} ${libs} ${mbedcrypto_static_target})
+    target_include_directories(${mbedx509_static_target}
+        PUBLIC ${CMAKE_SOURCE_DIR}/include/
+        PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/)
 
     add_library(${mbedtls_static_target} STATIC ${src_tls})
     set_target_properties(${mbedtls_static_target} PROPERTIES OUTPUT_NAME mbedtls)
     target_link_libraries(${mbedtls_static_target} ${libs} ${mbedx509_static_target})
+    target_include_directories(${mbedtls_static_target}
+        PUBLIC ${CMAKE_SOURCE_DIR}/include/
+        PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/
+        )
 
-    install(TARGETS ${mbedtls_static_target} ${mbedx509_static_target} ${mbedcrypto_static_target}
-            DESTINATION ${LIB_INSTALL_DIR}
-            PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+    if(USE_CRYPTO_SUBMODULE)
+        install(TARGETS ${mbedtls_static_target} ${mbedx509_static_target}
+                DESTINATION ${LIB_INSTALL_DIR}
+                PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+    else()
+        install(TARGETS ${mbedtls_static_target} ${mbedx509_static_target} ${mbedcrypto_static_target}
+                DESTINATION ${LIB_INSTALL_DIR}
+                PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+    endif()
 endif(USE_STATIC_MBEDTLS_LIBRARY)
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
-    add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.14.0 SOVERSION 3)
-    target_link_libraries(mbedcrypto ${libs})
+    if(NOT USE_CRYPTO_SUBMODULE)
+        add_library(mbedcrypto SHARED ${src_crypto})
+        set_target_properties(mbedcrypto PROPERTIES VERSION 2.14.0 SOVERSION 3)
+        target_link_libraries(mbedcrypto ${libs})
+        target_include_directories(mbedcrypto PUBLIC ${CMAKE_SOURCE_DIR}/include/)
+    endif()
 
     add_library(mbedx509 SHARED ${src_x509})
     set_target_properties(mbedx509 PROPERTIES VERSION 2.14.0 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
+    target_include_directories(mbedx509
+        PUBLIC ${CMAKE_SOURCE_DIR}/include/
+        PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/)
 
     add_library(mbedtls SHARED ${src_tls})
     set_target_properties(mbedtls PROPERTIES VERSION 2.14.0 SOVERSION 12)
     target_link_libraries(mbedtls ${libs} mbedx509)
+    target_include_directories(mbedtls
+        PUBLIC ${CMAKE_SOURCE_DIR}/include/
+        PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/)
 
-    install(TARGETS mbedtls mbedx509 mbedcrypto
-            DESTINATION ${LIB_INSTALL_DIR}
-            PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+    if(USE_CRYPTO_SUBMODULE)
+        install(TARGETS mbedtls mbedx509
+                DESTINATION ${LIB_INSTALL_DIR}
+                PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+    else()
+        install(TARGETS mbedtls mbedx509 mbedcrypto
+                DESTINATION ${LIB_INSTALL_DIR}
+                PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+    endif()
 endif(USE_SHARED_MBEDTLS_LIBRARY)
 
-add_custom_target(lib DEPENDS mbedcrypto mbedx509 mbedtls)
-if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
-    add_dependencies(lib mbedcrypto_static mbedx509_static mbedtls_static)
+if(USE_CRYPTO_SUBMODULE)
+    add_custom_target(lib DEPENDS mbedx509 mbedtls)
+    if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
+        add_dependencies(lib mbedx509_static mbedtls_static)
+    endif()
+else()
+    add_custom_target(lib DEPENDS mbedcrypto mbedx509 mbedtls)
+    if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
+        add_dependencies(lib mbedcrypto_static mbedx509_static mbedtls_static)
+    endif()
 endif()
diff --git a/library/Makefile b/library/Makefile
index 430c598..f01b1a1 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -63,6 +63,13 @@
 endif
 endif
 
+
+ifdef USE_CRYPTO_SUBMODULE
+# Look in crypto for libmbedcrypto.
+LOCAL_LDFLAGS += -L../crypto/library
+LOCAL_CFLAGS += -I../crypto/include
+CRYPTO := ../crypto/library/
+else
 OBJS_CRYPTO=	aes.o		aesni.o		arc4.o		\
 		aria.o		asn1parse.o	asn1write.o	\
 		base64.o	bignum.o	blowfish.o	\
@@ -85,6 +92,8 @@
 		sha1.o		sha256.o	sha512.o	\
 		threading.o	timing.o	version.o	\
 		version_features.o		xtea.o
+CRYPTO :=
+endif
 
 OBJS_X509=	certs.o		pkcs11.o	x509.o		\
 		x509_create.o	x509_crl.o	x509_crt.o	\
@@ -148,7 +157,7 @@
 endif
 endif
 
-libmbedx509.$(SOEXT_X509): $(OBJS_X509) libmbedcrypto.so
+libmbedx509.$(SOEXT_X509): $(OBJS_X509) $(CRYPTO)libmbedcrypto.so
 	echo "  LD    $@"
 	$(CC) -shared -Wl,-soname,$@ -L. -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_X509)
 
@@ -165,6 +174,10 @@
 	$(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_X509) -lws2_32 -lwinmm -lgdi32 -L. -lmbedcrypto -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 # crypto
+ifdef USE_CRYPTO_SUBMODULE
+libmbedcrypto.%:
+	$(MAKE) CRYPTO_INCLUDES:="-I../../include -I../include" -C ../crypto/library $@
+else
 libmbedcrypto.a: $(OBJS_CRYPTO)
 	echo "  AR    $@"
 	$(AR) $(ARFLAGS) $@ $(OBJS_CRYPTO)
@@ -190,6 +203,7 @@
 libmbedcrypto.dll: $(OBJS_CRYPTO)
 	echo "  LD    $@"
 	$(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_CRYPTO) -lws2_32 -lwinmm -lgdi32 -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS)
+endif
 
 .c.o:
 	echo "  CC    $<"
diff --git a/library/version_features.c b/library/version_features.c
index f1798a7..e2e9949 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -513,6 +513,9 @@
 #if defined(MBEDTLS_THREADING_PTHREAD)
     "MBEDTLS_THREADING_PTHREAD",
 #endif /* MBEDTLS_THREADING_PTHREAD */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    "MBEDTLS_USE_PSA_CRYPTO",
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 #if defined(MBEDTLS_VERSION_FEATURES)
     "MBEDTLS_VERSION_FEATURES",
 #endif /* MBEDTLS_VERSION_FEATURES */
@@ -681,6 +684,9 @@
 #if defined(MBEDTLS_POLY1305_C)
     "MBEDTLS_POLY1305_C",
 #endif /* MBEDTLS_POLY1305_C */
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+    "MBEDTLS_PSA_CRYPTO_C",
+#endif /* MBEDTLS_PSA_CRYPTO_C */
 #if defined(MBEDTLS_RIPEMD160_C)
     "MBEDTLS_RIPEMD160_C",
 #endif /* MBEDTLS_RIPEMD160_C */
diff --git a/programs/Makefile b/programs/Makefile
index b6d1fa2..d379ddf 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -14,6 +14,10 @@
 		-lmbedx509$(SHARED_SUFFIX)	\
 		-lmbedcrypto$(SHARED_SUFFIX)
 
+ifdef USE_CRYPTO_SUBMODULE
+LOCAL_LDFLAGS += -L../crypto/library
+endif
+
 ifndef SHARED
 DEP=../library/libmbedcrypto.a ../library/libmbedx509.a ../library/libmbedtls.a
 else
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 15c778d..87b9ab1 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -59,6 +59,10 @@
 #include "mbedtls/debug.h"
 #include "mbedtls/timing.h"
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -555,6 +559,9 @@
 #endif
     char *p, *q;
     const int *list;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_status_t status;
+#endif
 
     /*
      * Make sure memory references are valid.
@@ -573,6 +580,17 @@
     memset( (void * ) alpn_list, 0, sizeof( alpn_list ) );
 #endif
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    status = psa_crypto_init();
+    if( status != PSA_SUCCESS )
+    {
+        mbedtls_fprintf( stderr, "Failed to initialize PSA Crypto implementation: %d\n",
+                         (int) status );
+        ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
+        goto exit;
+    }
+#endif
+
     if( argc == 0 )
     {
     usage:
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index efda65d..1c6ccae 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -60,6 +60,10 @@
 #include "mbedtls/debug.h"
 #include "mbedtls/timing.h"
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -1238,6 +1242,9 @@
     int i;
     char *p, *q;
     const int *list;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_status_t status;
+#endif
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@@ -1277,6 +1284,17 @@
     mbedtls_ssl_cookie_init( &cookie_ctx );
 #endif
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    status = psa_crypto_init();
+    if( status != PSA_SUCCESS )
+    {
+        mbedtls_fprintf( stderr, "Failed to initialize PSA Crypto implementation: %d\n",
+                         (int) status );
+        ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
+        goto exit;
+    }
+#endif
+
 #if !defined(_WIN32)
     /* Abort cleanly on SIGTERM and SIGINT */
     signal( SIGTERM, term_handler );
diff --git a/scripts/abi_check.py b/scripts/abi_check.py
index 8f9cd0f..fe5dd3f 100755
--- a/scripts/abi_check.py
+++ b/scripts/abi_check.py
@@ -64,7 +64,7 @@
         )
         git_worktree_path = tempfile.mkdtemp()
         worktree_process = subprocess.Popen(
-            [self.git_command, "worktree", "add", git_worktree_path, git_rev],
+            [self.git_command, "worktree", "add", "--detach", git_worktree_path, git_rev],
             cwd=self.repo_path,
             stdout=subprocess.PIPE,
             stderr=subprocess.STDOUT
@@ -75,6 +75,18 @@
             raise Exception("Checking out worktree failed, aborting")
         return git_worktree_path
 
+    def update_git_submodules(self, git_worktree_path):
+        process = subprocess.Popen(
+            [self.git_command, "submodule", "update", "--init", '--recursive'],
+            cwd=git_worktree_path,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT
+        )
+        output, _ = process.communicate()
+        self.log.info(output.decode("utf-8"))
+        if process.returncode != 0:
+            raise Exception("git submodule update failed, aborting")
+
     def build_shared_libraries(self, git_worktree_path):
         my_environment = os.environ.copy()
         my_environment["CFLAGS"] = "-g -Og"
@@ -131,6 +143,7 @@
 
     def get_abi_dump_for_ref(self, git_rev):
         git_worktree_path = self.get_clean_worktree_for_git_revision(git_rev)
+        self.update_git_submodules(git_worktree_path)
         self.build_shared_libraries(git_worktree_path)
         abi_dumps = self.get_abi_dumps_from_shared_libraries(
             git_rev, git_worktree_path
diff --git a/scripts/config.pl b/scripts/config.pl
index 3d2884c..dda30bb 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -28,6 +28,7 @@
 #   MBEDTLS_ECP_DP_M511_ENABLED
 #   MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
 #   MBEDTLS_NO_PLATFORM_ENTROPY
+#   MBEDTLS_PSA_CRYPTO_C
 #   MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 #   MBEDTLS_SSL_HW_RECORD_ACCEL
 #   MBEDTLS_RSA_NO_CRT
@@ -36,6 +37,8 @@
 #       - this could be enabled if the respective tests were adapted
 #   MBEDTLS_ZLIB_SUPPORT
 #   MBEDTLS_PKCS11_C
+#   MBEDTLS_USE_PSA_CRYPTO
+#       - experimental, and more an alternative implementation than a feature
 #   and any symbol beginning _ALT
 #
 
@@ -87,6 +90,7 @@
 MBEDTLS_ECP_DP_M511_ENABLED
 MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
 MBEDTLS_NO_PLATFORM_ENTROPY
+MBEDTLS_PSA_CRYPTO_C
 MBEDTLS_RSA_NO_CRT
 MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 MBEDTLS_SSL_HW_RECORD_ACCEL
@@ -96,6 +100,7 @@
 MBEDTLS_PKCS11_C
 MBEDTLS_NO_UDBL_DIVISION
 MBEDTLS_NO_64BIT_MULTIPLICATION
+MBEDTLS_USE_PSA_CRYPTO
 _ALT\s*$
 );
 
diff --git a/tests/Makefile b/tests/Makefile
index b6e49bf..4118c14 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -12,15 +12,22 @@
 		-lmbedx509$(SHARED_SUFFIX)	\
 		-lmbedcrypto$(SHARED_SUFFIX)
 
+ifdef USE_CRYPTO_SUBMODULE
+LOCAL_LDFLAGS += -L../crypto/library
+CRYPTO := ../crypto/library/
+else
+CRYPTO := ../library/
+endif
+
 # Enable definition of various functions used throughout the testsuite
 # (gethostname, strdup, fileno...) even when compiling with -std=c99. Harmless
 # on non-POSIX platforms.
 LOCAL_CFLAGS += -D_POSIX_C_SOURCE=200809L
 
 ifndef SHARED
-DEP=../library/libmbedcrypto.a ../library/libmbedx509.a ../library/libmbedtls.a
+DEP=$(CRYPTO)libmbedcrypto.a ../library/libmbedx509.a ../library/libmbedtls.a
 else
-DEP=../library/libmbedcrypto.$(DLEXT) ../library/libmbedx509.$(DLEXT) ../library/libmbedtls.$(DLEXT)
+DEP=$(CRYPTO)libmbedcrypto.$(DLEXT) ../library/libmbedx509.$(DLEXT) ../library/libmbedtls.$(DLEXT)
 endif
 
 ifdef DEBUG
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 19baf5e..6dba7a5 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -88,6 +88,11 @@
     exit 1
 fi
 
+if ! [ -f crypto/Makefile ]; then
+    echo "Please initialize the crypto submodule" >&2
+    exit 1
+fi
+
 CONFIG_H='include/mbedtls/config.h'
 CONFIG_BAK="$CONFIG_H.bak"
 
@@ -154,9 +159,12 @@
     fi
 
     command make clean
+    cd crypto
+    command make clean
+    cd ..
 
     # Remove CMake artefacts
-    find . -name .git -prune \
+    find . -name .git -prune -o \
            -iname CMakeFiles -exec rm -rf {} \+ -o \
            \( -iname cmake_install.cmake -o \
               -iname CTestTestfile.cmake -o \
@@ -165,6 +173,11 @@
     rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile
     git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile
     git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile
+    cd crypto
+    rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile
+    git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile
+    git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile
+    cd ..
 
     if [ -f "$CONFIG_BAK" ]; then
         mv "$CONFIG_BAK" "$CONFIG_H"
@@ -574,6 +587,95 @@
 msg "test: compat.sh ARIA + ChachaPoly"
 if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
 
+# USE_CRYPTO_SUBMODULE: check that the build works with CMake
+msg "build: cmake, full config + USE_CRYPTO_SUBMODULE, gcc+debug"
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl full # enables md4 and submodule doesn't enable md4
+scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+CC=gcc cmake -D USE_CRYPTO_SUBMODULE=1 -D CMAKE_BUILD_TYPE=Debug .
+make
+msg "test: top-level libmbedcrypto wasn't built (USE_CRYPTO_SUBMODULE, cmake)"
+if_build_succeeded not test -f library/libmbedcrypto.a
+msg "test: libmbedcrypto symbols are from crypto files (USE_CRYPTO_SUBMODULE, cmake)"
+if_build_succeeded objdump -g crypto/library/libmbedcrypto.a | grep -E 'crypto/library$' > /dev/null
+msg "test: libmbedcrypto uses top-level config (USE_CRYPTO_SUBMODULE, cmake)"
+if_build_succeeded objdump -g crypto/library/libmbedcrypto.a | grep 'md4.c' > /dev/null
+msg "test: main suites (USE_CRYPTO_SUBMODULE, cmake)"
+make test
+msg "test: ssl-opt.sh (USE_CRYPTO_SUBMODULE, cmake)"
+if_build_succeeded tests/ssl-opt.sh
+
+# USE_CRYPTO_SUBMODULE: check that the build works with make
+msg "build: make, full config + USE_CRYPTO_SUBMODULE, gcc+debug"
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl full # enables md4 and submodule doesn't enable md4
+scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+make CC=gcc CFLAGS='-g' USE_CRYPTO_SUBMODULE=1
+msg "test: top-level libmbedcrypto wasn't built (USE_CRYPTO_SUBMODULE, make)"
+if_build_succeeded not test -f library/libmbedcrypto.a
+msg "test: libmbedcrypto symbols are from crypto files (USE_CRYPTO_SUBMODULE, make)"
+if_build_succeeded objdump -g crypto/library/libmbedcrypto.a | grep -E 'crypto/library$' > /dev/null
+msg "test: libmbedcrypto uses top-level config (USE_CRYPTO_SUBMODULE, make)"
+if_build_succeeded objdump -g crypto/library/libmbedcrypto.a | grep 'md4.c' > /dev/null
+msg "test: main suites (USE_CRYPTO_SUBMODULE, make)"
+make CC=gcc USE_CRYPTO_SUBMODULE=1 test
+msg "test: ssl-opt.sh (USE_CRYPTO_SUBMODULE, make)"
+if_build_succeeded tests/ssl-opt.sh
+
+# Don't USE_CRYPTO_SUBMODULE: check that the submodule is not used with make
+msg "build: make, full config - USE_CRYPTO_SUBMODULE, gcc+debug"
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl full
+make CC=gcc CFLAGS='-g'
+msg "test: submodule libmbedcrypto wasn't built (USE_CRYPTO_SUBMODULE, make)"
+if_build_succeeded not test -f crypto/library/libmbedcrypto.a
+msg "test: libmbedcrypto symbols are from library files (USE_CRYPTO_SUBMODULE, make)"
+if_build_succeeded objdump -g library/libmbedcrypto.a | grep -E 'library$' | not grep 'crypto' > /dev/null
+
+# Don't USE_CRYPTO_SUBMODULE: check that the submodule is not used with CMake
+msg "build: cmake, full config - USE_CRYPTO_SUBMODULE, gcc+debug"
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl full
+CC=gcc cmake -D CMAKE_BUILD_TYPE=Debug .
+make
+msg "test: submodule libmbedcrypto wasn't built (USE_CRYPTO_SUBMODULE, cmake)"
+if_build_succeeded not test -f crypto/library/libmbedcrypto.a
+msg "test: libmbedcrypto symbols are from library files (USE_CRYPTO_SUBMODULE, cmake)"
+if_build_succeeded objdump -g library/libmbedcrypto.a | grep -E 'library$' | not grep 'crypto' > /dev/null
+
+# MBEDTLS_USE_PSA_CRYPTO: run the same set of tests as basic-build-test.sh
+msg "build: cmake, full config + MBEDTLS_USE_PSA_CRYPTO, ASan"
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl full
+scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+scripts/config.pl set MBEDTLS_PSA_CRYPTO_C
+scripts/config.pl set MBEDTLS_USE_PSA_CRYPTO
+CC=gcc cmake -D USE_CRYPTO_SUBMODULE -D CMAKE_BUILD_TYPE:String=Asan .
+make
+
+msg "test: main suites (MBEDTLS_USE_PSA_CRYPTO)"
+make test
+
+msg "test: ssl-opt.sh (MBEDTLS_USE_PSA_CRYPTO)"
+if_build_succeeded tests/ssl-opt.sh
+
+msg "test: compat.sh default (MBEDTLS_USE_PSA_CRYPTO)"
+if_build_succeeded tests/compat.sh
+
+msg "test: compat.sh ssl3 (MBEDTLS_USE_PSA_CRYPTO)"
+if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" tests/compat.sh -m 'ssl3'
+
+msg "test: compat.sh RC4, DES & NULL (MBEDTLS_USE_PSA_CRYPTO)"
+if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR'
+
+msg "test: compat.sh ARIA + ChachaPoly (MBEDTLS_USE_PSA_CRYPTO)"
+if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
+
 msg "build: make, full config + DEPRECATED_WARNING, gcc -O" # ~ 30s
 cleanup
 cp "$CONFIG_H" "$CONFIG_BAK"
diff --git a/tests/scripts/run-test-suites.pl b/tests/scripts/run-test-suites.pl
index 6fe6abf..4e57658 100755
--- a/tests/scripts/run-test-suites.pl
+++ b/tests/scripts/run-test-suites.pl
@@ -41,8 +41,8 @@
 die "$0: no test suite found\n" unless @suites;
 
 # in case test suites are linked dynamically
-$ENV{'LD_LIBRARY_PATH'} = '../library';
-$ENV{'DYLD_LIBRARY_PATH'} = '../library';
+$ENV{'LD_LIBRARY_PATH'} = '../library:../crypto/library';
+$ENV{'DYLD_LIBRARY_PATH'} = '../library:../crypto/library';
 
 my $prefix = $^O eq "MSWin32" ? '' : './';
 
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 2ba919c..8bd408c 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -25,6 +25,9 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 /*----------------------------------------------------------------------------*/
 /* Common helper code */
@@ -221,8 +224,22 @@
                          ret );
         return( -1 );
     }
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    {
+        psa_status_t status;
+        status = psa_crypto_init();
+        if( status != PSA_SUCCESS )
+        {
+            mbedtls_fprintf( stderr,
+                          "FATAL: Failed to initialize PSA Crypto - error %d\n",
+                          status );
+            return( -1 );
+        }
+    }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
     ret = execute_tests( argc, argv );
     platform_teardown();
     return( ret );
 }
-
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 73c92bd..133fd06 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -204,6 +204,7 @@
     <ClInclude Include="..\..\include\mbedtls\platform_time.h" />

     <ClInclude Include="..\..\include\mbedtls\platform_util.h" />

     <ClInclude Include="..\..\include\mbedtls\poly1305.h" />

+    <ClInclude Include="..\..\include\mbedtls\psa_util.h" />

     <ClInclude Include="..\..\include\mbedtls\ripemd160.h" />

     <ClInclude Include="..\..\include\mbedtls\rsa.h" />

     <ClInclude Include="..\..\include\mbedtls\rsa_internal.h" />