Merge pull request #80 from ARMmbed/psa-crypto_sizes_header_creation

Create psa/crypto_size.h
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index dcf1ba2..07ee000 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -900,8 +900,8 @@
  * - For Triple-DES, the format is the concatenation of the
  *   two or three DES keys.
  * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEYPAIR), the format
- *   is the non-encrypted DER representation defined by PKCS\#8 (RFC 5208)
- *   as PrivateKeyInfo.
+ *   is the non-encrypted DER representation defined by PKCS\#1 (RFC 8017)
+ *   as RSAPrivateKey.
  * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the format
  *   is the DER representation defined by RFC 5280 as SubjectPublicKeyInfo.
  *
@@ -1333,28 +1333,6 @@
  * as directed by the documentation of a specific implementation. */
 typedef struct psa_mac_operation_s psa_mac_operation_t;
 
-/** The size of the output of psa_mac_finish(), in bytes.
- *
- * This is also the MAC size that psa_mac_verify() expects.
- *
- * \param key_type      The type of the MAC key.
- * \param key_bits      The size of the MAC key in bits.
- * \param alg           A MAC algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_MAC(alg) is true).
- *
- * \return              The MAC size for the specified algorithm with
- *                      the specified key parameters.
- * \return              0 if the MAC algorithm is not recognized.
- * \return              Either 0 or the correct size for a MAC algorithm that
- *                      the implementation recognizes, but does not support.
- * \return              Unspecified if the key parameters are not consistent
- *                      with the algorithm.
- */
-#define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg)                     \
-    (PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg)) : \
-     PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
-     0)
-
 /** Start a multipart MAC operation.
  *
  * The sequence of operations to calculate a MAC (message authentication code)
@@ -1575,30 +1553,6 @@
      (alg) == PSA_ALG_CCM ? 16 :           \
      0)
 
-/** The maximum size of the output of psa_aead_encrypt(), in bytes.
- *
- * If the size of the ciphertext buffer is at least this large, it is
- * guaranteed that psa_aead_encrypt() will not fail due to an
- * insufficient buffer size. Depending on the algorithm, the actual size of
- * the ciphertext may be smaller.
- *
- * \param alg                 An AEAD algorithm
- *                            (\c PSA_ALG_XXX value such that
- *                            #PSA_ALG_IS_AEAD(alg) is true).
- * \param plaintext_length    Size of the plaintext in bytes.
- *
- * \return                    The AEAD ciphertext size for the specified
- *                            algorithm.
- *                            If the AEAD algorithm is not recognized, return 0.
- *                            An implementation may return either 0 or a
- *                            correct size for an AEAD algorithm that it
- *                            recognizes, but does not support.
- */
-#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length)     \
-    (PSA_AEAD_TAG_SIZE(alg) != 0 ?                              \
-     (plaintext_length) + PSA_AEAD_TAG_SIZE(alg) :              \
-     0)
-
 /** Process an authenticated encryption operation.
  *
  * \param key                     Slot containing the key to use.
@@ -1652,30 +1606,6 @@
                                size_t ciphertext_size,
                                size_t *ciphertext_length );
 
-/** The maximum size of the output of psa_aead_decrypt(), in bytes.
- *
- * If the size of the plaintext buffer is at least this large, it is
- * guaranteed that psa_aead_decrypt() will not fail due to an
- * insufficient buffer size. Depending on the algorithm, the actual size of
- * the plaintext may be smaller.
- *
- * \param alg                 An AEAD algorithm
- *                            (\c PSA_ALG_XXX value such that
- *                            #PSA_ALG_IS_AEAD(alg) is true).
- * \param ciphertext_length   Size of the plaintext in bytes.
- *
- * \return                    The AEAD ciphertext size for the specified
- *                            algorithm.
- *                            If the AEAD algorithm is not recognized, return 0.
- *                            An implementation may return either 0 or a
- *                            correct size for an AEAD algorithm that it
- *                            recognizes, but does not support.
- */
-#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length)    \
-    (PSA_AEAD_TAG_SIZE(alg) != 0 ?                              \
-     (plaintext_length) - PSA_AEAD_TAG_SIZE(alg) :              \
-     0)
-
 /** Process an authenticated decryption operation.
  *
  * \param key                     Slot containing the key to use.
@@ -1746,38 +1676,6 @@
 #define PSA_ECDSA_SIGNATURE_SIZE(curve_bits)    \
     (PSA_BITS_TO_BYTES(curve_bits) * 2)
 
-/** Safe signature buffer size for psa_asymmetric_sign().
- *
- * This macro returns a safe buffer size for a signature using a key
- * of the specified type and size, with the specified algorithm.
- * Note that the actual size of the signature may be smaller
- * (some algorithms produce a variable-size signature).
- *
- * \warning This function may call its arguments multiple times or
- *          zero times, so you should not pass arguments that contain
- *          side effects.
- *
- * \param key_type  An asymmetric key type (this may indifferently be a
- *                  key pair type or a public key type).
- * \param key_bits  The size of the key in bits.
- * \param alg       The signature algorithm.
- *
- * \return If the parameters are valid and supported, return
- *         a buffer size in bytes that guarantees that
- *         psa_asymmetric_sign() will not fail with
- *         #PSA_ERROR_BUFFER_TOO_SMALL.
- *         If the parameters are a valid combination that is not supported
- *         by the implementation, this macro either shall return either a
- *         sensible size or 0.
- *         If the parameters are not valid, the
- *         return value is unspecified.
- *
- */
-#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE(key_type, key_bits, alg)        \
-    (PSA_KEY_TYPE_IS_RSA(key_type) ? ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
-     PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
-     ((void)alg, 0))
-
 /**
  * \brief Sign a hash or short message with a private key.
  *
@@ -1880,18 +1778,10 @@
                                    const uint8_t *signature,
                                    size_t signature_length);
 
-#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg)     \
-    (PSA_KEY_TYPE_IS_RSA(key_type) ?                                    \
-     ((void)alg, PSA_BITS_TO_BYTES(key_bits)) :                         \
-     0)
 #define PSA_RSA_MINIMUM_PADDING_SIZE(alg)                               \
     (PSA_ALG_IS_RSA_OAEP_MGF1(alg) ?                                    \
      2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_GET_HASH(alg)) + 1 :           \
      11 /*PKCS#1v1.5*/)
-#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg)     \
-    (PSA_KEY_TYPE_IS_RSA(key_type) ?                                    \
-     PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) :  \
-     0)
 
 /**
  * \brief Encrypt a short message with a public key.
@@ -2070,6 +1960,10 @@
 }
 #endif
 
+/* The file "crypto_sizes.h" contains definitions for size calculation
+ * macros whose definitions are implementation-specific. */
+#include "crypto_sizes.h"
+
 /* The file "crypto_struct.h" contains definitions for
  * implementation-specific structs that are declared above. */
 #include "crypto_struct.h"
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index b9e12bb..2d03f73 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -2,6 +2,11 @@
  * \file psa/crypto_extra.h
  *
  * \brief PSA cryptography module: Mbed TLS vendor extensions
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file is reserved for vendor-specific definitions.
  */
 /*
  *  Copyright (C) 2018, ARM Limited, All Rights Reserved
diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h
index 7aabd1b..9af320d 100644
--- a/include/psa/crypto_platform.h
+++ b/include/psa/crypto_platform.h
@@ -2,6 +2,16 @@
  * \file psa/crypto_platform.h
  *
  * \brief PSA cryptography module: Mbed TLS platfom definitions
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains platform-dependent type definitions.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, implementers should take care to ensure that
+ * the definitions that are exposed to applications match what the
+ * module implements.
  */
 /*
  *  Copyright (C) 2018, ARM Limited, All Rights Reserved
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
new file mode 100644
index 0000000..80b2f9d
--- /dev/null
+++ b/include/psa/crypto_sizes.h
@@ -0,0 +1,256 @@
+/**
+ * \file psa/crypto_sizes.h
+ *
+ * \brief PSA cryptography module: Mbed TLS buffer size macros
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains the definitions of macros that are useful to
+ * compute buffer sizes. The signatures and semantics of these macros
+ * are standardized, but the definitions are not, because they depend on
+ * the available algorithms and, in some cases, on permitted tolerances
+ * on buffer sizes.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, implementers should take care to ensure that
+ * the definitions that are exposed to applications match what the
+ * module implements.
+ *
+ * Macros that compute sizes whose values do not depend on the
+ * implementation are in crypto.h.
+ */
+/*
+ *  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef PSA_CRYPTO_SIZES_H
+#define PSA_CRYPTO_SIZES_H
+
+/* 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"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/** \def PSA_HASH_MAX_SIZE
+ *
+ * Maximum size of a hash.
+ *
+ * This macro must expand to a compile-time constant integer. This value
+ * should be the maximum size of a hash supported by the implementation,
+ * in bytes, and must be no smaller than this maximum.
+ */
+#if defined(MBEDTLS_SHA512_C)
+#define PSA_HASH_MAX_SIZE 64
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
+#else
+#define PSA_HASH_MAX_SIZE 32
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
+#endif
+
+/** \def PSA_MAC_MAX_SIZE
+ *
+ * Maximum size of a MAC.
+ *
+ * This macro must expand to a compile-time constant integer. This value
+ * should be the maximum size of a MAC supported by the implementation,
+ * in bytes, and must be no smaller than this maximum.
+ */
+/* All non-HMAC MACs have a maximum size that's smaller than the
+ * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */
+#define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE
+
+/* The maximum size of an RSA key on this implementation, in bits.
+ * This is a vendor-specific macro.
+ *
+ * Mbed TLS does not set a hard limit on the size of RSA keys: any key
+ * whose parameters fit in a bignum is accepted. However large keys can
+ * induce a large memory usage and long computation times. Unlike other
+ * auxiliary macros in this file and in crypto.h, which reflect how the
+ * library is configured, this macro defines how the library is
+ * configured. This implementation refuses to import or generate an
+ * RSA key whose size is larger than the value defined here.
+ *
+ * Note that an implementation may set different size limits for different
+ * operations, and does not need to accept all key sizes up to the limit. */
+#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096
+
+/* The maximum size of an ECC key on this implementation, in bits.
+ * This is a vendor-specific macro. */
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521
+#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 512
+#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 448
+#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384
+#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384
+#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256
+#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256
+#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256
+#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 255
+#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224
+#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224
+#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192
+#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192
+#else
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 0
+#endif
+
+/** \def PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE
+ *
+ * Maximum size of an asymmetric signature.
+ *
+ * This macro must expand to a compile-time constant integer. This value
+ * should be the maximum size of a MAC supported by the implementation,
+ * in bytes, and must be no smaller than this maximum.
+ */
+#define PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE                               \
+    PSA_BITS_TO_BYTES(                                                  \
+        PSA_VENDOR_RSA_MAX_KEY_BITS > PSA_VENDOR_ECC_MAX_CURVE_BITS ?   \
+        PSA_VENDOR_RSA_MAX_KEY_BITS :                                   \
+        PSA_VENDOR_ECC_MAX_CURVE_BITS                                   \
+        )
+
+
+
+/** The size of the output of psa_mac_finish(), in bytes.
+ *
+ * This is also the MAC size that psa_mac_verify() expects.
+ *
+ * \param key_type      The type of the MAC key.
+ * \param key_bits      The size of the MAC key in bits.
+ * \param alg           A MAC algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_MAC(alg) is true).
+ *
+ * \return              The MAC size for the specified algorithm with
+ *                      the specified key parameters.
+ * \return              0 if the MAC algorithm is not recognized.
+ * \return              Either 0 or the correct size for a MAC algorithm that
+ *                      the implementation recognizes, but does not support.
+ * \return              Unspecified if the key parameters are not consistent
+ *                      with the algorithm.
+ */
+#define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg)                     \
+    (PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg)) : \
+     PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+     0)
+
+/** The maximum size of the output of psa_aead_encrypt(), in bytes.
+ *
+ * If the size of the ciphertext buffer is at least this large, it is
+ * guaranteed that psa_aead_encrypt() will not fail due to an
+ * insufficient buffer size. Depending on the algorithm, the actual size of
+ * the ciphertext may be smaller.
+ *
+ * \param alg                 An AEAD algorithm
+ *                            (\c PSA_ALG_XXX value such that
+ *                            #PSA_ALG_IS_AEAD(alg) is true).
+ * \param plaintext_length    Size of the plaintext in bytes.
+ *
+ * \return                    The AEAD ciphertext size for the specified
+ *                            algorithm.
+ *                            If the AEAD algorithm is not recognized, return 0.
+ *                            An implementation may return either 0 or a
+ *                            correct size for an AEAD algorithm that it
+ *                            recognizes, but does not support.
+ */
+#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length)     \
+    (PSA_AEAD_TAG_SIZE(alg) != 0 ?                              \
+     (plaintext_length) + PSA_AEAD_TAG_SIZE(alg) :              \
+     0)
+
+/** The maximum size of the output of psa_aead_decrypt(), in bytes.
+ *
+ * If the size of the plaintext buffer is at least this large, it is
+ * guaranteed that psa_aead_decrypt() will not fail due to an
+ * insufficient buffer size. Depending on the algorithm, the actual size of
+ * the plaintext may be smaller.
+ *
+ * \param alg                 An AEAD algorithm
+ *                            (\c PSA_ALG_XXX value such that
+ *                            #PSA_ALG_IS_AEAD(alg) is true).
+ * \param ciphertext_length   Size of the plaintext in bytes.
+ *
+ * \return                    The AEAD ciphertext size for the specified
+ *                            algorithm.
+ *                            If the AEAD algorithm is not recognized, return 0.
+ *                            An implementation may return either 0 or a
+ *                            correct size for an AEAD algorithm that it
+ *                            recognizes, but does not support.
+ */
+#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length)    \
+    (PSA_AEAD_TAG_SIZE(alg) != 0 ?                              \
+     (plaintext_length) - PSA_AEAD_TAG_SIZE(alg) :              \
+     0)
+
+/** Safe signature buffer size for psa_asymmetric_sign().
+ *
+ * This macro returns a safe buffer size for a signature using a key
+ * of the specified type and size, with the specified algorithm.
+ * Note that the actual size of the signature may be smaller
+ * (some algorithms produce a variable-size signature).
+ *
+ * \warning This function may call its arguments multiple times or
+ *          zero times, so you should not pass arguments that contain
+ *          side effects.
+ *
+ * \param key_type  An asymmetric key type (this may indifferently be a
+ *                  key pair type or a public key type).
+ * \param key_bits  The size of the key in bits.
+ * \param alg       The signature algorithm.
+ *
+ * \return If the parameters are valid and supported, return
+ *         a buffer size in bytes that guarantees that
+ *         psa_asymmetric_sign() will not fail with
+ *         #PSA_ERROR_BUFFER_TOO_SMALL.
+ *         If the parameters are a valid combination that is not supported
+ *         by the implementation, this macro either shall return either a
+ *         sensible size or 0.
+ *         If the parameters are not valid, the
+ *         return value is unspecified.
+ *
+ */
+#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE(key_type, key_bits, alg)        \
+    (PSA_KEY_TYPE_IS_RSA(key_type) ? ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
+     PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
+     ((void)alg, 0))
+
+#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg)     \
+    (PSA_KEY_TYPE_IS_RSA(key_type) ?                                    \
+     ((void)alg, PSA_BITS_TO_BYTES(key_bits)) :                         \
+     0)
+#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg)     \
+    (PSA_KEY_TYPE_IS_RSA(key_type) ?                                    \
+     PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) :  \
+     0)
+
+#endif /* PSA_CRYPTO_SIZES_H */
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 0dbd86c..b981f23 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -2,6 +2,16 @@
  * \file psa/crypto_struct.h
  *
  * \brief PSA cryptography module: Mbed TLS structured type implementations
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains the definitions of some data structures with
+ * implementation-specific definitions.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, it is expected that the front-end and the back-end
+ * would have different versions of this file.
  */
 /*
  *  Copyright (C) 2018, ARM Limited, All Rights Reserved
@@ -45,14 +55,6 @@
 #include "mbedtls/sha256.h"
 #include "mbedtls/sha512.h"
 
-#if defined(MBEDTLS_SHA512_C)
-#define PSA_HASH_MAX_SIZE 64
-#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
-#else
-#define PSA_HASH_MAX_SIZE 32
-#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
-#endif
-
 struct psa_hash_operation_s
 {
     psa_algorithm_t alg;
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 1d8eb50..8ce668c 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -502,7 +502,13 @@
             case MBEDTLS_PK_RSA:
                 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
                     type == PSA_KEY_TYPE_RSA_KEYPAIR )
-                    slot->data.rsa = mbedtls_pk_rsa( pk );
+                {
+                    mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk );
+                    size_t bits = mbedtls_rsa_get_bitlen( rsa );
+                    if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
+                        return( PSA_ERROR_NOT_SUPPORTED );
+                    slot->data.rsa = rsa;
+                }
                 else
                     status = PSA_ERROR_INVALID_ARGUMENT;
                 break;
@@ -1579,10 +1585,6 @@
                                      mac_size, mac_length ) );
 }
 
-#define PSA_MAC_MAX_SIZE                                \
-    ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ?  \
-      MBEDTLS_MD_MAX_SIZE :                             \
-      MBEDTLS_MAX_BLOCK_LENGTH )
 psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
                              const uint8_t *mac,
                              size_t mac_length )
@@ -2862,6 +2864,8 @@
         mbedtls_rsa_context *rsa;
         int ret;
         int exponent = 65537;
+        if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
+            return( PSA_ERROR_NOT_SUPPORTED );
         if( parameters != NULL )
         {
             const unsigned *p = parameters;
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 1181fcd..b281cb3 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -129,6 +129,12 @@
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_RSA_C
 import:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):PSA_ERROR_INVALID_ARGUMENT
 
+PSA import RSA key pair: maximum size exceeded
+import_rsa_made_up:PSA_VENDOR_RSA_MAX_KEY_BITS+8:1:PSA_ERROR_NOT_SUPPORTED
+
+PSA import RSA public key: maximum size exceeded
+import_rsa_made_up:PSA_VENDOR_RSA_MAX_KEY_BITS+8:0:PSA_ERROR_NOT_SUPPORTED
+
 PSA key policy set and get
 key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE
 
@@ -681,6 +687,9 @@
 depends_on:MBEDTLS_RSA_C
 generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS
 
+PSA generate key: RSA, maximum size exceeded
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:PSA_VENDOR_RSA_MAX_KEY_BITS+1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED
+
 PSA generate key: ECC, SECP256R1, good
 depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_C
 generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 1959e13..0d1a25c 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -1,5 +1,6 @@
 /* BEGIN_HEADER */
 #include <stdint.h>
+#include "mbedtls/asn1write.h"
 #include "psa/crypto.h"
 
 #if(UINT32_MAX > SIZE_MAX)
@@ -37,13 +38,95 @@
             category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
 }
 
+/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
+static int asn1_write_10x( unsigned char **p,
+                           unsigned char *start,
+                           size_t bits,
+                           unsigned char x )
+{
+    int ret;
+    int len = bits / 8 + 1;
+    if( x >= 1 << bits )
+        return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+    if( *p < start || *p - start < (ssize_t) len )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+    *p -= len;
+    ( *p )[len-1] = x;
+    if( bits % 8 == 0 )
+        ( *p )[1] |= 1;
+    else
+        ( *p )[0] |= 1 << ( bits % 8 );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
+                                                       MBEDTLS_ASN1_INTEGER ) );
+    return( len );
+}
+
+static int construct_fake_rsa_key( unsigned char *buffer,
+                                   size_t buffer_size,
+                                   unsigned char **p,
+                                   size_t bits,
+                                   int keypair )
+{
+    size_t half_bits = ( bits + 1 ) / 2;
+    int ret;
+    int len = 0;
+    /* Construct something that looks like a DER encoding of
+     * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
+     *   RSAPrivateKey ::= SEQUENCE {
+     *       version           Version,
+     *       modulus           INTEGER,  -- n
+     *       publicExponent    INTEGER,  -- e
+     *       privateExponent   INTEGER,  -- d
+     *       prime1            INTEGER,  -- p
+     *       prime2            INTEGER,  -- q
+     *       exponent1         INTEGER,  -- d mod (p-1)
+     *       exponent2         INTEGER,  -- d mod (q-1)
+     *       coefficient       INTEGER,  -- (inverse of q) mod p
+     *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
+     *   }
+     * Or, for a public key, the same structure with only
+     * version, modulus and publicExponent.
+     */
+    *p = buffer + buffer_size;
+    if( keypair )
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, /* pq */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDTLS_ASN1_CHK_ADD( len, /* dq */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDTLS_ASN1_CHK_ADD( len, /* dp */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDTLS_ASN1_CHK_ADD( len, /* q */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
+                              asn1_write_10x( p, buffer, half_bits, 3 ) );
+        MBEDTLS_ASN1_CHK_ADD( len, /* d */
+                              asn1_write_10x( p, buffer, bits, 1 ) );
+    }
+    MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
+                          asn1_write_10x( p, buffer, 17, 1 ) );
+    MBEDTLS_ASN1_CHK_ADD( len, /* n */
+                          asn1_write_10x( p, buffer, bits, 1 ) );
+    if( keypair )
+        MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
+                              mbedtls_asn1_write_int( p, buffer, 0 ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
+    {
+        const unsigned char tag =
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
+    }
+    return( len );
+}
+
 static int exercise_mac_key( psa_key_slot_t key,
                              psa_key_usage_t usage,
                              psa_algorithm_t alg )
 {
     psa_mac_operation_t operation;
     const unsigned char input[] = "foo";
-    unsigned char mac[64] = {0};
+    unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
     size_t mac_length = sizeof( mac );
 
     if( usage & PSA_KEY_USAGE_SIGN )
@@ -191,7 +274,7 @@
 {
     unsigned char payload[16] = {1};
     size_t payload_length = sizeof( payload );
-    unsigned char signature[256] = {0};
+    unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
     size_t signature_length = sizeof( signature );
 
     if( usage & PSA_KEY_USAGE_SIGN )
@@ -305,6 +388,41 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
+{
+    int slot = 1;
+    size_t bits = bits_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_status_t status;
+    psa_key_type_t type =
+        keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
+    size_t buffer_size = /* Slight overapproximations */
+        keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
+    unsigned char *buffer = mbedtls_calloc( 1, buffer_size );
+    unsigned char *p;
+    int ret;
+    size_t length;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    TEST_ASSERT( buffer != NULL );
+
+    TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
+                                                 bits, keypair ) ) >= 0 );
+    length = ret;
+
+    /* Try importing the key */
+    status = psa_import_key( slot, type, p, length );
+    TEST_ASSERT( status == expected_status );
+    if( status == PSA_SUCCESS )
+        TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
+
+exit:
+    mbedtls_free( buffer );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void import_export( data_t *data,
                     int type_arg,
                     int alg_arg,
@@ -709,6 +827,9 @@
     size_t actual_hash_length;
     psa_hash_operation_t operation;
 
+    TEST_ASSERT( expected_hash->len == PSA_HASH_SIZE( alg ) );
+    TEST_ASSERT( expected_hash->len <= PSA_HASH_MAX_SIZE );
+
     TEST_ASSERT( input != NULL );
     TEST_ASSERT( expected_hash != NULL );
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
@@ -737,6 +858,9 @@
     psa_algorithm_t alg = alg_arg;
     psa_hash_operation_t operation;
 
+    TEST_ASSERT( expected_hash->len == PSA_HASH_SIZE( alg ) );
+    TEST_ASSERT( expected_hash->len <= PSA_HASH_MAX_SIZE );
+
     TEST_ASSERT( input != NULL );
     TEST_ASSERT( expected_hash != NULL );
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
@@ -805,6 +929,8 @@
     psa_mac_operation_t operation;
     psa_key_policy_t policy;
 
+    TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
+
     TEST_ASSERT( key != NULL );
     TEST_ASSERT( input != NULL );
     TEST_ASSERT( expected_mac != NULL );
@@ -1594,6 +1720,7 @@
     signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
                                                       key_bits, alg );
     TEST_ASSERT( signature_size != 0 );
+    TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
     signature = mbedtls_calloc( 1, signature_size );
     TEST_ASSERT( signature != NULL );
 
@@ -1677,6 +1804,8 @@
     psa_algorithm_t alg = alg_arg;
     psa_key_policy_t policy;
 
+    TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
+
     TEST_ASSERT( key_data != NULL );
     TEST_ASSERT( hash_data != NULL );
     TEST_ASSERT( signature_data != NULL );