Merge pull request #192 from gilles-peskine-arm/psa-test-policy_bad_algorithm

Add some negative tests for policy checks
diff --git a/.gitignore b/.gitignore
index 789f57e..0f95b4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,17 @@
 # Python build artifacts:
 *.pyc
 
+# CMake generates *.dir/ folders for in-tree builds (used by MSVC projects), ignore all of those:
+*.dir/
+
+# Visual Studio artifacts
+/visualc/VS2010/.localhistory/
+/visualc/VS2010/.vs/
+/visualc/VS2010/Debug/
+/visualc/VS2010/Release/
+/visualc/VS2010/*.vcxproj.filters
+/visualc/VS2010/*.vcxproj.user
+
 # Generated documentation:
 /apidoc
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5d29839..6115f05 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,9 @@
     project("mbed TLS" C)
 endif()
 
+# Set the project root directory.
+set(MBEDTLS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
 option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
 
 option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
@@ -121,7 +124,10 @@
     # note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
     execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
                     OUTPUT_VARIABLE GCC_VERSION)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings")
+    if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvla")
+    endif()
     if (GCC_VERSION VERSION_GREATER 4.5 OR GCC_VERSION VERSION_EQUAL 4.5)
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlogical-op")
     endif()
@@ -138,7 +144,7 @@
 endif(CMAKE_COMPILER_IS_GNU)
 
 if(CMAKE_COMPILER_IS_CLANG)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla")
     set(CMAKE_C_FLAGS_RELEASE     "-O2")
     set(CMAKE_C_FLAGS_DEBUG       "-O0 -g3")
     set(CMAKE_C_FLAGS_COVERAGE    "-O0 -g3 --coverage")
@@ -216,13 +222,13 @@
             COMMAND mv DartConfiguration.tcl.bak DartConfiguration.tcl
         )
     endif(UNIX)
-endif()
 
-# Make scripts needed for testing available in an out-of-source build.
-if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
-    link_to_source(scripts)
-    # Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
-    # keep things simple with the sed commands in the memcheck target.
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
-                   ${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
+    # Make scripts needed for testing available in an out-of-source build.
+    if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+        link_to_source(scripts)
+        # Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
+        # keep things simple with the sed commands in the memcheck target.
+        configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
+                    ${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
+    endif()
 endif()
diff --git a/Makefile b/Makefile
index 64321cb..c9eb681 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,3 @@
-
 DESTDIR=/usr/local
 PREFIX=mbedtls_
 
diff --git a/configs/config-no-entropy.h b/configs/config-no-entropy.h
index 6f44899..502ca03 100644
--- a/configs/config-no-entropy.h
+++ b/configs/config-no-entropy.h
@@ -81,6 +81,6 @@
 /* Miscellaneous options */
 #define MBEDTLS_AES_ROM_TABLES
 
-#include "check_config.h"
+#include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/configs/config-psa-crypto.h b/configs/config-psa-crypto.h
index 97a1b2b..58a2c88 100644
--- a/configs/config-psa-crypto.h
+++ b/configs/config-psa-crypto.h
@@ -1971,6 +1971,6 @@
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 
-#include "check_config.h"
+#include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/docs/architecture/mbed-crypto-storage-specification.md b/docs/architecture/mbed-crypto-storage-specification.md
index 2c3119f..e7315eb 100644
--- a/docs/architecture/mbed-crypto-storage-specification.md
+++ b/docs/architecture/mbed-crypto-storage-specification.md
@@ -161,21 +161,21 @@
 
 It would simplify things to always have a 32-bit owner, with a nonzero value, and thus reserve the range 0–0xffffffff for internal library use.
 
-Mbed Crypto 1.0.1
+Mbed Crypto 1.1.0
 -----------------
 
-Tags: TBD
+Tags: mbedcrypto-1.1.0
 
-Released in May 2019. <br>
+Released in early June 2019. <br>
 Integrated in Mbed OS 5.13.
 
 Identical to [1.0.0](#mbed-crypto-1.0.0) except for some changes in the key file format.
 
-### Key file format for 1.0.1
+### Key file format for 1.1.0
 
 The key file format is identical to [1.0.0](#key-file-format-for-1.0.0), except for the following changes:
 
-* A new policy field, marked as [NEW:1.0.1] below.
+* A new policy field, marked as [NEW:1.1.0] below.
 * The encoding of key types, algorithms and key material has changed, therefore the storage format is not compatible (despite using the same value in the version field so far).
 
 A self-contained description of the file layout follows.
@@ -189,7 +189,7 @@
 * type (4 bytes): `psa_key_type_t` value
 * policy usage flags (4 bytes): `psa_key_usage_t` value
 * policy usage algorithm (4 bytes): `psa_algorithm_t` value
-* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value [NEW:1.0.1]
+* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value [NEW:1.1.0]
 * key material length (4 bytes)
 * key material: output of `psa_export_key`
 * Any trailing data is rejected on load.
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index dac97f4..02f924d 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -16,7 +16,7 @@
 endif(INSTALL_MBEDTLS_HEADERS)
 
 # Make config.h available in an out-of-source build.
-if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+if (ENABLE_TESTING AND NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
     link_to_source(mbedtls)
     link_to_source(psa)
 endif()
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index 94e7282..63c0f67 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -42,7 +42,7 @@
 #define MBEDTLS_AES_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/aesni.h b/include/mbedtls/aesni.h
index a4ca012..955b7c9 100644
--- a/include/mbedtls/aesni.h
+++ b/include/mbedtls/aesni.h
@@ -28,12 +28,12 @@
 #define MBEDTLS_AESNI_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "aes.h"
+#include "mbedtls/aes.h"
 
 #define MBEDTLS_AESNI_AES      0x02000000u
 #define MBEDTLS_AESNI_CLMUL    0x00000002u
diff --git a/include/mbedtls/arc4.h b/include/mbedtls/arc4.h
index fb044d5..acad623 100644
--- a/include/mbedtls/arc4.h
+++ b/include/mbedtls/arc4.h
@@ -29,7 +29,7 @@
 #define MBEDTLS_ARC4_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index 1e8956e..a72a8c2 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -31,7 +31,7 @@
 #define MBEDTLS_ARIA_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -39,7 +39,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
 
 #define MBEDTLS_ARIA_ENCRYPT     1 /**< ARIA encryption. */
 #define MBEDTLS_ARIA_DECRYPT     0 /**< ARIA decryption. */
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index f80acd7..ab947ab 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_ASN1_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -33,7 +33,7 @@
 #include <stddef.h>
 
 #if defined(MBEDTLS_BIGNUM_C)
-#include "bignum.h"
+#include "mbedtls/bignum.h"
 #endif
 
 /**
diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h
index 8aa01b4..336f2da 100644
--- a/include/mbedtls/asn1write.h
+++ b/include/mbedtls/asn1write.h
@@ -25,12 +25,12 @@
 #define MBEDTLS_ASN1_WRITE_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "asn1.h"
+#include "mbedtls/asn1.h"
 
 #define MBEDTLS_ASN1_CHK_ADD(g, f)                      \
     do                                                  \
diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h
index 0d02416..07ae3bf 100644
--- a/include/mbedtls/base64.h
+++ b/include/mbedtls/base64.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_BASE64_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index a04a145..0b26727 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_BIGNUM_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/blowfish.h b/include/mbedtls/blowfish.h
index f01573d..1e5dba3 100644
--- a/include/mbedtls/blowfish.h
+++ b/include/mbedtls/blowfish.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_BLOWFISH_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -33,7 +33,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
 
 #define MBEDTLS_BLOWFISH_ENCRYPT     1
 #define MBEDTLS_BLOWFISH_DECRYPT     0
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index c33bd8d..db03ba2 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -39,12 +39,12 @@
 #define MBEDTLS_BN_MUL_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "bignum.h"
+#include "mbedtls/bignum.h"
 
 #if defined(MBEDTLS_HAVE_ASM)
 
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 3eeb663..a832454 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_CAMELLIA_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -33,7 +33,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
 
 #define MBEDTLS_CAMELLIA_ENCRYPT     1
 #define MBEDTLS_CAMELLIA_DECRYPT     0
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index f03e3b5..ceac36c 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -50,12 +50,12 @@
 #define MBEDTLS_CCM_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "cipher.h"
+#include "mbedtls/cipher.h"
 
 #define MBEDTLS_ERR_CCM_BAD_INPUT       -0x000D /**< Bad input parameters to the function. */
 #define MBEDTLS_ERR_CCM_AUTH_FAILED     -0x000F /**< Authenticated decryption failed. */
diff --git a/include/mbedtls/certs.h b/include/mbedtls/certs.h
deleted file mode 100644
index b7c5708..0000000
--- a/include/mbedtls/certs.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * \file certs.h
- *
- * \brief Sample certificates and DHM parameters for testing
- */
-/*
- *  Copyright (C) 2006-2015, 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_CERTS_H
-#define MBEDTLS_CERTS_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(MBEDTLS_PEM_PARSE_C)
-/* Concatenation of all CA certificates in PEM format if available */
-extern const char   mbedtls_test_cas_pem[];
-extern const size_t mbedtls_test_cas_pem_len;
-#endif
-
-/* List of all CA certificates, terminated by NULL */
-extern const char * mbedtls_test_cas[];
-extern const size_t mbedtls_test_cas_len[];
-
-/*
- * Convenience for users who just want a certificate:
- * RSA by default, or ECDSA if RSA is not available
- */
-extern const char * mbedtls_test_ca_crt;
-extern const size_t mbedtls_test_ca_crt_len;
-extern const char * mbedtls_test_ca_key;
-extern const size_t mbedtls_test_ca_key_len;
-extern const char * mbedtls_test_ca_pwd;
-extern const size_t mbedtls_test_ca_pwd_len;
-extern const char * mbedtls_test_srv_crt;
-extern const size_t mbedtls_test_srv_crt_len;
-extern const char * mbedtls_test_srv_key;
-extern const size_t mbedtls_test_srv_key_len;
-extern const char * mbedtls_test_cli_crt;
-extern const size_t mbedtls_test_cli_crt_len;
-extern const char * mbedtls_test_cli_key;
-extern const size_t mbedtls_test_cli_key_len;
-
-#if defined(MBEDTLS_ECDSA_C)
-extern const char   mbedtls_test_ca_crt_ec[];
-extern const size_t mbedtls_test_ca_crt_ec_len;
-extern const char   mbedtls_test_ca_key_ec[];
-extern const size_t mbedtls_test_ca_key_ec_len;
-extern const char   mbedtls_test_ca_pwd_ec[];
-extern const size_t mbedtls_test_ca_pwd_ec_len;
-extern const char   mbedtls_test_srv_crt_ec[];
-extern const size_t mbedtls_test_srv_crt_ec_len;
-extern const char   mbedtls_test_srv_key_ec[];
-extern const size_t mbedtls_test_srv_key_ec_len;
-extern const char   mbedtls_test_cli_crt_ec[];
-extern const size_t mbedtls_test_cli_crt_ec_len;
-extern const char   mbedtls_test_cli_key_ec[];
-extern const size_t mbedtls_test_cli_key_ec_len;
-#endif
-
-#if defined(MBEDTLS_RSA_C)
-extern const char   mbedtls_test_ca_crt_rsa[];
-extern const size_t mbedtls_test_ca_crt_rsa_len;
-extern const char   mbedtls_test_ca_key_rsa[];
-extern const size_t mbedtls_test_ca_key_rsa_len;
-extern const char   mbedtls_test_ca_pwd_rsa[];
-extern const size_t mbedtls_test_ca_pwd_rsa_len;
-extern const char   mbedtls_test_srv_crt_rsa[];
-extern const size_t mbedtls_test_srv_crt_rsa_len;
-extern const char   mbedtls_test_srv_key_rsa[];
-extern const size_t mbedtls_test_srv_key_rsa_len;
-extern const char   mbedtls_test_cli_crt_rsa[];
-extern const size_t mbedtls_test_cli_crt_rsa_len;
-extern const char   mbedtls_test_cli_key_rsa[];
-extern const size_t mbedtls_test_cli_key_rsa_len;
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* certs.h */
diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h
index 2ae5e6e..243ae63 100644
--- a/include/mbedtls/chacha20.h
+++ b/include/mbedtls/chacha20.h
@@ -34,7 +34,7 @@
 #define MBEDTLS_CHACHA20_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h
index 49e615d..3d842ef 100644
--- a/include/mbedtls/chachapoly.h
+++ b/include/mbedtls/chachapoly.h
@@ -34,13 +34,13 @@
 #define MBEDTLS_CHACHAPOLY_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
 /* for shared error codes */
-#include "poly1305.h"
+#include "mbedtls/poly1305.h"
 
 #define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE            -0x0054 /**< The requested operation is not permitted in the current state. */
 #define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED          -0x0056 /**< Authenticated decryption failed: data was not authentic. */
@@ -58,7 +58,7 @@
 
 #if !defined(MBEDTLS_CHACHAPOLY_ALT)
 
-#include "chacha20.h"
+#include "mbedtls/chacha20.h"
 
 typedef struct mbedtls_chachapoly_context
 {
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index ea00703..96efd93 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -30,13 +30,13 @@
 #define MBEDTLS_CIPHER_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
 #include <stddef.h>
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
 
 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 #define MBEDTLS_CIPHER_MODE_AEAD
diff --git a/include/mbedtls/cipher_internal.h b/include/mbedtls/cipher_internal.h
index 8ea2a98..5930f0e 100644
--- a/include/mbedtls/cipher_internal.h
+++ b/include/mbedtls/cipher_internal.h
@@ -27,12 +27,12 @@
 #define MBEDTLS_CIPHER_WRAP_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "cipher.h"
+#include "mbedtls/cipher.h"
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 #include "psa/crypto.h"
diff --git a/include/mbedtls/cmac.h b/include/mbedtls/cmac.h
index 9d42b3f..792fbdc 100644
--- a/include/mbedtls/cmac.h
+++ b/include/mbedtls/cmac.h
@@ -29,12 +29,12 @@
 #define MBEDTLS_CMAC_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "cipher.h"
+#include "mbedtls/cipher.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
index a58b4724..361cf56 100644
--- a/include/mbedtls/compat-1.3.h
+++ b/include/mbedtls/compat-1.3.h
@@ -26,7 +26,7 @@
  */
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index bd6f7b6..e202cb4 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -277,28 +277,52 @@
  * For example, when a function accepts as input a pointer to a buffer that may
  * contain untrusted data, and its documentation mentions that this pointer
  * must not be NULL:
- * - the pointer is checked to be non-NULL only if this option is enabled
- * - the content of the buffer is always validated
+ * - The pointer is checked to be non-NULL only if this option is enabled.
+ * - The content of the buffer is always validated.
  *
  * When this flag is defined, if a library function receives a parameter that
- * is invalid, it will:
- * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
- *   call to the function mbedtls_param_failed()
- * - immediately return (with a specific error code unless the function
- *   returns void and can't communicate an error).
+ * is invalid:
+ * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED().
+ * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function
+ *   will immediately return. If the function returns an Mbed TLS error code,
+ *   the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
  *
- * When defining this flag, you also need to:
- * - either provide a definition of the function mbedtls_param_failed() in
- *   your application (see platform_util.h for its prototype) as the library
- *   calls that function, but does not provide a default definition for it,
- * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
- *   below if the above mechanism is not flexible enough to suit your needs.
- *   See the documentation of this macro later in this file.
+ * When defining this flag, you also need to arrange a definition for
+ * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods:
+ * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a
+ *   function mbedtls_param_failed(), but the library does not define this
+ *   function. If you do not make any other arrangements, you must provide
+ *   the function mbedtls_param_failed() in your application.
+ *   See `platform_util.h` for its prototype.
+ * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
+ *   library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
+ *   You can still supply an alternative definition of
+ *   MBEDTLS_PARAM_FAILED(), which may call `assert`.
+ * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
+ *   or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`,
+ *   the library will call the macro that you defined and will not supply
+ *   its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`,
+ *   you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source
+ *   files include `<assert.h>`.
  *
  * Uncomment to enable validation of application-controlled parameters.
  */
 //#define MBEDTLS_CHECK_PARAMS
 
+/**
+ * \def MBEDTLS_CHECK_PARAMS_ASSERT
+ *
+ * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to
+ * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined.
+ *
+ * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to
+ * calling a function mbedtls_param_failed(). See the documentation of
+ * #MBEDTLS_CHECK_PARAMS for details.
+ *
+ * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`.
+ */
+//#define MBEDTLS_CHECK_PARAMS_ASSERT
+
 /* \} name SECTION: System support */
 
 /**
@@ -1007,18 +1031,27 @@
 /**
  * \def MBEDTLS_USE_PSA_CRYPTO
  *
- * Make the X.509 and TLS library use PSA for cryptographic operations, see
- * #MBEDTLS_PSA_CRYPTO_C.
+ * Make the X.509 and TLS library use PSA for cryptographic operations, and
+ * enable new APIs for using keys handled by PSA Crypto.
  *
- * 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.
+ * \note Development of this option is currently in progress, and parts of Mbed
+ * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts
+ * will still continue to 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.
+ * \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.
+ *
+ * \warning This option enables new Mbed TLS APIs that are dependent on the
+ * PSA Crypto API, so can't come with the same stability guarantees as the
+ * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for
+ * now, access to these APIs is opt-in (via enabling the present option), in
+ * order to clearly differentiate them from the stable Mbed TLS APIs.
  *
  * Requires: MBEDTLS_PSA_CRYPTO_C.
+ *
+ * Uncomment this to enable internal use of PSA Crypto and new associated APIs.
  */
 //#define MBEDTLS_USE_PSA_CRYPTO
 
@@ -1702,6 +1735,10 @@
  *
  * Enable the Platform Security Architecture cryptography API.
  *
+ * \warning The PSA Crypto API is still beta status. While you're welcome to
+ * experiment using it, incompatible API changes are still possible, and some
+ * parts may not have reached the same quality as the rest of Mbed TLS yet.
+ *
  * Module:  library/psa_crypto.c
  *
  * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
@@ -1967,6 +2004,42 @@
 //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 
 /**
+ * \brief       This macro is invoked by the library when an invalid parameter
+ *              is detected that is only checked with #MBEDTLS_CHECK_PARAMS
+ *              (see the documentation of that option for context).
+ *
+ *              When you leave this undefined here, the library provides
+ *              a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT
+ *              is defined, the default definition is `assert(cond)`,
+ *              otherwise the default definition calls a function
+ *              mbedtls_param_failed(). This function is declared in
+ *              `platform_util.h` for the benefit of the library, but
+ *              you need to define in your application.
+ *
+ *              When you define this here, this replaces the default
+ *              definition in platform_util.h (which no longer declares the
+ *              function mbedtls_param_failed()) and it is your responsibility
+ *              to make sure this macro expands to something suitable (in
+ *              particular, that all the necessary declarations are visible
+ *              from within the library - you can ensure that by providing
+ *              them in this file next to the macro definition).
+ *              If you define this macro to call `assert`, also define
+ *              #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files
+ *              include `<assert.h>`.
+ *
+ *              Note that you may define this macro to expand to nothing, in
+ *              which case you don't have to worry about declarations or
+ *              definitions. However, you will then be notified about invalid
+ *              parameters only in non-void functions, and void function will
+ *              just silently return early on invalid parameters, which
+ *              partially negates the benefits of enabling
+ *              #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
+ *
+ * \param cond  The expression that should evaluate to true, but doesn't.
+ */
+//#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
+
+/**
  * Uncomment the macro to let mbed TLS use your alternate implementation of
  * mbedtls_platform_zeroize(). This replaces the default implementation in
  * platform_util.c.
@@ -2016,6 +2089,6 @@
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 
-#include "check_config.h"
+#include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index cc3df7b..ffaf8ad 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -37,15 +37,15 @@
 #define MBEDTLS_CTR_DRBG_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "aes.h"
+#include "mbedtls/aes.h"
 
 #if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
 #endif
 
 #define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED        -0x0034  /**< The entropy source failed. */
diff --git a/include/mbedtls/des.h b/include/mbedtls/des.h
index 54e6b78..1c80b53 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -30,7 +30,7 @@
 #define MBEDTLS_DES_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index 49eb6a4..831cfd7 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -66,11 +66,11 @@
 #define MBEDTLS_DHM_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
-#include "bignum.h"
+#include "mbedtls/bignum.h"
 
 /*
  * DHM Error codes
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 384c3dc..d870a5b 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -35,12 +35,12 @@
 #define MBEDTLS_ECDH_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "ecp.h"
+#include "mbedtls/ecp.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index 2943945..effbb1e 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -33,13 +33,13 @@
 #define MBEDTLS_ECDSA_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "ecp.h"
-#include "md.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/md.h"
 
 /**
  * \brief           Maximum ECDSA signature size for a given curve bit size
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index 3d8d02a..97387c3 100644
--- a/include/mbedtls/ecjpake.h
+++ b/include/mbedtls/ecjpake.h
@@ -41,13 +41,13 @@
  * also be use outside TLS.
  */
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "ecp.h"
-#include "md.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/md.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 1a6ec13..6aa677a 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -37,12 +37,12 @@
 #define MBEDTLS_ECP_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "bignum.h"
+#include "mbedtls/bignum.h"
 
 /*
  * ECP error codes
diff --git a/include/mbedtls/ecp_internal.h b/include/mbedtls/ecp_internal.h
index 7625ed4..3b6fbf1 100644
--- a/include/mbedtls/ecp_internal.h
+++ b/include/mbedtls/ecp_internal.h
@@ -62,7 +62,7 @@
 #define MBEDTLS_ECP_INTERNAL_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index ca06dc3..06aaffa 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_ENTROPY_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -33,21 +33,21 @@
 #include <stddef.h>
 
 #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
-#include "sha512.h"
+#include "mbedtls/sha512.h"
 #define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
 #else
 #if defined(MBEDTLS_SHA256_C)
 #define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
-#include "sha256.h"
+#include "mbedtls/sha256.h"
 #endif
 #endif
 
 #if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
 #endif
 
 #if defined(MBEDTLS_HAVEGE_C)
-#include "havege.h"
+#include "mbedtls/havege.h"
 #endif
 
 #define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED                 -0x003C  /**< Critical entropy source failure. */
diff --git a/include/mbedtls/entropy_poll.h b/include/mbedtls/entropy_poll.h
index 94dd657..ba42805 100644
--- a/include/mbedtls/entropy_poll.h
+++ b/include/mbedtls/entropy_poll.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_ENTROPY_POLL_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index bee0fe4..20a245a 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_ERROR_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -100,8 +100,8 @@
  * ECP       4   10 (Started from top)
  * MD        5   5
  * HKDF      5   1 (Started from top)
- * CIPHER    6   8
- * SSL       6   23 (Started from top)
+ * CIPHER    6   8 (Started from 0x6080)
+ * SSL       6   24 (Started from top, plus 0x6000)
  * SSL       7   32
  *
  * Module dependent error code (5 bits 0x.00.-0x.F8.)
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index fd130ab..a71a2af 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -34,12 +34,12 @@
 #define MBEDTLS_GCM_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "cipher.h"
+#include "mbedtls/cipher.h"
 
 #include <stdint.h>
 
diff --git a/include/mbedtls/havege.h b/include/mbedtls/havege.h
index 4c1c860..acd7e48 100644
--- a/include/mbedtls/havege.h
+++ b/include/mbedtls/havege.h
@@ -25,12 +25,13 @@
 #define MBEDTLS_HAVEGE_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
 #include <stddef.h>
+#include <stdint.h>
 
 #define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
 
@@ -43,9 +44,9 @@
  */
 typedef struct mbedtls_havege_state
 {
-    int PT1, PT2, offset[2];
-    int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
-    int WALK[8192];
+    uint32_t PT1, PT2, offset[2];
+    uint32_t pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
+    uint32_t WALK[8192];
 }
 mbedtls_havege_state;
 
diff --git a/include/mbedtls/hkdf.h b/include/mbedtls/hkdf.h
index 40ee64e..20f325d 100644
--- a/include/mbedtls/hkdf.h
+++ b/include/mbedtls/hkdf.h
@@ -28,12 +28,12 @@
 #define MBEDTLS_HKDF_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "md.h"
+#include "mbedtls/md.h"
 
 /**
  *  \name HKDF Error codes
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index f1289cb..46536a1 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -25,15 +25,15 @@
 #define MBEDTLS_HMAC_DRBG_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "md.h"
+#include "mbedtls/md.h"
 
 #if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
 #endif
 
 /*
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index 69ab21f..0b0ec91 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -30,7 +30,7 @@
 #include <stddef.h>
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/md2.h b/include/mbedtls/md2.h
index fe97cf0..df1d5f7 100644
--- a/include/mbedtls/md2.h
+++ b/include/mbedtls/md2.h
@@ -30,7 +30,7 @@
 #define MBEDTLS_MD2_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/md4.h b/include/mbedtls/md4.h
index ce703c0..e7accd4 100644
--- a/include/mbedtls/md4.h
+++ b/include/mbedtls/md4.h
@@ -30,7 +30,7 @@
 #define MBEDTLS_MD4_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/md5.h b/include/mbedtls/md5.h
index 6eed6cc..4206c1f 100644
--- a/include/mbedtls/md5.h
+++ b/include/mbedtls/md5.h
@@ -29,7 +29,7 @@
 #define MBEDTLS_MD5_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/md_internal.h b/include/mbedtls/md_internal.h
index 04de482..267ceba 100644
--- a/include/mbedtls/md_internal.h
+++ b/include/mbedtls/md_internal.h
@@ -29,12 +29,12 @@
 #define MBEDTLS_MD_WRAP_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "md.h"
+#include "mbedtls/md.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/memory_buffer_alloc.h b/include/mbedtls/memory_buffer_alloc.h
index 705f9a6..8e77f6f 100644
--- a/include/mbedtls/memory_buffer_alloc.h
+++ b/include/mbedtls/memory_buffer_alloc.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_MEMORY_BUFFER_ALLOC_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/nist_kw.h b/include/mbedtls/nist_kw.h
index 3b67b59..b39406f 100644
--- a/include/mbedtls/nist_kw.h
+++ b/include/mbedtls/nist_kw.h
@@ -38,12 +38,12 @@
 #define MBEDTLS_NIST_KW_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "cipher.h"
+#include "mbedtls/cipher.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index 17cdba7..59ce020 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -25,22 +25,22 @@
 #define MBEDTLS_OID_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "asn1.h"
-#include "pk.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/pk.h"
 
 #include <stddef.h>
 
 #if defined(MBEDTLS_CIPHER_C)
-#include "cipher.h"
+#include "mbedtls/cipher.h"
 #endif
 
 #if defined(MBEDTLS_MD_C)
-#include "md.h"
+#include "mbedtls/md.h"
 #endif
 
 #define MBEDTLS_ERR_OID_NOT_FOUND                         -0x002E  /**< OID is not found. */
diff --git a/include/mbedtls/padlock.h b/include/mbedtls/padlock.h
index 721a5d4..513d72f 100644
--- a/include/mbedtls/padlock.h
+++ b/include/mbedtls/padlock.h
@@ -29,12 +29,12 @@
 #define MBEDTLS_PADLOCK_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "aes.h"
+#include "mbedtls/aes.h"
 
 #define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED               -0x0030  /**< Input data should be aligned. */
 
diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h
index a29e9ce..f7bf1a6 100644
--- a/include/mbedtls/pem.h
+++ b/include/mbedtls/pem.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_PEM_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -112,17 +112,27 @@
  * \brief           Write a buffer of PEM information from a DER encoded
  *                  buffer.
  *
- * \param header    header string to write
- * \param footer    footer string to write
- * \param der_data  DER data to write
- * \param der_len   length of the DER data
- * \param buf       buffer to write to
- * \param buf_len   length of output buffer
- * \param olen      total length written / required (if buf_len is not enough)
+ * \param header    The header string to write.
+ * \param footer    The footer string to write.
+ * \param der_data  The DER data to encode.
+ * \param der_len   The length of the DER data \p der_data in Bytes.
+ * \param buf       The buffer to write to.
+ * \param buf_len   The length of the output buffer \p buf in Bytes.
+ * \param olen      The address at which to store the total length written
+ *                  or required (if \p buf_len is not enough).
  *
- * \return          0 on success, or a specific PEM or BASE64 error code. On
- *                  MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required
- *                  size.
+ * \note            You may pass \c NULL for \p buf and \c 0 for \p buf_len
+ *                  to request the length of the resulting PEM buffer in
+ *                  `*olen`.
+ *
+ * \note            This function may be called with overlapping \p der_data
+ *                  and \p buf buffers.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large
+ *                  enough to hold the PEM buffer. In  this case, `*olen` holds
+ *                  the required minimum size of \p buf.
+ * \return          Another PEM or BASE64 error code on other kinds of failure.
  */
 int mbedtls_pem_write_buffer( const char *header, const char *footer,
                       const unsigned char *der_data, size_t der_len,
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 0e24b1a..d750004 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -26,23 +26,23 @@
 #define MBEDTLS_PK_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "md.h"
+#include "mbedtls/md.h"
 
 #if defined(MBEDTLS_RSA_C)
-#include "rsa.h"
+#include "mbedtls/rsa.h"
 #endif
 
 #if defined(MBEDTLS_ECP_C)
-#include "ecp.h"
+#include "mbedtls/ecp.h"
 #endif
 
 #if defined(MBEDTLS_ECDSA_C)
-#include "ecdsa.h"
+#include "mbedtls/ecdsa.h"
 #endif
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
diff --git a/include/mbedtls/pk_internal.h b/include/mbedtls/pk_internal.h
index fc9ba13..7ef6322 100644
--- a/include/mbedtls/pk_internal.h
+++ b/include/mbedtls/pk_internal.h
@@ -26,12 +26,12 @@
 #define MBEDTLS_PK_WRAP_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "pk.h"
+#include "mbedtls/pk.h"
 
 struct mbedtls_pk_info_t
 {
diff --git a/include/mbedtls/pkcs12.h b/include/mbedtls/pkcs12.h
index d441357..9d42d7f 100644
--- a/include/mbedtls/pkcs12.h
+++ b/include/mbedtls/pkcs12.h
@@ -25,14 +25,14 @@
 #define MBEDTLS_PKCS12_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "md.h"
-#include "cipher.h"
-#include "asn1.h"
+#include "mbedtls/md.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/asn1.h"
 
 #include <stddef.h>
 
diff --git a/include/mbedtls/pkcs5.h b/include/mbedtls/pkcs5.h
index c92185f..bbec7e7 100644
--- a/include/mbedtls/pkcs5.h
+++ b/include/mbedtls/pkcs5.h
@@ -27,13 +27,13 @@
 #define MBEDTLS_PKCS5_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "asn1.h"
-#include "md.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/md.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index 801a948..b402f8f 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -34,13 +34,13 @@
 #define MBEDTLS_PLATFORM_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
 #if defined(MBEDTLS_HAVE_TIME)
-#include "platform_time.h"
+#include "mbedtls/platform_time.h"
 #endif
 
 #define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED     -0x0070 /**< Hardware accelerator failed */
@@ -256,6 +256,7 @@
  *   the destination buffer is too short.
  */
 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include <stdarg.h>
 /* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
 int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
 #endif
diff --git a/include/mbedtls/platform_time.h b/include/mbedtls/platform_time.h
index 2ed36f5..fe484fd 100644
--- a/include/mbedtls/platform_time.h
+++ b/include/mbedtls/platform_time.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_PLATFORM_TIME_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index dba6d45..cf0130a 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -26,14 +26,14 @@
 #define MBEDTLS_PLATFORM_UTIL_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
 #include <stddef.h>
 #if defined(MBEDTLS_HAVE_TIME_DATE)
-#include "platform_time.h"
+#include "mbedtls/platform_time.h"
 #include <time.h>
 #endif /* MBEDTLS_HAVE_TIME_DATE */
 
@@ -43,6 +43,12 @@
 
 #if defined(MBEDTLS_CHECK_PARAMS)
 
+#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
+ * (which is what our config.h suggests). */
+#include <assert.h>
+#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
+
 #if defined(MBEDTLS_PARAM_FAILED)
 /** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
  *
@@ -50,6 +56,11 @@
  * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
  */
 #define MBEDTLS_PARAM_FAILED_ALT
+
+#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
+#define MBEDTLS_PARAM_FAILED_ALT
+
 #else /* MBEDTLS_PARAM_FAILED */
 #define MBEDTLS_PARAM_FAILED( cond ) \
     mbedtls_param_failed( #cond, __FILE__, __LINE__ )
diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h
index f0ec44c..05866a2 100644
--- a/include/mbedtls/poly1305.h
+++ b/include/mbedtls/poly1305.h
@@ -34,7 +34,7 @@
 #define MBEDTLS_POLY1305_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index b5f0b7f..8d18fcc 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -29,7 +29,7 @@
 #define MBEDTLS_PSA_UTIL_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -38,10 +38,10 @@
 
 #include "psa/crypto.h"
 
-#include "ecp.h"
-#include "md.h"
-#include "pk.h"
-#include "oid.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/md.h"
+#include "mbedtls/pk.h"
+#include "mbedtls/oid.h"
 
 #include <string.h>
 
diff --git a/include/mbedtls/ripemd160.h b/include/mbedtls/ripemd160.h
index b42f6d2..3c1f5bf 100644
--- a/include/mbedtls/ripemd160.h
+++ b/include/mbedtls/ripemd160.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_RIPEMD160_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -57,7 +57,7 @@
 mbedtls_ripemd160_context;
 
 #else  /* MBEDTLS_RIPEMD160_ALT */
-#include "ripemd160.h"
+#include "ripemd160_alt.h"
 #endif /* MBEDTLS_RIPEMD160_ALT */
 
 /**
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index 489f2ed..840540b 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -31,16 +31,16 @@
 #define MBEDTLS_RSA_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "bignum.h"
-#include "md.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/md.h"
 
 #if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
 #endif
 
 /*
diff --git a/include/mbedtls/rsa_internal.h b/include/mbedtls/rsa_internal.h
index 53abd3c..c1c844e 100644
--- a/include/mbedtls/rsa_internal.h
+++ b/include/mbedtls/rsa_internal.h
@@ -58,12 +58,12 @@
 #define MBEDTLS_RSA_INTERNAL_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "bignum.h"
+#include "mbedtls/bignum.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index bb6ecf0..988d2f9 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -32,7 +32,7 @@
 #define MBEDTLS_SHA1_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index d647398..1c59740 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -28,7 +28,7 @@
 #define MBEDTLS_SHA256_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index c06ceed..48923e5 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -27,7 +27,7 @@
 #define MBEDTLS_SHA512_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index 92e6e6b..cab40f7 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_THREADING_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h
index a965fe0..b264a5a 100644
--- a/include/mbedtls/timing.h
+++ b/include/mbedtls/timing.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_TIMING_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 79b42b2..fd77830 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -29,7 +29,7 @@
 #define MBEDTLS_VERSION_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/mbedtls/xtea.h b/include/mbedtls/xtea.h
index b47f553..2dc0afc 100644
--- a/include/mbedtls/xtea.h
+++ b/include/mbedtls/xtea.h
@@ -25,7 +25,7 @@
 #define MBEDTLS_XTEA_H
 
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index b2d4633..130ce75 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -89,7 +89,7 @@
     psa_key_attributes_t *attributes,
     psa_algorithm_t alg2)
 {
-    attributes->policy.alg2 = alg2;
+    attributes->core.policy.alg2 = alg2;
 }
 
 /** Retrieve the enrollment algorithm policy from key attributes.
@@ -101,9 +101,82 @@
 static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
     const psa_key_attributes_t *attributes)
 {
-    return( attributes->policy.alg2 );
+    return( attributes->core.policy.alg2 );
 }
 
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+
+/** Retrieve the slot number where a key is stored.
+ *
+ * A slot number is only defined for keys that are stored in a secure
+ * element.
+ *
+ * This information is only useful if the secure element is not entirely
+ * managed through the PSA Cryptography API. It is up to the secure
+ * element driver to decide how PSA slot numbers map to any other interface
+ * that the secure element may have.
+ *
+ * \param[in] attributes        The key attribute structure to query.
+ * \param[out] slot_number      On success, the slot number containing the key.
+ *
+ * \retval #PSA_SUCCESS
+ *         The key is located in a secure element, and \p *slot_number
+ *         indicates the slot number that contains it.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ *         The caller is not permitted to query the slot number.
+ *         Mbed Crypto currently does not return this error.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The key is not located in a secure element.
+ */
+psa_status_t psa_get_key_slot_number(
+    const psa_key_attributes_t *attributes,
+    psa_key_slot_number_t *slot_number );
+
+/** Choose the slot number where a key is stored.
+ *
+ * This function declares a slot number in the specified attribute
+ * structure.
+ *
+ * A slot number is only meaningful for keys that are stored in a secure
+ * element. It is up to the secure element driver to decide how PSA slot
+ * numbers map to any other interface that the secure element may have.
+ *
+ * \note Setting a slot number in key attributes for a key creation can
+ *       cause the following errors when creating the key:
+ *       - #PSA_ERROR_NOT_SUPPORTED if the selected secure element does
+ *         not support choosing a specific slot number.
+ *       - #PSA_ERROR_NOT_PERMITTED if the caller is not permitted to
+ *         choose slot numbers in general or to choose this specific slot.
+ *       - #PSA_ERROR_INVALID_ARGUMENT if the chosen slot number is not
+ *         valid in general or not valid for this specific key.
+ *       - #PSA_ERROR_ALREADY_EXISTS if there is already a key in the
+ *         selected slot.
+ *
+ * \param[out] attributes       The attribute structure to write to.
+ * \param slot_number           The slot number to set.
+ */
+static inline void psa_set_key_slot_number(
+    psa_key_attributes_t *attributes,
+    psa_key_slot_number_t slot_number )
+{
+    attributes->core.flags |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
+    attributes->slot_number = slot_number;
+}
+
+/** Remove the slot number attribute from a key attribute structure.
+ *
+ * This function undoes the action of psa_set_key_slot_number().
+ *
+ * \param[out] attributes       The attribute structure to write to.
+ */
+static inline void psa_clear_key_slot_number(
+    psa_key_attributes_t *attributes )
+{
+    attributes->core.flags &= ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
 /**@}*/
 
 /**
diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h
index 42cdad3..86af08f 100644
--- a/include/psa/crypto_platform.h
+++ b/include/psa/crypto_platform.h
@@ -38,7 +38,7 @@
 /* Include the Mbed TLS configuration file, the way Mbed TLS does it
  * in each of its header files. */
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "../mbedtls/config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/psa/crypto_se_driver.h b/include/psa/crypto_se_driver.h
index 9aebc45..69cdaba 100644
--- a/include/psa/crypto_se_driver.h
+++ b/include/psa/crypto_se_driver.h
@@ -134,10 +134,17 @@
                                           void *persistent_data,
                                           psa_key_lifetime_t lifetime);
 
+#if defined(__DOXYGEN_ONLY__) || !defined(MBEDTLS_PSA_CRYPTO_SE_C)
+/* Mbed Crypto with secure element support enabled defines this type in
+ * crypto_types.h because it is also visible to applications through an
+ * implementation-specific extension.
+ * For the PSA Cryptography specification, this type is only visible
+ * via crypto_se_driver.h. */
 /** An internal designation of a key slot between the core part of the
  * PSA Crypto implementation and the driver. The meaning of this value
  * is driver-dependent. */
 typedef uint64_t psa_key_slot_number_t;
+#endif /* __DOXYGEN_ONLY__ || !MBEDTLS_PSA_CRYPTO_SE_C */
 
 /**@}*/
 
@@ -833,14 +840,18 @@
  *
  * \param[in,out] drv_context   The driver context structure.
  * \param[in] key_slot          Slot where the key will be stored
- *                              This must be a valid slot for a key of the chosen
- *                              type. It must be unoccupied.
+ *                              This must be a valid slot for a key of the
+ *                              chosen type. It must be unoccupied.
  * \param[in] lifetime          The required lifetime of the key storage
  * \param[in] type              Key type (a \c PSA_KEY_TYPE_XXX value)
  * \param[in] algorithm         Key algorithm (a \c PSA_ALG_XXX value)
  * \param[in] usage             The allowed uses of the key
  * \param[in] p_data            Buffer containing the key data
  * \param[in] data_length       Size of the `data` buffer in bytes
+ * \param[out] bits             On success, the key size in bits. The driver
+ *                              must determine this value after parsing the
+ *                              key according to the key type.
+ *                              This value is not used if the function fails.
  *
  * \retval #PSA_SUCCESS
  *         Success.
@@ -852,7 +863,8 @@
                                                 psa_algorithm_t algorithm,
                                                 psa_key_usage_t usage,
                                                 const uint8_t *p_data,
-                                                size_t data_length);
+                                                size_t data_length,
+                                                size_t *bits);
 
 /**
  * \brief A function that destroys a secure element key and restore the slot to
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index 09a292b..bcca724 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -45,7 +45,7 @@
 /* Include the Mbed TLS configuration file, the way Mbed TLS does it
  * in each of its header files. */
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "../mbedtls/config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 0ddc7a3..fbfe77e 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -38,7 +38,7 @@
 /* Include the Mbed TLS configuration file, the way Mbed TLS does it
  * in each of its header files. */
 #if !defined(MBEDTLS_CONFIG_FILE)
-#include "../mbedtls/config.h"
+#include "mbedtls/config.h"
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
@@ -309,18 +309,70 @@
     return( v );
 }
 
+/* The type used internally for key sizes.
+ * Public interfaces use size_t, but internally we use a smaller type. */
+typedef uint16_t psa_key_bits_t;
+/* The maximum value of the type used to represent bit-sizes.
+ * This is used to mark an invalid key size. */
+#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) )
+/* The maximum size of a key in bits.
+ * Currently defined as the maximum that can be represented, rounded down
+ * to a whole number of bytes.
+ * This is an uncast value so that it can be used in preprocessor
+ * conditionals. */
+#define PSA_MAX_KEY_BITS 0xfff8
+
+/** A mask of flags that can be stored in key attributes.
+ *
+ * This type is also used internally to store flags in slots. Internal
+ * flags are defined in library/psa_crypto_core.h. Internal flags may have
+ * the same value as external flags if they are properly handled during
+ * key creation and in psa_get_key_attributes.
+ */
+typedef uint16_t psa_key_attributes_flag_t;
+
+#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER     \
+    ( (psa_key_attributes_flag_t) 0x0001 )
+
+/* A mask of key attribute flags used externally only.
+ * Only meant for internal checks inside the library. */
+#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY (      \
+        MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER |    \
+        0 )
+
+/* A mask of key attribute flags used both internally and externally.
+ * Currently there aren't any. */
+#define MBEDTLS_PSA_KA_MASK_DUAL_USE (          \
+        0 )
+
+typedef struct
+{
+    psa_key_type_t type;
+    psa_key_lifetime_t lifetime;
+    psa_key_id_t id;
+    psa_key_policy_t policy;
+    psa_key_bits_t bits;
+    psa_key_attributes_flag_t flags;
+} psa_core_key_attributes_t;
+
+#define PSA_CORE_KEY_ATTRIBUTES_INIT {0, 0, 0, {0, 0, 0}, 0, 0}
+
 struct psa_key_attributes_s
 {
-    psa_key_id_t id;
-    psa_key_lifetime_t lifetime;
-    psa_key_policy_t policy;
-    psa_key_type_t type;
-    size_t bits;
+    psa_core_key_attributes_t core;
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+    psa_key_slot_number_t slot_number;
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
     void *domain_parameters;
     size_t domain_parameters_size;
 };
 
-#define PSA_KEY_ATTRIBUTES_INIT {0, 0, {0, 0, 0}, 0, 0, NULL, 0}
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0}
+#else
+#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0}
+#endif
+
 static inline struct psa_key_attributes_s psa_key_attributes_init( void )
 {
     const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
@@ -330,53 +382,53 @@
 static inline void psa_set_key_id(psa_key_attributes_t *attributes,
                                   psa_key_id_t id)
 {
-    attributes->id = id;
-    if( attributes->lifetime == PSA_KEY_LIFETIME_VOLATILE )
-        attributes->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
+    attributes->core.id = id;
+    if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE )
+        attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
 }
 
 static inline psa_key_id_t psa_get_key_id(
     const psa_key_attributes_t *attributes)
 {
-    return( attributes->id );
+    return( attributes->core.id );
 }
 
 static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
                                         psa_key_lifetime_t lifetime)
 {
-    attributes->lifetime = lifetime;
+    attributes->core.lifetime = lifetime;
     if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
-        attributes->id = 0;
+        attributes->core.id = 0;
 }
 
 static inline psa_key_lifetime_t psa_get_key_lifetime(
     const psa_key_attributes_t *attributes)
 {
-    return( attributes->lifetime );
+    return( attributes->core.lifetime );
 }
 
 static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
                                            psa_key_usage_t usage_flags)
 {
-    attributes->policy.usage = usage_flags;
+    attributes->core.policy.usage = usage_flags;
 }
 
 static inline psa_key_usage_t psa_get_key_usage_flags(
     const psa_key_attributes_t *attributes)
 {
-    return( attributes->policy.usage );
+    return( attributes->core.policy.usage );
 }
 
 static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
                                          psa_algorithm_t alg)
 {
-    attributes->policy.alg = alg;
+    attributes->core.policy.alg = alg;
 }
 
 static inline psa_algorithm_t psa_get_key_algorithm(
     const psa_key_attributes_t *attributes)
 {
-    return( attributes->policy.alg );
+    return( attributes->core.policy.alg );
 }
 
 /* This function is declared in crypto_extra.h, which comes after this
@@ -392,7 +444,7 @@
     if( attributes->domain_parameters == NULL )
     {
         /* Common case: quick path */
-        attributes->type = type;
+        attributes->core.type = type;
     }
     else
     {
@@ -407,19 +459,22 @@
 static inline psa_key_type_t psa_get_key_type(
     const psa_key_attributes_t *attributes)
 {
-    return( attributes->type );
+    return( attributes->core.type );
 }
 
 static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
                                     size_t bits)
 {
-    attributes->bits = bits;
+    if( bits > PSA_MAX_KEY_BITS )
+        attributes->core.bits = PSA_KEY_BITS_TOO_LARGE;
+    else
+        attributes->core.bits = (psa_key_bits_t) bits;
 }
 
 static inline size_t psa_get_key_bits(
     const psa_key_attributes_t *attributes)
 {
-    return( attributes->bits );
+    return( attributes->core.bits );
 }
 
 #endif /* PSA_CRYPTO_STRUCT_H */
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index 1944be4..9af4957 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -244,6 +244,17 @@
  */
 typedef struct psa_key_attributes_s psa_key_attributes_t;
 
+
+#ifndef __DOXYGEN_ONLY__
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+/* Mbed Crypto defines this type in crypto_types.h because it is also
+ * visible to applications through an implementation-specific extension.
+ * For the PSA Cryptography specification, this type is only visible
+ * via crypto_se_driver.h. */
+typedef uint64_t psa_key_slot_number_t;
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+#endif /* !__DOXYGEN_ONLY__ */
+
 /**@}*/
 
 /** \defgroup derivation Key derivation
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 78c233a..b1f1fb3 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -1,6 +1,14 @@
 option(USE_STATIC_MBEDTLS_LIBRARY "Build mbed TLS static library." ON)
 option(USE_SHARED_MBEDTLS_LIBRARY "Build mbed TLS shared library." OFF)
 option(LINK_WITH_PTHREAD "Explicitly link mbed TLS library to pthread." OFF)
+option(LINK_WITH_TRUSTED_STORAGE "Explicitly link mbed TLS library to trusted_storage." OFF)
+
+# Set the project root directory if it's not already defined, as may happen if
+# the library folder is included directly by a parent project, without
+# including the top level CMakeLists.txt.
+if(NOT DEFINED MBEDTLS_DIR)
+    set(MBEDTLS_DIR ${CMAKE_SOURCE_DIR})
+endif()
 
 set(src_crypto
     aes.c
@@ -73,9 +81,9 @@
 if(USE_CRYPTO_SUBMODULE)
 set(src_crypto
     ${src_crypto}
-    ${CMAKE_SOURCE_DIR}/library/version.c
-    ${CMAKE_SOURCE_DIR}/library/version_features.c
-    ${CMAKE_SOURCE_DIR}/library/error.c
+    ${MBEDTLS_DIR}/library/version.c
+    ${MBEDTLS_DIR}/library/version_features.c
+    ${MBEDTLS_DIR}/library/error.c
 )
 else()
 set(src_crypto
@@ -119,6 +127,10 @@
     set(libs ${libs} pthread)
 endif()
 
+if(LINK_WITH_TRUSTED_STORAGE)
+    set(libs ${libs} trusted_storage)
+endif()
+
 if (NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY)
     message(FATAL_ERROR "Need to choose static or shared mbedtls build!")
 endif(NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY)
@@ -134,8 +146,8 @@
     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/
-        PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/)
+        PUBLIC ${MBEDTLS_DIR}/include/
+        PUBLIC ${MBEDTLS_DIR}/crypto/include/)
 
     install(TARGETS ${mbedcrypto_static_target}
             DESTINATION ${LIB_INSTALL_DIR}
@@ -147,8 +159,8 @@
     set_target_properties(mbedcrypto PROPERTIES VERSION 2.17.0 SOVERSION 3)
     target_link_libraries(mbedcrypto ${libs})
     target_include_directories(mbedcrypto
-        PUBLIC ${CMAKE_SOURCE_DIR}/include/
-        PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/)
+        PUBLIC ${MBEDTLS_DIR}/include/
+        PUBLIC ${MBEDTLS_DIR}/crypto/include/)
 
     install(TARGETS mbedcrypto
             DESTINATION ${LIB_INSTALL_DIR}
diff --git a/library/Makefile b/library/Makefile
index 2b979b4..736ce09 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -2,7 +2,7 @@
 # Also see "include/mbedtls/config.h"
 
 CFLAGS	?= -O2
-WARNING_CFLAGS ?=  -Wall -W -Wdeclaration-after-statement
+WARNING_CFLAGS ?=  -Wall -Wextra
 LDFLAGS ?=
 
 CRYPTO_INCLUDES ?= -I../include
diff --git a/library/dhm.c b/library/dhm.c
index fb6937e..8255632 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -649,12 +649,28 @@
 
 #if defined(MBEDTLS_SELF_TEST)
 
+#if defined(MBEDTLS_PEM_PARSE_C)
 static const char mbedtls_test_dhm_params[] =
 "-----BEGIN DH PARAMETERS-----\r\n"
 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
 "-----END DH PARAMETERS-----\r\n";
+#else /* MBEDTLS_PEM_PARSE_C */
+static const char mbedtls_test_dhm_params[] = {
+  0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
+  0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
+  0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
+  0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
+  0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
+  0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
+  0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
+  0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
+  0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
+  0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
+  0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
+  0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
+#endif /* MBEDTLS_PEM_PARSE_C */
 
 static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
 
diff --git a/library/ecp.c b/library/ecp.c
index 03f5fef..ccc0788 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -2004,8 +2004,10 @@
      * Make sure w is within bounds.
      * (The last test is useful only for very small curves in the test suite.)
      */
+#if( MBEDTLS_ECP_WINDOW_SIZE < 6 )
     if( w > MBEDTLS_ECP_WINDOW_SIZE )
         w = MBEDTLS_ECP_WINDOW_SIZE;
+#endif
     if( w >= grp->nbits )
         w = 2;
 
diff --git a/library/havege.c b/library/havege.c
index 54f897c..ca7dd17 100644
--- a/library/havege.c
+++ b/library/havege.c
@@ -38,6 +38,7 @@
 #include "mbedtls/timing.h"
 #include "mbedtls/platform_util.h"
 
+#include <stdint.h>
 #include <string.h>
 
 /* ------------------------------------------------------------------------
@@ -54,7 +55,7 @@
  * ------------------------------------------------------------------------
  */
 
-#define SWAP(X,Y) { int *T = (X); (X) = (Y); (Y) = T; }
+#define SWAP(X,Y) { uint32_t *T = (X); (X) = (Y); (Y) = T; }
 
 #define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
 #define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
@@ -77,7 +78,7 @@
     PTX = (PT1 >> 18) & 7;                              \
     PT1 &= 0x1FFF;                                      \
     PT2 &= 0x1FFF;                                      \
-    CLK = (int) mbedtls_timing_hardclock();                            \
+    CLK = (uint32_t) mbedtls_timing_hardclock();        \
                                                         \
     i = 0;                                              \
     A = &WALK[PT1    ]; RES[i++] ^= *A;                 \
@@ -100,7 +101,7 @@
                                                         \
     IN = (*A >> (5)) ^ (*A << (27)) ^ CLK;              \
     *A = (*B >> (6)) ^ (*B << (26)) ^ CLK;              \
-    *B = IN; CLK = (int) mbedtls_timing_hardclock();                   \
+    *B = IN; CLK = (uint32_t) mbedtls_timing_hardclock();       \
     *C = (*C >> (7)) ^ (*C << (25)) ^ CLK;              \
     *D = (*D >> (8)) ^ (*D << (24)) ^ CLK;              \
                                                         \
@@ -158,10 +159,11 @@
  */
 static void havege_fill( mbedtls_havege_state *hs )
 {
-    int i, n = 0;
-    int  U1,  U2, *A, *B, *C, *D;
-    int PT1, PT2, *WALK, RES[16];
-    int PTX, PTY, CLK, PTEST, IN;
+    size_t n = 0;
+    size_t i;
+    uint32_t  U1,  U2, *A, *B, *C, *D;
+    uint32_t PT1, PT2, *WALK, RES[16];
+    uint32_t PTX, PTY, CLK, PTEST, IN;
 
     WALK = hs->WALK;
     PT1  = hs->PT1;
@@ -212,7 +214,7 @@
  */
 int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
 {
-    int val;
+    uint32_t val;
     size_t use_len;
     mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng;
     unsigned char *p = buf;
@@ -220,8 +222,8 @@
     while( len > 0 )
     {
         use_len = len;
-        if( use_len > sizeof(int) )
-            use_len = sizeof(int);
+        if( use_len > sizeof( val ) )
+            use_len = sizeof( val );
 
         if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
             havege_fill( hs );
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 0b33d76..5cb88de 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -40,6 +40,7 @@
  * stored keys. */
 #include "psa_crypto_storage.h"
 
+#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include "mbedtls/platform.h"
@@ -366,7 +367,7 @@
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 static inline int psa_key_slot_is_external( const psa_key_slot_t *slot )
 {
-    return( psa_key_lifetime_is_external( slot->lifetime ) );
+    return( psa_key_lifetime_is_external( slot->attr.lifetime ) );
 }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
@@ -695,7 +696,45 @@
 }
 #endif /* defined(MBEDTLS_ECP_C) */
 
-/** Import key data into a slot. `slot->type` must have been set
+
+/** Return the size of the key in the given slot, in bits.
+ *
+ * \param[in] slot      A key slot.
+ *
+ * \return The key size in bits, read from the metadata in the slot.
+ */
+static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
+{
+    return( slot->attr.bits );
+}
+
+/** Calculate the size of the key in the given slot, in bits.
+ *
+ * \param[in] slot      A key slot containing a transparent key.
+ *
+ * \return The key size in bits, calculated from the key data.
+ */
+static psa_key_bits_t psa_calculate_key_bits( const psa_key_slot_t *slot )
+{
+    size_t bits = 0; /* return 0 on an empty slot */
+
+    if( key_type_is_raw_bytes( slot->attr.type ) )
+        bits = PSA_BYTES_TO_BITS( slot->data.raw.bytes );
+#if defined(MBEDTLS_RSA_C)
+    else if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
+        bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) );
+#endif /* defined(MBEDTLS_RSA_C) */
+#if defined(MBEDTLS_ECP_C)
+    else if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
+        bits = slot->data.ecp->grp.pbits;
+#endif /* defined(MBEDTLS_ECP_C) */
+
+    /* We know that the size fits in psa_key_bits_t thanks to checks
+     * when the key was created. */
+    return( (psa_key_bits_t) bits );
+}
+
+/** Import key data into a slot. `slot->attr.type` must have been set
  * previously. This function assumes that the slot does not contain
  * any key material yet. On failure, the slot content is unchanged. */
 psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
@@ -704,13 +743,17 @@
 {
     psa_status_t status = PSA_SUCCESS;
 
-    if( key_type_is_raw_bytes( slot->type ) )
+    if( key_type_is_raw_bytes( slot->attr.type ) )
     {
-        /* Ensure that a bytes-to-bit conversion won't overflow. */
+        size_t bit_size = PSA_BYTES_TO_BITS( data_length );
+        /* Ensure that the bytes-to-bit conversion didn't overflow. */
         if( data_length > SIZE_MAX / 8 )
             return( PSA_ERROR_NOT_SUPPORTED );
-        status = prepare_raw_data_slot( slot->type,
-                                        PSA_BYTES_TO_BITS( data_length ),
+        /* Enforce a size limit, and in particular ensure that the bit
+         * size fits in its representation type. */
+        if( bit_size > PSA_MAX_KEY_BITS )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        status = prepare_raw_data_slot( slot->attr.type, bit_size,
                                         &slot->data.raw );
         if( status != PSA_SUCCESS )
             return( status );
@@ -719,25 +762,25 @@
     }
     else
 #if defined(MBEDTLS_ECP_C)
-    if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->type ) )
+    if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) )
     {
-        status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
+        status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->attr.type ),
                                             data, data_length,
                                             &slot->data.ecp );
     }
-    else if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( slot->type ) )
+    else if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( slot->attr.type ) )
     {
         status = psa_import_ec_public_key(
-            PSA_KEY_TYPE_GET_CURVE( slot->type ),
+            PSA_KEY_TYPE_GET_CURVE( slot->attr.type ),
             data, data_length,
             &slot->data.ecp );
     }
     else
 #endif /* MBEDTLS_ECP_C */
 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
-    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
+    if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
     {
-        status = psa_import_rsa_key( slot->type,
+        status = psa_import_rsa_key( slot->attr.type,
             data, data_length,
             &slot->data.rsa );
     }
@@ -746,6 +789,14 @@
     {
         return( PSA_ERROR_NOT_SUPPORTED );
     }
+
+    if( status == PSA_SUCCESS )
+    {
+        /* Write the actual key size to the slot.
+         * psa_start_key_creation() wrote the size declared by the
+         * caller, which may be 0 (meaning unspecified) or wrong. */
+        slot->attr.bits = psa_calculate_key_bits( slot );
+    }
     return( status );
 }
 
@@ -851,20 +902,18 @@
     status = psa_get_key_slot( handle, &slot );
     if( status != PSA_SUCCESS )
         return( status );
-    if( slot->type == PSA_KEY_TYPE_NONE )
-        return( PSA_ERROR_DOES_NOT_EXIST );
 
     /* Enforce that usage policy for the key slot contains all the flags
      * required by the usage parameter. There is one exception: public
      * keys can always be exported, so we treat public key objects as
      * if they had the export flag. */
-    if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
+    if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
         usage &= ~PSA_KEY_USAGE_EXPORT;
-    if( ( slot->policy.usage & usage ) != usage )
+    if( ( slot->attr.policy.usage & usage ) != usage )
         return( PSA_ERROR_NOT_PERMITTED );
 
     /* Enforce that the usage policy permits the requested algortihm. */
-    if( alg != 0 && ! psa_key_policy_permits( &slot->policy, alg ) )
+    if( alg != 0 && ! psa_key_policy_permits( &slot->attr.policy, alg ) )
         return( PSA_ERROR_NOT_PERMITTED );
 
     *p_slot = slot;
@@ -911,17 +960,17 @@
     }
     else
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
-    if( slot->type == PSA_KEY_TYPE_NONE )
+    if( slot->attr.type == PSA_KEY_TYPE_NONE )
     {
         /* No key material to clean. */
     }
-    else if( key_type_is_raw_bytes( slot->type ) )
+    else if( key_type_is_raw_bytes( slot->attr.type ) )
     {
         mbedtls_free( slot->data.raw.data );
     }
     else
 #if defined(MBEDTLS_RSA_C)
-    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
+    if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
     {
         mbedtls_rsa_free( slot->data.rsa );
         mbedtls_free( slot->data.rsa );
@@ -929,7 +978,7 @@
     else
 #endif /* defined(MBEDTLS_RSA_C) */
 #if defined(MBEDTLS_ECP_C)
-    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
+    if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
     {
         mbedtls_ecp_keypair_free( slot->data.ecp );
         mbedtls_free( slot->data.ecp );
@@ -978,7 +1027,7 @@
         return( status );
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-    driver = psa_get_se_driver_entry( slot->lifetime );
+    driver = psa_get_se_driver_entry( slot->attr.lifetime );
     if( driver != NULL )
     {
         /* For a key in a secure element, we need to do three things:
@@ -987,9 +1036,9 @@
          * persistent data. Start a transaction that will encompass these
          * three actions. */
         psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
-        psa_crypto_transaction.key.lifetime = slot->lifetime;
+        psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
         psa_crypto_transaction.key.slot = slot->data.se.slot_number;
-        psa_crypto_transaction.key.id = slot->persistent_storage_id;
+        psa_crypto_transaction.key.id = slot->attr.id;
         status = psa_crypto_save_transaction( );
         if( status != PSA_SUCCESS )
         {
@@ -1003,10 +1052,10 @@
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
-    if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
+    if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
     {
         storage_status =
-            psa_destroy_persistent_key( slot->persistent_storage_id );
+            psa_destroy_persistent_key( slot->attr.id );
     }
 #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
 
@@ -1032,23 +1081,6 @@
     return( storage_status );
 }
 
-/* Return the size of the key in the given slot, in bits. */
-static size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
-{
-    if( key_type_is_raw_bytes( slot->type ) )
-        return( slot->data.raw.bytes * 8 );
-#if defined(MBEDTLS_RSA_C)
-    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
-        return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
-#endif /* defined(MBEDTLS_RSA_C) */
-#if defined(MBEDTLS_ECP_C)
-    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
-        return( slot->data.ecp->grp.pbits );
-#endif /* defined(MBEDTLS_ECP_C) */
-    /* Shouldn't happen except on an empty slot. */
-    return( 0 );
-}
-
 void psa_reset_key_attributes( psa_key_attributes_t *attributes )
 {
     mbedtls_free( attributes->domain_parameters );
@@ -1081,7 +1113,7 @@
 
     attributes->domain_parameters = copy;
     attributes->domain_parameters_size = data_length;
-    attributes->type = type;
+    attributes->core.type = type;
     return( PSA_SUCCESS );
 }
 
@@ -1140,20 +1172,6 @@
 }
 #endif /* MBEDTLS_RSA_C */
 
-/** Retrieve the readily-accessible attributes of a key in a slot.
- *
- * This function does not compute attributes that are not directly
- * stored in the slot, such as the bit size of a transparent key.
- */
-static void psa_get_key_slot_attributes( psa_key_slot_t *slot,
-                                         psa_key_attributes_t *attributes )
-{
-    attributes->id = slot->persistent_storage_id;
-    attributes->lifetime = slot->lifetime;
-    attributes->policy = slot->policy;
-    attributes->type = slot->type;
-}
-
 /** Retrieve all the publicly-accessible attributes of a key.
  */
 psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
@@ -1164,21 +1182,33 @@
 
     psa_reset_key_attributes( attributes );
 
-    status = psa_get_transparent_key( handle, &slot, 0, 0 );
+    status = psa_get_key_from_slot( handle, &slot, 0, 0 );
     if( status != PSA_SUCCESS )
         return( status );
 
-    psa_get_key_slot_attributes( slot, attributes );
-    attributes->bits = psa_get_key_slot_bits( slot );
+    attributes->core = slot->attr;
+    attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
+                                MBEDTLS_PSA_KA_MASK_DUAL_USE );
 
-    switch( slot->type )
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+    if( psa_key_slot_is_external( slot ) )
+        psa_set_key_slot_number( attributes, slot->data.se.slot_number );
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
+    switch( slot->attr.type )
     {
 #if defined(MBEDTLS_RSA_C)
         case PSA_KEY_TYPE_RSA_KEY_PAIR:
         case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+            /* TOnogrepDO: reporting the public exponent for opaque keys
+             * is not yet implemented. */
+            if( psa_key_slot_is_external( slot ) )
+                break;
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
             status = psa_get_rsa_public_exponent( slot->data.rsa, attributes );
             break;
-#endif
+#endif /* MBEDTLS_RSA_C */
         default:
             /* Nothing else to do. */
             break;
@@ -1189,6 +1219,21 @@
     return( status );
 }
 
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+psa_status_t psa_get_key_slot_number(
+    const psa_key_attributes_t *attributes,
+    psa_key_slot_number_t *slot_number )
+{
+    if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
+    {
+        *slot_number = attributes->slot_number;
+        return( PSA_SUCCESS );
+    }
+    else
+        return( PSA_ERROR_INVALID_ARGUMENT );
+}
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
 #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
 static int pk_write_pubkey_simple( mbedtls_pk_context *key,
                                    unsigned char *buf, size_t size )
@@ -1218,11 +1263,11 @@
 
     *data_length = 0;
 
-    if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
+    if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-    if( psa_get_se_driver( slot->lifetime, &drv, &drv_context ) )
+    if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
     {
         psa_drv_se_export_key_t method;
         if( drv->key_management == NULL )
@@ -1238,7 +1283,7 @@
     }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
-    if( key_type_is_raw_bytes( slot->type ) )
+    if( key_type_is_raw_bytes( slot->attr.type ) )
     {
         if( slot->data.raw.bytes > data_size )
             return( PSA_ERROR_BUFFER_TOO_SMALL );
@@ -1252,11 +1297,11 @@
         return( PSA_SUCCESS );
     }
 #if defined(MBEDTLS_ECP_C)
-    if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->type ) && !export_public_key )
+    if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) && !export_public_key )
     {
         psa_status_t status;
 
-        size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_slot_bits( slot ) );
+        size_t bytes = PSA_BITS_TO_BYTES( slot->attr.bits );
         if( bytes > data_size )
             return( PSA_ERROR_BUFFER_TOO_SMALL );
         status = mbedtls_to_psa_error(
@@ -1271,12 +1316,12 @@
     else
     {
 #if defined(MBEDTLS_PK_WRITE_C)
-        if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
-            PSA_KEY_TYPE_IS_ECC( slot->type ) )
+        if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ||
+            PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
         {
             mbedtls_pk_context pk;
             int ret;
-            if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
+            if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
             {
 #if defined(MBEDTLS_RSA_C)
                 mbedtls_pk_init( &pk );
@@ -1296,7 +1341,7 @@
                 return( PSA_ERROR_NOT_SUPPORTED );
 #endif
             }
-            if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
+            if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
             {
                 ret = pk_write_pubkey_simple( &pk, data, data_size );
             }
@@ -1385,9 +1430,22 @@
                                      data_length, 1 ) );
 }
 
-static psa_status_t psa_set_key_policy_internal(
-    psa_key_slot_t *slot,
-    const psa_key_policy_t *policy )
+#if defined(static_assert)
+static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
+               "One or more key attribute flag is listed as both external-only and dual-use" );
+static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
+               "One or more key attribute flag is listed as both internal-only and dual-use" );
+static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
+               "One or more key attribute flag is listed as both internal-only and external-only" );
+#endif
+
+/** Validate that a key policy is internally well-formed.
+ *
+ * This function only rejects invalid policies. It does not validate the
+ * consistency of the policy with respect to other attributes of the key
+ * such as the key type.
+ */
+static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy )
 {
     if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
                              PSA_KEY_USAGE_COPY |
@@ -1398,7 +1456,53 @@
                              PSA_KEY_USAGE_DERIVE ) ) != 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
-    slot->policy = *policy;
+    return( PSA_SUCCESS );
+}
+
+/** Validate the internal consistency of key attributes.
+ *
+ * This function only rejects invalid attribute values. If does not
+ * validate the consistency of the attributes with any key data that may
+ * be involved in the creation of the key.
+ *
+ * Call this function early in the key creation process.
+ *
+ * \param[in] attributes    Key attributes for the new key.
+ * \param[out] p_drv        On any return, the driver for the key, if any.
+ *                          NULL for a transparent key.
+ *
+ */
+static psa_status_t psa_validate_key_attributes(
+    const psa_key_attributes_t *attributes,
+    psa_se_drv_table_entry_t **p_drv )
+{
+    psa_status_t status;
+
+    if( attributes->core.lifetime != PSA_KEY_LIFETIME_VOLATILE )
+    {
+        status = psa_validate_persistent_key_parameters(
+            attributes->core.lifetime, attributes->core.id,
+            p_drv, 1 );
+        if( status != PSA_SUCCESS )
+            return( status );
+    }
+
+    status = psa_validate_key_policy( &attributes->core.policy );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    /* Refuse to create overly large keys.
+     * Note that this doesn't trigger on import if the attributes don't
+     * explicitly specify a size (so psa_get_key_bits returns 0), so
+     * psa_import_key() needs its own checks. */
+    if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS )
+        return( PSA_ERROR_NOT_SUPPORTED );
+
+    /* Reject invalid flags. These should not be reachable through the API. */
+    if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
+                                     MBEDTLS_PSA_KA_MASK_DUAL_USE ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
     return( PSA_SUCCESS );
 }
 
@@ -1438,26 +1542,29 @@
 
     *p_drv = NULL;
 
-    status = psa_internal_allocate_key_slot( handle, p_slot );
+    status = psa_validate_key_attributes( attributes, p_drv );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    status = psa_get_empty_key_slot( handle, p_slot );
     if( status != PSA_SUCCESS )
         return( status );
     slot = *p_slot;
 
-    status = psa_set_key_policy_internal( slot, &attributes->policy );
-    if( status != PSA_SUCCESS )
-        return( status );
-    slot->lifetime = attributes->lifetime;
+    /* We're storing the declared bit-size of the key. It's up to each
+     * creation mechanism to verify that this information is correct.
+     * It's automatically correct for mechanisms that use the bit-size as
+     * an input (generate, device) but not for those where the bit-size
+     * is optional (import, copy). */
 
-    if( attributes->lifetime != PSA_KEY_LIFETIME_VOLATILE )
-    {
-        status = psa_validate_persistent_key_parameters( attributes->lifetime,
-                                                         attributes->id,
-                                                         p_drv, 1 );
-        if( status != PSA_SUCCESS )
-            return( status );
-        slot->persistent_storage_id = attributes->id;
-    }
-    slot->type = attributes->type;
+    slot->attr = attributes->core;
+
+    /* Erase external-only flags from the internal copy. To access
+     * external-only flags, query `attributes`. Thanks to the check
+     * in psa_validate_key_attributes(), this leaves the dual-use
+     * flags and any internal flag that psa_get_empty_key_slot()
+     * may have set. */
+    slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     /* For a key in a secure element, we need to do three things:
@@ -1475,14 +1582,18 @@
      * we can roll back to a state where the key doesn't exist. */
     if( *p_drv != NULL )
     {
+        /* Choosing a slot number is not supported yet. */
+        if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
+            return( PSA_ERROR_NOT_SUPPORTED );
+
         status = psa_find_se_slot_for_key( attributes, *p_drv,
                                            &slot->data.se.slot_number );
         if( status != PSA_SUCCESS )
             return( status );
         psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
-        psa_crypto_transaction.key.lifetime = slot->lifetime;
+        psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
         psa_crypto_transaction.key.slot = slot->data.se.slot_number;
-        psa_crypto_transaction.key.id = slot->persistent_storage_id;
+        psa_crypto_transaction.key.id = slot->attr.id;
         status = psa_crypto_save_transaction( );
         if( status != PSA_SUCCESS )
         {
@@ -1521,42 +1632,44 @@
     (void) driver;
 
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
-    if( slot->lifetime != PSA_KEY_LIFETIME_VOLATILE )
+    if( slot->attr.lifetime != PSA_KEY_LIFETIME_VOLATILE )
     {
-        uint8_t *buffer = NULL;
-        size_t buffer_size = 0;
-        size_t length = 0;
-
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
         if( driver != NULL )
         {
-            buffer = (uint8_t*) &slot->data.se.slot_number;
-            length = sizeof( slot->data.se.slot_number );
+            psa_se_key_data_storage_t data;
+#if defined(static_assert)
+            static_assert( sizeof( slot->data.se.slot_number ) ==
+                           sizeof( data.slot_number ),
+                           "Slot number size does not match psa_se_key_data_storage_t" );
+            static_assert( sizeof( slot->attr.bits ) == sizeof( data.bits ),
+                           "Bit-size size does not match psa_se_key_data_storage_t" );
+#endif
+            memcpy( &data.slot_number, &slot->data.se.slot_number,
+                    sizeof( slot->data.se.slot_number ) );
+            memcpy( &data.bits, &slot->attr.bits,
+                    sizeof( slot->attr.bits ) );
+            status = psa_save_persistent_key( &slot->attr,
+                                              (uint8_t*) &data,
+                                              sizeof( data ) );
         }
         else
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
         {
-            buffer_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type,
-                                                   psa_get_key_slot_bits( slot ) );
-            buffer = mbedtls_calloc( 1, buffer_size );
+            size_t buffer_size =
+                PSA_KEY_EXPORT_MAX_SIZE( slot->attr.type,
+                                         slot->attr.bits );
+            uint8_t *buffer = mbedtls_calloc( 1, buffer_size );
+            size_t length = 0;
             if( buffer == NULL && buffer_size != 0 )
                 return( PSA_ERROR_INSUFFICIENT_MEMORY );
             status = psa_internal_export_key( slot,
                                               buffer, buffer_size, &length,
                                               0 );
-        }
+            if( status == PSA_SUCCESS )
+                status = psa_save_persistent_key( &slot->attr,
+                                                  buffer, length );
 
-        if( status == PSA_SUCCESS )
-        {
-            psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-            psa_get_key_slot_attributes( slot, &attributes );
-            status = psa_save_persistent_key( &attributes, buffer, length );
-        }
-
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-        if( driver == NULL )
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
-        {
             if( buffer_size != 0 )
                 mbedtls_platform_zeroize( buffer, buffer_size );
             mbedtls_free( buffer );
@@ -1570,7 +1683,7 @@
         status = psa_save_se_persistent_data( driver );
         if( status != PSA_SUCCESS )
         {
-            psa_destroy_persistent_key( slot->persistent_storage_id );
+            psa_destroy_persistent_key( slot->attr.id );
             return( status );
         }
         status = psa_crypto_stop_transaction( );
@@ -1617,20 +1730,29 @@
     psa_wipe_key_slot( slot );
 }
 
-static psa_status_t psa_check_key_slot_attributes(
+/** Validate optional attributes during key creation.
+ *
+ * Some key attributes are optional during key creation. If they are
+ * specified in the attributes structure, check that they are consistent
+ * with the data in the slot.
+ *
+ * This function should be called near the end of key creation, after
+ * the slot in memory is fully populated but before saving persistent data.
+ */
+static psa_status_t psa_validate_optional_attributes(
     const psa_key_slot_t *slot,
     const psa_key_attributes_t *attributes )
 {
-    if( attributes->type != 0 )
+    if( attributes->core.type != 0 )
     {
-        if( attributes->type != slot->type )
+        if( attributes->core.type != slot->attr.type )
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
 
     if( attributes->domain_parameters_size != 0 )
     {
 #if defined(MBEDTLS_RSA_C)
-        if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
+        if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
         {
             mbedtls_mpi actual, required;
             int ret;
@@ -1660,9 +1782,9 @@
         }
     }
 
-    if( attributes->bits != 0 )
+    if( attributes->core.bits != 0 )
     {
-        if( attributes->bits != psa_get_key_slot_bits( slot ) )
+        if( attributes->core.bits != slot->attr.bits )
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
 
@@ -1686,6 +1808,7 @@
     if( driver != NULL )
     {
         const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
+        size_t bits;
         if( drv->key_management == NULL ||
             drv->key_management->p_import == NULL )
         {
@@ -1695,9 +1818,18 @@
         status = drv->key_management->p_import(
             psa_get_se_driver_context( driver ),
             slot->data.se.slot_number,
-            slot->lifetime, slot->type, slot->policy.alg, slot->policy.usage,
-            data, data_length );
-        /* TOnogrepDO: psa_check_key_slot_attributes? */
+            slot->attr.lifetime, slot->attr.type,
+            slot->attr.policy.alg, slot->attr.policy.usage,
+            data, data_length,
+            &bits );
+        if( status != PSA_SUCCESS )
+            goto exit;
+        if( bits > PSA_MAX_KEY_BITS )
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        slot->attr.bits = (psa_key_bits_t) bits;
     }
     else
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
@@ -1705,10 +1837,10 @@
         status = psa_import_key_into_slot( slot, data, data_length );
         if( status != PSA_SUCCESS )
             goto exit;
-        status = psa_check_key_slot_attributes( slot, attributes );
-        if( status != PSA_SUCCESS )
-            goto exit;
     }
+    status = psa_validate_optional_attributes( slot, attributes );
+    if( status != PSA_SUCCESS )
+        goto exit;
 
     status = psa_finish_key_creation( slot, driver );
 exit:
@@ -1728,7 +1860,7 @@
     size_t buffer_size = 0;
     size_t length;
 
-    buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->type,
+    buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->attr.type,
                                            psa_get_key_slot_bits( source ) );
     buffer = mbedtls_calloc( 1, buffer_size );
     if( buffer == NULL && buffer_size != 0 )
@@ -1736,7 +1868,7 @@
     status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
     if( status != PSA_SUCCESS )
         goto exit;
-    target->type = source->type;
+    target->attr.type = source->attr.type;
     status = psa_import_key_into_slot( target, buffer, length );
 
 exit:
@@ -1761,12 +1893,13 @@
     if( status != PSA_SUCCESS )
         goto exit;
 
-    status = psa_check_key_slot_attributes( source_slot, specified_attributes );
+    status = psa_validate_optional_attributes( source_slot,
+                                               specified_attributes );
     if( status != PSA_SUCCESS )
         goto exit;
 
-    status = psa_restrict_key_policy( &actual_attributes.policy,
-                                      &source_slot->policy );
+    status = psa_restrict_key_policy( &actual_attributes.core.policy,
+                                      &source_slot->attr.policy );
     if( status != PSA_SUCCESS )
         goto exit;
 
@@ -2556,7 +2689,7 @@
     {
         const mbedtls_cipher_info_t *cipher_info =
             mbedtls_cipher_info_from_psa( full_length_alg,
-                                          slot->type, key_bits, NULL );
+                                          slot->attr.type, key_bits, NULL );
         int ret;
         if( cipher_info == NULL )
         {
@@ -2588,7 +2721,7 @@
             goto exit;
         }
 
-        if( slot->type != PSA_KEY_TYPE_HMAC )
+        if( slot->attr.type != PSA_KEY_TYPE_HMAC )
         {
             status = PSA_ERROR_INVALID_ARGUMENT;
             goto exit;
@@ -3128,14 +3261,14 @@
     status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
     if( status != PSA_SUCCESS )
         goto exit;
-    if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->type ) )
+    if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
     {
         status = PSA_ERROR_INVALID_ARGUMENT;
         goto exit;
     }
 
 #if defined(MBEDTLS_RSA_C)
-    if( slot->type == PSA_KEY_TYPE_RSA_KEY_PAIR )
+    if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
     {
         status = psa_rsa_sign( slot->data.rsa,
                                alg,
@@ -3146,7 +3279,7 @@
     else
 #endif /* defined(MBEDTLS_RSA_C) */
 #if defined(MBEDTLS_ECP_C)
-    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
+    if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
     {
 #if defined(MBEDTLS_ECDSA_C)
         if(
@@ -3203,7 +3336,7 @@
         return( status );
 
 #if defined(MBEDTLS_RSA_C)
-    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
+    if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
     {
         return( psa_rsa_verify( slot->data.rsa,
                                 alg,
@@ -3213,7 +3346,7 @@
     else
 #endif /* defined(MBEDTLS_RSA_C) */
 #if defined(MBEDTLS_ECP_C)
-    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
+    if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
     {
 #if defined(MBEDTLS_ECDSA_C)
         if( PSA_ALG_IS_ECDSA( alg ) )
@@ -3271,12 +3404,12 @@
     status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
     if( status != PSA_SUCCESS )
         return( status );
-    if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
-            PSA_KEY_TYPE_IS_KEY_PAIR( slot->type ) ) )
+    if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ||
+            PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
 #if defined(MBEDTLS_RSA_C)
-    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
+    if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
     {
         mbedtls_rsa_context *rsa = slot->data.rsa;
         int ret;
@@ -3351,11 +3484,11 @@
     status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
     if( status != PSA_SUCCESS )
         return( status );
-    if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->type ) )
+    if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
 #if defined(MBEDTLS_RSA_C)
-    if( slot->type == PSA_KEY_TYPE_RSA_KEY_PAIR )
+    if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
     {
         mbedtls_rsa_context *rsa = slot->data.rsa;
         int ret;
@@ -3462,7 +3595,7 @@
         goto exit;
     key_bits = psa_get_key_slot_bits( slot );
 
-    cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
+    cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL );
     if( cipher_info == NULL )
     {
         status = PSA_ERROR_NOT_SUPPORTED;
@@ -3474,7 +3607,7 @@
         goto exit;
 
 #if defined(MBEDTLS_DES_C)
-    if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
+    if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 )
     {
         /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
         uint8_t keys[24];
@@ -3516,10 +3649,10 @@
 
     operation->key_set = 1;
     operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
-                              PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
+                              PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) );
     if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
     {
-        operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
+        operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type );
     }
 #if defined(MBEDTLS_CHACHA20_C)
     else
@@ -3801,7 +3934,7 @@
     key_bits = psa_get_key_slot_bits( operation->slot );
 
     operation->cipher_info =
-        mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
+        mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits,
                                       &cipher_id );
     if( operation->cipher_info == NULL )
         return( PSA_ERROR_NOT_SUPPORTED );
@@ -3815,7 +3948,7 @@
             /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
              * The call to mbedtls_ccm_encrypt_and_tag or
              * mbedtls_ccm_auth_decrypt will validate the tag length. */
-            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
+            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
                 return( PSA_ERROR_INVALID_ARGUMENT );
             mbedtls_ccm_init( &operation->ctx.ccm );
             status = mbedtls_to_psa_error(
@@ -3834,7 +3967,7 @@
             /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
              * The call to mbedtls_gcm_crypt_and_tag or
              * mbedtls_gcm_auth_decrypt will validate the tag length. */
-            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
+            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
                 return( PSA_ERROR_INVALID_ARGUMENT );
             mbedtls_gcm_init( &operation->ctx.gcm );
             status = mbedtls_to_psa_error(
@@ -4659,7 +4792,7 @@
     size_t bytes = PSA_BITS_TO_BYTES( bits );
     psa_status_t status;
 
-    if( ! key_type_is_raw_bytes( slot->type ) )
+    if( ! key_type_is_raw_bytes( slot->attr.type ) )
         return( PSA_ERROR_INVALID_ARGUMENT );
     if( bits % 8 != 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
@@ -4671,7 +4804,7 @@
     if( status != PSA_SUCCESS )
         goto exit;
 #if defined(MBEDTLS_DES_C)
-    if( slot->type == PSA_KEY_TYPE_DES )
+    if( slot->attr.type == PSA_KEY_TYPE_DES )
         psa_des_set_key_parity( data, bytes );
 #endif /* MBEDTLS_DES_C */
     status = psa_import_key_into_slot( slot, data, bytes );
@@ -4699,7 +4832,7 @@
     if( status == PSA_SUCCESS )
     {
         status = psa_generate_derived_key_internal( slot,
-                                                    attributes->bits,
+                                                    attributes->core.bits,
                                                     operation );
     }
     if( status == PSA_SUCCESS )
@@ -4980,7 +5113,7 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    if( slot->type != PSA_KEY_TYPE_DERIVE )
+    if( slot->attr.type != PSA_KEY_TYPE_DERIVE )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
     status = psa_key_derivation_internal( operation,
@@ -5355,7 +5488,7 @@
                                       operation->alg );
     if( status != PSA_SUCCESS )
         return( status );
-    if( slot->type != PSA_KEY_TYPE_DERIVE )
+    if( slot->attr.type != PSA_KEY_TYPE_DERIVE )
         return( PSA_ERROR_INVALID_ARGUMENT );
     /* Don't allow a key to be used as an input that is usually public.
      * This is debatable. It's ok from a cryptographic perspective to
@@ -5435,7 +5568,7 @@
     {
 #if defined(MBEDTLS_ECDH_C)
         case PSA_ALG_ECDH:
-            if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->type ) )
+            if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
                 return( PSA_ERROR_INVALID_ARGUMENT );
             return( psa_key_agreement_ecdh( peer_key, peer_key_length,
                                             private_key->data.ecp,
@@ -5564,6 +5697,17 @@
     int ret;
     GUARD_MODULE_INITIALIZED;
 
+    while( output_size > MBEDTLS_CTR_DRBG_MAX_REQUEST )
+    {
+        ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
+                                       output,
+                                       MBEDTLS_CTR_DRBG_MAX_REQUEST );
+        if( ret != 0 )
+            return( mbedtls_to_psa_error( ret ) );
+        output += MBEDTLS_CTR_DRBG_MAX_REQUEST;
+        output_size -= MBEDTLS_CTR_DRBG_MAX_REQUEST;
+    }
+
     ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
     return( mbedtls_to_psa_error( ret ) );
 }
@@ -5618,7 +5762,7 @@
     psa_key_slot_t *slot, size_t bits,
     const uint8_t *domain_parameters, size_t domain_parameters_size )
 {
-    psa_key_type_t type = slot->type;
+    psa_key_type_t type = slot->attr.type;
 
     if( domain_parameters == NULL && domain_parameters_size != 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
@@ -5632,10 +5776,7 @@
         status = psa_generate_random( slot->data.raw.data,
                                       slot->data.raw.bytes );
         if( status != PSA_SUCCESS )
-        {
-            mbedtls_free( slot->data.raw.data );
             return( status );
-        }
 #if defined(MBEDTLS_DES_C)
         if( type == PSA_KEY_TYPE_DES )
             psa_des_set_key_parity( slot->data.raw.data,
@@ -5737,7 +5878,7 @@
     if( status == PSA_SUCCESS )
     {
         status = psa_generate_key_internal(
-            slot, attributes->bits,
+            slot, attributes->core.bits,
             attributes->domain_parameters, attributes->domain_parameters_size );
     }
     if( status == PSA_SUCCESS )
@@ -5828,6 +5969,15 @@
 
     /* Initialize the random generator. */
     global_data.entropy_init( &global_data.entropy );
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+    defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
+    /* The PSA entropy injection feature depends on using NV seed as an entropy
+     * source. Add NV seed as an entropy source for PSA entropy injection. */
+    mbedtls_entropy_add_source( &global_data.entropy,
+                                mbedtls_nv_seed_poll, NULL,
+                                MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
     mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
     global_data.rng_state = RNG_INITIALIZED;
     status = mbedtls_to_psa_error(
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index 6096810..edf3ab6 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -39,11 +39,7 @@
  */
 typedef struct
 {
-    psa_key_type_t type;
-    psa_key_policy_t policy;
-    psa_key_lifetime_t lifetime;
-    psa_key_file_id_t persistent_storage_id;
-    unsigned allocated : 1;
+    psa_core_key_attributes_t attr;
     union
     {
         /* Raw-data key (key_type_is_raw_bytes() in psa_crypto.c) */
@@ -60,14 +56,85 @@
         /* EC public key or key pair */
         mbedtls_ecp_keypair *ecp;
 #endif /* MBEDTLS_ECP_C */
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
         /* Any key type in a secure element */
         struct se
         {
             psa_key_slot_number_t slot_number;
         } se;
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
     } data;
 } psa_key_slot_t;
 
+/* A mask of key attribute flags used only internally.
+ * Currently there aren't any. */
+#define PSA_KA_MASK_INTERNAL_ONLY (     \
+        0 )
+
+/** Test whether a key slot is occupied.
+ *
+ * A key slot is occupied iff the key type is nonzero. This works because
+ * no valid key can have 0 as its key type.
+ *
+ * \param[in] slot      The key slot to test.
+ *
+ * \return 1 if the slot is occupied, 0 otherwise.
+ */
+static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot )
+{
+    return( slot->attr.type != 0 );
+}
+
+/** Retrieve flags from psa_key_slot_t::attr::core::flags.
+ *
+ * \param[in] slot      The key slot to query.
+ * \param mask          The mask of bits to extract.
+ *
+ * \return The key attribute flags in the given slot,
+ *         bitwise-anded with \p mask.
+ */
+static inline uint16_t psa_key_slot_get_flags( const psa_key_slot_t *slot,
+                                               uint16_t mask )
+{
+    return( slot->attr.flags & mask );
+}
+
+/** Set flags in psa_key_slot_t::attr::core::flags.
+ *
+ * \param[in,out] slot  The key slot to modify.
+ * \param mask          The mask of bits to modify.
+ * \param value         The new value of the selected bits.
+ */
+static inline void psa_key_slot_set_flags( psa_key_slot_t *slot,
+                                           uint16_t mask,
+                                           uint16_t value )
+{
+    slot->attr.flags = ( ( ~mask & slot->attr.flags ) |
+                              ( mask & value ) );
+}
+
+/** Turn on flags in psa_key_slot_t::attr::core::flags.
+ *
+ * \param[in,out] slot  The key slot to modify.
+ * \param mask          The mask of bits to set.
+ */
+static inline void psa_key_slot_set_bits_in_flags( psa_key_slot_t *slot,
+                                                   uint16_t mask )
+{
+    slot->attr.flags |= mask;
+}
+
+/** Turn off flags in psa_key_slot_t::attr::core::flags.
+ *
+ * \param[in,out] slot  The key slot to modify.
+ * \param mask          The mask of bits to clear.
+ */
+static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot,
+                                            uint16_t mask )
+{
+    slot->attr.flags &= ~mask;
+}
+
 /** Completely wipe a slot in memory, including its policy.
  *
  * Persistent storage is not affected.
diff --git a/library/psa_crypto_its.h b/library/psa_crypto_its.h
index 44d5198..3809787 100644
--- a/library/psa_crypto_its.h
+++ b/library/psa_crypto_its.h
@@ -91,6 +91,7 @@
  * \param[in] data_offset       The starting offset of the data requested
  * \param[in] data_length       the amount of data requested (and the minimum allocated size of the `p_data` buffer)
  * \param[out] p_data           The buffer where the data will be placed upon successful completion
+ * \param[out] p_data_length    The amount of data returned in the p_data buffer
  *
  *
  * \return      A status indicating the success/failure of the operation
@@ -106,7 +107,8 @@
 psa_status_t psa_its_get(psa_storage_uid_t uid,
                          uint32_t data_offset,
                          uint32_t data_length,
-                         void *p_data);
+                         void *p_data,
+                         size_t *p_data_length );
 
 /**
  * \brief Retrieve the metadata about the provided uid
diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c
index aece47d..bc73251 100644
--- a/library/psa_crypto_se.c
+++ b/library/psa_crypto_se.c
@@ -148,17 +148,23 @@
 {
     psa_status_t status;
     psa_storage_uid_t uid;
+    size_t length;
 
     status = psa_get_se_driver_its_file_uid( driver, &uid );
     if( status != PSA_SUCCESS )
         return( status );
 
+    /* Read the amount of persistent data that the driver requests.
+     * If the data in storage is larger, it is truncated. If the data
+     * in storage is smaller, silently keep what is already at the end
+     * of the output buffer. */
     /* psa_get_se_driver_its_file_uid ensures that the size_t
      * persistent_data_size is in range, but compilers don't know that,
      * so cast to reassure them. */
     return( psa_its_get( uid, 0,
                          (uint32_t) driver->internal.persistent_data_size,
-                         driver->internal.persistent_data ) );
+                         driver->internal.persistent_data,
+                         &length ) );
 }
 
 psa_status_t psa_save_se_persistent_data(
@@ -198,7 +204,7 @@
     psa_drv_se_allocate_key_t p_allocate = NULL;
 
     /* If the lifetime is wrong, it's a bug in the library. */
-    if( driver->lifetime != attributes->lifetime )
+    if( driver->lifetime != psa_get_key_lifetime( attributes ) )
         return( PSA_ERROR_CORRUPTION_DETECTED );
 
     /* If the driver doesn't support key creation in any way, give up now. */
diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h
index 08e658c..378c78f 100644
--- a/library/psa_crypto_se.h
+++ b/library/psa_crypto_se.h
@@ -171,4 +171,13 @@
  */
 psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime );
 
+
+/** The storage representation of a key whose data is in a secure element.
+ */
+typedef struct
+{
+    uint8_t slot_number[sizeof( psa_key_slot_number_t )];
+    uint8_t bits[sizeof( psa_key_bits_t )];
+} psa_se_key_data_storage_t;
+
 #endif /* PSA_CRYPTO_SE_H */
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 6b87ea0..fe92148 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -33,6 +33,9 @@
 #include "psa_crypto_core.h"
 #include "psa_crypto_slot_management.h"
 #include "psa_crypto_storage.h"
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+#include "psa_crypto_se.h"
+#endif
 
 #include <stdlib.h>
 #include <string.h>
@@ -71,8 +74,8 @@
         return( PSA_ERROR_INVALID_HANDLE );
     slot = &global_data.key_slots[handle - 1];
 
-    /* If the slot hasn't been allocated, the handle is invalid. */
-    if( ! slot->allocated )
+    /* If the slot isn't occupied, the handle is invalid. */
+    if( ! psa_is_key_slot_occupied( slot ) )
         return( PSA_ERROR_INVALID_HANDLE );
 
     *p_slot = slot;
@@ -99,7 +102,7 @@
     global_data.key_slots_initialized = 0;
 }
 
-psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle,
+psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
                                              psa_key_slot_t **p_slot )
 {
     if( ! global_data.key_slots_initialized )
@@ -108,49 +111,44 @@
     for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) )
     {
         *p_slot = &global_data.key_slots[*handle - 1];
-        if( ! ( *p_slot )->allocated )
-        {
-            ( *p_slot )->allocated = 1;
+        if( ! psa_is_key_slot_occupied( *p_slot ) )
             return( PSA_SUCCESS );
-        }
     }
     *p_slot = NULL;
     return( PSA_ERROR_INSUFFICIENT_MEMORY );
 }
 
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
-static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
+static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot )
 {
     psa_status_t status = PSA_SUCCESS;
     uint8_t *key_data = NULL;
     size_t key_data_length = 0;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
-    psa_set_key_id( &attributes, p_slot->persistent_storage_id );
-    status = psa_load_persistent_key( &attributes,
+    status = psa_load_persistent_key( &slot->attr,
                                       &key_data, &key_data_length );
     if( status != PSA_SUCCESS )
         goto exit;
-    p_slot->lifetime = psa_get_key_lifetime( &attributes );
-    p_slot->type = psa_get_key_type( &attributes );
-    p_slot->policy = attributes.policy;
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-    if( psa_key_lifetime_is_external( p_slot->lifetime ) )
+    if( psa_key_lifetime_is_external( slot->attr.lifetime ) )
     {
-        if( key_data_length != sizeof( p_slot->data.se.slot_number ) )
+        psa_se_key_data_storage_t *data;
+        if( key_data_length != sizeof( *data ) )
         {
             status = PSA_ERROR_STORAGE_FAILURE;
             goto exit;
         }
-        memcpy( &p_slot->data.se.slot_number, key_data,
-                sizeof( p_slot->data.se.slot_number ) );
+        data = (psa_se_key_data_storage_t *) key_data;
+        memcpy( &slot->data.se.slot_number, &data->slot_number,
+                sizeof( slot->data.se.slot_number ) );
+        memcpy( &slot->attr.bits, &data->bits,
+                sizeof( slot->attr.bits ) );
     }
     else
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
     {
-        status = psa_import_key_into_slot( p_slot,
-                                           key_data, key_data_length );
+        status = psa_import_key_into_slot( slot, key_data, key_data_length );
     }
 
 exit:
@@ -230,12 +228,12 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    status = psa_internal_allocate_key_slot( handle, &slot );
+    status = psa_get_empty_key_slot( handle, &slot );
     if( status != PSA_SUCCESS )
         return( status );
 
-    slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
-    slot->persistent_storage_id = id;
+    slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
+    slot->attr.id = id;
 
     status = psa_load_persistent_key_into_slot( slot );
     if( status != PSA_SUCCESS )
@@ -270,28 +268,25 @@
     memset( stats, 0, sizeof( *stats ) );
     for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
     {
-        psa_key_slot_t *slot = &global_data.key_slots[key - 1];
-        if( slot->type == PSA_KEY_TYPE_NONE )
+        const psa_key_slot_t *slot = &global_data.key_slots[key - 1];
+        if( ! psa_is_key_slot_occupied( slot ) )
         {
-            if( slot->allocated )
-                ++stats->half_filled_slots;
-            else
-                ++stats->empty_slots;
+            ++stats->empty_slots;
             continue;
         }
-        if( slot->lifetime == PSA_KEY_LIFETIME_VOLATILE )
+        if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
             ++stats->volatile_slots;
-        else if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
+        else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
         {
             ++stats->persistent_slots;
-            if( slot->persistent_storage_id > stats->max_open_internal_key_id )
-                stats->max_open_internal_key_id = slot->persistent_storage_id;
+            if( slot->attr.id > stats->max_open_internal_key_id )
+                stats->max_open_internal_key_id = slot->attr.id;
         }
         else
         {
             ++stats->external_slots;
-            if( slot->persistent_storage_id > stats->max_open_external_key_id )
-                stats->max_open_external_key_id = slot->persistent_storage_id;
+            if( slot->attr.id > stats->max_open_external_key_id )
+                stats->max_open_external_key_id = slot->attr.id;
         }
     }
 }
diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h
index 049520d..472253d 100644
--- a/library/psa_crypto_slot_management.h
+++ b/library/psa_crypto_slot_management.h
@@ -58,21 +58,21 @@
  * This does not affect persistent storage. */
 void psa_wipe_all_key_slots( void );
 
-/** Find a free key slot and mark it as in use.
+/** Find a free key slot.
+ *
+ * This function returns a key slot that is available for use and is in its
+ * ground state (all-bits-zero).
  *
  * \param[out] handle   On success, a slot number that can be used as a
- *                      handle to the slot. The selected slot was not
- *                      in use before. This function marks it as in use
- *                      and otherwise leaves it in a freshly-initialized
- *                      state.
+ *                      handle to the slot.
  * \param[out] p_slot   On success, a pointer to the slot.
  *
  * \retval #PSA_SUCCESS
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
  * \retval #PSA_ERROR_BAD_STATE
  */
-psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle,
-                                             psa_key_slot_t **p_slot );
+psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
+                                     psa_key_slot_t **p_slot );
 
 /** Test whether a lifetime designates a key in an external cryptoprocessor.
  *
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index b8569be..a27442c 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -102,12 +102,15 @@
     psa_status_t status;
     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
     struct psa_storage_info_t data_identifier_info;
+    size_t data_length = 0;
 
     status = psa_its_get_info( data_identifier, &data_identifier_info );
     if( status  != PSA_SUCCESS )
         return( status );
 
-    status = psa_its_get( data_identifier, 0, (uint32_t) data_size, data );
+    status = psa_its_get( data_identifier, 0, (uint32_t) data_size, data, &data_length );
+    if( data_size  != data_length )
+        return( PSA_ERROR_STORAGE_FAILURE );
 
     return( status );
 }
@@ -264,7 +267,7 @@
 
 void psa_format_key_data_for_storage( const uint8_t *data,
                                       const size_t data_length,
-                                      const psa_key_attributes_t *attributes,
+                                      const psa_core_key_attributes_t *attr,
                                       uint8_t *storage_data )
 {
     psa_persistent_key_storage_format *storage_format =
@@ -272,11 +275,11 @@
 
     memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
     PUT_UINT32_LE( 0, storage_format->version, 0 );
-    PUT_UINT32_LE( psa_get_key_lifetime( attributes ), storage_format->lifetime, 0 );
-    PUT_UINT32_LE( psa_get_key_type( attributes ), storage_format->type, 0 );
-    PUT_UINT32_LE( psa_get_key_usage_flags( attributes ), storage_format->policy, 0 );
-    PUT_UINT32_LE( psa_get_key_algorithm( attributes ), storage_format->policy, sizeof( uint32_t ) );
-    PUT_UINT32_LE( psa_get_key_enrollment_algorithm( attributes ), storage_format->policy, 2 * sizeof( uint32_t ) );
+    PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
+    PUT_UINT32_LE( attr->type, storage_format->type, 0 );
+    PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
+    PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
+    PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
     PUT_UINT32_LE( data_length, storage_format->data_len, 0 );
     memcpy( storage_format->key_data, data, data_length );
 }
@@ -293,7 +296,7 @@
                                               size_t storage_data_length,
                                               uint8_t **key_data,
                                               size_t *key_data_length,
-                                              psa_key_attributes_t *attributes )
+                                              psa_core_key_attributes_t *attr )
 {
     psa_status_t status;
     const psa_persistent_key_storage_format *storage_format =
@@ -328,16 +331,16 @@
         memcpy( *key_data, storage_format->key_data, *key_data_length );
     }
 
-    GET_UINT32_LE( attributes->lifetime, storage_format->lifetime, 0 );
-    GET_UINT32_LE( attributes->type, storage_format->type, 0 );
-    GET_UINT32_LE( attributes->policy.usage, storage_format->policy, 0 );
-    GET_UINT32_LE( attributes->policy.alg, storage_format->policy, sizeof( uint32_t ) );
-    GET_UINT32_LE( attributes->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
+    GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
+    GET_UINT32_LE( attr->type, storage_format->type, 0 );
+    GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
+    GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
+    GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
 
     return( PSA_SUCCESS );
 }
 
-psa_status_t psa_save_persistent_key( const psa_key_attributes_t *attributes,
+psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
                                       const uint8_t *data,
                                       const size_t data_length )
 {
@@ -353,10 +356,9 @@
     if( storage_data == NULL )
         return( PSA_ERROR_INSUFFICIENT_MEMORY );
 
-    psa_format_key_data_for_storage( data, data_length, attributes,
-                                     storage_data );
+    psa_format_key_data_for_storage( data, data_length, attr, storage_data );
 
-    status = psa_crypto_storage_store( psa_get_key_id( attributes ),
+    status = psa_crypto_storage_store( attr->id,
                                        storage_data, storage_data_length );
 
     mbedtls_free( storage_data );
@@ -373,14 +375,14 @@
     mbedtls_free( key_data );
 }
 
-psa_status_t psa_load_persistent_key( psa_key_attributes_t *attributes,
+psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
                                       uint8_t **data,
                                       size_t *data_length )
 {
     psa_status_t status = PSA_SUCCESS;
     uint8_t *loaded_data;
     size_t storage_data_length = 0;
-    psa_key_id_t key = psa_get_key_id( attributes );
+    psa_key_id_t key = attr->id;
 
     status = psa_crypto_storage_get_data_length( key, &storage_data_length );
     if( status != PSA_SUCCESS )
@@ -396,7 +398,7 @@
         goto exit;
 
     status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
-                                              data, data_length, attributes );
+                                              data, data_length, attr );
 
 exit:
     mbedtls_free( loaded_data );
@@ -434,9 +436,16 @@
 
 psa_status_t psa_crypto_load_transaction( void )
 {
-    return( psa_its_get( PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
-                         sizeof( psa_crypto_transaction ),
-                         &psa_crypto_transaction ) );
+    psa_status_t status;
+    size_t length;
+    status = psa_its_get( PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
+                          sizeof( psa_crypto_transaction ),
+                          &psa_crypto_transaction, &length );
+    if( status != PSA_SUCCESS )
+        return( status );
+    if( length != sizeof( psa_crypto_transaction ) )
+        return( PSA_ERROR_STORAGE_FAILURE );
+    return( PSA_SUCCESS );
 }
 
 psa_status_t psa_crypto_stop_transaction( void )
diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h
index 8fe20ac..1b7dbd6 100644
--- a/library/psa_crypto_storage.h
+++ b/library/psa_crypto_storage.h
@@ -35,9 +35,14 @@
 #include <stdint.h>
 #include <string.h>
 
-/* Limit the maximum key size to 30kB (just in case someone tries to
- * inadvertently store an obscene amount of data) */
-#define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 )
+/* Limit the maximum key size in storage. This should have no effect
+ * since the key size is limited in memory. */
+#define PSA_CRYPTO_MAX_STORAGE_SIZE ( PSA_BITS_TO_BYTES( PSA_MAX_KEY_BITS ) )
+/* Sanity check: a file size must fit in 32 bits. Allow a generous
+ * 64kB of metadata. */
+#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
+#error PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
+#endif
 
 /** The maximum permitted persistent slot number.
  *
@@ -83,7 +88,7 @@
  * already occupied non-persistent key, as well as validating the key data.
  *
  *
- * \param[in] attributes    The attributes of the key to save.
+ * \param[in] attr          The attributes of the key to save.
  *                          The key identifier field in the attributes
  *                          determines the key's location.
  * \param[in] data          Buffer containing the key data.
@@ -95,7 +100,7 @@
  * \retval PSA_ERROR_STORAGE_FAILURE
  * \retval PSA_ERROR_ALREADY_EXISTS
  */
-psa_status_t psa_save_persistent_key( const psa_key_attributes_t *attributes,
+psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
                                       const uint8_t *data,
                                       const size_t data_length );
 
@@ -111,8 +116,7 @@
  * this function to zeroize and free this buffer, regardless of whether this
  * function succeeds or fails.
  *
- * \param[in,out] attributes
- *                          On input, the key identifier field identifies
+ * \param[in,out] attr      On input, the key identifier field identifies
  *                          the key to load. Other fields are ignored.
  *                          On success, the attribute structure contains
  *                          the key metadata that was loaded from storage.
@@ -124,7 +128,7 @@
  * \retval PSA_ERROR_STORAGE_FAILURE
  * \retval PSA_ERROR_DOES_NOT_EXIST
  */
-psa_status_t psa_load_persistent_key( psa_key_attributes_t *attributes,
+psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
                                       uint8_t **data,
                                       size_t *data_length );
 
@@ -158,13 +162,13 @@
  *
  * \param[in] data          Buffer containing the key data.
  * \param data_length       Length of the key data buffer.
- * \param[in] attributes    The attributes of the key.
+ * \param[in] attr          The core attributes of the key.
  * \param[out] storage_data Output buffer for the formatted data.
  *
  */
 void psa_format_key_data_for_storage( const uint8_t *data,
                                       const size_t data_length,
-                                      const psa_key_attributes_t *attributes,
+                                      const psa_core_key_attributes_t *attr,
                                       uint8_t *storage_data );
 
 /**
@@ -176,7 +180,7 @@
  *                             containing the key data. This must be freed
  *                             using psa_free_persistent_key_data()
  * \param[out] key_data_length Length of the key data buffer
- * \param[out] attributes      On success, the attribute structure is filled
+ * \param[out] attr            On success, the attribute structure is filled
  *                             with the loaded key metadata.
  *
  * \retval PSA_SUCCESS
@@ -188,7 +192,7 @@
                                               size_t storage_data_length,
                                               uint8_t **key_data,
                                               size_t *key_data_length,
-                                              psa_key_attributes_t *attributes );
+                                              psa_core_key_attributes_t *attr );
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 /** This symbol is defined if transaction support is required. */
diff --git a/library/psa_its_file.c b/library/psa_its_file.c
index 8cdf783..05ca8af 100644
--- a/library/psa_its_file.c
+++ b/library/psa_its_file.c
@@ -44,7 +44,9 @@
 #include <stdio.h>
 #include <string.h>
 
+#if !defined(PSA_ITS_STORAGE_PREFIX)
 #define PSA_ITS_STORAGE_PREFIX ""
+#endif
 
 #define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx"
 #define PSA_ITS_STORAGE_SUFFIX ".psa_its"
@@ -137,7 +139,8 @@
 psa_status_t psa_its_get( psa_storage_uid_t uid,
                           uint32_t data_offset,
                           uint32_t data_length,
-                          void *p_data )
+                          void *p_data,
+                          size_t *p_data_length )
 {
     psa_status_t status;
     FILE *stream = NULL;
@@ -172,6 +175,8 @@
     if( n != data_length )
         goto exit;
     status = PSA_SUCCESS;
+    if( p_data_length != NULL )
+        *p_data_length = n;
 
 exit:
     if( stream != NULL )
diff --git a/library/timing.c b/library/timing.c
index 413d133..009516a 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -51,7 +51,6 @@
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
 #include <windows.h>
-#include <winbase.h>
 #include <process.h>
 
 struct _hr_time
diff --git a/library/version_features.c b/library/version_features.c
index 5701598..cd75cc0 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -31,7 +31,7 @@
 
 #include <string.h>
 
-static const char *features[] = {
+static const char * const features[] = {
 #if defined(MBEDTLS_VERSION_FEATURES)
 #if defined(MBEDTLS_HAVE_ASM)
     "MBEDTLS_HAVE_ASM",
@@ -90,6 +90,9 @@
 #if defined(MBEDTLS_CHECK_PARAMS)
     "MBEDTLS_CHECK_PARAMS",
 #endif /* MBEDTLS_CHECK_PARAMS */
+#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+    "MBEDTLS_CHECK_PARAMS_ASSERT",
+#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
 #if defined(MBEDTLS_TIMING_ALT)
     "MBEDTLS_TIMING_ALT",
 #endif /* MBEDTLS_TIMING_ALT */
@@ -597,7 +600,7 @@
 
 int mbedtls_version_check_feature( const char *feature )
 {
-    const char **idx = features;
+    const char * const *idx = features;
 
     if( *idx == NULL )
         return( -2 );
diff --git a/programs/Makefile b/programs/Makefile
index c7cc995..1a69b74 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -2,8 +2,8 @@
 # To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS
 
 CFLAGS	?= -O2
-WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement
-WARNING_CXXFLAGS ?= -Wall -W
+WARNING_CFLAGS ?= -Wall -Wextra
+WARNING_CXXFLAGS ?= -Wall -Wextra
 LDFLAGS ?=
 
 LOCAL_CFLAGS = $(WARNING_CFLAGS) -I../include -D_FILE_OFFSET_BITS=64
@@ -244,6 +244,7 @@
 clean:
 ifndef WINDOWS
 	rm -f $(APPS) $(EXTRA_GENERATED)
+	-rm -f test/cpp_dummy_build$(EXEXT)
 else
 	if exist *.o del /S /Q /F *.o
 	if exist *.exe del /S /Q /F *.exe
diff --git a/programs/aes/aescrypt2.c b/programs/aes/aescrypt2.c
index bdeac3a..8242ea7 100644
--- a/programs/aes/aescrypt2.c
+++ b/programs/aes/aescrypt2.c
@@ -80,17 +80,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index f58e616..a5acf5b 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -82,17 +82,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c
index 4b7fe37..709a149 100644
--- a/programs/hash/generic_sum.c
+++ b/programs/hash/generic_sum.c
@@ -52,17 +52,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 static int generic_wrapper( const mbedtls_md_info_t *md_info, char *filename, unsigned char *sum )
 {
diff --git a/programs/hash/hello.c b/programs/hash/hello.c
index 6046f86..55a0c7e 100644
--- a/programs/hash/hello.c
+++ b/programs/hash/hello.c
@@ -48,17 +48,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( void )
 {
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index cca43ca..bf5482e 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -69,17 +69,6 @@
  */
 #define GENERATOR "4"
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char **argv )
 {
diff --git a/programs/pkey/ecdh_curve25519.c b/programs/pkey/ecdh_curve25519.c
index 9267c7e..9f849dd 100644
--- a/programs/pkey/ecdh_curve25519.c
+++ b/programs/pkey/ecdh_curve25519.c
@@ -53,17 +53,6 @@
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/ecdh.h"
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index 4471a20..b851c31 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -100,17 +100,6 @@
 #define dump_pubkey( a, b )
 #endif
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 35fc149..23e4e14 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -137,17 +137,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 /*
  * global options
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index b4860fe..19dcdfe 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -64,7 +64,6 @@
     "    password_file=%%s    default: \"\"\n"          \
     "\n"
 
-
 #if !defined(MBEDTLS_BIGNUM_C) ||                                  \
     !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO)
 int main( void )
@@ -75,17 +74,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 /*
  * global options
diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c
index b81530c..6096429 100644
--- a/programs/pkey/key_app_writer.c
+++ b/programs/pkey/key_app_writer.c
@@ -98,17 +98,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 /*
  * global options
diff --git a/programs/pkey/mpi_demo.c b/programs/pkey/mpi_demo.c
index 80573c0..ecdcd32 100644
--- a/programs/pkey/mpi_demo.c
+++ b/programs/pkey/mpi_demo.c
@@ -50,17 +50,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( void )
 {
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index 978f39e..bf42507 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -48,7 +48,6 @@
 #include <string.h>
 #endif
 
-
 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_PK_PARSE_C) ||  \
     !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_ENTROPY_C) || \
     !defined(MBEDTLS_CTR_DRBG_C)
@@ -61,17 +60,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c
index 806c59a..a32b147 100644
--- a/programs/pkey/pk_encrypt.c
+++ b/programs/pkey/pk_encrypt.c
@@ -61,17 +61,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 7354082..47a098a 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -60,17 +60,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/pk_verify.c b/programs/pkey/pk_verify.c
index 9fcf029..a6bfe3f 100644
--- a/programs/pkey/pk_verify.c
+++ b/programs/pkey/pk_verify.c
@@ -56,17 +56,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
@@ -112,7 +101,6 @@
         goto exit;
     }
 
-
     i = fread( buf, 1, sizeof(buf), f );
 
     fclose( f );
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index dc8a920..ff71bd0 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -59,17 +59,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index e9effe8..4a71c15 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -59,17 +59,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c
index c66f4e7..f2b7b50 100644
--- a/programs/pkey/rsa_genkey.c
+++ b/programs/pkey/rsa_genkey.c
@@ -63,17 +63,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( void )
 {
diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c
index f014872..9bcd7a6 100644
--- a/programs/pkey/rsa_sign.c
+++ b/programs/pkey/rsa_sign.c
@@ -56,17 +56,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index cb69fa6..5019f28 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -60,17 +60,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c
index 5d1c085..94f0ef9 100644
--- a/programs/pkey/rsa_verify.c
+++ b/programs/pkey/rsa_verify.c
@@ -55,17 +55,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_verify_pss.c b/programs/pkey/rsa_verify_pss.c
index d745274..de28337 100644
--- a/programs/pkey/rsa_verify_pss.c
+++ b/programs/pkey/rsa_verify_pss.c
@@ -59,17 +59,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
@@ -124,7 +113,6 @@
         goto exit;
     }
 
-
     i = fread( buf, 1, MBEDTLS_MPI_MAX_SIZE, f );
 
     fclose( f );
diff --git a/programs/random/gen_entropy.c b/programs/random/gen_entropy.c
index 3b350ed..6ae63b7 100644
--- a/programs/random/gen_entropy.c
+++ b/programs/random/gen_entropy.c
@@ -51,17 +51,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c
index a50402f..59df34b 100644
--- a/programs/random/gen_random_ctr_drbg.c
+++ b/programs/random/gen_random_ctr_drbg.c
@@ -54,17 +54,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/random/gen_random_havege.c b/programs/random/gen_random_havege.c
index ef888ff..5ea52ae 100644
--- a/programs/random/gen_random_havege.c
+++ b/programs/random/gen_random_havege.c
@@ -52,17 +52,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index e31faaf..2b86566 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -258,17 +258,6 @@
          rsa, dhm, ecdsa, ecdh;
 } todo_list;
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/test/cmake_subproject/.gitignore b/programs/test/cmake_subproject/.gitignore
new file mode 100644
index 0000000..464833b
--- /dev/null
+++ b/programs/test/cmake_subproject/.gitignore
@@ -0,0 +1,3 @@
+build
+Makefile
+cmake_subproject
diff --git a/programs/test/cmake_subproject/CMakeLists.txt b/programs/test/cmake_subproject/CMakeLists.txt
new file mode 100644
index 0000000..3afbdb2
--- /dev/null
+++ b/programs/test/cmake_subproject/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.6)
+
+# We use the parent Mbed TLS directory as the MBEDTLS_DIR for this test. Other
+# projects that use Mbed TLS as a subproject are likely to add by their own
+# relative paths.
+set(MBEDTLS_DIR ../../../)
+
+# Add Mbed TLS as a subdirectory.
+add_subdirectory(${MBEDTLS_DIR} build)
+
+# Link against the Mbed Crypto library.
+set(libs
+    mbedcrypto
+)
+
+add_executable(cmake_subproject cmake_subproject.c)
+target_link_libraries(cmake_subproject ${libs})
diff --git a/programs/test/cmake_subproject/cmake_subproject.c b/programs/test/cmake_subproject/cmake_subproject.c
new file mode 100644
index 0000000..ca899bc
--- /dev/null
+++ b/programs/test/cmake_subproject/cmake_subproject.c
@@ -0,0 +1,56 @@
+/*
+ *  Simple program to test that CMake builds with Mbed TLS as a subdirectory
+ *  work correctly.
+ *
+ *  Copyright (C) 2006-2019, 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)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_fprintf         fprintf
+#define mbedtls_printf          printf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
+#endif /* MBEDTLS_PLATFORM_C */
+
+#include "mbedtls/version.h"
+
+/* The main reason to build this is for testing the CMake build, so the program
+ * doesn't need to do very much. It calls a single library function to ensure
+ * linkage works, but that is all. */
+int main()
+{
+    /* This version string is 18 bytes long, as advised by version.h. */
+    char version[18];
+
+    mbedtls_version_get_string_full( version );
+
+    mbedtls_printf( "Built against %s\n", version );
+
+    return( 0 );
+}
diff --git a/programs/test/cpp_dummy_build.cpp b/programs/test/cpp_dummy_build.cpp
index c1dc743..81ca32c 100644
--- a/programs/test/cpp_dummy_build.cpp
+++ b/programs/test/cpp_dummy_build.cpp
@@ -38,13 +38,13 @@
 #include "mbedtls/bn_mul.h"
 #include "mbedtls/camellia.h"
 #include "mbedtls/ccm.h"
-#include "mbedtls/certs.h"
 #include "mbedtls/chacha20.h"
 #include "mbedtls/chachapoly.h"
 #include "mbedtls/check_config.h"
 #include "mbedtls/cipher.h"
 #include "mbedtls/cipher_internal.h"
 #include "mbedtls/cmac.h"
+#include "mbedtls/compat-1.3.h"
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/des.h"
 #include "mbedtls/dhm.h"
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index ee754d9..f57ca31 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -47,7 +47,6 @@
 #include "mbedtls/blowfish.h"
 #include "mbedtls/camellia.h"
 #include "mbedtls/ccm.h"
-#include "mbedtls/certs.h"
 #include "mbedtls/chacha20.h"
 #include "mbedtls/chachapoly.h"
 #include "mbedtls/cipher.h"
@@ -269,6 +268,14 @@
     }
 #endif /* MBEDTLS_CHECK_PARAMS */
 
+#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+    if( strcmp( "MBEDTLS_CHECK_PARAMS_ASSERT", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_CHECK_PARAMS_ASSERT );
+        return( 0 );
+    }
+#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
+
 #if defined(MBEDTLS_TIMING_ALT)
     if( strcmp( "MBEDTLS_TIMING_ALT", config ) == 0 )
     {
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index fac7e92..638ef70 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -76,17 +76,6 @@
 #include "mbedtls/memory_buffer_alloc.h"
 #endif
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
 {
diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c
index 0cc9d06..f184939 100644
--- a/programs/util/pem2der.c
+++ b/programs/util/pem2der.c
@@ -65,17 +65,6 @@
 }
 #else
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#define mbedtls_exit            exit
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    mbedtls_printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-}
-#endif
 
 /*
  * global options
diff --git a/scripts/abi_check.py b/scripts/abi_check.py
index 30c3fe5..533aaea 100755
--- a/scripts/abi_check.py
+++ b/scripts/abi_check.py
@@ -59,9 +59,7 @@
 
     @staticmethod
     def check_repo_path():
-        current_dir = os.path.realpath('.')
-        root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-        if current_dir != root_dir:
+        if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
             raise Exception("Must be run from Mbed TLS root")
 
     def _setup_logger(self):
@@ -108,6 +106,12 @@
             stderr=subprocess.STDOUT
         )
         self.log.debug(worktree_output.decode("utf-8"))
+        version.commit = subprocess.check_output(
+            [self.git_command, "rev-parse", worktree_rev],
+            cwd=git_worktree_path,
+            stderr=subprocess.STDOUT
+        ).decode("ascii").rstrip()
+        self.log.debug("Commit is {}".format(version.commit))
         return git_worktree_path
 
     def _update_git_submodules(self, git_worktree_path, version):
@@ -163,6 +167,13 @@
                     os.path.join(root, file)
                 )
 
+    @staticmethod
+    def _pretty_revision(version):
+        if version.revision == version.commit:
+            return version.revision
+        else:
+            return "{} ({})".format(version.revision, version.commit)
+
     def _get_abi_dumps_from_shared_libraries(self, version):
         """Generate the ABI dumps for the specified git revision.
         The shared libraries must have been built and the module paths
@@ -177,7 +188,7 @@
                 "abi-dumper",
                 module_path,
                 "-o", output_path,
-                "-lver", version.revision
+                "-lver", self._pretty_revision(version),
             ]
             abi_dump_output = subprocess.check_output(
                 abi_dump_command,
@@ -214,7 +225,7 @@
 
     def _remove_extra_detail_from_report(self, report_root):
         for tag in ['test_info', 'test_results', 'problem_summary',
-                    'added_symbols', 'removed_symbols', 'affected']:
+                    'added_symbols', 'affected']:
             self._remove_children_with_tag(report_root, tag)
 
         for report in report_root:
@@ -222,69 +233,84 @@
                 if not problems.getchildren():
                     report.remove(problems)
 
+    def _abi_compliance_command(self, mbed_module, output_path):
+        """Build the command to run to analyze the library mbed_module.
+        The report will be placed in output_path."""
+        abi_compliance_command = [
+            "abi-compliance-checker",
+            "-l", mbed_module,
+            "-old", self.old_version.abi_dumps[mbed_module],
+            "-new", self.new_version.abi_dumps[mbed_module],
+            "-strict",
+            "-report-path", output_path,
+        ]
+        if self.skip_file:
+            abi_compliance_command += ["-skip-symbols", self.skip_file,
+                                       "-skip-types", self.skip_file]
+        if self.brief:
+            abi_compliance_command += ["-report-format", "xml",
+                                       "-stdout"]
+        return abi_compliance_command
+
+    def _is_library_compatible(self, mbed_module, compatibility_report):
+        """Test if the library mbed_module has remained compatible.
+        Append a message regarding compatibility to compatibility_report."""
+        output_path = os.path.join(
+            self.report_dir, "{}-{}-{}.html".format(
+                mbed_module, self.old_version.revision,
+                self.new_version.revision
+            )
+        )
+        try:
+            subprocess.check_output(
+                self._abi_compliance_command(mbed_module, output_path),
+                stderr=subprocess.STDOUT
+            )
+        except subprocess.CalledProcessError as err:
+            if err.returncode != 1:
+                raise err
+            if self.brief:
+                self.log.info(
+                    "Compatibility issues found for {}".format(mbed_module)
+                )
+                report_root = ET.fromstring(err.output.decode("utf-8"))
+                self._remove_extra_detail_from_report(report_root)
+                self.log.info(ET.tostring(report_root).decode("utf-8"))
+            else:
+                self.can_remove_report_dir = False
+                compatibility_report.append(
+                    "Compatibility issues found for {}, "
+                    "for details see {}".format(mbed_module, output_path)
+                )
+            return False
+        compatibility_report.append(
+            "No compatibility issues for {}".format(mbed_module)
+        )
+        if not (self.keep_all_reports or self.brief):
+            os.remove(output_path)
+        return True
+
     def get_abi_compatibility_report(self):
         """Generate a report of the differences between the reference ABI
         and the new ABI. ABI dumps from self.old_version and self.new_version
         must be available."""
-        compatibility_report = ""
+        compatibility_report = ["Checking evolution from {} to {}".format(
+            self._pretty_revision(self.old_version),
+            self._pretty_revision(self.new_version)
+        )]
         compliance_return_code = 0
         shared_modules = list(set(self.old_version.modules.keys()) &
                               set(self.new_version.modules.keys()))
         for mbed_module in shared_modules:
-            output_path = os.path.join(
-                self.report_dir, "{}-{}-{}.html".format(
-                    mbed_module, self.old_version.revision,
-                    self.new_version.revision
-                )
-            )
-            abi_compliance_command = [
-                "abi-compliance-checker",
-                "-l", mbed_module,
-                "-old", self.old_version.abi_dumps[mbed_module],
-                "-new", self.new_version.abi_dumps[mbed_module],
-                "-strict",
-                "-report-path", output_path,
-            ]
-            if self.skip_file:
-                abi_compliance_command += ["-skip-symbols", self.skip_file,
-                                           "-skip-types", self.skip_file]
-            if self.brief:
-                abi_compliance_command += ["-report-format", "xml",
-                                           "-stdout"]
-            try:
-                subprocess.check_output(
-                    abi_compliance_command,
-                    stderr=subprocess.STDOUT
-                )
-            except subprocess.CalledProcessError as err:
-                if err.returncode == 1:
-                    compliance_return_code = 1
-                    if self.brief:
-                        self.log.info(
-                            "Compatibility issues found for {}".format(mbed_module)
-                        )
-                        report_root = ET.fromstring(err.output.decode("utf-8"))
-                        self._remove_extra_detail_from_report(report_root)
-                        self.log.info(ET.tostring(report_root).decode("utf-8"))
-                    else:
-                        self.can_remove_report_dir = False
-                        compatibility_report += (
-                            "Compatibility issues found for {}, "
-                            "for details see {}\n".format(mbed_module, output_path)
-                        )
-                else:
-                    raise err
-            else:
-                compatibility_report += (
-                    "No compatibility issues for {}\n".format(mbed_module)
-                )
-                if not (self.keep_all_reports or self.brief):
-                    os.remove(output_path)
-            os.remove(self.old_version.abi_dumps[mbed_module])
-            os.remove(self.new_version.abi_dumps[mbed_module])
+            if not self._is_library_compatible(mbed_module,
+                                               compatibility_report):
+                compliance_return_code = 1
+        for version in [self.old_version, self.new_version]:
+            for mbed_module, mbed_module_dump in version.abi_dumps.items():
+                os.remove(mbed_module_dump)
         if self.can_remove_report_dir:
             os.rmdir(self.report_dir)
-        self.log.info(compatibility_report)
+        self.log.info("\n".join(compatibility_report))
         return compliance_return_code
 
     def check_for_abi_changes(self):
@@ -356,7 +382,9 @@
         )
         parser.add_argument(
             "-s", "--skip-file", type=str,
-            help="path to file containing symbols and types to skip"
+            help=("path to file containing symbols and types to skip "
+                  "(typically \"-s identifiers\" after running "
+                  "\"tests/scripts/list-identifiers.sh --internal\")")
         )
         parser.add_argument(
             "-b", "--brief", action="store_true",
@@ -370,6 +398,7 @@
             version="old",
             repository=abi_args.old_repo,
             revision=abi_args.old_rev,
+            commit=None,
             crypto_repository=abi_args.old_crypto_repo,
             crypto_revision=abi_args.old_crypto_rev,
             abi_dumps={},
@@ -379,6 +408,7 @@
             version="new",
             repository=abi_args.new_repo,
             revision=abi_args.new_rev,
+            commit=None,
             crypto_repository=abi_args.new_crypto_repo,
             crypto_revision=abi_args.new_crypto_rev,
             abi_dumps={},
diff --git a/scripts/config.pl b/scripts/config.pl
index 6479c6d..4588757 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -29,8 +29,9 @@
 #   MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
 #   MBEDTLS_NO_PLATFORM_ENTROPY
 #   MBEDTLS_RSA_NO_CRT
-#   MBEDTLS_USE_PSA_CRYPTO
-#       - experimental, and more an alternative implementation than a feature
+#   MBEDTLS_PSA_CRYPTO_SPM
+#   MBEDTLS_PSA_INJECT_ENTROPY
+#   MBEDTLS_ECP_RESTARTABLE
 #   and any symbol beginning _ALT
 #
 
@@ -89,7 +90,7 @@
 MBEDTLS_PSA_CRYPTO_SPM
 MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
 MBEDTLS_PSA_INJECT_ENTROPY
-MBEDTLS_USE_PSA_CRYPTO
+MBEDTLS_ECP_RESTARTABLE
 _ALT\s*$
 );
 
@@ -108,10 +109,9 @@
 MBEDTLS_MEMORY_BUFFER_ALLOC_C
 MBEDTLS_PLATFORM_TIME_ALT
 MBEDTLS_PLATFORM_FPRINTF_ALT
+MBEDTLS_PSA_ITS_FILE_C
 MBEDTLS_PSA_CRYPTO_SE_C
 MBEDTLS_PSA_CRYPTO_STORAGE_C
-MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
-MBEDTLS_PSA_ITS_FILE_C
 );
 
 # Things that should be enabled in "full" even if they match @excluded
diff --git a/scripts/data_files/query_config.fmt b/scripts/data_files/query_config.fmt
index 600f130..911900f 100644
--- a/scripts/data_files/query_config.fmt
+++ b/scripts/data_files/query_config.fmt
@@ -47,7 +47,6 @@
 #include "mbedtls/blowfish.h"
 #include "mbedtls/camellia.h"
 #include "mbedtls/ccm.h"
-#include "mbedtls/certs.h"
 #include "mbedtls/chacha20.h"
 #include "mbedtls/chachapoly.h"
 #include "mbedtls/cipher.h"
diff --git a/scripts/data_files/version_features.fmt b/scripts/data_files/version_features.fmt
index 767eda1..63ae94c 100644
--- a/scripts/data_files/version_features.fmt
+++ b/scripts/data_files/version_features.fmt
@@ -31,7 +31,7 @@
 
 #include <string.h>
 
-static const char *features[] = {
+static const char * const features[] = {
 #if defined(MBEDTLS_VERSION_FEATURES)
 FEATURE_DEFINES
 #endif /* MBEDTLS_VERSION_FEATURES */
@@ -40,7 +40,7 @@
 
 int mbedtls_version_check_feature( const char *feature )
 {
-    const char **idx = features;
+    const char * const *idx = features;
 
     if( *idx == NULL )
         return( -2 );
diff --git a/scripts/data_files/vs2010-app-template.vcxproj b/scripts/data_files/vs2010-app-template.vcxproj
index fac9812..1db7ee4 100644
--- a/scripts/data_files/vs2010-app-template.vcxproj
+++ b/scripts/data_files/vs2010-app-template.vcxproj
Binary files differ
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 323ad2d..7e54370 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -2,6 +2,13 @@
     mbedcrypto
 )
 
+# Set the project root directory if it's not already defined, as may happen if
+# the tests folder is included directly by a parent project, without including
+# the top level CMakeLists.txt.
+if(NOT DEFINED MBEDTLS_DIR)
+    set(MBEDTLS_DIR ${CMAKE_SOURCE_DIR})
+endif()
+
 find_package(Perl)
 if(NOT PERL_FOUND)
     message(FATAL_ERROR "Cannot build test suites without Perl")
@@ -43,9 +50,9 @@
     add_executable(${exe_name} test_suite_${data_name}.c)
     target_link_libraries(${exe_name} ${libs})
     target_include_directories(${exe_name}
-        PUBLIC ${CMAKE_SOURCE_DIR}/include/
-        PUBLIC ${CMAKE_SOURCE_DIR}/crypto/include/
-        PRIVATE ${CMAKE_SOURCE_DIR}/crypto/library/)
+        PUBLIC ${MBEDTLS_DIR}/include/
+        PUBLIC ${MBEDTLS_DIR}/crypto/include/
+        PUBLIC ${MBEDTLS_DIR}/crypto/library/)
 
     if(${data_name} MATCHES ${SKIP_TEST_SUITES_REGEX})
         message(STATUS "The test suite ${data_name} will not be executed.")
diff --git a/tests/Makefile b/tests/Makefile
index 94f0bc4..6b72523 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -2,7 +2,7 @@
 # To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS
 
 CFLAGS	?= -O2
-WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement -Wno-unused-function -Wno-unused-value
+WARNING_CFLAGS ?= -Wall -Wextra
 LDFLAGS ?=
 
 CRYPTO_INCLUDES ?= -I../include
diff --git a/tests/docker/bionic/Dockerfile b/tests/docker/bionic/Dockerfile
new file mode 100644
index 0000000..1b2d40f
--- /dev/null
+++ b/tests/docker/bionic/Dockerfile
@@ -0,0 +1,168 @@
+# Dockerfile
+#
+# Purpose
+# -------
+# Defines a Docker container suitable to build and run all tests (all.sh),
+# except for those that use a proprietary toolchain.
+
+# Copyright (C) 2006-2019, Arm Limited (or its affiliates), 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)
+ARG MAKEFLAGS_PARALLEL=""
+ARG MY_REGISTRY=
+
+FROM ${MY_REGISTRY}ubuntu:bionic
+
+
+ENV DEBIAN_FRONTEND noninteractive
+
+RUN apt-get update \
+    && apt-get -y install software-properties-common \
+    && rm -rf /var/lib/apt/lists
+
+RUN add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
+
+RUN apt-get update \
+    && apt-get -y install \
+    # mbedtls build/test dependencies
+    build-essential \
+    clang \
+    cmake \
+    doxygen \
+    gcc-arm-none-eabi \
+    gcc-mingw-w64-i686 \
+    gcc-multilib \
+    g++-multilib \
+    gdb \
+    git \
+    graphviz \
+    lsof \
+    python \
+    python3-pip \
+    python3 \
+    pylint3 \
+    valgrind \
+    wget \
+    # libnettle build dependencies
+    libgmp-dev \
+    m4 \
+    pkg-config \
+    && rm -rf /var/lib/apt/lists/*
+
+# Build a static, legacy openssl from sources with sslv3 enabled
+# Based on https://gist.github.com/bmaupin/8caca3a1e8c3c5686141 (build-openssl.sh)
+# Note: openssl-1.0.2 and earlier has known build issues with parallel make.
+RUN cd /tmp \
+    && wget https://www.openssl.org/source/old/1.0.1/openssl-1.0.1j.tar.gz -qO- | tar xz \
+    && cd openssl-1.0.1j \
+    && ./config --openssldir=/usr/local/openssl-1.0.1j no-shared \
+    && (make ${MAKEFLAGS_PARALLEL} || make -j 1) \
+    && make install_sw \
+    && rm -rf /tmp/openssl*
+ENV OPENSSL_LEGACY=/usr/local/openssl-1.0.1j/bin/openssl
+
+# Build OPENSSL as 1.0.2g
+RUN cd /tmp \
+    && wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2g.tar.gz -qO- | tar xz \
+    && cd openssl-1.0.2g \
+    && ./config --openssldir=/usr/local/openssl-1.0.2g no-shared \
+    && (make ${MAKEFLAGS_PARALLEL} || make -j 1) \
+    && make install_sw \
+    && rm -rf /tmp/openssl*
+ENV OPENSSL=/usr/local/openssl-1.0.2g/bin/openssl
+
+# Build a new openssl binary for ARIA/CHACHA20 support
+# Based on https://gist.github.com/bmaupin/8caca3a1e8c3c5686141 (build-openssl.sh)
+RUN cd /tmp \
+    && wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz -qO- | tar xz \
+    && cd openssl-1.1.1a \
+    && ./config --prefix=/usr/local/openssl-1.1.1a -Wl,--enable-new-dtags,-rpath,'${LIBRPATH}' no-shared \
+    && make ${MAKEFLAGS_PARALLEL} \
+    && make install_sw \
+    && rm -rf /tmp/openssl*
+ENV OPENSSL_NEXT=/usr/local/openssl-1.1.1a/bin/openssl
+
+# Build libnettle 2.7.1 (needed by legacy gnutls)
+RUN cd /tmp \
+    && wget https://ftp.gnu.org/gnu/nettle/nettle-2.7.1.tar.gz -qO- | tar xz \
+    && cd nettle-2.7.1 \
+    && ./configure --disable-documentation \
+    && make ${MAKEFLAGS_PARALLEL} \
+    && make install \
+    && /sbin/ldconfig \
+    && rm -rf /tmp/nettle*
+
+# Build legacy gnutls (3.3.8)
+RUN cd /tmp \
+    && wget https://www.gnupg.org/ftp/gcrypt/gnutls/v3.3/gnutls-3.3.8.tar.xz -qO- | tar xJ \
+    && cd gnutls-3.3.8 \
+    && ./configure --prefix=/usr/local/gnutls-3.3.8 --exec_prefix=/usr/local/gnutls-3.3.8 --disable-shared --disable-guile --disable-doc \
+    && make ${MAKEFLAGS_PARALLEL} \
+    && make install \
+    && rm -rf /tmp/gnutls*
+ENV GNUTLS_LEGACY_CLI=/usr/local/gnutls-3.3.8/bin/gnutls-cli
+ENV GNUTLS_LEGACY_SERV=/usr/local/gnutls-3.3.8/bin/gnutls-serv
+
+# Build libnettle 3.1 (needed by gnutls)
+RUN cd /tmp \
+    && wget https://ftp.gnu.org/gnu/nettle/nettle-3.1.tar.gz -qO- | tar xz \
+    && cd nettle-3.1 \
+    && ./configure --disable-documentation \
+    && make ${MAKEFLAGS_PARALLEL} \
+    && make install \
+    && /sbin/ldconfig \
+    && rm -rf /tmp/nettle*
+
+# Build gnutls (3.4.10)
+RUN cd /tmp \
+    && wget https://www.gnupg.org/ftp/gcrypt/gnutls/v3.4/gnutls-3.4.10.tar.xz -qO- | tar xJ \
+    && cd gnutls-3.4.10 \
+    && ./configure --prefix=/usr/local/gnutls-3.4.10 --exec_prefix=/usr/local/gnutls-3.4.10 \
+        --with-included-libtasn1 --without-p11-kit \
+        --disable-shared --disable-guile --disable-doc \
+    && make ${MAKEFLAGS_PARALLEL} \
+    && make install \
+    && rm -rf /tmp/gnutls*
+ENV GNUTLS_CLI=/usr/local/gnutls-3.4.10/bin/gnutls-cli
+ENV GNUTLS_SERV=/usr/local/gnutls-3.4.10/bin/gnutls-serv
+
+# Build libnettle 3.4 (needed by gnutls next)
+RUN cd /tmp \
+    && wget https://ftp.gnu.org/gnu/nettle/nettle-3.4.1.tar.gz -qO- | tar xz \
+    && cd nettle-3.4.1 \
+    && ./configure --disable-documentation \
+    && make ${MAKEFLAGS_PARALLEL} \
+    && make install \
+    && /sbin/ldconfig \
+    && rm -rf /tmp/nettle*
+
+# Build gnutls next (3.6.5)
+RUN cd /tmp \
+    && wget https://www.gnupg.org/ftp/gcrypt/gnutls/v3.6/gnutls-3.6.5.tar.xz -qO- | tar xJ \
+    && cd gnutls-3.6.5 \
+    && ./configure --prefix=/usr/local/gnutls-3.6.5 --exec_prefix=/usr/local/gnutls-3.6.5 \
+        --with-included-libtasn1 --with-included-unistring --without-p11-kit \
+        --disable-shared --disable-guile --disable-doc \
+    && make ${MAKEFLAGS_PARALLEL} \
+    && make install \
+    && rm -rf /tmp/gnutls*
+
+ENV GNUTLS_NEXT_CLI=/usr/local/gnutls-3.6.5/bin/gnutls-cli
+ENV GNUTLS_NEXT_SERV=/usr/local/gnutls-3.6.5/bin/gnutls-serv
+
+RUN pip3 install --no-cache-dir \
+    mbed-host-tests \
+    mock
diff --git a/tests/make-in-docker.sh b/tests/make-in-docker.sh
new file mode 100755
index 0000000..4fbfe1c
--- /dev/null
+++ b/tests/make-in-docker.sh
@@ -0,0 +1,31 @@
+#!/bin/bash -eu
+
+# make-in-docker.sh
+#
+# Purpose
+# -------
+# This runs make in a Docker container.
+#
+# See also:
+# - scripts/docker_env.sh for general Docker prerequisites and other information.
+
+# Copyright (C) 2006-2019, Arm Limited (or its affiliates), 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)
+
+source tests/scripts/docker_env.sh
+
+run_in_docker make $@
diff --git a/tests/scripts/all-in-docker.sh b/tests/scripts/all-in-docker.sh
new file mode 100755
index 0000000..ee9a092
--- /dev/null
+++ b/tests/scripts/all-in-docker.sh
@@ -0,0 +1,37 @@
+#!/bin/bash -eu
+
+# all-in-docker.sh
+#
+# Purpose
+# -------
+# This runs all.sh (except for armcc) in a Docker container.
+#
+# Notes for users
+# ---------------
+# See docker_env.sh for prerequisites and other information.
+#
+# See also all.sh for notes about invocation of that script.
+
+# Copyright (C) 2006-2019, Arm Limited (or its affiliates), 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)
+
+source tests/scripts/docker_env.sh
+
+# Run tests that are possible with openly available compilers
+run_in_docker tests/scripts/all.sh \
+    --no-armcc \
+    $@
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 2822589..fa77436 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -218,6 +218,16 @@
     git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile
     git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile
 
+    # Remove any artifacts from the component_test_cmake_as_subdirectory test.
+    rm -rf programs/test/cmake_subproject/build
+    rm -f programs/test/cmake_subproject/Makefile
+    rm -f programs/test/cmake_subproject/cmake_subproject
+
+    # Remove any artifacts from the component_test_cmake_as_subdirectory test.
+    rm -rf programs/test/cmake_subproject/build
+    rm -f programs/test/cmake_subproject/Makefile
+    rm -f programs/test/cmake_subproject/cmake_subproject
+
     if [ -f "$CONFIG_BAK" ]; then
         mv "$CONFIG_BAK" "$CONFIG_H"
     fi
@@ -536,7 +546,7 @@
 
 component_check_names () {
     msg "test/build: declared and exported names" # < 3s
-    record_status tests/scripts/check-names.sh
+    record_status tests/scripts/check-names.sh -v
 }
 
 component_check_doxygen_warnings () {
@@ -575,6 +585,19 @@
     record_status tests/scripts/test-ref-configs.pl
 }
 
+component_test_no_pem_no_fs () {
+    msg "build: Default + !MBEDTLS_PEM_PARSE_C + !MBEDTLS_FS_IO (ASan build)"
+    scripts/config.pl unset MBEDTLS_PEM_PARSE_C
+    scripts/config.pl unset MBEDTLS_FS_IO
+    scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C # requires a filesystem
+    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C # requires PSA ITS
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+}
+
 component_test_rsa_no_crt () {
     msg "build: Default + RSA_NO_CRT (ASan build)" # ~ 6 min
     scripts/config.pl set MBEDTLS_RSA_NO_CRT
@@ -602,13 +625,23 @@
     CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On .
     make
 
-    msg "test: main suites (full config)" # ~ 5s
+    msg "test: main suites (full config, clang)" # ~ 5s
     make test
 
-    msg "test: psa_constant_names (full config)" # ~ 1s
+    msg "test: psa_constant_names (full config, clang)" # ~ 1s
     record_status tests/scripts/test_psa_constant_names.py
 }
 
+component_test_full_make_gcc_o0 () {
+    msg "build: make, full config, gcc -O0" # ~ 50s
+    scripts/config.pl full
+    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+    make CC=gcc CFLAGS='-O0'
+
+    msg "test: main suites (full config, gcc -O0)" # ~ 5s
+    make test
+}
+
 component_build_deprecated () {
     msg "build: make, full config + DEPRECATED_WARNING, gcc -O" # ~ 30s
     scripts/config.pl full
@@ -627,7 +660,6 @@
     make CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests
 }
 
-
 component_test_depends_curves () {
     msg "test/build: curves.pl (gcc)" # ~ 4 min
     record_status tests/scripts/curves.pl
@@ -654,24 +686,38 @@
     make TEST_CPP=1
 }
 
-component_test_use_psa_crypto_full_cmake_asan() {
-    # MBEDTLS_USE_PSA_CRYPTO: run the same set of tests as basic-build-test.sh
+component_test_no_use_psa_crypto_full_cmake_asan() {
+    # full minus 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"
     scripts/config.pl full
     scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
-    scripts/config.pl unset MBEDTLS_ECP_RESTARTABLE  # restartable ECC not supported through PSA
+    scripts/config.pl set MBEDTLS_ECP_RESTARTABLE  # not using PSA, so enable restartable ECC
     scripts/config.pl set MBEDTLS_PSA_CRYPTO_C
-    scripts/config.pl set MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.pl unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C
+    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C
     CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
     make
 
-    msg "test: main suites (MBEDTLS_USE_PSA_CRYPTO)"
+    msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO)"
     make test
 }
 
+component_test_check_params_functionality () {
+    msg "build+test: MBEDTLS_CHECK_PARAMS functionality"
+    scripts/config.pl full # includes CHECK_PARAMS
+    # Make MBEDTLS_PARAM_FAILED call mbedtls_param_failed().
+    scripts/config.pl unset MBEDTLS_CHECK_PARAMS_ASSERT
+    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    # Only build and run tests. Do not build sample programs, because
+    # they don't have a mbedtls_param_failed() function.
+    make CC=gcc CFLAGS='-Werror -O1' lib test
+}
+
 component_test_check_params_without_platform () {
     msg "build+test: MBEDTLS_CHECK_PARAMS without MBEDTLS_PLATFORM_C"
     scripts/config.pl full # includes CHECK_PARAMS
+    # Keep MBEDTLS_PARAM_FAILED as assert.
     scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
     scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
     scripts/config.pl unset MBEDTLS_PLATFORM_EXIT_ALT
@@ -689,6 +735,7 @@
     msg "build+test: MBEDTLS_CHECK_PARAMS with alternative MBEDTLS_PARAM_FAILED()"
     scripts/config.pl full # includes CHECK_PARAMS
     scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+    # Set MBEDTLS_PARAM_FAILED to nothing.
     sed -i 's/.*\(#define MBEDTLS_PARAM_FAILED( cond )\).*/\1/' "$CONFIG_H"
     make CC=gcc CFLAGS='-Werror -O1' all test
 }
@@ -712,7 +759,6 @@
     scripts/config.pl unset MBEDTLS_PSA_CRYPTO_SE_C
     scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C
     scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
     # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
     # to re-enable platform integration features otherwise disabled in C99 builds
     make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs
@@ -803,14 +849,14 @@
 
 component_test_make_shared () {
     msg "build/test: make shared" # ~ 40s
-    make SHARED=1 all check
+    make SHARED=1 all check -j1
 }
 
 component_test_m32_o0 () {
     # Build once with -O0, to compile out the i386 specific inline assembly
     msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s
     scripts/config.pl full
-    make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address'
+    make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32 -fsanitize=address'
 
     msg "test: i386, make, gcc -O0 (ASan build)"
     make test
@@ -829,7 +875,7 @@
     scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
     scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
     scripts/config.pl unset MBEDTLS_MEMORY_DEBUG
-    make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address'
+    make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32 -fsanitize=address'
 
     msg "test: i386, make, gcc -O1 (ASan build)"
     make test
@@ -841,7 +887,7 @@
 component_test_mx32 () {
     msg "build: 64-bit ILP32, make, gcc" # ~ 30s
     scripts/config.pl full
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32'
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32' LDFLAGS='-mx32'
 
     msg "test: 64-bit ILP32, make, gcc"
     make test
@@ -909,41 +955,13 @@
 
 component_build_arm_none_eabi_gcc () {
     msg "build: arm-none-eabi-gcc, make" # ~ 10s
-    scripts/config.pl full
-    scripts/config.pl unset MBEDTLS_TIMING_C
-    scripts/config.pl unset MBEDTLS_FS_IO
-    scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
-    # following things are not in the default config
-    scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
-    scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
-    scripts/config.pl unset MBEDTLS_THREADING_C
-    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
-    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
+    scripts/config.pl baremetal
     make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib
 }
 
 component_build_arm_none_eabi_gcc_no_udbl_division () {
     msg "build: arm-none-eabi-gcc -DMBEDTLS_NO_UDBL_DIVISION, make" # ~ 10s
-    scripts/config.pl full
-    scripts/config.pl unset MBEDTLS_TIMING_C
-    scripts/config.pl unset MBEDTLS_FS_IO
-    scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
-    # following things are not in the default config
-    scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
-    scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
-    scripts/config.pl unset MBEDTLS_THREADING_C
-    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
-    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
+    scripts/config.pl baremetal
     scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION
     make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib
     echo "Checking that software 64-bit division is not required"
@@ -952,21 +970,7 @@
 
 component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
     msg "build: arm-none-eabi-gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s
-    scripts/config.pl full
-    scripts/config.pl unset MBEDTLS_TIMING_C
-    scripts/config.pl unset MBEDTLS_FS_IO
-    scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
-    # following things are not in the default config
-    scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
-    scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
-    scripts/config.pl unset MBEDTLS_THREADING_C
-    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
-    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
+    scripts/config.pl baremetal
     scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION
     make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -O1 -march=armv6-m -mthumb' lib
     echo "Checking that software 64-bit multiplication is not required"
@@ -975,25 +979,7 @@
 
 component_build_armcc () {
     msg "build: ARM Compiler 5, make"
-    scripts/config.pl full
-    scripts/config.pl unset MBEDTLS_TIMING_C
-    scripts/config.pl unset MBEDTLS_FS_IO
-    scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
-    scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.pl unset MBEDTLS_HAVE_TIME
-    scripts/config.pl unset MBEDTLS_HAVE_TIME_DATE
-    scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
-    # following things are not in the default config
-    scripts/config.pl unset MBEDTLS_DEPRECATED_WARNING
-    scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
-    scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
-    scripts/config.pl unset MBEDTLS_THREADING_C
-    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
-    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
-    scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT # depends on MBEDTLS_HAVE_TIME
+    scripts/config.pl baremetal
 
     make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib
     make clean
@@ -1016,15 +1002,15 @@
 
 component_build_mingw () {
     msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs -j1
 
     # note Make tests only builds the tests, but doesn't run them
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror' WINDOWS_BUILD=1 tests
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror' WINDOWS_BUILD=1 tests -j1
     make WINDOWS_BUILD=1 clean
 
     msg "build: Windows cross build - mingw64, make (DLL)" # ~ 30s
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 lib programs
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 tests
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 lib programs -j1
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 tests -j1
     make WINDOWS_BUILD=1 clean
 }
 support_build_mingw() {
@@ -1069,6 +1055,19 @@
     unset MBEDTLS_ROOT_DIR
 }
 
+component_test_cmake_as_subdirectory () {
+    msg "build: cmake 'as-subdirectory' build"
+    MBEDTLS_ROOT_DIR="$PWD"
+
+    cd programs/test/cmake_subproject
+    cmake .
+    make
+    if_build_succeeded ./cmake_subproject
+
+    cd "$MBEDTLS_ROOT_DIR"
+    unset MBEDTLS_ROOT_DIR
+}
+
 component_test_zeroize () {
     # Test that the function mbedtls_platform_zeroize() is not optimized away by
     # different combinations of compilers and optimization flags by using an
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index a653001..54ca934 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -43,6 +43,7 @@
 
 # Step 1 - Make and instrumented build for code coverage
 export CFLAGS=' --coverage -g3 -O0 '
+export LDFLAGS=' --coverage'
 make clean
 cp "$CONFIG_H" "$CONFIG_BAK"
 scripts/config.pl full
@@ -53,6 +54,9 @@
 # Step 2 - Execute the tests
 TEST_OUTPUT=out_${PPID}
 cd tests
+if [ ! -f "seedfile" ]; then
+    dd if=/dev/urandom of="seedfile" bs=32 count=1
+fi
 
 # Step 2a - Unit Tests
 perl scripts/run-test-suites.pl -v 2 |tee unit-test-$TEST_OUTPUT
diff --git a/tests/scripts/basic-in-docker.sh b/tests/scripts/basic-in-docker.sh
new file mode 100755
index 0000000..096f8ed
--- /dev/null
+++ b/tests/scripts/basic-in-docker.sh
@@ -0,0 +1,47 @@
+#!/bin/bash -eu
+
+# basic-in-docker.sh
+#
+# Purpose
+# -------
+# This runs a rough equivalent of the travis.yml in a Docker container.
+# The tests are run for both clang and gcc.
+#
+# Notes for users
+# ---------------
+# See docker_env.sh for prerequisites and other information.
+
+# Copyright (C) 2006-2019, Arm Limited (or its affiliates), 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)
+
+source tests/scripts/docker_env.sh
+
+run_in_docker tests/scripts/recursion.pl library/*.c
+run_in_docker tests/scripts/check-generated-files.sh
+run_in_docker tests/scripts/check-doxy-blocks.pl
+run_in_docker tests/scripts/check-names.sh
+run_in_docker tests/scripts/check-files.py
+run_in_docker tests/scripts/doxygen.sh
+
+for compiler in clang gcc; do
+    run_in_docker -e CC=${compiler} cmake -D CMAKE_BUILD_TYPE:String="Check" .
+    run_in_docker -e CC=${compiler} make
+    run_in_docker -e CC=${compiler} make test
+    run_in_docker programs/test/selftest
+    run_in_docker tests/scripts/test-ref-configs.pl
+    run_in_docker tests/scripts/curves.pl
+done
diff --git a/tests/scripts/check-files.py b/tests/scripts/check-files.py
index 00fd0ed..255bed8 100755
--- a/tests/scripts/check-files.py
+++ b/tests/scripts/check-files.py
@@ -1,14 +1,12 @@
 #!/usr/bin/env python3
+
+# This file is part of Mbed TLS (https://tls.mbed.org)
+# Copyright (c) 2018, Arm Limited, All Rights Reserved
+
 """
-This file is part of Mbed TLS (https://tls.mbed.org)
-
-Copyright (c) 2018, Arm Limited, All Rights Reserved
-
-Purpose
-
 This script checks the current state of the source code for minor issues,
 including incorrect file permissions, presence of tabs, non-Unix line endings,
-trailing whitespace, presence of UTF-8 BOM, and TODO comments.
+trailing whitespace, and presence of UTF-8 BOM.
 Note: requires python 3, must be run from Mbed TLS root.
 """
 
@@ -170,19 +168,6 @@
             return True
         return False
 
-class TodoIssueTracker(LineIssueTracker):
-    """Track lines containing ``TODO``."""
-
-    heading = "TODO present:"
-    files_exemptions = frozenset([
-        os.path.basename(__file__),
-        "benchmark.c",
-        "pull_request_template.md",
-    ])
-
-    def issue_with_line(self, line, _filepath):
-        return b"todo" in line.lower()
-
 
 class IntegrityChecker(object):
     """Sanity-check files under the current directory."""
@@ -211,7 +196,6 @@
             TrailingWhitespaceIssueTracker(),
             TabIssueTracker(),
             MergeArtifactIssueTracker(),
-            TodoIssueTracker(),
         ]
 
     @staticmethod
@@ -257,15 +241,7 @@
 
 
 def run_main():
-    parser = argparse.ArgumentParser(
-        description=(
-            "This script checks the current state of the source code for "
-            "minor issues, including incorrect file permissions, "
-            "presence of tabs, non-Unix line endings, trailing whitespace, "
-            "presence of UTF-8 BOM, and TODO comments. "
-            "Note: requires python 3, must be run from Mbed TLS root."
-        )
-    )
+    parser = argparse.ArgumentParser(description=__doc__)
     parser.add_argument(
         "-l", "--log_file", type=str, help="path to optional output log",
     )
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
index 925037c..7d2302c 100755
--- a/tests/scripts/check-names.sh
+++ b/tests/scripts/check-names.sh
@@ -2,26 +2,42 @@
 #
 # This file is part of mbed TLS (https://tls.mbed.org)
 #
-# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
-#
-# Purpose
-#
-# This script confirms that the naming of all symbols and identifiers in mbed
-# TLS are consistent with the house style and are also self-consistent.
-#
+# Copyright (c) 2015-2019, ARM Limited, All Rights Reserved
+
 set -eu
 
+if [ $# -ne 0 ] && [ "$1" = "--help" ]; then
+    cat <<EOF
+$0 [-v]
+This script confirms that the naming of all symbols and identifiers in mbed
+TLS are consistent with the house style and are also self-consistent.
+
+  -v    If the script fails unexpectedly, print a command trace.
+EOF
+    exit
+fi
+
 if grep --version|head -n1|grep GNU >/dev/null; then :; else
     echo "This script requires GNU grep.">&2
     exit 1
 fi
 
+trace=
+if [ $# -ne 0 ] && [ "$1" = "-v" ]; then
+  shift
+  trace='-x'
+  exec 2>check-names.err
+  trap 'echo "FAILED UNEXPECTEDLY, status=$?";
+        cat check-names.err' EXIT
+  set -x
+fi
+
 printf "Analysing source code...\n"
 
-tests/scripts/list-macros.sh
+sh $trace tests/scripts/list-macros.sh
 tests/scripts/list-enum-consts.pl
-tests/scripts/list-identifiers.sh
-tests/scripts/list-symbols.sh
+sh $trace tests/scripts/list-identifiers.sh
+sh $trace tests/scripts/list-symbols.sh
 
 FAIL=0
 
@@ -82,6 +98,12 @@
     FAIL=1
 fi
 
+if [ -n "$trace" ]; then
+  set +x
+  trap - EXIT
+  rm check-names.err
+fi
+
 printf "\nOverall: "
 if [ "$FAIL" -eq 0 ]; then
     rm macros actual-macros enum-consts identifiers exported-symbols
diff --git a/tests/scripts/curves.pl b/tests/scripts/curves.pl
index ddc90c5..4791d55 100755
--- a/tests/scripts/curves.pl
+++ b/tests/scripts/curves.pl
@@ -57,7 +57,7 @@
 
     system( "CFLAGS='-Werror -Wall -Wextra' make lib" )
         and abort "Failed to build lib: $curve\n";
-    system( "cd tests && make" ) and abort "Failed to build tests: $curve\n";
+    system( "make" ) and abort "Failed to build tests: $curve\n";
     system( "make test" ) and abort "Failed test suite: $curve\n";
 
 }
diff --git a/tests/scripts/docker_env.sh b/tests/scripts/docker_env.sh
new file mode 100755
index 0000000..8bdc425
--- /dev/null
+++ b/tests/scripts/docker_env.sh
@@ -0,0 +1,93 @@
+#!/bin/bash -eu
+
+# docker_env.sh
+#
+# Purpose
+# -------
+#
+# This is a helper script to enable running tests under a Docker container,
+# thus making it easier to get set up as well as isolating test dependencies
+# (which include legacy/insecure configurations of openssl and gnutls).
+#
+# Notes for users
+# ---------------
+# This script expects a Linux x86_64 system with a recent version of Docker
+# installed and available for use, as well as http/https access. If a proxy
+# server must be used, invoke this script with the usual environment variables
+# (http_proxy and https_proxy) set appropriately. If an alternate Docker
+# registry is needed, specify MBEDTLS_DOCKER_REGISTRY to point at the
+# host name.
+#
+#
+# Running this script directly will check for Docker availability and set up
+# the Docker image.
+
+# Copyright (C) 2006-2019, Arm Limited (or its affiliates), 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)
+
+
+# default values, can be overridden by the environment
+: ${MBEDTLS_DOCKER_GUEST:=bionic}
+
+
+DOCKER_IMAGE_TAG="armmbed/mbedtls-test:${MBEDTLS_DOCKER_GUEST}"
+
+# Make sure docker is available
+if ! which docker > /dev/null; then
+    echo "Docker is required but doesn't seem to be installed. See https://www.docker.com/ to get started"
+    exit 1
+fi
+
+# Figure out if we need to 'sudo docker'
+if groups | grep docker > /dev/null; then
+    DOCKER="docker"
+else
+    echo "Using sudo to invoke docker since you're not a member of the docker group..."
+    DOCKER="sudo docker"
+fi
+
+# Build the Docker image
+echo "Getting docker image up to date (this may take a few minutes)..."
+${DOCKER} image build \
+    -t ${DOCKER_IMAGE_TAG} \
+    --cache-from=${DOCKER_IMAGE_TAG} \
+    --build-arg MAKEFLAGS_PARALLEL="-j $(nproc)" \
+    --network host \
+    ${http_proxy+--build-arg http_proxy=${http_proxy}} \
+    ${https_proxy+--build-arg https_proxy=${https_proxy}} \
+    ${MBEDTLS_DOCKER_REGISTRY+--build-arg MY_REGISTRY="${MBEDTLS_DOCKER_REGISTRY}/"} \
+    tests/docker/${MBEDTLS_DOCKER_GUEST}
+
+run_in_docker()
+{
+    ENV_ARGS=""
+    while [ "$1" == "-e" ]; do
+        ENV_ARGS="${ENV_ARGS} $1 $2"
+        shift 2
+    done
+
+    ${DOCKER} container run -it --rm \
+        --cap-add SYS_PTRACE \
+        --user "$(id -u):$(id -g)" \
+        --volume $PWD:$PWD \
+        --workdir $PWD \
+        -e MAKEFLAGS \
+        -e PYLINTHOME=/tmp/.pylintd \
+        ${ENV_ARGS} \
+        ${DOCKER_IMAGE_TAG} \
+        $@
+}
diff --git a/tests/scripts/list-symbols.sh b/tests/scripts/list-symbols.sh
index c258719..930722c 100755
--- a/tests/scripts/list-symbols.sh
+++ b/tests/scripts/list-symbols.sh
@@ -14,8 +14,21 @@
 
 cp include/mbedtls/config.h include/mbedtls/config.h.bak
 scripts/config.pl full
-CFLAGS=-fno-asynchronous-unwind-tables make clean lib >/dev/null 2>&1
+make clean
+make_ret=
+CFLAGS=-fno-asynchronous-unwind-tables make lib \
+      >list-symbols.make.log 2>&1 ||
+  {
+    make_ret=$?
+    echo "Build failure: CFLAGS=-fno-asynchronous-unwind-tables make lib"
+    cat list-symbols.make.log >&2
+  }
+rm list-symbols.make.log
 mv include/mbedtls/config.h.bak include/mbedtls/config.h
+if [ -n "$make_ret" ]; then
+    exit "$make_ret"
+fi
+
 if uname | grep -F Darwin >/dev/null; then
     nm -gUj library/libmbed*.a 2>/dev/null | sed -n -e 's/^_//p'
 elif uname | grep -F Linux >/dev/null; then
diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py
index ac2912d..6ac68a4 100755
--- a/tests/scripts/mbedtls_test.py
+++ b/tests/scripts/mbedtls_test.py
@@ -79,7 +79,7 @@
         split_colon_fn = lambda x: re.sub(r'\\' + split_char, split_char, x)
         if len(split_char) > 1:
             raise ValueError('Expected split character. Found string!')
-        out = map(split_colon_fn, re.split(r'(?<!\\)' + split_char, inp_str))
+        out = list(map(split_colon_fn, re.split(r'(?<!\\)' + split_char, inp_str)))
         out = [x for x in out if x]
         return out
 
@@ -99,11 +99,11 @@
 
             # Check dependencies
             dependencies = []
-            line = data_f.next().strip()
+            line = next(data_f).strip()
             match = re.search('depends_on:(.*)', line)
             if match:
                 dependencies = [int(x) for x in match.group(1).split(':')]
-                line = data_f.next().strip()
+                line = next(data_f).strip()
 
             # Read test vectors
             line = line.replace('\\n', '\n')
@@ -115,7 +115,7 @@
                 err_str_fmt = "Number of test arguments({}) should be even: {}"
                 raise TestDataParserError(err_str_fmt.format(args_count, line))
             grouped_args = [(args[i * 2], args[(i * 2) + 1])
-                            for i in range(len(args)/2)]
+                            for i in range(int(len(args)/2))]
             self.tests.append((name, function_name, dependencies,
                                grouped_args))
 
@@ -261,21 +261,21 @@
         data_bytes += bytearray([function_id, len(parameters)])
         for typ, param in parameters:
             if typ == 'int' or typ == 'exp':
-                i = int(param)
-                data_bytes += 'I' if typ == 'int' else 'E'
+                i = int(param, 0)
+                data_bytes += b'I' if typ == 'int' else b'E'
                 self.align_32bit(data_bytes)
                 data_bytes += self.int32_to_big_endian_bytes(i)
             elif typ == 'char*':
                 param = param.strip('"')
                 i = len(param) + 1  # + 1 for null termination
-                data_bytes += 'S'
+                data_bytes += b'S'
                 self.align_32bit(data_bytes)
                 data_bytes += self.int32_to_big_endian_bytes(i)
-                data_bytes += bytearray(list(param))
-                data_bytes += '\0'   # Null terminate
+                data_bytes += bytearray(param, encoding='ascii')
+                data_bytes += b'\0'   # Null terminate
             elif typ == 'hex':
                 binary_data = self.hex_str_bytes(param)
-                data_bytes += 'H'
+                data_bytes += b'H'
                 self.align_32bit(data_bytes)
                 i = len(binary_data)
                 data_bytes += self.int32_to_big_endian_bytes(i)
@@ -310,7 +310,7 @@
 
         param_bytes, length = self.test_vector_to_bytes(function_id,
                                                         dependencies, args)
-        self.send_kv(length, param_bytes)
+        self.send_kv(''.join('{:02x}'.format(x) for x in length), ''.join('{:02x}'.format(x) for x in param_bytes))
 
     @staticmethod
     def get_result(value):
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index e065272..03f2062 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -278,7 +278,7 @@
 #define TEST_VALID_PARAM( TEST )                                    \
     TEST_ASSERT( ( TEST, 1 ) );
 
-#define assert(a) if( !( a ) )                                      \
+#define TEST_HELPER_ASSERT(a) if( !( a ) )                                      \
 {                                                                   \
     mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n",   \
                              __FILE__, __LINE__, #a );              \
@@ -401,7 +401,7 @@
 /*----------------------------------------------------------------------------*/
 /* Helper Functions */
 
-static void test_fail( const char *test, int line_no, const char* filename )
+void test_fail( const char *test, int line_no, const char* filename )
 {
     test_info.failed = 1;
     test_info.test = test;
@@ -492,11 +492,11 @@
 }
 #endif /* __unix__ || __APPLE__ __MACH__ */
 
-static int unhexify( unsigned char *obuf, const char *ibuf )
+int unhexify( unsigned char *obuf, const char *ibuf )
 {
     unsigned char c, c2;
     int len = strlen( ibuf ) / 2;
-    assert( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */
+    TEST_HELPER_ASSERT( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */
 
     while( *ibuf != 0 )
     {
@@ -508,7 +508,7 @@
         else if( c >= 'A' && c <= 'F' )
             c -= 'A' - 10;
         else
-            assert( 0 );
+            TEST_HELPER_ASSERT( 0 );
 
         c2 = *ibuf++;
         if( c2 >= '0' && c2 <= '9' )
@@ -518,7 +518,7 @@
         else if( c2 >= 'A' && c2 <= 'F' )
             c2 -= 'A' - 10;
         else
-            assert( 0 );
+            TEST_HELPER_ASSERT( 0 );
 
         *obuf++ = ( c << 4 ) | c2;
     }
@@ -526,7 +526,7 @@
     return len;
 }
 
-static void hexify( unsigned char *obuf, const unsigned char *ibuf, int len )
+void hexify( unsigned char *obuf, const unsigned char *ibuf, int len )
 {
     unsigned char l, h;
 
@@ -563,7 +563,7 @@
     size_t actual_len = ( len != 0 ) ? len : 1;
 
     p = mbedtls_calloc( 1, actual_len );
-    assert( p != NULL );
+    TEST_HELPER_ASSERT( p != NULL );
 
     memset( p, 0x00, actual_len );
 
@@ -580,7 +580,7 @@
  *
  * For convenience, dies if allocation fails.
  */
-static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen )
+unsigned char *unhexify_alloc( const char *ibuf, size_t *olen )
 {
     unsigned char *obuf;
 
@@ -590,7 +590,7 @@
         return( zero_alloc( *olen ) );
 
     obuf = mbedtls_calloc( 1, *olen );
-    assert( obuf != NULL );
+    TEST_HELPER_ASSERT( obuf != NULL );
 
     (void) unhexify( obuf, ibuf );
 
@@ -631,7 +631,7 @@
  *
  * rng_state shall be NULL.
  */
-static int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len )
+int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len )
 {
     if( rng_state != NULL )
         rng_state  = NULL;
@@ -658,7 +658,7 @@
  *
  * After the buffer is empty it will return rand();
  */
-static int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len )
+int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len )
 {
     rnd_buf_info *info = (rnd_buf_info *) rng_state;
     size_t use_len;
@@ -704,7 +704,7 @@
  *
  * rng_state shall be a pointer to a rnd_pseudo_info structure.
  */
-static int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
+int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
 {
     rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state;
     uint32_t i, *k, sum, delta=0x9E3779B9;
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 3c43032..fe6a2bc 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -179,7 +179,7 @@
             if( p + 1 < buf + len )
             {
                 cur = p + 1;
-                assert( cnt < params_len );
+                TEST_HELPER_ASSERT( cnt < params_len );
                 params[cnt++] = cur;
             }
             *p = '\0';
diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function
index 56abf29..d430d9d 100644
--- a/tests/suites/target_test.function
+++ b/tests/suites/target_test.function
@@ -13,11 +13,11 @@
  */
 #define INCR_ASSERT(p, start, len, step) do                     \
 {                                                               \
-    assert( ( p ) >= ( start ) );                               \
-    assert( sizeof( *( p ) ) == sizeof( *( start ) ) );         \
+    TEST_HELPER_ASSERT( ( p ) >= ( start ) );                               \
+    TEST_HELPER_ASSERT( sizeof( *( p ) ) == sizeof( *( start ) ) );         \
     /* <= is checked to support use inside a loop where         \
        pointer is incremented after reading data.       */      \
-    assert( (uint32_t)( ( ( p ) - ( start ) ) + ( step ) ) <= ( len ) );\
+    TEST_HELPER_ASSERT( (uint32_t)( ( ( p ) - ( start ) ) + ( step ) ) <= ( len ) );\
     ( p ) += ( step );                                          \
 }                                                               \
 while( 0 )
@@ -59,10 +59,29 @@
     return( DEPENDENCY_SUPPORTED );
 }
 
+/**
+ * \brief       Receives hex string on serial interface, and converts to a byte.
+ *
+ * \param none
+ *
+ * \return      unsigned int8
+ */
+uint8_t receive_byte()
+{
+    uint8_t byte;
+    uint8_t c[3];
+    char *endptr;
+    c[0] = greentea_getc();
+    c[1] = greentea_getc();
+    c[2] = '\0';
+
+    assert( unhexify( &byte, c ) != 2 );
+    return( byte );
+}
 
 /**
  * \brief       Receives unsigned integer on serial interface.
- *              Integers are encoded in network order.
+ *              Integers are encoded in network order, and sent as hex ascii string.
  *
  * \param none
  *
@@ -71,10 +90,17 @@
 uint32_t receive_uint32()
 {
     uint32_t value;
-    value =  (uint8_t)greentea_getc() << 24;
-    value |= (uint8_t)greentea_getc() << 16;
-    value |= (uint8_t)greentea_getc() << 8;
-    value |= (uint8_t)greentea_getc();
+    const uint8_t c[9] = { greentea_getc(),
+                           greentea_getc(),
+                           greentea_getc(),
+                           greentea_getc(),
+                           greentea_getc(),
+                           greentea_getc(),
+                           greentea_getc(),
+                           greentea_getc(),
+                           '\0'
+                         };
+    assert( unhexify( &value, c ) != 8 );
     return( (uint32_t)value );
 }
 
@@ -127,12 +153,12 @@
     /* Read data length */
     *data_len = receive_uint32();
     data = (uint8_t *)malloc( *data_len );
-    assert( data != NULL );
+    TEST_HELPER_ASSERT( data != NULL );
 
     greentea_getc(); // read ';' received after key i.e. *data_len
 
     for( i = 0; i < *data_len; i++ )
-        data[i] = greentea_getc();
+        data[i] = receive_byte();
 
     /* Read closing braces */
     for( i = 0; i < 2; i++ )
@@ -221,7 +247,7 @@
     hex_count = find_hex_count(count, data, data_len);
 
     params = (void **)malloc( sizeof( void *) * ( count + hex_count ) );
-    assert( params != NULL );
+    TEST_HELPER_ASSERT( params != NULL );
     cur = params;
 
     p = data;
@@ -360,7 +386,7 @@
         {
             /* Read dependency count */
             count = *p;
-            assert( count < data_len );
+            TEST_HELPER_ASSERT( count < data_len );
             INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
             ret = verify_dependencies( count, p );
             if ( ret != DEPENDENCY_SUPPORTED )
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index 1a8ff1e..c42fc79 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -1,6 +1,6 @@
 Decrypt empty buffer
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
-dec_empty_buf:
+dec_empty_buf:MBEDTLS_CIPHER_AES_128_CBC
 
 AES-128 CBC - Encrypt and decrypt 0 bytes with PKCS7 padding
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
diff --git a/tests/suites/test_suite_cipher.chacha20.data b/tests/suites/test_suite_cipher.chacha20.data
index c67e582..11de103 100644
--- a/tests/suites/test_suite_cipher.chacha20.data
+++ b/tests/suites/test_suite_cipher.chacha20.data
@@ -1,7 +1,3 @@
-Decrypt empty buffer
-depends_on:MBEDTLS_CHACHA20_C
-dec_empty_buf:
-
 Chacha20 RFC 7539 Test Vector #1
 depends_on:MBEDTLS_CHACHA20_C
 decrypt_test_vec:MBEDTLS_CIPHER_CHACHA20:-1:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"":"":0:0
diff --git a/tests/suites/test_suite_cipher.chachapoly.data b/tests/suites/test_suite_cipher.chachapoly.data
index 7310a84..ccd0dfb 100644
--- a/tests/suites/test_suite_cipher.chachapoly.data
+++ b/tests/suites/test_suite_cipher.chachapoly.data
@@ -1,6 +1,6 @@
 Decrypt empty buffer
 depends_on:MBEDTLS_CHACHAPOLY_C
-dec_empty_buf:
+dec_empty_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305
 
 ChaCha20+Poly1305 Encrypt and decrypt 0 bytes
 depends_on:MBEDTLS_CHACHAPOLY_C
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index ca39937..f6367f1 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -4,6 +4,11 @@
 #if defined(MBEDTLS_GCM_C)
 #include "mbedtls/gcm.h"
 #endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa_crypto_helpers.h"
+#endif
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -710,7 +715,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void dec_empty_buf(  )
+void dec_empty_buf( int cipher )
 {
     unsigned char key[32];
     unsigned char iv[16];
@@ -723,6 +728,8 @@
 
     size_t outlen = 0;
 
+    int expected_ret;
+
     memset( key, 0, 32 );
     memset( iv , 0, 16 );
 
@@ -732,12 +739,15 @@
     memset( decbuf, 0, 64 );
 
     /* Initialise context */
-    cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_CBC );
+    cipher_info = mbedtls_cipher_info_from_type( cipher );
     TEST_ASSERT( NULL != cipher_info);
+    TEST_ASSERT( sizeof(key) * 8 >= cipher_info->key_bitlen );
 
     TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );
 
-    TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx_dec, key, 128, MBEDTLS_DECRYPT ) );
+    TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx_dec,
+                                             key, cipher_info->key_bitlen,
+                                             MBEDTLS_DECRYPT ) );
 
     TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, 16 ) );
 
@@ -750,8 +760,23 @@
     /* decode 0-byte string */
     TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_dec, encbuf, 0, decbuf, &outlen ) );
     TEST_ASSERT( 0 == outlen );
-    TEST_ASSERT( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED == mbedtls_cipher_finish(
-                 &ctx_dec, decbuf + outlen, &outlen ) );
+
+    if ( cipher_info->mode == MBEDTLS_MODE_CBC ||
+         cipher_info->mode == MBEDTLS_MODE_ECB )
+    {
+        /* CBC and ECB ciphers need a full block of input. */
+        expected_ret = MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
+    }
+    else
+    {
+        /* Non-CBC and non-ECB ciphers are OK with decrypting empty buffers and
+         * return success, not MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED, when
+         * decrypting an empty buffer. */
+        expected_ret = 0;
+    }
+
+    TEST_ASSERT( expected_ret == mbedtls_cipher_finish(
+                                    &ctx_dec, decbuf + outlen, &outlen ) );
     TEST_ASSERT( 0 == outlen );
 
 exit:
@@ -962,7 +987,7 @@
 #else
     if( use_psa == 1 )
     {
-        TEST_ASSERT( psa_crypto_init() == 0 );
+        PSA_ASSERT( psa_crypto_init( ) );
 
         /* PSA requires that the tag immediately follows the ciphertext. */
         tmp_cipher = mbedtls_calloc( 1, cipher->len + tag->len );
@@ -1046,14 +1071,15 @@
 
 exit:
 
+    mbedtls_cipher_free( &ctx );
+
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     if( use_psa == 1 )
     {
         mbedtls_free( tmp_cipher );
+        PSA_DONE( );
     }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-    mbedtls_cipher_free( &ctx );
 }
 /* END_CASE */
 
@@ -1123,7 +1149,7 @@
 #else
     if( use_psa == 1 )
     {
-        TEST_ASSERT( psa_crypto_init() == 0 );
+        PSA_ASSERT( psa_crypto_init( ) );
         TEST_ASSERT( 0 == mbedtls_cipher_setup_psa( &ctx,
                               mbedtls_cipher_info_from_type( cipher_id ), 0 ) );
     }
@@ -1152,6 +1178,9 @@
 
 exit:
     mbedtls_cipher_free( &ctx );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    PSA_DONE( );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
index 0b1cfe8..46137da 100644
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -48,7 +48,7 @@
  * This might break memory checks in the future if sources need 'free-ing' then
  * as well.
  */
-static void entropy_clear_sources( mbedtls_entropy_context *ctx )
+void entropy_clear_sources( mbedtls_entropy_context *ctx )
 {
     ctx->source_count = 0;
 }
@@ -58,7 +58,7 @@
  */
 static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
 
-static int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
+int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
 {
     if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
         return( -1 );
@@ -67,7 +67,7 @@
     return( 0 );
 }
 
-static int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
+int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
 {
     if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
         return( -1 );
@@ -98,7 +98,7 @@
     return( 0 );
 }
 
-static int read_nv_seed( unsigned char *buf, size_t buf_len )
+int read_nv_seed( unsigned char *buf, size_t buf_len )
 {
     FILE *f;
 
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 3d38535..fbb6907 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -13,6 +13,13 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 #include "mbedtls/psa_util.h"
 #include "psa_crypto_helpers.h"
+#define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) )
+#else
+/* Define empty macros so that we can use them in the preamble and teardown
+ * of every test function that uses PSA conditionally based on
+ * MBEDTLS_USE_PSA_CRYPTO. */
+#define PSA_INIT( ) ( (void) 0 )
+#define PSA_DONE( ) ( (void) 0 )
 #endif
 
 static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len );
@@ -117,7 +124,7 @@
     size_t len;
     mbedtls_pk_debug_item dbg;
 
-    TEST_ASSERT( psa_crypto_init() == 0 );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     mbedtls_pk_init( &pk );
     mbedtls_pk_init( &pk2 );
@@ -173,6 +180,7 @@
 exit:
     mbedtls_pk_free( &pk ); /* redundant except upon error */
     mbedtls_pk_free( &pk2 );
+    PSA_DONE( );
 }
 /* END_CASE */
 
@@ -763,7 +771,7 @@
     mbedtls_ecp_keypair *eckey;
 
     mbedtls_pk_init( &pk );
-
+    PSA_INIT( );
 
     TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
 
@@ -780,6 +788,7 @@
 
 exit:
     mbedtls_pk_free( &pk );
+    PSA_DONE( );
 }
 /* END_CASE */
 
@@ -904,6 +913,7 @@
 #endif
 
     mbedtls_pk_init( &pk );
+    PSA_INIT( );
 
     memset( hash, 0x2a, sizeof hash );
     memset( sig, 0, sizeof sig );
@@ -955,6 +965,7 @@
     mbedtls_pk_restart_free( rs_ctx );
 #endif
     mbedtls_pk_free( &pk );
+    PSA_DONE( );
 }
 /* END_CASE */
 
@@ -1210,6 +1221,8 @@
      * - parse it to a PK context and verify the signature this way
      */
 
+    PSA_ASSERT( psa_crypto_init( ) );
+
     /* Create legacy EC public/private key in PK context. */
     mbedtls_pk_init( &pk );
     TEST_ASSERT( mbedtls_pk_setup( &pk,
@@ -1259,5 +1272,6 @@
 
 exit:
     mbedtls_pk_free( &pk );
+    PSA_DONE( );
 }
 /* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 5c12caa..21e3c52 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -19,6 +19,9 @@
 PSA key attributes: lifetime then id
 persistence_attributes:0x1234:3:0x1235:0x1235:3
 
+PSA key attributes: slot number
+slot_number_attribute:
+
 PSA import/export raw: 0 bytes
 import_export:"":PSA_KEY_TYPE_RAW_DATA:PSA_KEY_USAGE_EXPORT:0:0:0:PSA_SUCCESS:1
 
@@ -52,9 +55,18 @@
 PSA invalid handle (largest plausible handle)
 invalid_handle:-1
 
+PSA import: bad usage flag
+import_with_policy:PSA_KEY_TYPE_RAW_DATA:0x40000000:0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import: invalid type (0)
+import_with_policy:PSA_KEY_TYPE_NONE:0:0:PSA_ERROR_NOT_SUPPORTED
+
+PSA import: invalid type (PSA_KEY_TYPE_CATEGORY_MASK)
+import_with_policy:PSA_KEY_TYPE_CATEGORY_MASK:0:0:PSA_ERROR_NOT_SUPPORTED
+
 PSA import AES: bad key size
 depends_on:MBEDTLS_AES_C
-import:"0123456789abcdef":PSA_KEY_TYPE_AES:0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"0123456789abcdef":PSA_KEY_TYPE_AES:0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import/export RSA public key: good, 1024-bit
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
@@ -110,19 +122,19 @@
 
 PSA import RSA keypair: truncated
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import RSA keypair: public key
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import RSA public key: key pair
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import RSA keypair: valid key but EC
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import/export-public RSA public key: good, 1024-bit
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
@@ -150,19 +162,19 @@
 
 PSA import RSA public key: 1022-bit (not supported)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
-import:"30818802818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd134450230203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED
+import_with_data:"30818802818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd134450230203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED
 
 PSA import RSA keypair: 1022-bit (not supported)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
-import:"3082025802010002818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd1344502302030100010281800ad9700e01e8bf68ff4c90c4465dfa13fea0e76295d817349ccb257d382acf89b3d7b31e18606af4ac92baf3710426fe0b54225ddfa527c31218b3346e03a9cae5395a780ade880b996f4061fad65689393fc8e77f46a4c1a29b0450cdaaef0710e523cd1028abe1653d23f0d5ec805a629bdf1fc4c1c00737760e1714f6b7f102407d5e545484b546bd61972b446a04af0cf17b126a8872b977da5035ca82dd0e4fef1381a6480f60db07628348602f86ba89a271563d9a3fb613b9b39703498f9902407017641093065eed178ff848b5f8a2b502a187511db28549ea7646f3e7b3ea171f4c34c0ecf0566adc4d172c057be077a45fcf8019a36a4588c4de3b8c0a631b02407cc7fccbbae2eb2be80c9c8615b7dfbbd4469907ec13b44274cacd1f69ad38679b2021352e18106131327e54f5579893e6160714bd6fdfe60c30136e45595c51024055250f779f96f94873db82a808c24325e847b6b8212cd81e9ba118a8715ab2f8b96773b310c8477c88b76e609c11cb22569408d4afa4f836b57b85ac09e661fd02400e5fc5df9614c95d77e9bc2df63d48e7a08a0034174f0f745eef4413ee36d929f194557e6990e148b7438e949a41e92bc9d9136c3e6563904151a578a2f4fc1b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED
+import_with_data:"3082025802010002818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd1344502302030100010281800ad9700e01e8bf68ff4c90c4465dfa13fea0e76295d817349ccb257d382acf89b3d7b31e18606af4ac92baf3710426fe0b54225ddfa527c31218b3346e03a9cae5395a780ade880b996f4061fad65689393fc8e77f46a4c1a29b0450cdaaef0710e523cd1028abe1653d23f0d5ec805a629bdf1fc4c1c00737760e1714f6b7f102407d5e545484b546bd61972b446a04af0cf17b126a8872b977da5035ca82dd0e4fef1381a6480f60db07628348602f86ba89a271563d9a3fb613b9b39703498f9902407017641093065eed178ff848b5f8a2b502a187511db28549ea7646f3e7b3ea171f4c34c0ecf0566adc4d172c057be077a45fcf8019a36a4588c4de3b8c0a631b02407cc7fccbbae2eb2be80c9c8615b7dfbbd4469907ec13b44274cacd1f69ad38679b2021352e18106131327e54f5579893e6160714bd6fdfe60c30136e45595c51024055250f779f96f94873db82a808c24325e847b6b8212cd81e9ba118a8715ab2f8b96773b310c8477c88b76e609c11cb22569408d4afa4f836b57b85ac09e661fd02400e5fc5df9614c95d77e9bc2df63d48e7a08a0034174f0f745eef4413ee36d929f194557e6990e148b7438e949a41e92bc9d9136c3e6563904151a578a2f4fc1b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED
 
 PSA import RSA public key: 1023-bit (not supported)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
-import:"3081880281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED
+import_with_data:"3081880281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED
 
 PSA import RSA keypair: 1023-bit (not supported)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
-import:"3082025a0201000281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001028180491b277413fb35efe82dace68b544a9dd6aa8917d329731955ec66ec3b0178fcf5a29196e1a6c093bf6c8064b36a8f0d9840a78003d11392754a70a77788975515a1442a6c806cafa2f07fe99cac78a86fa868888d654cec4baf205352cf8255acaa47e2455f23b58c0e5ae43fa297bbffe5b970caa80f71e82084fd35425479024100ef27f3fb2df90ac4910ed95fdde4877d09b0dc4e95079f12a7e2041300a8884a39372a1c79691338cd5c3965bcf3a24f2ce9e10de19d4cb87c7546d60ca0aa0d024073e9e1283475e9ab3075da0b005ca7c7b05e76325f8deb648238831c8353041d594307f784cd527cfee9187b997713d71c0ff98f01beac4d1a85583be52e90e302402f0c801e311c2677274671933f96fee4a56c6adaf6ccaa09c4875d5fd3a8542fadf3e14ffabea62e6d90302688b6b17ebc0a42e1353a79e66d6db102d9371e5d02406731ef3c8607fbf266806590a9cfd3a79a435ee355e2d9906fc6b4236c5f3a288ed178844a7d295512f49ed15b3d82325e4f729478af3262aa9bd083f273d49502410090a32c0e8ca3bcd4c66f092cdc369cd1abb4a05b9a6f0e65e5a51da1d96d5aca8c1525b3f11322c0588062fc8592ebf25b7950f918d39018e82b8acccc8f7e7a":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED
+import_with_data:"3082025a0201000281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001028180491b277413fb35efe82dace68b544a9dd6aa8917d329731955ec66ec3b0178fcf5a29196e1a6c093bf6c8064b36a8f0d9840a78003d11392754a70a77788975515a1442a6c806cafa2f07fe99cac78a86fa868888d654cec4baf205352cf8255acaa47e2455f23b58c0e5ae43fa297bbffe5b970caa80f71e82084fd35425479024100ef27f3fb2df90ac4910ed95fdde4877d09b0dc4e95079f12a7e2041300a8884a39372a1c79691338cd5c3965bcf3a24f2ce9e10de19d4cb87c7546d60ca0aa0d024073e9e1283475e9ab3075da0b005ca7c7b05e76325f8deb648238831c8353041d594307f784cd527cfee9187b997713d71c0ff98f01beac4d1a85583be52e90e302402f0c801e311c2677274671933f96fee4a56c6adaf6ccaa09c4875d5fd3a8542fadf3e14ffabea62e6d90302688b6b17ebc0a42e1353a79e66d6db102d9371e5d02406731ef3c8607fbf266806590a9cfd3a79a435ee355e2d9906fc6b4236c5f3a288ed178844a7d295512f49ed15b3d82325e4f729478af3262aa9bd083f273d49502410090a32c0e8ca3bcd4c66f092cdc369cd1abb4a05b9a6f0e65e5a51da1d96d5aca8c1525b3f11322c0588062fc8592ebf25b7950f918d39018e82b8acccc8f7e7a":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED
 
 PSA import/export EC secp224r1 key pair: good
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP224R1_ENABLED
@@ -256,31 +268,31 @@
 
 PSA import EC keypair: DER format
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import EC keypair: too short
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-import:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import EC keypair: public key
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-import:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import EC keypair: secp256r1, all-bits-zero (bad)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-import:"0000000000000000000000000000000000000000000000000000000000000000":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"0000000000000000000000000000000000000000000000000000000000000000":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import EC keypair: secp256r1, d == n - 1 (good)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-import:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_SUCCESS
+import_with_data:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_SUCCESS
 
 PSA import EC keypair: secp256r1, d == n (bad)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-import:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import EC keypair: secp256r1, d > n (bad)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-import:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import EC public key: key pair
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
@@ -288,31 +300,39 @@
 # one would expect the status to be PSA_ERROR_INVALID_ARGUMENT. But the
 # Mbed TLS pkparse module returns MBEDTLS_ERR_PK_INVALID_ALG, I think because
 # it's looking for an OID where there is no OID.
-import:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_NOT_SUPPORTED
+import_with_data:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_NOT_SUPPORTED
 
 PSA import EC keypair: valid key but RSA
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_RSA_C
-import:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):0:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import AES: bits=0 ok
 depends_on:MBEDTLS_AES_C
-import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:0:PSA_SUCCESS
+import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:0:PSA_SUCCESS
 
 PSA import AES: bits=128 ok
 depends_on:MBEDTLS_AES_C
-import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_SUCCESS
+import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_SUCCESS
 
 PSA import AES: bits=256 wrong
 depends_on:MBEDTLS_AES_C
-import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import AES: bits=256 ok
 depends_on:MBEDTLS_AES_C
-import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_SUCCESS
+import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_SUCCESS
 
 PSA import AES: bits=128 wrong
 depends_on:MBEDTLS_AES_C
-import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_ERROR_INVALID_ARGUMENT
+import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import large key: raw, 65528 bits (ok)
+depends_on:HAVE_RAM_AVAILABLE_128K
+import_large_key:PSA_KEY_TYPE_RAW_DATA:8191:PSA_SUCCESS
+
+PSA import large key: raw, 65536 bits (not supported)
+depends_on:HAVE_RAM_AVAILABLE_128K
+import_large_key:PSA_KEY_TYPE_RAW_DATA:8192:PSA_ERROR_NOT_SUPPORTED
 
 PSA import RSA key pair: maximum size exceeded
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
@@ -2099,6 +2119,25 @@
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
 derive_key_export:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":1:41
 
+PSA key derivation: invalid type (0)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_NONE:128:PSA_ERROR_NOT_SUPPORTED
+
+PSA key derivation: invalid type (PSA_KEY_TYPE_CATEGORY_MASK)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_CATEGORY_MASK:128:PSA_ERROR_NOT_SUPPORTED
+
+# This test assumes that PSA_MAX_KEY_BITS (currently 65536-8 bits = 8191 bytes
+# and not expected to be raised any time soon) is less than the maximum
+# output from HKDF-SHA512 (255*64 = 16320 bytes).
+PSA key derivation: largest possible key
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_512):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:PSA_MAX_KEY_BITS:PSA_SUCCESS
+
+PSA key derivation: key too large
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_512):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:PSA_MAX_KEY_BITS + 1:PSA_ERROR_NOT_SUPPORTED
+
 PSA key agreement setup: ECDH + HKDF-SHA-256: good
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_MD_C:MBEDTLS_SHA256_C
 key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_SUCCESS
@@ -2197,6 +2236,18 @@
 PSA generate random: 260 bytes
 generate_random:260
 
+PSA generate random: MBEDTLS_CTR_DRBG_MAX_REQUEST bytes
+generate_random:MBEDTLS_CTR_DRBG_MAX_REQUEST
+
+PSA generate random: MBEDTLS_CTR_DRBG_MAX_REQUEST+1 bytes
+generate_random:MBEDTLS_CTR_DRBG_MAX_REQUEST + 1
+
+PSA generate random: 2*MBEDTLS_CTR_DRBG_MAX_REQUEST+1 bytes
+generate_random:2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1
+
+PSA generate key: bad type (0)
+generate_key:PSA_KEY_TYPE_NONE:128:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
+
 PSA generate key: bad type (PSA_KEY_TYPE_CATEGORY_MASK)
 generate_key:PSA_KEY_TYPE_CATEGORY_MASK:128:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
 
@@ -2212,6 +2263,19 @@
 PSA generate key: raw data, 8 bits
 generate_key:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
 
+PSA generate key: raw data, (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+generate_key:PSA_KEY_TYPE_RAW_DATA:(MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+
+PSA generate key: raw data, (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+generate_key:PSA_KEY_TYPE_RAW_DATA:(2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+
+PSA generate key: raw data, 65528 bits (ok)
+depends_on:HAVE_RAM_AVAILABLE_128K
+generate_key:PSA_KEY_TYPE_RAW_DATA:65528:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+
+PSA generate key: raw data, 65536 bits (not supported)
+generate_key:PSA_KEY_TYPE_RAW_DATA:65536:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
+
 PSA generate key: AES, 128 bits, CTR
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
 generate_key:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 1d06d62..3225bef 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -5,8 +5,21 @@
 #include "mbedtls/asn1write.h"
 #include "mbedtls/oid.h"
 
+/* For MBEDTLS_CTR_DRBG_MAX_REQUEST, knowing that psa_generate_random()
+ * uses mbedtls_ctr_drbg internally. */
+#include "mbedtls/ctr_drbg.h"
+
 #include "psa_crypto_helpers.h"
 
+/* Tests that require more than 128kB of RAM plus change have this symbol
+ * as a dependency. Currently we always define this symbol, so the tests
+ * are always executed. In the future we should make this conditional
+ * so that tests that require a lot of memory are skipped on constrained
+ * platforms. */
+#define HAVE_RAM_AVAILABLE_128K
+
+#include "psa/crypto.h"
+
 /** An invalid export length that will never be set by psa_export_key(). */
 static const size_t INVALID_EXPORT_LENGTH = ~0U;
 
@@ -556,7 +569,8 @@
         TEST_ASSERT( ! "Key derivation algorithm not supported" );
     }
 
-    PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
+    if( capacity != SIZE_MAX )
+        PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
 
     return( 1 );
 
@@ -712,9 +726,9 @@
     return( ok );
 }
 
-static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
-                              size_t min_bits, size_t max_bits,
-                              int must_be_odd )
+int asn1_skip_integer( unsigned char **p, const unsigned char *end,
+                       size_t min_bits, size_t max_bits,
+                       int must_be_odd )
 {
     size_t len;
     size_t actual_bits;
@@ -839,10 +853,10 @@
     {
         uint8_t *p = exported;
         uint8_t *end = exported + exported_length;
-        size_t len;
 #if defined(MBEDTLS_RSA_C)
         if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
         {
+            size_t len;
             /*   RSAPublicKey ::= SEQUENCE {
              *      modulus            INTEGER,    -- n
              *      publicExponent     INTEGER  }  -- e
@@ -1099,6 +1113,23 @@
     return( ok );
 }
 
+/* Assert that a key isn't reported as having a slot number. */
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+#define ASSERT_NO_SLOT_NUMBER( attributes )                             \
+    do                                                                  \
+    {                                                                   \
+        psa_key_slot_number_t ASSERT_NO_SLOT_NUMBER_slot_number;        \
+        TEST_EQUAL( psa_get_key_slot_number(                            \
+                        attributes,                                     \
+                        &ASSERT_NO_SLOT_NUMBER_slot_number ),           \
+                    PSA_ERROR_INVALID_ARGUMENT );                       \
+    }                                                                   \
+    while( 0 )
+#else /* MBEDTLS_PSA_CRYPTO_SE_C */
+#define ASSERT_NO_SLOT_NUMBER( attributes )     \
+    ( (void) 0 )
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
 /* An overapproximation of the amount of storage needed for a key of the
  * given type and with the given content. The API doesn't make it easy
  * to find a good value for the size. The current implementation doesn't
@@ -1200,10 +1231,94 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_SE_C */
+void slot_number_attribute( )
+{
+    psa_key_slot_number_t slot_number = 0xdeadbeef;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    /* Initially, there is no slot number. */
+    TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Test setting a slot number. */
+    psa_set_key_slot_number( &attributes, 0 );
+    PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
+    TEST_EQUAL( slot_number, 0 );
+
+    /* Test changing the slot number. */
+    psa_set_key_slot_number( &attributes, 42 );
+    PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
+    TEST_EQUAL( slot_number, 42 );
+
+    /* Test clearing the slot number. */
+    psa_clear_key_slot_number( &attributes );
+    TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Clearing again should have no effect. */
+    psa_clear_key_slot_number( &attributes );
+    TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Test that reset clears the slot number. */
+    psa_set_key_slot_number( &attributes, 42 );
+    PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
+    TEST_EQUAL( slot_number, 42 );
+    psa_reset_key_attributes( &attributes );
+    TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
+                PSA_ERROR_INVALID_ARGUMENT );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
-void import( data_t *data, int type_arg,
-             int attr_bits_arg,
-             int expected_status_arg )
+void import_with_policy( int type_arg,
+                         int usage_arg, int alg_arg,
+                         int expected_status_arg )
+{
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_handle_t handle = 0;
+    psa_key_type_t type = type_arg;
+    psa_key_usage_t usage = usage_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    const uint8_t key_material[16] = {0};
+    psa_status_t status;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_type( &attributes, type );
+    psa_set_key_usage_flags( &attributes, usage );
+    psa_set_key_algorithm( &attributes, alg );
+
+    status = psa_import_key( &attributes,
+                             key_material, sizeof( key_material ),
+                             &handle );
+    TEST_EQUAL( status, expected_status );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
+    TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
+    TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
+    TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
+    ASSERT_NO_SLOT_NUMBER( &got_attributes );
+
+    PSA_ASSERT( psa_destroy_key( handle ) );
+    test_operations_on_invalid_handle( handle );
+
+exit:
+    psa_destroy_key( handle );
+    psa_reset_key_attributes( &got_attributes );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void import_with_data( data_t *data, int type_arg,
+                       int attr_bits_arg,
+                       int expected_status_arg )
 {
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -1217,6 +1332,7 @@
 
     psa_set_key_type( &attributes, type );
     psa_set_key_bits( &attributes, attr_bits );
+
     status = psa_import_key( &attributes, data->x, data->len, &handle );
     TEST_EQUAL( status, expected_status );
     if( status != PSA_SUCCESS )
@@ -1225,7 +1341,8 @@
     PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
     TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
     if( attr_bits != 0 )
-        TEST_EQUAL( attr_bits, got_attributes.bits );
+        TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) );
+    ASSERT_NO_SLOT_NUMBER( &got_attributes );
 
     PSA_ASSERT( psa_destroy_key( handle ) );
     test_operations_on_invalid_handle( handle );
@@ -1238,6 +1355,55 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void import_large_key( int type_arg, int byte_size_arg,
+                       int expected_status_arg )
+{
+    psa_key_type_t type = type_arg;
+    size_t byte_size = byte_size_arg;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_handle_t handle = 0;
+    psa_status_t status;
+    uint8_t *buffer = NULL;
+    size_t buffer_size = byte_size + 1;
+    size_t n;
+
+    /* It would be better to skip the test than fail it if the allocation
+     * fails, but the test framework doesn't support this yet. */
+    ASSERT_ALLOC( buffer, buffer_size );
+    memset( buffer, 'K', byte_size );
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    /* Try importing the key */
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
+    psa_set_key_type( &attributes, type );
+    status = psa_import_key( &attributes, buffer, byte_size, &handle );
+    TEST_EQUAL( status, expected_status );
+
+    if( status == PSA_SUCCESS )
+    {
+        PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
+        TEST_EQUAL( psa_get_key_type( &attributes ), type );
+        TEST_EQUAL( psa_get_key_bits( &attributes ),
+                    PSA_BYTES_TO_BITS( byte_size ) );
+        ASSERT_NO_SLOT_NUMBER( &attributes );
+        memset( buffer, 0, byte_size + 1 );
+        PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) );
+        for( n = 0; n < byte_size; n++ )
+            TEST_EQUAL( buffer[n], 'K' );
+        for( n = byte_size; n < buffer_size; n++ )
+            TEST_EQUAL( buffer[n], 0 );
+    }
+
+exit:
+    psa_destroy_key( handle );
+    PSA_DONE( );
+    mbedtls_free( buffer );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
 {
     psa_key_handle_t handle = 0;
@@ -1314,6 +1480,7 @@
     PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
     TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
     TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
+    ASSERT_NO_SLOT_NUMBER( &got_attributes );
 
     /* Export the key */
     status = psa_export_key( handle,
@@ -4564,6 +4731,51 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void derive_key( int alg_arg,
+                 data_t *key_data, data_t *input1, data_t *input2,
+                 int type_arg, int bits_arg,
+                 int expected_status_arg )
+{
+    psa_key_handle_t base_handle = 0;
+    psa_key_handle_t derived_handle = 0;
+    psa_algorithm_t alg = alg_arg;
+    psa_key_type_t type = type_arg;
+    size_t bits = bits_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
+    psa_set_key_algorithm( &base_attributes, alg );
+    psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
+    PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
+                                &base_handle ) );
+
+    if( !setup_key_derivation_wrap( &operation, base_handle, alg,
+                                    input1->x, input1->len,
+                                    input2->x, input2->len, SIZE_MAX ) )
+        goto exit;
+
+    psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
+    psa_set_key_algorithm( &derived_attributes, 0 );
+    psa_set_key_type( &derived_attributes, type );
+    psa_set_key_bits( &derived_attributes, bits );
+    TEST_EQUAL( psa_key_derivation_output_key( &derived_attributes, &operation,
+                                               &derived_handle ),
+                expected_status );
+
+exit:
+    psa_key_derivation_abort( &operation );
+    psa_destroy_key( base_handle );
+    psa_destroy_key( derived_handle );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void key_agreement_setup( int alg_arg,
                           int our_key_type_arg, data_t *our_key_data,
                           data_t *peer_key_data,
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data
index 925c0f5..3f40d35 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.data
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.data
@@ -19,10 +19,10 @@
 # Not specific to files, but only run this test in an environment where the maximum size could be reached.
 Save maximum size persistent raw key
 depends_on:MBEDTLS_PSA_ITS_FILE_C
-save_large_persistent_key:0:PSA_SUCCESS
+save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE:PSA_SUCCESS
 
 Save larger than maximum size persistent raw key, should fail
-save_large_persistent_key:1:PSA_ERROR_INSUFFICIENT_STORAGE
+save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE + 1:PSA_ERROR_NOT_SUPPORTED
 
 Persistent key destroy
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index b76c733..115bfea 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -45,7 +45,7 @@
     file_data_length = key_data->len + sizeof( psa_persistent_key_storage_format );
     file_data = mbedtls_calloc( 1, file_data_length );
     psa_format_key_data_for_storage( key_data->x, key_data->len,
-                                     &attributes,
+                                     &attributes.core,
                                      file_data );
 
     ASSERT_COMPARE( expected_file_data->x, expected_file_data->len,
@@ -71,7 +71,7 @@
 
     status = psa_parse_key_data_from_storage( file_data->x, file_data->len,
                                               &key_data, &key_data_length,
-                                              &attributes );
+                                              &attributes.core );
 
     TEST_EQUAL( status, expected_status );
     if( status != PSA_SUCCESS )
@@ -96,17 +96,14 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void save_large_persistent_key( int data_too_large, int expected_status )
+void save_large_persistent_key( int data_length_arg, int expected_status )
 {
     psa_key_id_t key_id = 42;
     psa_key_handle_t handle = 0;
     uint8_t *data = NULL;
-    size_t data_length = PSA_CRYPTO_MAX_STORAGE_SIZE;
+    size_t data_length = data_length_arg;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
-    if( data_too_large )
-        data_length += 1;
-
     ASSERT_ALLOC( data, data_length );
 
     PSA_ASSERT( psa_crypto_init() );
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
index e0b8d29..9a57464 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -62,7 +62,8 @@
                                  psa_algorithm_t algorithm,
                                  psa_key_usage_t usage,
                                  const uint8_t *p_data,
-                                 size_t data_length )
+                                 size_t data_length,
+                                 size_t *bits )
 {
     (void) context;
     (void) slot_number;
@@ -71,7 +72,9 @@
     (void) algorithm;
     (void) usage;
     (void) p_data;
-    (void) data_length;
+    /* We're supposed to return a key size. Return one that's correct for
+     * plain data keys. */
+    *bits = PSA_BYTES_TO_BITS( data_length );
     return( PSA_SUCCESS );
 }
 
@@ -110,7 +113,8 @@
                                 psa_algorithm_t algorithm,
                                 psa_key_usage_t usage,
                                 const uint8_t *p_data,
-                                size_t data_length )
+                                size_t data_length,
+                                size_t *bits )
 {
     (void) context;
     DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
@@ -119,6 +123,7 @@
     ram_slots[slot_number].lifetime = lifetime;
     ram_slots[slot_number].type = type;
     ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length );
+    *bits = PSA_BYTES_TO_BITS( data_length );
     (void) algorithm;
     (void) usage;
     memcpy( ram_slots[slot_number].content, p_data, data_length );
@@ -178,6 +183,66 @@
 /* Other test helper functions */
 /****************************************************************/
 
+/* Check that the attributes of a key reported by psa_get_key_attributes()
+ * are consistent with the attributes used when creating the key. */
+static int check_key_attributes(
+    psa_key_handle_t handle,
+    const psa_key_attributes_t *reference_attributes )
+{
+    int ok = 0;
+    psa_key_attributes_t actual_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    PSA_ASSERT( psa_get_key_attributes( handle, &actual_attributes ) );
+
+    TEST_EQUAL( psa_get_key_id( &actual_attributes ),
+                psa_get_key_id( reference_attributes ) );
+    TEST_EQUAL( psa_get_key_lifetime( &actual_attributes ),
+                psa_get_key_lifetime( reference_attributes ) );
+    TEST_EQUAL( psa_get_key_type( &actual_attributes ),
+                psa_get_key_type( reference_attributes ) );
+    TEST_EQUAL( psa_get_key_usage_flags( &actual_attributes ),
+                psa_get_key_usage_flags( reference_attributes ) );
+    TEST_EQUAL( psa_get_key_algorithm( &actual_attributes ),
+                psa_get_key_algorithm( reference_attributes ) );
+    TEST_EQUAL( psa_get_key_enrollment_algorithm( &actual_attributes ),
+                psa_get_key_enrollment_algorithm( reference_attributes ) );
+    if( psa_get_key_bits( reference_attributes ) != 0 )
+    {
+        TEST_EQUAL( psa_get_key_bits( &actual_attributes ),
+                    psa_get_key_bits( reference_attributes ) );
+    }
+
+    {
+        psa_key_slot_number_t actual_slot_number = 0xdeadbeef;
+        psa_key_slot_number_t desired_slot_number = 0xb90cc011;
+        psa_key_lifetime_t lifetime =
+            psa_get_key_lifetime( &actual_attributes );
+        psa_status_t status = psa_get_key_slot_number( &actual_attributes,
+                                                       &actual_slot_number );
+        if( lifetime < MIN_DRIVER_LIFETIME )
+        {
+            /* The key is not in a secure element. */
+            TEST_EQUAL( status, PSA_ERROR_INVALID_ARGUMENT );
+        }
+        else
+        {
+            /* The key is in a secure element. If it had been created
+             * in a specific slot, check that it is reported there. */
+            PSA_ASSERT( status );
+            status = psa_get_key_slot_number( reference_attributes,
+                                              &desired_slot_number );
+            if( status == PSA_SUCCESS )
+            {
+                TEST_EQUAL( desired_slot_number, actual_slot_number );
+            }
+        }
+    }
+    ok = 1;
+
+exit:
+    return( ok );
+}
+
 /* Check that a function's return status is "smoke-free", i.e. that
  * it's an acceptable error code when calling an API function that operates
  * on a key with potentially bogus parameters. */
@@ -445,6 +510,14 @@
     /* Test that the key was created in the expected slot. */
     TEST_ASSERT( ram_slots[min_slot].type == PSA_KEY_TYPE_RAW_DATA );
 
+    /* Test the key attributes, including the reported slot number. */
+    psa_set_key_bits( &attributes,
+                      PSA_BYTES_TO_BITS( sizeof( key_material ) ) );
+    psa_set_key_slot_number( &attributes, min_slot );
+    if( ! check_key_attributes( handle, &attributes ) )
+        goto exit;
+
+    /* Test the key data. */
     PSA_ASSERT( psa_export_key( handle,
                                 exported, sizeof( exported ),
                                 &exported_length ) );
diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function
index 8b15005..a1d39bf 100644
--- a/tests/suites/test_suite_psa_its.function
+++ b/tests/suites/test_suite_psa_its.function
@@ -71,6 +71,7 @@
     uint32_t flags = flags_arg;
     struct psa_storage_info_t info;
     unsigned char *buffer = NULL;
+    size_t ret_len = 0;
 
     ASSERT_ALLOC( buffer, data->len );
 
@@ -79,8 +80,8 @@
     PSA_ASSERT( psa_its_get_info( uid, &info ) );
     TEST_ASSERT( info.size == data->len );
     TEST_ASSERT( info.flags == flags );
-    PSA_ASSERT( psa_its_get( uid, 0, data->len, buffer ) );
-    ASSERT_COMPARE( data->x, data->len, buffer, data->len );
+    PSA_ASSERT( psa_its_get( uid, 0, data->len, buffer, &ret_len ) );
+    ASSERT_COMPARE( data->x, data->len, buffer, ret_len );
 
     PSA_ASSERT( psa_its_remove( uid ) );
 
@@ -100,6 +101,7 @@
     uint32_t flags2 = flags2_arg;
     struct psa_storage_info_t info;
     unsigned char *buffer = NULL;
+    size_t ret_len = 0;
 
     ASSERT_ALLOC( buffer, MAX( data1->len, data2->len ) );
 
@@ -107,15 +109,16 @@
     PSA_ASSERT( psa_its_get_info( uid, &info ) );
     TEST_ASSERT( info.size == data1->len );
     TEST_ASSERT( info.flags == flags1 );
-    PSA_ASSERT( psa_its_get( uid, 0, data1->len, buffer ) );
-    ASSERT_COMPARE( data1->x, data1->len, buffer, data1->len );
+    PSA_ASSERT( psa_its_get( uid, 0, data1->len, buffer, &ret_len ) );
+    ASSERT_COMPARE( data1->x, data1->len, buffer, ret_len );
 
     PSA_ASSERT( psa_its_set_wrap( uid, data2->len, data2->x, flags2 ) );
     PSA_ASSERT( psa_its_get_info( uid, &info ) );
     TEST_ASSERT( info.size == data2->len );
     TEST_ASSERT( info.flags == flags2 );
-    PSA_ASSERT( psa_its_get( uid, 0, data2->len, buffer ) );
-    ASSERT_COMPARE( data2->x, data2->len, buffer, data2->len );
+    ret_len = 0;
+    PSA_ASSERT( psa_its_get( uid, 0, data2->len, buffer, &ret_len ) );
+    ASSERT_COMPARE( data2->x, data2->len, buffer, ret_len );
 
     PSA_ASSERT( psa_its_remove( uid ) );
 
@@ -132,6 +135,7 @@
     psa_storage_uid_t uid;
     char stored[40];
     char retrieved[40];
+    size_t ret_len = 0;
 
     memset( stored, '.', sizeof( stored ) );
     for( uid = uid0; uid < uid0 + count; uid++ )
@@ -145,11 +149,11 @@
     {
         mbedtls_snprintf( stored, sizeof( stored ),
                           "Content of file 0x%08lx", (unsigned long) uid );
-        PSA_ASSERT( psa_its_get( uid, 0, sizeof( stored ), retrieved ) );
-        ASSERT_COMPARE( retrieved, sizeof( stored ),
+        PSA_ASSERT( psa_its_get( uid, 0, sizeof( stored ), retrieved, &ret_len ) );
+        ASSERT_COMPARE( retrieved, ret_len,
                         stored, sizeof( stored ) );
         PSA_ASSERT( psa_its_remove( uid ) );
-        TEST_ASSERT( psa_its_get( uid, 0, 0, NULL ) ==
+        TEST_ASSERT( psa_its_get( uid, 0, 0, NULL, NULL ) ==
                      PSA_ERROR_DOES_NOT_EXIST );
     }
 
@@ -173,7 +177,7 @@
     TEST_ASSERT( psa_its_remove( uid ) == PSA_ERROR_DOES_NOT_EXIST );
     TEST_ASSERT( psa_its_get_info( uid, &info ) ==
                  PSA_ERROR_DOES_NOT_EXIST );
-    TEST_ASSERT( psa_its_get( uid, 0, 0, NULL ) ==
+    TEST_ASSERT( psa_its_get( uid, 0, 0, NULL, NULL ) ==
                  PSA_ERROR_DOES_NOT_EXIST );
 
 exit:
@@ -192,6 +196,7 @@
     size_t length = length_arg >= 0 ? length_arg : 0;
     unsigned char *trailer;
     size_t i;
+    size_t ret_len = 0;
 
     ASSERT_ALLOC( buffer, length + 16 );
     trailer = buffer + length;
@@ -199,11 +204,11 @@
 
     PSA_ASSERT( psa_its_set_wrap( uid, data->len, data->x, 0 ) );
 
-    status = psa_its_get( uid, offset, length_arg, buffer );
+    status = psa_its_get( uid, offset, length_arg, buffer, &ret_len );
     TEST_ASSERT( status == (psa_status_t) expected_status );
     if( status == PSA_SUCCESS )
-        ASSERT_COMPARE( data->x + offset, length,
-                        buffer, length );
+        ASSERT_COMPARE( data->x + offset, (size_t) length_arg,
+                        buffer, ret_len );
     for( i = 0; i < 16; i++ )
         TEST_ASSERT( trailer[i] == '-' );
     PSA_ASSERT( psa_its_remove( uid ) );
diff --git a/visualc/VS2010/aescrypt2.vcxproj b/visualc/VS2010/aescrypt2.vcxproj
index db387f9..63a124a 100644
--- a/visualc/VS2010/aescrypt2.vcxproj
+++ b/visualc/VS2010/aescrypt2.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/benchmark.vcxproj b/visualc/VS2010/benchmark.vcxproj
index 934c844..ffbd1ad 100644
--- a/visualc/VS2010/benchmark.vcxproj
+++ b/visualc/VS2010/benchmark.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/crypt_and_hash.vcxproj b/visualc/VS2010/crypt_and_hash.vcxproj
index 99199d9..fb7ef77 100644
--- a/visualc/VS2010/crypt_and_hash.vcxproj
+++ b/visualc/VS2010/crypt_and_hash.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/crypto_examples.vcxproj b/visualc/VS2010/crypto_examples.vcxproj
index 9ca6b64..2fa23a7 100644
--- a/visualc/VS2010/crypto_examples.vcxproj
+++ b/visualc/VS2010/crypto_examples.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/dh_genprime.vcxproj b/visualc/VS2010/dh_genprime.vcxproj
index d9c1900..fdd6c6f 100644
--- a/visualc/VS2010/dh_genprime.vcxproj
+++ b/visualc/VS2010/dh_genprime.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/ecdh_curve25519.vcxproj b/visualc/VS2010/ecdh_curve25519.vcxproj
index 1120111..748b6d1 100644
--- a/visualc/VS2010/ecdh_curve25519.vcxproj
+++ b/visualc/VS2010/ecdh_curve25519.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/ecdsa.vcxproj b/visualc/VS2010/ecdsa.vcxproj
index 3718c9f..03418d0 100644
--- a/visualc/VS2010/ecdsa.vcxproj
+++ b/visualc/VS2010/ecdsa.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/gen_entropy.vcxproj b/visualc/VS2010/gen_entropy.vcxproj
index 4c57655..89b41c0 100644
--- a/visualc/VS2010/gen_entropy.vcxproj
+++ b/visualc/VS2010/gen_entropy.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/gen_key.vcxproj b/visualc/VS2010/gen_key.vcxproj
index a07e1aa..c8ea11f 100644
--- a/visualc/VS2010/gen_key.vcxproj
+++ b/visualc/VS2010/gen_key.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/gen_random_ctr_drbg.vcxproj b/visualc/VS2010/gen_random_ctr_drbg.vcxproj
index 11740c4..64200af 100644
--- a/visualc/VS2010/gen_random_ctr_drbg.vcxproj
+++ b/visualc/VS2010/gen_random_ctr_drbg.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/gen_random_havege.vcxproj b/visualc/VS2010/gen_random_havege.vcxproj
index 01253ce..70c8138 100644
--- a/visualc/VS2010/gen_random_havege.vcxproj
+++ b/visualc/VS2010/gen_random_havege.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/generic_sum.vcxproj b/visualc/VS2010/generic_sum.vcxproj
index 0f2ecb4..21bd90f 100644
--- a/visualc/VS2010/generic_sum.vcxproj
+++ b/visualc/VS2010/generic_sum.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/hello.vcxproj b/visualc/VS2010/hello.vcxproj
index c986b07..b5f6eb0 100644
--- a/visualc/VS2010/hello.vcxproj
+++ b/visualc/VS2010/hello.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/key_app.vcxproj b/visualc/VS2010/key_app.vcxproj
index f96a0b0..0fc246a 100644
--- a/visualc/VS2010/key_app.vcxproj
+++ b/visualc/VS2010/key_app.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/key_app_writer.vcxproj b/visualc/VS2010/key_app_writer.vcxproj
index 0e4af3a..e4ef62b 100644
--- a/visualc/VS2010/key_app_writer.vcxproj
+++ b/visualc/VS2010/key_app_writer.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/key_ladder_demo.vcxproj b/visualc/VS2010/key_ladder_demo.vcxproj
index 80914ff..b8fe6a0 100644
--- a/visualc/VS2010/key_ladder_demo.vcxproj
+++ b/visualc/VS2010/key_ladder_demo.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 2034a84..2db9a16 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -158,7 +158,6 @@
     <ClInclude Include="..\..\include\mbedtls\bn_mul.h" />

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

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

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

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

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

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

diff --git a/visualc/VS2010/mpi_demo.vcxproj b/visualc/VS2010/mpi_demo.vcxproj
index d68bc75..d770d35 100644
--- a/visualc/VS2010/mpi_demo.vcxproj
+++ b/visualc/VS2010/mpi_demo.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/pem2der.vcxproj b/visualc/VS2010/pem2der.vcxproj
index 507c79a..2f1248c 100644
--- a/visualc/VS2010/pem2der.vcxproj
+++ b/visualc/VS2010/pem2der.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/pk_decrypt.vcxproj b/visualc/VS2010/pk_decrypt.vcxproj
index 5ccaf4f..168adf3 100644
--- a/visualc/VS2010/pk_decrypt.vcxproj
+++ b/visualc/VS2010/pk_decrypt.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/pk_encrypt.vcxproj b/visualc/VS2010/pk_encrypt.vcxproj
index d5ef208..bb09f06 100644
--- a/visualc/VS2010/pk_encrypt.vcxproj
+++ b/visualc/VS2010/pk_encrypt.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/pk_sign.vcxproj b/visualc/VS2010/pk_sign.vcxproj
index d21f17a..98941f4 100644
--- a/visualc/VS2010/pk_sign.vcxproj
+++ b/visualc/VS2010/pk_sign.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/pk_verify.vcxproj b/visualc/VS2010/pk_verify.vcxproj
index 637ddd6..6d3006e 100644
--- a/visualc/VS2010/pk_verify.vcxproj
+++ b/visualc/VS2010/pk_verify.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/psa_constant_names.vcxproj b/visualc/VS2010/psa_constant_names.vcxproj
index 2618c7c..41cb85b 100644
--- a/visualc/VS2010/psa_constant_names.vcxproj
+++ b/visualc/VS2010/psa_constant_names.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/query_compile_time_config.vcxproj b/visualc/VS2010/query_compile_time_config.vcxproj
index dcb6f32..8e7f07b 100644
--- a/visualc/VS2010/query_compile_time_config.vcxproj
+++ b/visualc/VS2010/query_compile_time_config.vcxproj
@@ -55,7 +55,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/rsa_decrypt.vcxproj b/visualc/VS2010/rsa_decrypt.vcxproj
index 9e1d0a2..ffba32a 100644
--- a/visualc/VS2010/rsa_decrypt.vcxproj
+++ b/visualc/VS2010/rsa_decrypt.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/rsa_encrypt.vcxproj b/visualc/VS2010/rsa_encrypt.vcxproj
index c3b0371..9f5f327 100644
--- a/visualc/VS2010/rsa_encrypt.vcxproj
+++ b/visualc/VS2010/rsa_encrypt.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/rsa_genkey.vcxproj b/visualc/VS2010/rsa_genkey.vcxproj
index e6b5060..824e304 100644
--- a/visualc/VS2010/rsa_genkey.vcxproj
+++ b/visualc/VS2010/rsa_genkey.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/rsa_sign.vcxproj b/visualc/VS2010/rsa_sign.vcxproj
index c1147c3..dda4756 100644
--- a/visualc/VS2010/rsa_sign.vcxproj
+++ b/visualc/VS2010/rsa_sign.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/rsa_sign_pss.vcxproj b/visualc/VS2010/rsa_sign_pss.vcxproj
index adfee6d..31da8ca 100644
--- a/visualc/VS2010/rsa_sign_pss.vcxproj
+++ b/visualc/VS2010/rsa_sign_pss.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/rsa_verify.vcxproj b/visualc/VS2010/rsa_verify.vcxproj
index bb44b4f..b78dfc3 100644
--- a/visualc/VS2010/rsa_verify.vcxproj
+++ b/visualc/VS2010/rsa_verify.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/rsa_verify_pss.vcxproj b/visualc/VS2010/rsa_verify_pss.vcxproj
index 7781aa5..220ad2d 100644
--- a/visualc/VS2010/rsa_verify_pss.vcxproj
+++ b/visualc/VS2010/rsa_verify_pss.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/selftest.vcxproj b/visualc/VS2010/selftest.vcxproj
index 12ff76d..1f5e109 100644
--- a/visualc/VS2010/selftest.vcxproj
+++ b/visualc/VS2010/selftest.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/strerror.vcxproj b/visualc/VS2010/strerror.vcxproj
index d7ec570..c3ec8fa 100644
--- a/visualc/VS2010/strerror.vcxproj
+++ b/visualc/VS2010/strerror.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/visualc/VS2010/zeroize.vcxproj b/visualc/VS2010/zeroize.vcxproj
index 9d311c7..dff71d3 100644
--- a/visualc/VS2010/zeroize.vcxproj
+++ b/visualc/VS2010/zeroize.vcxproj
@@ -54,7 +54,6 @@
     <UseDebugLibraries>false</UseDebugLibraries>

     <WholeProgramOptimization>true</WholeProgramOptimization>

     <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">