Merge tag 'mbedtls-2.16.0' into all_sh-2.14

Merge the work on all.sh that was done on mbedtls-2.14.0 with the
changes from mbedtls-2.14.0 to mbedtls-2.16.0.

There is a merge conflict in test/scripts/all.sh, which is the only
file that was modified in the all.sh work branch. I resolved it by
taking the copy from the all.sh branch and applying the changes
between mbedtls-2.14.0 and mbedtls-2.16.0. These changes consisted of
two commits:

* "Add tests to all.sh for CHECK_PARAMS edge cases": adds two
  test components which are reproduced here as
  test_check_params_without_platform and component_test_check_params_silent.
* "tests: Backup config.h before modifying it": moot because the
  component framework introduced in the all.sh branch backs up config.h
  systematically.
diff --git a/.travis.yml b/.travis.yml
index 4d23652..4fc31c9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,13 @@
 - gcc
 sudo: false
 cache: ccache
+
+# blocklist
+branches:
+  except:
+  - development-psa
+  - coverity_scan
+
 script:
 - tests/scripts/recursion.pl library/*.c
 - tests/scripts/check-generated-files.sh
@@ -34,7 +41,7 @@
   coverity_scan:
     project:
       name: "ARMmbed/mbedtls"
-    notification_email: p.j.bakker@polarssl.org
+    notification_email: simon.butcher@arm.com
     build_command_prepend:
     build_command: make
     branch_pattern: coverity_scan
diff --git a/ChangeLog b/ChangeLog
index 8f0e8c1..be28645 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,91 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
+= mbed TLS 2.16.0 branch released 2018-12-21
+
+Features
+   * Add a new config.h option of MBEDTLS_CHECK_PARAMS that enables validation
+     of parameters in the API. This allows detection of obvious misuses of the
+     API, such as passing NULL pointers. The API of existing functions hasn't
+     changed, but requirements on parameters have been made more explicit in
+     the documentation. See the corresponding API documentation for each
+     function to see for which parameter values it is defined. This feature is
+     disabled by default. See its API documentation in config.h for additional
+     steps you have to take when enabling it.
+
+API Changes
+   * The following functions in the random generator modules have been
+     deprecated and replaced as shown below. The new functions change
+     the return type from void to int to allow returning error codes when
+     using MBEDTLS_<MODULE>_ALT for the underlying AES or message digest
+     primitive. Fixes #1798.
+     mbedtls_ctr_drbg_update() -> mbedtls_ctr_drbg_update_ret()
+     mbedtls_hmac_drbg_update() -> mbedtls_hmac_drbg_update_ret()
+   * Extend ECDH interface to enable alternative implementations.
+   * Deprecate error codes of the form MBEDTLS_ERR_xxx_INVALID_KEY_LENGTH for
+     ARIA, CAMELLIA and Blowfish. These error codes will be replaced by
+     the more generic per-module error codes MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
+   * Additional parameter validation checks have been added for the following
+     modules - AES, ARIA, Blowfish, CAMELLIA, CCM, GCM, DHM, ECP, ECDSA, ECDH,
+     ECJPAKE, SHA, Chacha20 and Poly1305, cipher, pk, RSA, and MPI.
+     Where modules have had parameter validation added, existing parameter
+     checks may have changed. Some modules, such as Chacha20 had existing
+     parameter validation whereas other modules had little. This has now been
+     changed so that the same level of validation is present in all modules, and
+     that it is now optional with the MBEDTLS_CHECK_PARAMS flag which by default
+     is off. That means that checks which were previously present by default
+     will no longer be.
+
+New deprecations
+   * Deprecate mbedtls_ctr_drbg_update and mbedtls_hmac_drbg_update
+     in favor of functions that can return an error code.
+
+Bugfix
+   * Fix for Clang, which was reporting a warning for the bignum.c inline
+     assembly for AMD64 targets creating string literals greater than those
+     permitted by the ISO C99 standard. Found by Aaron Jones. Fixes #482.
+   * Fix runtime error in `mbedtls_platform_entropy_poll()` when run
+     through qemu user emulation. Reported and fix suggested by randombit
+     in #1212. Fixes #1212.
+   * Fix an unsafe bounds check when restoring an SSL session from a ticket.
+     This could lead to a buffer overflow, but only in case ticket authentication
+     was broken. Reported and fix suggested by Guido Vranken in #659.
+   * Add explicit integer to enumeration type casts to example program
+     programs/pkey/gen_key which previously led to compilation failure
+     on some toolchains. Reported by phoenixmcallister. Fixes #2170.
+   * Fix double initialization of ECC hardware that made some accelerators
+     hang.
+   * Clarify documentation of mbedtls_ssl_set_own_cert() regarding the absence
+     of check for certificate/key matching. Reported by Attila Molnar, #507.
+
+= mbed TLS 2.14.1 branch released 2018-11-30
+
+Security
+   * Fix timing variations and memory access variations in RSA PKCS#1 v1.5
+     decryption that could lead to a Bleichenbacher-style padding oracle
+     attack. In TLS, this affects servers that accept ciphersuites based on
+     RSA decryption (i.e. ciphersuites whose name contains RSA but not
+     (EC)DH(E)). Discovered by Eyal Ronen (Weizmann Institute),  Robert Gillham
+     (University of Adelaide), Daniel Genkin (University of Michigan),
+     Adi Shamir (Weizmann Institute), David Wong (NCC Group), and Yuval Yarom
+     (University of Adelaide, Data61). The attack is described in more detail
+     in the paper available here: http://cat.eyalro.net/cat.pdf  CVE-2018-19608
+   * In mbedtls_mpi_write_binary(), don't leak the exact size of the number
+     via branching and memory access patterns. An attacker who could submit
+     a plaintext for RSA PKCS#1 v1.5 decryption but only observe the timing
+     of the decryption and not its result could nonetheless decrypt RSA
+     plaintexts and forge RSA signatures. Other asymmetric algorithms may
+     have been similarly vulnerable. Reported by Eyal Ronen, Robert Gillham,
+     Daniel Genkin, Adi Shamir, David Wong and Yuval Yarom.
+   * Wipe sensitive buffers on the stack in the CTR_DRBG and HMAC_DRBG
+     modules.
+
+API Changes
+   * The new functions mbedtls_ctr_drbg_update_ret() and
+     mbedtls_hmac_drbg_update_ret() are similar to mbedtls_ctr_drbg_update()
+     and mbedtls_hmac_drbg_update() respectively, but the new functions
+     report errors whereas the old functions return void. We recommend that
+     applications use the new functions.
+
 = mbed TLS 2.14.0 branch released 2018-11-19
 
 Security
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 44280d2..ffc3cec 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -24,7 +24,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.14.0 source code documentation
+ * @mainpage mbed TLS v2.16.0 source code documentation
  *
  * This documentation describes the internal structure of mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index fd22cdb..574db8d 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.14.0"
+PROJECT_NAME           = "mbed TLS v2.16.0"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index cfb20c4..b42e564 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -121,7 +121,7 @@
  *                 It must be the first API called before using
  *                 the context.
  *
- * \param ctx      The AES context to initialize.
+ * \param ctx      The AES context to initialize. This must not be \c NULL.
  */
 void mbedtls_aes_init( mbedtls_aes_context *ctx );
 
@@ -129,6 +129,8 @@
  * \brief          This function releases and clears the specified AES context.
  *
  * \param ctx      The AES context to clear.
+ *                 If this is \c NULL, this function does nothing.
+ *                 Otherwise, the context must have been at least initialized.
  */
 void mbedtls_aes_free( mbedtls_aes_context *ctx );
 
@@ -139,7 +141,7 @@
  *                 It must be the first API called before using
  *                 the context.
  *
- * \param ctx      The AES XTS context to initialize.
+ * \param ctx      The AES XTS context to initialize. This must not be \c NULL.
  */
 void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
 
@@ -147,6 +149,8 @@
  * \brief          This function releases and clears the specified AES XTS context.
  *
  * \param ctx      The AES XTS context to clear.
+ *                 If this is \c NULL, this function does nothing.
+ *                 Otherwise, the context must have been at least initialized.
  */
 void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
 #endif /* MBEDTLS_CIPHER_MODE_XTS */
@@ -155,7 +159,9 @@
  * \brief          This function sets the encryption key.
  *
  * \param ctx      The AES context to which the key should be bound.
+ *                 It must be initialized.
  * \param key      The encryption key.
+ *                 This must be a readable buffer of size \p keybits bits.
  * \param keybits  The size of data passed in bits. Valid options are:
  *                 <ul><li>128 bits</li>
  *                 <li>192 bits</li>
@@ -171,7 +177,9 @@
  * \brief          This function sets the decryption key.
  *
  * \param ctx      The AES context to which the key should be bound.
+ *                 It must be initialized.
  * \param key      The decryption key.
+ *                 This must be a readable buffer of size \p keybits bits.
  * \param keybits  The size of data passed. Valid options are:
  *                 <ul><li>128 bits</li>
  *                 <li>192 bits</li>
@@ -189,8 +197,10 @@
  *                 sets the encryption key.
  *
  * \param ctx      The AES XTS context to which the key should be bound.
+ *                 It must be initialized.
  * \param key      The encryption key. This is comprised of the XTS key1
  *                 concatenated with the XTS key2.
+ *                 This must be a readable buffer of size \p keybits bits.
  * \param keybits  The size of \p key passed in bits. Valid options are:
  *                 <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
  *                 <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
@@ -207,8 +217,10 @@
  *                 sets the decryption key.
  *
  * \param ctx      The AES XTS context to which the key should be bound.
+ *                 It must be initialized.
  * \param key      The decryption key. This is comprised of the XTS key1
  *                 concatenated with the XTS key2.
+ *                 This must be a readable buffer of size \p keybits bits.
  * \param keybits  The size of \p key passed in bits. Valid options are:
  *                 <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
  *                 <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
@@ -234,10 +246,13 @@
  *                 call to this API with the same context.
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT.
- * \param input    The 16-Byte buffer holding the input data.
- * \param output   The 16-Byte buffer holding the output data.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and at least \c 16 Bytes long.
+ * \param output   The buffer where the output data will be written.
+ *                 It must be writeable and at least \c 16 Bytes long.
 
  * \return         \c 0 on success.
  */
@@ -260,8 +275,8 @@
  *         mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
  *         before the first call to this API with the same context.
  *
- * \note   This function operates on aligned blocks, that is, the input size
- *         must be a multiple of the AES block size of 16 Bytes.
+ * \note   This function operates on full blocks, that is, the input size
+ *         must be a multiple of the AES block size of \c 16 Bytes.
  *
  * \note   Upon exit, the content of the IV is updated so that you can
  *         call the same function again on the next
@@ -272,13 +287,17 @@
  *
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT.
  * \param length   The length of the input data in Bytes. This must be a
- *                 multiple of the block size (16 Bytes).
+ *                 multiple of the block size (\c 16 Bytes).
  * \param iv       Initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
  * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
  * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
  *
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
@@ -306,9 +325,10 @@
  *             returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
  *
  * \param ctx          The AES XTS context to use for AES XTS operations.
+ *                     It must be initialized and bound to a key.
  * \param mode         The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                     #MBEDTLS_AES_DECRYPT.
- * \param length       The length of a data unit in bytes. This can be any
+ * \param length       The length of a data unit in Bytes. This can be any
  *                     length between 16 bytes and 2^24 bytes inclusive
  *                     (between 1 and 2^20 block cipher blocks).
  * \param data_unit    The address of the data unit encoded as an array of 16
@@ -316,15 +336,15 @@
  *                     is typically the index of the block device sector that
  *                     contains the data.
  * \param input        The buffer holding the input data (which is an entire
- *                     data unit). This function reads \p length bytes from \p
+ *                     data unit). This function reads \p length Bytes from \p
  *                     input.
  * \param output       The buffer holding the output data (which is an entire
- *                     data unit). This function writes \p length bytes to \p
+ *                     data unit). This function writes \p length Bytes to \p
  *                     output.
  *
  * \return             \c 0 on success.
  * \return             #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
- *                     smaller than an AES block in size (16 bytes) or if \p
+ *                     smaller than an AES block in size (16 Bytes) or if \p
  *                     length is larger than 2^20 blocks (16 MiB).
  */
 int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
@@ -360,13 +380,18 @@
  *
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT.
- * \param length   The length of the input data.
+ * \param length   The length of the input data in Bytes.
  * \param iv_off   The offset in IV (updated after use).
+ *                 It must point to a valid \c size_t.
  * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
  * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
  * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
  *
  * \return         \c 0 on success.
  */
@@ -401,12 +426,16 @@
  *
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT
  * \param length   The length of the input data.
  * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
  * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
  * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
  *
  * \return         \c 0 on success.
  */
@@ -451,11 +480,16 @@
  *              will compromise security.
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param length   The length of the input data.
  * \param iv_off   The offset in IV (updated after use).
+ *                 It must point to a valid \c size_t.
  * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
  * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
  * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
  *
  * \return         \c 0 on success.
  */
@@ -527,15 +561,21 @@
  *             securely discarded as soon as it's no longer needed.
  *
  * \param ctx              The AES context to use for encryption or decryption.
+ *                         It must be initialized and bound to a key.
  * \param length           The length of the input data.
  * \param nc_off           The offset in the current \p stream_block, for
  *                         resuming within the current cipher stream. The
  *                         offset pointer should be 0 at the start of a stream.
+ *                         It must point to a valid \c size_t.
  * \param nonce_counter    The 128-bit nonce and counter.
+ *                         It must be a readable-writeable buffer of \c 16 Bytes.
  * \param stream_block     The saved stream block for resuming. This is
  *                         overwritten by the function.
+ *                         It must be a readable-writeable buffer of \c 16 Bytes.
  * \param input            The buffer holding the input data.
+ *                         It must be readable and of size \p length Bytes.
  * \param output           The buffer holding the output data.
+ *                         It must be writeable and of size \p length Bytes.
  *
  * \return                 \c 0 on success.
  */
@@ -588,7 +628,7 @@
  * \brief           Deprecated internal AES block encryption function
  *                  without return value.
  *
- * \deprecated      Superseded by mbedtls_aes_encrypt_ext() in 2.5.0.
+ * \deprecated      Superseded by mbedtls_internal_aes_encrypt()
  *
  * \param ctx       The AES context to use for encryption.
  * \param input     Plaintext block.
@@ -602,7 +642,7 @@
  * \brief           Deprecated internal AES block decryption function
  *                  without return value.
  *
- * \deprecated      Superseded by mbedtls_aes_decrypt_ext() in 2.5.0.
+ * \deprecated      Superseded by mbedtls_internal_aes_decrypt()
  *
  * \param ctx       The AES context to use for decryption.
  * \param input     Ciphertext block.
diff --git a/include/mbedtls/aesni.h b/include/mbedtls/aesni.h
index 746baa0..0196f49 100644
--- a/include/mbedtls/aesni.h
+++ b/include/mbedtls/aesni.h
@@ -2,6 +2,9 @@
  * \file aesni.h
  *
  * \brief AES-NI for hardware AES acceleration on some Intel processors
+ *
+ * \warning These functions are only for internal use by other library
+ *          functions; you must not call them directly.
  */
 /*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@@ -42,7 +45,10 @@
 #endif
 
 /**
- * \brief          AES-NI features detection routine
+ * \brief          Internal function to detect the AES-NI feature in CPUs.
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param what     The feature to detect
  *                 (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)
@@ -52,7 +58,10 @@
 int mbedtls_aesni_has_support( unsigned int what );
 
 /**
- * \brief          AES-NI AES-ECB block en(de)cryption
+ * \brief          Internal AES-NI AES-ECB block encryption and decryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param ctx      AES context
  * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@@ -62,12 +71,15 @@
  * \return         0 on success (cannot fail)
  */
 int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
-                     int mode,
-                     const unsigned char input[16],
-                     unsigned char output[16] );
+                             int mode,
+                             const unsigned char input[16],
+                             unsigned char output[16] );
 
 /**
- * \brief          GCM multiplication: c = a * b in GF(2^128)
+ * \brief          Internal GCM multiplication: c = a * b in GF(2^128)
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param c        Result
  * \param a        First operand
@@ -77,21 +89,29 @@
  *                 elements of GF(2^128) as per the GCM spec.
  */
 void mbedtls_aesni_gcm_mult( unsigned char c[16],
-                     const unsigned char a[16],
-                     const unsigned char b[16] );
+                             const unsigned char a[16],
+                             const unsigned char b[16] );
 
 /**
- * \brief           Compute decryption round keys from encryption round keys
+ * \brief           Internal round key inversion. This function computes
+ *                  decryption round keys from the encryption round keys.
+ *
+ * \note            This function is only for internal use by other library
+ *                  functions; you must not call it directly.
  *
  * \param invkey    Round keys for the equivalent inverse cipher
  * \param fwdkey    Original round keys (for encryption)
  * \param nr        Number of rounds (that is, number of round keys minus one)
  */
 void mbedtls_aesni_inverse_key( unsigned char *invkey,
-                        const unsigned char *fwdkey, int nr );
+                                const unsigned char *fwdkey,
+                                int nr );
 
 /**
- * \brief           Perform key expansion (for encryption)
+ * \brief           Internal key expansion for encryption
+ *
+ * \note            This function is only for internal use by other library
+ *                  functions; you must not call it directly.
  *
  * \param rk        Destination buffer where the round keys are written
  * \param key       Encryption key
@@ -100,8 +120,8 @@
  * \return          0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
  */
 int mbedtls_aesni_setkey_enc( unsigned char *rk,
-                      const unsigned char *key,
-                      size_t bits );
+                              const unsigned char *key,
+                              size_t bits );
 
 #ifdef __cplusplus
 }
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index 483d4c2..1e8956e 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -39,6 +39,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "platform_util.h"
+
 #define MBEDTLS_ARIA_ENCRYPT     1 /**< ARIA encryption. */
 #define MBEDTLS_ARIA_DECRYPT     0 /**< ARIA decryption. */
 
@@ -46,8 +48,12 @@
 #define MBEDTLS_ARIA_MAX_ROUNDS  16 /**< Maxiumum number of rounds in ARIA. */
 #define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
 
-#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH   -0x005C  /**< Invalid key length. */
-#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E  /**< Invalid data input length. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */
+
+#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */
 
 /* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used.
  */
@@ -85,14 +91,16 @@
  *                 It must be the first API called before using
  *                 the context.
  *
- * \param ctx      The ARIA context to initialize.
+ * \param ctx      The ARIA context to initialize. This must not be \c NULL.
  */
 void mbedtls_aria_init( mbedtls_aria_context *ctx );
 
 /**
  * \brief          This function releases and clears the specified ARIA context.
  *
- * \param ctx      The ARIA context to clear.
+ * \param ctx      The ARIA context to clear. This may be \c NULL, in which
+ *                 case this function returns immediately. If it is not \c NULL,
+ *                 it must point to an initialized ARIA context.
  */
 void mbedtls_aria_free( mbedtls_aria_context *ctx );
 
@@ -100,14 +108,16 @@
  * \brief          This function sets the encryption key.
  *
  * \param ctx      The ARIA context to which the key should be bound.
- * \param key      The encryption key.
- * \param keybits  The size of data passed in bits. Valid options are:
+ *                 This must be initialized.
+ * \param key      The encryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The size of \p key in Bits. Valid options are:
  *                 <ul><li>128 bits</li>
  *                 <li>192 bits</li>
  *                 <li>256 bits</li></ul>
  *
- * \return         \c 0 on success or #MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
                              const unsigned char *key,
@@ -117,13 +127,16 @@
  * \brief          This function sets the decryption key.
  *
  * \param ctx      The ARIA context to which the key should be bound.
- * \param key      The decryption key.
+ *                 This must be initialized.
+ * \param key      The decryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
  * \param keybits  The size of data passed. Valid options are:
  *                 <ul><li>128 bits</li>
  *                 <li>192 bits</li>
  *                 <li>256 bits</li></ul>
  *
- * \return         \c 0 on success, or #MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH on failure.
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
                              const unsigned char *key,
@@ -142,10 +155,12 @@
  *                 call to this API with the same context.
  *
  * \param ctx      The ARIA context to use for encryption or decryption.
+ *                 This must be initialized and bound to a key.
  * \param input    The 16-Byte buffer holding the input data.
  * \param output   The 16-Byte buffer holding the output data.
 
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
                             const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
@@ -177,16 +192,21 @@
  *
  *
  * \param ctx      The ARIA context to use for encryption or decryption.
- * \param mode     The ARIA operation: #MBEDTLS_ARIA_ENCRYPT or
- *                 #MBEDTLS_ARIA_DECRYPT.
+ *                 This must be initialized and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_ARIA_ENCRYPT for encryption, or
+ *                 #MBEDTLS_ARIA_DECRYPT for decryption.
  * \param length   The length of the input data in Bytes. This must be a
  *                 multiple of the block size (16 Bytes).
  * \param iv       Initialization vector (updated after use).
- * \param input    The buffer holding the input data.
- * \param output   The buffer holding the output data.
+ *                 This must be a readable buffer of size 16 Bytes.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must
+ *                 be a writable buffer of length \p length Bytes.
  *
- * \return         \c 0 on success, or #MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
                             int mode,
@@ -221,15 +241,22 @@
  *
  *
  * \param ctx      The ARIA context to use for encryption or decryption.
- * \param mode     The ARIA operation: #MBEDTLS_ARIA_ENCRYPT or
- *                 #MBEDTLS_ARIA_DECRYPT.
- * \param length   The length of the input data.
+ *                 This must be initialized and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_ARIA_ENCRYPT for encryption, or
+ *                 #MBEDTLS_ARIA_DECRYPT for decryption.
+ * \param length   The length of the input data \p input in Bytes.
  * \param iv_off   The offset in IV (updated after use).
+ *                 This must not be larger than 15.
  * \param iv       The initialization vector (updated after use).
- * \param input    The buffer holding the input data.
- * \param output   The buffer holding the output data.
+ *                 This must be a readable buffer of size 16 Bytes.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must
+ *                 be a writable buffer of length \p length Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
                                int mode,
@@ -299,17 +326,24 @@
  *             securely discarded as soon as it's no longer needed.
  *
  * \param ctx              The ARIA context to use for encryption or decryption.
- * \param length           The length of the input data.
- * \param nc_off           The offset in the current \p stream_block, for
- *                         resuming within the current cipher stream. The
- *                         offset pointer should be 0 at the start of a stream.
- * \param nonce_counter    The 128-bit nonce and counter.
- * \param stream_block     The saved stream block for resuming. This is
- *                         overwritten by the function.
- * \param input            The buffer holding the input data.
- * \param output           The buffer holding the output data.
+ *                         This must be initialized and bound to a key.
+ * \param length           The length of the input data \p input in Bytes.
+ * \param nc_off           The offset in Bytes in the current \p stream_block,
+ *                         for resuming within the current cipher stream. The
+ *                         offset pointer should be \c 0 at the start of a
+ *                         stream. This must not be larger than \c 15 Bytes.
+ * \param nonce_counter    The 128-bit nonce and counter. This must point to
+ *                         a read/write buffer of length \c 16 bytes.
+ * \param stream_block     The saved stream block for resuming. This must
+ *                         point to a read/write buffer of length \c 16 bytes.
+ *                         This is overwritten by the function.
+ * \param input            The buffer holding the input data. This must
+ *                         be a readable buffer of length \p length Bytes.
+ * \param output           The buffer holding the output data. This must
+ *                         be a writable buffer of length \p length Bytes.
  *
- * \return     \c 0 on success.
+ * \return                 \c 0 on success.
+ * \return                 A negative error code on failure.
  */
 int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
                             size_t length,
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 40cfab4..141a8e9 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -186,96 +186,115 @@
 mbedtls_mpi;
 
 /**
- * \brief           Initialize one MPI (make internal references valid)
- *                  This just makes it ready to be set or freed,
+ * \brief           Initialize an MPI context.
+ *
+ *                  This makes the MPI ready to be set or freed,
  *                  but does not define a value for the MPI.
  *
- * \param X         One MPI to initialize.
+ * \param X         The MPI context to initialize. This must not be \c NULL.
  */
 void mbedtls_mpi_init( mbedtls_mpi *X );
 
 /**
- * \brief          Unallocate one MPI
+ * \brief          This function frees the components of an MPI context.
  *
- * \param X        One MPI to unallocate.
+ * \param X        The MPI context to be cleared. This may be \c NULL,
+ *                 in which case this function is a no-op. If it is
+ *                 not \c NULL, it must point to an initialized MPI.
  */
 void mbedtls_mpi_free( mbedtls_mpi *X );
 
 /**
- * \brief          Enlarge to the specified number of limbs
+ * \brief          Enlarge an MPI to the specified number of limbs.
  *
- *                 This function does nothing if the MPI is already large enough.
+ * \note           This function does nothing if the MPI is
+ *                 already large enough.
  *
- * \param X        MPI to grow
- * \param nblimbs  The target number of limbs
+ * \param X        The MPI to grow. It must be initialized.
+ * \param nblimbs  The target number of limbs.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs );
 
 /**
- * \brief          Resize down, keeping at least the specified number of limbs
+ * \brief          This function resizes an MPI downwards, keeping at least the
+ *                 specified number of limbs.
  *
  *                 If \c X is smaller than \c nblimbs, it is resized up
  *                 instead.
  *
- * \param X        MPI to shrink
- * \param nblimbs  The minimum number of limbs to keep
+ * \param X        The MPI to shrink. This must point to an initialized MPI.
+ * \param nblimbs  The minimum number of limbs to keep.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
  *                 (this can only happen when resizing up).
+ * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs );
 
 /**
- * \brief          Copy the contents of Y into X
+ * \brief          Make a copy of an MPI.
  *
- * \param X        Destination MPI. It is enlarged if necessary.
- * \param Y        Source MPI.
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param Y        The source MPI. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \note           The limb-buffer in the destination MPI is enlarged
+ *                 if necessary to hold the value in the source MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y );
 
 /**
- * \brief          Swap the contents of X and Y
+ * \brief          Swap the contents of two MPIs.
  *
- * \param X        First MPI value
- * \param Y        Second MPI value
+ * \param X        The first MPI. It must be initialized.
+ * \param Y        The second MPI. It must be initialized.
  */
 void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y );
 
 /**
- * \brief          Safe conditional assignement X = Y if assign is 1
+ * \brief          Perform a safe conditional copy of MPI which doesn't
+ *                 reveal whether the condition was true or not.
  *
- * \param X        MPI to conditionally assign to
- * \param Y        Value to be assigned
- * \param assign   1: perform the assignment, 0: keep X's original value
- *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * \param X        The MPI to conditionally assign to. This must point
+ *                 to an initialized MPI.
+ * \param Y        The MPI to be assigned from. This must point to an
+ *                 initialized MPI.
+ * \param assign   The condition deciding whether to perform the
+ *                 assignment or not. Possible values:
+ *                 * \c 1: Perform the assignment `X = Y`.
+ *                 * \c 0: Keep the original value of \p X.
  *
  * \note           This function is equivalent to
- *                      if( assign ) mbedtls_mpi_copy( X, Y );
+ *                      `if( assign ) mbedtls_mpi_copy( X, Y );`
  *                 except that it avoids leaking any information about whether
  *                 the assignment was done or not (the above code may leak
  *                 information through branch prediction and/or memory access
  *                 patterns analysis).
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign );
 
 /**
- * \brief          Safe conditional swap X <-> Y if swap is 1
+ * \brief          Perform a safe conditional swap which doesn't
+ *                 reveal whether the condition was true or not.
  *
- * \param X        First mbedtls_mpi value
- * \param Y        Second mbedtls_mpi value
- * \param assign   1: perform the swap, 0: keep X and Y's original values
- *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * \param X        The first MPI. This must be initialized.
+ * \param Y        The second MPI. This must be initialized.
+ * \param assign   The condition deciding whether to perform
+ *                 the swap or not. Possible values:
+ *                 * \c 1: Swap the values of \p X and \p Y.
+ *                 * \c 0: Keep the original values of \p X and \p Y.
  *
  * \note           This function is equivalent to
  *                      if( assign ) mbedtls_mpi_swap( X, Y );
@@ -283,415 +302,512 @@
  *                 the assignment was done or not (the above code may leak
  *                 information through branch prediction and/or memory access
  *                 patterns analysis).
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
+ *
  */
 int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign );
 
 /**
- * \brief          Set value from integer
+ * \brief          Store integer value in MPI.
  *
- * \param X        MPI to set
- * \param z        Value to use
+ * \param X        The MPI to set. This must be initialized.
+ * \param z        The value to use.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z );
 
 /**
- * \brief          Get a specific bit from X
+ * \brief          Get a specific bit from an MPI.
  *
- * \param X        MPI to use
- * \param pos      Zero-based index of the bit in X
+ * \param X        The MPI to query. This must be initialized.
+ * \param pos      Zero-based index of the bit to query.
  *
- * \return         Either a 0 or a 1
+ * \return         \c 0 or \c 1 on success, depending on whether bit \c pos
+ *                 of \c X is unset or set.
+ * \return         A negative error code on failure.
  */
 int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos );
 
 /**
- * \brief          Set a bit of X to a specific value of 0 or 1
+ * \brief          Modify a specific bit in an MPI.
  *
- * \note           Will grow X if necessary to set a bit to 1 in a not yet
- *                 existing limb. Will not grow if bit should be set to 0
+ * \note           This function will grow the target MPI if necessary to set a
+ *                 bit to \c 1 in a not yet existing limb. It will not grow if
+ *                 the bit should be set to \c 0.
  *
- * \param X        MPI to use
- * \param pos      Zero-based index of the bit in X
- * \param val      The value to set the bit to (0 or 1)
+ * \param X        The MPI to modify. This must be initialized.
+ * \param pos      Zero-based index of the bit to modify.
+ * \param val      The desired value of bit \c pos: \c 0 or \c 1.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val );
 
 /**
- * \brief          Return the number of zero-bits before the least significant
- *                 '1' bit
+ * \brief          Return the number of bits of value \c 0 before the
+ *                 least significant bit of value \c 1.
  *
- * Note: Thus also the zero-based index of the least significant '1' bit
+ * \note           This is the same as the zero-based index of
+ *                 the least significant bit of value \c 1.
  *
- * \param X        MPI to use
+ * \param X        The MPI to query.
+ *
+ * \return         The number of bits of value \c 0 before the least significant
+ *                 bit of value \c 1 in \p X.
  */
 size_t mbedtls_mpi_lsb( const mbedtls_mpi *X );
 
 /**
  * \brief          Return the number of bits up to and including the most
- *                 significant '1' bit'
+ *                 significant bit of value \c 1.
  *
- * Note: Thus also the one-based index of the most significant '1' bit
+ * * \note         This is same as the one-based index of the most
+ *                 significant bit of value \c 1.
  *
- * \param X        MPI to use
+ * \param X        The MPI to query. This must point to an initialized MPI.
+ *
+ * \return         The number of bits up to and including the most
+ *                 significant bit of value \c 1.
  */
 size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X );
 
 /**
- * \brief          Return the total size in bytes
+ * \brief          Return the total size of an MPI value in bytes.
  *
- * \param X        MPI to use
+ * \param X        The MPI to use. This must point to an initialized MPI.
+ *
+ * \note           The value returned by this function may be less than
+ *                 the number of bytes used to store \p X internally.
+ *                 This happens if and only if there are trailing bytes
+ *                 of value zero.
+ *
+ * \return         The least number of bytes capable of storing
+ *                 the absolute value of \p X.
  */
 size_t mbedtls_mpi_size( const mbedtls_mpi *X );
 
 /**
- * \brief          Import from an ASCII string
+ * \brief          Import an MPI from an ASCII string.
  *
- * \param X        Destination MPI
- * \param radix    Input numeric base
- * \param s        Null-terminated string buffer
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base of the input string.
+ * \param s        Null-terminated string buffer.
  *
- * \return         0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s );
 
 /**
- * \brief          Export into an ASCII string
+ * \brief          Export an MPI to an ASCII string.
  *
- * \param X        Source MPI
- * \param radix    Output numeric base
- * \param buf      Buffer to write the string to
- * \param buflen   Length of buf
- * \param olen     Length of the string written, including final NUL byte
+ * \param X        The source MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base of the output string.
+ * \param buf      The buffer to write the string to. This must be writable
+ *                 buffer of length \p buflen Bytes.
+ * \param buflen   The available size in Bytes of \p buf.
+ * \param olen     The address at which to store the length of the string
+ *                 written, including the  final \c NULL byte. This must
+ *                 not be \c NULL.
  *
- * \return         0 if successful, or a MBEDTLS_ERR_MPI_XXX error code.
- *                 *olen is always updated to reflect the amount
- *                 of data that has (or would have) been written.
+ * \note           You can call this function with `buflen == 0` to obtain the
+ *                 minimum required buffer size in `*olen`.
  *
- * \note           Call this function with buflen = 0 to obtain the
- *                 minimum required buffer size in *olen.
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf
+ *                 is too small to hold the value of \p X in the desired base.
+ *                 In this case, `*olen` is nonetheless updated to contain the
+ *                 size of \p buf required for a successful call.
+ * \return         Another negative error code on different kinds of failure.
  */
 int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
                               char *buf, size_t buflen, size_t *olen );
 
 #if defined(MBEDTLS_FS_IO)
 /**
- * \brief          Read MPI from a line in an opened file
+ * \brief          Read an MPI from a line in an opened file.
  *
- * \param X        Destination MPI
- * \param radix    Input numeric base
- * \param fin      Input file handle
- *
- * \return         0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if
- *                 the file read buffer is too small or a
- *                 MBEDTLS_ERR_MPI_XXX error code
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base of the string representation used
+ *                 in the source line.
+ * \param fin      The input file handle to use. This must not be \c NULL.
  *
  * \note           On success, this function advances the file stream
  *                 to the end of the current line or to EOF.
  *
- *                 The function returns 0 on an empty line.
+ *                 The function returns \c 0 on an empty line.
  *
  *                 Leading whitespaces are ignored, as is a
- *                 '0x' prefix for radix 16.
+ *                 '0x' prefix for radix \c 16.
  *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer
+ *                 is too small.
+ * \return         Another negative error code on failure.
  */
 int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin );
 
 /**
- * \brief          Write X into an opened file, or stdout if fout is NULL
+ * \brief          Export an MPI into an opened file.
  *
- * \param p        Prefix, can be NULL
- * \param X        Source MPI
- * \param radix    Output numeric base
- * \param fout     Output file handle (can be NULL)
+ * \param p        A string prefix to emit prior to the MPI data.
+ *                 For example, this might be a label, or "0x" when
+ *                 printing in base \c 16. This may be \c NULL if no prefix
+ *                 is needed.
+ * \param X        The source MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base to be used in the emitted string.
+ * \param fout     The output file handle. This may be \c NULL, in which case
+ *                 the output is written to \c stdout.
  *
- * \return         0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
- *
- * \note           Set fout == NULL to print X on the console.
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
-int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout );
+int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X,
+                            int radix, FILE *fout );
 #endif /* MBEDTLS_FS_IO */
 
 /**
- * \brief          Import X from unsigned binary data, big endian
+ * \brief          Import an MPI from unsigned big endian binary data.
  *
- * \param X        Destination MPI
- * \param buf      Input buffer
- * \param buflen   Input buffer size
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param buf      The input buffer. This must be a readable buffer of length
+ *                 \p buflen Bytes.
+ * \param buflen   The length of the input buffer \p p in Bytes.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen );
+int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf,
+                             size_t buflen );
 
 /**
- * \brief          Export X into unsigned binary data, big endian.
- *                 Always fills the whole buffer, which will start with zeros
- *                 if the number is smaller.
+ * \brief          Export an MPI into unsigned big endian binary data
+ *                 of fixed size.
  *
- * \param X        Source MPI
- * \param buf      Output buffer
- * \param buflen   Output buffer size
+ * \param X        The source MPI. This must point to an initialized MPI.
+ * \param buf      The output buffer. This must be a writable buffer of length
+ *                 \p buflen Bytes.
+ * \param buflen   The size of the output buffer \p buf in Bytes.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
+ *                 large enough to hold the value of \p X.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen );
+int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf,
+                              size_t buflen );
 
 /**
- * \brief          Left-shift: X <<= count
+ * \brief          Perform a left-shift on an MPI: X <<= count
  *
- * \param X        MPI to shift
- * \param count    Amount to shift
+ * \param X        The MPI to shift. This must point to an initialized MPI.
+ * \param count    The number of bits to shift by.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
 int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count );
 
 /**
- * \brief          Right-shift: X >>= count
+ * \brief          Perform a right-shift on an MPI: X >>= count
  *
- * \param X        MPI to shift
- * \param count    Amount to shift
+ * \param X        The MPI to shift. This must point to an initialized MPI.
+ * \param count    The number of bits to shift by.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
 int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count );
 
 /**
- * \brief          Compare unsigned values
+ * \brief          Compare the absolute values of two MPIs.
  *
- * \param X        Left-hand MPI
- * \param Y        Right-hand MPI
+ * \param X        The left-hand MPI. This must point to an initialized MPI.
+ * \param Y        The right-hand MPI. This must point to an initialized MPI.
  *
- * \return         1 if |X| is greater than |Y|,
- *                -1 if |X| is lesser  than |Y| or
- *                 0 if |X| is equal to |Y|
+ * \return         \c 1 if `|X|` is greater than `|Y|`.
+ * \return         \c -1 if `|X|` is lesser than `|Y|`.
+ * \return         \c 0 if `|X|` is equal to `|Y|`.
  */
 int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y );
 
 /**
- * \brief          Compare signed values
+ * \brief          Compare two MPIs.
  *
- * \param X        Left-hand MPI
- * \param Y        Right-hand MPI
+ * \param X        The left-hand MPI. This must point to an initialized MPI.
+ * \param Y        The right-hand MPI. This must point to an initialized MPI.
  *
- * \return         1 if X is greater than Y,
- *                -1 if X is lesser  than Y or
- *                 0 if X is equal to Y
+ * \return         \c 1 if \p X is greater than \p Y.
+ * \return         \c -1 if \p X is lesser than \p Y.
+ * \return         \c 0 if \p X is equal to \p Y.
  */
 int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
 
 /**
- * \brief          Compare signed values
+ * \brief          Compare an MPI with an integer.
  *
- * \param X        Left-hand MPI
- * \param z        The integer value to compare to
+ * \param X        The left-hand MPI. This must point to an initialized MPI.
+ * \param z        The integer value to compare \p X to.
  *
- * \return         1 if X is greater than z,
- *                -1 if X is lesser  than z or
- *                 0 if X is equal to z
+ * \return         \c 1 if \p X is greater than \p z.
+ * \return         \c -1 if \p X is lesser than \p z.
+ * \return         \c 0 if \p X is equal to \p z.
  */
 int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z );
 
 /**
- * \brief          Unsigned addition: X = |A| + |B|
+ * \brief          Perform an unsigned addition of MPIs: X = |A| + |B|
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first summand. This must point to an initialized MPI.
+ * \param B        The second summand. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
 
 /**
- * \brief          Unsigned subtraction: X = |A| - |B|
+ * \brief          Perform an unsigned subtraction of MPIs: X = |A| - |B|
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The minuend. This must point to an initialized MPI.
+ * \param B        The subtrahend. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A.
+ * \return         Another negative error code on different kinds of failure.
+ *
  */
-int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
 
 /**
- * \brief          Signed addition: X = A + B
+ * \brief          Perform a signed addition of MPIs: X = A + B
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first summand. This must point to an initialized MPI.
+ * \param B        The second summand. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
 
 /**
- * \brief          Signed subtraction: X = A - B
+ * \brief          Perform a signed subtraction of MPIs: X = A - B
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The minuend. This must point to an initialized MPI.
+ * \param B        The subtrahend. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
 
 /**
- * \brief          Signed addition: X = A + b
+ * \brief          Perform a signed addition of an MPI and an integer: X = A + b
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param b        The integer value to add
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first summand. This must point to an initialized MPI.
+ * \param b        The second summand.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
 
 /**
- * \brief          Signed subtraction: X = A - b
+ * \brief          Perform a signed subtraction of an MPI and an integer:
+ *                 X = A - b
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param b        The integer value to subtract
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The minuend. This must point to an initialized MPI.
+ * \param b        The subtrahend.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
 
 /**
- * \brief          Baseline multiplication: X = A * B
+ * \brief          Perform a multiplication of two MPIs: X = A * B
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first factor. This must point to an initialized MPI.
+ * \param B        The second factor. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ *
  */
-int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
 
 /**
- * \brief          Baseline multiplication: X = A * b
+ * \brief          Perform a multiplication of an MPI with an unsigned integer:
+ *                 X = A * b
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param b        The unsigned integer value to multiply with
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first factor. This must point to an initialized MPI.
+ * \param b        The second factor.
  *
- * \note           b is unsigned
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
  */
-int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b );
+int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         mbedtls_mpi_uint b );
 
 /**
- * \brief          Division by mbedtls_mpi: A = Q * B + R
+ * \brief          Perform a division with remainder of two MPIs:
+ *                 A = Q * B + R
  *
- * \param Q        Destination MPI for the quotient
- * \param R        Destination MPI for the rest value
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param Q        The destination MPI for the quotient.
+ *                 This may be \c NULL if the value of the
+ *                 quotient is not needed.
+ * \param R        The destination MPI for the remainder value.
+ *                 This may be \c NULL if the value of the
+ *                 remainder is not needed.
+ * \param A        The dividend. This must point to an initialized MPi.
+ * \param B        The divisor. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0
- *
- * \note           Either Q or R can be NULL.
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
 
 /**
- * \brief          Division by int: A = Q * b + R
+ * \brief          Perform a division with remainder of an MPI by an integer:
+ *                 A = Q * b + R
  *
- * \param Q        Destination MPI for the quotient
- * \param R        Destination MPI for the rest value
- * \param A        Left-hand MPI
- * \param b        Integer to divide by
+ * \param Q        The destination MPI for the quotient.
+ *                 This may be \c NULL if the value of the
+ *                 quotient is not needed.
+ * \param R        The destination MPI for the remainder value.
+ *                 This may be \c NULL if the value of the
+ *                 remainder is not needed.
+ * \param A        The dividend. This must point to an initialized MPi.
+ * \param b        The divisor.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0
- *
- * \note           Either Q or R can be NULL.
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
 
 /**
- * \brief          Modulo: R = A mod B
+ * \brief          Perform a modular reduction. R = A mod B
  *
- * \param R        Destination MPI for the rest value
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param R        The destination MPI for the residue value.
+ *                 This must point to an initialized MPI.
+ * \param A        The MPI to compute the residue of.
+ *                 This must point to an initialized MPI.
+ * \param B        The base of the modular reduction.
+ *                 This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0,
- *                 MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B < 0
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
+ * \return         #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative.
+ * \return         Another negative error code on different kinds of failure.
+ *
  */
-int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
 
 /**
- * \brief          Modulo: r = A mod b
+ * \brief          Perform a modular reduction with respect to an integer.
+ *                 r = A mod b
  *
- * \param r        Destination mbedtls_mpi_uint
- * \param A        Left-hand MPI
- * \param b        Integer to divide by
+ * \param r        The address at which to store the residue.
+ *                 This must not be \c NULL.
+ * \param A        The MPI to compute the residue of.
+ *                 This must point to an initialized MPi.
+ * \param b        The integer base of the modular reduction.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0,
- *                 MBEDTLS_ERR_MPI_NEGATIVE_VALUE if b < 0
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
+ * \return         #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
 
 /**
- * \brief          Sliding-window exponentiation: X = A^E mod N
+ * \brief          Perform a sliding-window exponentiation: X = A^E mod N
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param E        Exponent MPI
- * \param N        Modular MPI
- * \param _RR      Speed-up MPI used for recalculations
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The base of the exponentiation.
+ *                 This must point to an initialized MPI.
+ * \param E        The exponent MPI. This must point to an initialized MPI.
+ * \param N        The base for the modular reduction. This must point to an
+ *                 initialized MPI.
+ * \param _RR      A helper MPI depending solely on \p N which can be used to
+ *                 speed-up multiple modular exponentiations for the same value
+ *                 of \p N. This may be \c NULL. If it is not \c NULL, it must
+ *                 point to an initialized MPI. If it hasn't been used after
+ *                 the call to mbedtls_mpi_init(), this function will compute
+ *                 the helper value and store it in \p _RR for reuse on
+ *                 subsequent calls to this function. Otherwise, the function
+ *                 will assume that \p _RR holds the helper value set by a
+ *                 previous call to mbedtls_mpi_exp_mod(), and reuse it.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or even or
- *                 if E is negative
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
+ *                 even, or if \c E is negative.
+ * \return         Another negative error code on different kinds of failures.
  *
- * \note           _RR is used to avoid re-computing R*R mod N across
- *                 multiple calls, which speeds up things a bit. It can
- *                 be set to NULL if the extra performance is unneeded.
  */
-int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR );
+int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *E, const mbedtls_mpi *N,
+                         mbedtls_mpi *_RR );
 
 /**
- * \brief          Fill an MPI X with size bytes of random
+ * \brief          Fill an MPI with a number of random bytes.
  *
- * \param X        Destination MPI
- * \param size     Size in bytes
- * \param f_rng    RNG function
- * \param p_rng    RNG parameter
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param size     The number of random bytes to generate.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context argument.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on failure.
  *
- * \note           The bytes obtained from the PRNG are interpreted
+ * \note           The bytes obtained from the RNG are interpreted
  *                 as a big-endian representation of an MPI; this can
  *                 be relevant in applications like deterministic ECDSA.
  */
@@ -700,30 +816,37 @@
                      void *p_rng );
 
 /**
- * \brief          Greatest common divisor: G = gcd(A, B)
+ * \brief          Compute the greatest common divisor: G = gcd(A, B)
  *
- * \param G        Destination MPI
- * \param A        Left-hand MPI
- * \param B        Right-hand MPI
+ * \param G        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first operand. This must point to an initialized MPI.
+ * \param B        The second operand. This must point to an initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
  */
-int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A,
+                     const mbedtls_mpi *B );
 
 /**
- * \brief          Modular inverse: X = A^-1 mod N
+ * \brief          Compute the modular inverse: X = A^-1 mod N
  *
- * \param X        Destination MPI
- * \param A        Left-hand MPI
- * \param N        Right-hand MPI
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The MPI to calculate the modular inverse of. This must point
+ *                 to an initialized MPI.
+ * \param N        The base of the modular inversion. This must point to an
+ *                 initialized MPI.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is <= 1,
-                   MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N.
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than
+ *                 or equal to one.
+ * \return         #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse
+ *                 with respect to \p N.
  */
-int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N );
+int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *N );
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 #if defined(MBEDTLS_DEPRECATED_WARNING)
@@ -732,19 +855,23 @@
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief          Miller-Rabin primality test with error probability of
- *                 2<sup>-80</sup>
+ * \brief          Perform a Miller-Rabin primality test with error
+ *                 probability of 2<sup>-80</sup>.
  *
  * \deprecated     Superseded by mbedtls_mpi_is_prime_ext() which allows
  *                 specifying the number of Miller-Rabin rounds.
  *
- * \param X        MPI to check
- * \param f_rng    RNG function
- * \param p_rng    RNG parameter
+ * \param X        The MPI to check for primality.
+ *                 This must point to an initialized MPI.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't use a
+ *                 context parameter.
  *
- * \return         0 if successful (probably prime),
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ * \return         \c 0 if successful, i.e. \p X is probably prime.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime.
+ * \return         Another negative error code on other kinds of failure.
  */
 MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
                           int (*f_rng)(void *, unsigned char *, size_t),
@@ -764,16 +891,20 @@
  *                 case when mbedtls_mpi_gen_prime calls this function), then
  *                 \p rounds can be much lower.
  *
- * \param X        MPI to check
- * \param rounds   Number of bases to perform Miller-Rabin primality test for.
- *                 The probability of returning 0 on a composite is at most
- *                 2<sup>-2*\p rounds</sup>.
- * \param f_rng    RNG function
- * \param p_rng    RNG parameter
+ * \param X        The MPI to check for primality.
+ *                 This must point to an initialized MPI.
+ * \param rounds   The number of bases to perform the Miller-Rabin primality
+ *                 test for. The probability of returning 0 on a composite is
+ *                 at most 2<sup>-2*\p rounds</sup>.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't use
+ *                 a context parameter.
  *
- * \return         0 if successful (probably prime),
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ * \return         \c 0 if successful, i.e. \p X is probably prime.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime.
+ * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
                               int (*f_rng)(void *, unsigned char *, size_t),
@@ -790,18 +921,23 @@
 } mbedtls_mpi_gen_prime_flag_t;
 
 /**
- * \brief          Prime number generation
+ * \brief          Generate a prime number.
  *
- * \param X        Destination MPI
- * \param nbits    Required size of X in bits
- *                 ( 3 <= nbits <= MBEDTLS_MPI_MAX_BITS )
- * \param flags    Mask of flags of type #mbedtls_mpi_gen_prime_flag_t
- * \param f_rng    RNG function
- * \param p_rng    RNG parameter
+ * \param X        The destination MPI to store the generated prime in.
+ *                 This must point to an initialized MPi.
+ * \param nbits    The required size of the destination MPI in bits.
+ *                 This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS.
+ * \param flags    A mask of flags of type #mbedtls_mpi_gen_prime_flag_t.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't use
+ *                 a context parameter.
  *
- * \return         0 if successful (probably prime),
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ * \return         \c 0 if successful, in which case \p X holds a
+ *                 probably prime number.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between
+ *                 \c 3 and #MBEDTLS_MPI_MAX_BITS.
  */
 int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
                    int (*f_rng)(void *, unsigned char *, size_t),
diff --git a/include/mbedtls/blowfish.h b/include/mbedtls/blowfish.h
index 82b772a..f01573d 100644
--- a/include/mbedtls/blowfish.h
+++ b/include/mbedtls/blowfish.h
@@ -33,6 +33,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "platform_util.h"
+
 #define MBEDTLS_BLOWFISH_ENCRYPT     1
 #define MBEDTLS_BLOWFISH_DECRYPT     0
 #define MBEDTLS_BLOWFISH_MAX_KEY_BITS     448
@@ -40,14 +42,17 @@
 #define MBEDTLS_BLOWFISH_ROUNDS      16         /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
 #define MBEDTLS_BLOWFISH_BLOCKSIZE   8          /* Blowfish uses 64 bit blocks */
 
-#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH                -0x0016  /**< Invalid key length. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */
+
+#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
 
 /* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used.
  */
 #define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED                   -0x0017  /**< Blowfish hardware accelerator failed. */
 
-#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH              -0x0018  /**< Invalid data input length. */
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -71,40 +76,53 @@
 #endif /* MBEDTLS_BLOWFISH_ALT */
 
 /**
- * \brief          Initialize Blowfish context
+ * \brief          Initialize a Blowfish context.
  *
- * \param ctx      Blowfish context to be initialized
+ * \param ctx      The Blowfish context to be initialized.
+ *                 This must not be \c NULL.
  */
 void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx );
 
 /**
- * \brief          Clear Blowfish context
+ * \brief          Clear a Blowfish context.
  *
- * \param ctx      Blowfish context to be cleared
+ * \param ctx      The Blowfish context to be cleared.
+ *                 This may be \c NULL, in which case this function
+ *                 returns immediately. If it is not \c NULL, it must
+ *                 point to an initialized Blowfish context.
  */
 void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx );
 
 /**
- * \brief          Blowfish key schedule
+ * \brief          Perform a Blowfish key schedule operation.
  *
- * \param ctx      Blowfish context to be initialized
- * \param key      encryption key
- * \param keybits  must be between 32 and 448 bits
+ * \param ctx      The Blowfish context to perform the key schedule on.
+ * \param key      The encryption key. This must be a readable buffer of
+ *                 length \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be between
+ *                 \c 32 and \c 448 and a multiple of \c 8.
  *
- * \return         0 if successful, or MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
                      unsigned int keybits );
 
 /**
- * \brief          Blowfish-ECB block encryption/decryption
+ * \brief          Perform a Blowfish-ECB block encryption/decryption operation.
  *
- * \param ctx      Blowfish context
- * \param mode     MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
- * \param input    8-byte input block
- * \param output   8-byte output block
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param input    The input block. This must be a readable buffer
+ *                 of size \c 8 Bytes.
+ * \param output   The output block. This must be a writable buffer
+ *                 of size \c 8 Bytes.
  *
- * \return         0 if successful
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
                         int mode,
@@ -113,9 +131,7 @@
 
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
 /**
- * \brief          Blowfish-CBC buffer encryption/decryption
- *                 Length should be a multiple of the block
- *                 size (8 bytes)
+ * \brief          Perform a Blowfish-CBC buffer encryption/decryption operation.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -125,15 +141,22 @@
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      Blowfish context
- * \param mode     MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
- * \param length   length of the input data
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes. This must be
+ *                 multiple of \c 8.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 8 Bytes. It is updated by this function.
+ * \param input    The input data. This must be a readable buffer of length
+ *                 \p length Bytes.
+ * \param output   The output data. This must be a writable buffer of length
+ *                 \p length Bytes.
  *
- * \return         0 if successful, or
- *                 MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
                         int mode,
@@ -145,7 +168,7 @@
 
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
 /**
- * \brief          Blowfish CFB buffer encryption/decryption.
+ * \brief          Perform a Blowfish CFB buffer encryption/decryption operation.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -155,15 +178,25 @@
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      Blowfish context
- * \param mode     MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
- * \param length   length of the input data
- * \param iv_off   offset in IV (updated after use)
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes.
+ * \param iv_off   The offset in the initialiation vector.
+ *                 The value pointed to must be smaller than \c 8 Bytes.
+ *                 It is updated by this function to support the aforementioned
+ *                 streaming usage.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of size \c 8 Bytes. It is updated after use.
+ * \param input    The input data. This must be a readable buffer of length
+ *                 \p length Bytes.
+ * \param output   The output data. This must be a writable buffer of length
+ *                 \p length Bytes.
  *
- * \return         0 if successful
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
                           int mode,
@@ -176,7 +209,7 @@
 
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /**
- * \brief               Blowfish-CTR buffer encryption/decryption
+ * \brief      Perform a Blowfish-CTR buffer encryption/decryption operation.
  *
  * \warning    You must never reuse a nonce value with the same key. Doing so
  *             would void the encryption for the two messages encrypted with
@@ -219,18 +252,24 @@
  *             content must not be written to insecure storage and should be
  *             securely discarded as soon as it's no longer needed.
  *
- * \param ctx           Blowfish context
- * \param length        The length of the data
+ * \param ctx           The Blowfish context to use. This must be initialized
+ *                      and bound to a key.
+ * \param length        The length of the input data in Bytes.
  * \param nc_off        The offset in the current stream_block (for resuming
- *                      within current cipher stream). The offset pointer to
- *                      should be 0 at the start of a stream.
- * \param nonce_counter The 64-bit nonce and counter.
- * \param stream_block  The saved stream-block for resuming. Is overwritten
- *                      by the function.
- * \param input         The input data stream
- * \param output        The output data stream
+ *                      within current cipher stream). The offset pointer
+ *                      should be \c 0 at the start of a stream and must be
+ *                      smaller than \c 8. It is updated by this function.
+ * \param nonce_counter The 64-bit nonce and counter. This must point to a
+ *                      read/write buffer of length \c 8 Bytes.
+ * \param stream_block  The saved stream-block for resuming. This must point to
+ *                      a read/write buffer of length \c 8 Bytes.
+ * \param input         The input data. This must be a readable buffer of
+ *                      length \p length Bytes.
+ * \param output        The output data. This must be a writable buffer of
+ *                      length \p length Bytes.
  *
- * \return         0 if successful
+ * \return              \c 0 if successful.
+ * \return              A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
                         size_t length,
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index 0af694c..2f7b72f 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -170,19 +170,19 @@
 
 #define MULADDC_INIT                        \
     asm(                                    \
-        "xorq   %%r8, %%r8          \n\t"
+        "xorq   %%r8, %%r8\n"
 
 #define MULADDC_CORE                        \
-        "movq   (%%rsi), %%rax      \n\t"   \
-        "mulq   %%rbx               \n\t"   \
-        "addq   $8,      %%rsi      \n\t"   \
-        "addq   %%rcx,   %%rax      \n\t"   \
-        "movq   %%r8,    %%rcx      \n\t"   \
-        "adcq   $0,      %%rdx      \n\t"   \
-        "nop                        \n\t"   \
-        "addq   %%rax,   (%%rdi)    \n\t"   \
-        "adcq   %%rdx,   %%rcx      \n\t"   \
-        "addq   $8,      %%rdi      \n\t"
+        "movq   (%%rsi), %%rax\n"           \
+        "mulq   %%rbx\n"                    \
+        "addq   $8, %%rsi\n"                \
+        "addq   %%rcx, %%rax\n"             \
+        "movq   %%r8, %%rcx\n"              \
+        "adcq   $0, %%rdx\n"                \
+        "nop    \n"                         \
+        "addq   %%rax, (%%rdi)\n"           \
+        "adcq   %%rdx, %%rcx\n"             \
+        "addq   $8, %%rdi\n"
 
 #define MULADDC_STOP                        \
         : "+c" (c), "+D" (d), "+S" (s)      \
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 1555867..0f7c42c 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -33,11 +33,17 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "platform_util.h"
+
 #define MBEDTLS_CAMELLIA_ENCRYPT     1
 #define MBEDTLS_CAMELLIA_DECRYPT     0
 
-#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH           -0x0024  /**< Invalid key length. */
-#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH         -0x0026  /**< Invalid data input length. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */
+
+#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
 
 /* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used.
  */
@@ -66,52 +72,68 @@
 #endif /* MBEDTLS_CAMELLIA_ALT */
 
 /**
- * \brief          Initialize CAMELLIA context
+ * \brief          Initialize a CAMELLIA context.
  *
- * \param ctx      CAMELLIA context to be initialized
+ * \param ctx      The CAMELLIA context to be initialized.
+ *                 This must not be \c NULL.
  */
 void mbedtls_camellia_init( mbedtls_camellia_context *ctx );
 
 /**
- * \brief          Clear CAMELLIA context
+ * \brief          Clear a CAMELLIA context.
  *
- * \param ctx      CAMELLIA context to be cleared
+ * \param ctx      The CAMELLIA context to be cleared. This may be \c NULL,
+ *                 in which case this function returns immediately. If it is not
+ *                 \c NULL, it must be initialized.
  */
 void mbedtls_camellia_free( mbedtls_camellia_context *ctx );
 
 /**
- * \brief          CAMELLIA key schedule (encryption)
+ * \brief          Perform a CAMELLIA key schedule operation for encryption.
  *
- * \param ctx      CAMELLIA context to be initialized
- * \param key      encryption key
- * \param keybits  must be 128, 192 or 256
+ * \param ctx      The CAMELLIA context to use. This must be initialized.
+ * \param key      The encryption key to use. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be either \c 128,
+ *                 \c 192 or \c 256.
  *
- * \return         0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
-int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits );
+int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits );
 
 /**
- * \brief          CAMELLIA key schedule (decryption)
+ * \brief          Perform a CAMELLIA key schedule operation for decryption.
  *
- * \param ctx      CAMELLIA context to be initialized
- * \param key      decryption key
- * \param keybits  must be 128, 192 or 256
+ * \param ctx      The CAMELLIA context to use. This must be initialized.
+ * \param key      The decryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be either \c 128,
+ *                 \c 192 or \c 256.
  *
- * \return         0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
-int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits );
+int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits );
 
 /**
- * \brief          CAMELLIA-ECB block encryption/decryption
+ * \brief          Perform a CAMELLIA-ECB block encryption/decryption operation.
  *
- * \param ctx      CAMELLIA context
- * \param mode     MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
- * \param input    16-byte input block
- * \param output   16-byte output block
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param input    The input block. This must be a readable buffer
+ *                 of size \c 16 Bytes.
+ * \param output   The output block. This must be a writable buffer
+ *                 of size \c 16 Bytes.
  *
- * \return         0 if successful
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
                     int mode,
@@ -120,9 +142,7 @@
 
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
 /**
- * \brief          CAMELLIA-CBC buffer encryption/decryption
- *                 Length should be a multiple of the block
- *                 size (16 bytes)
+ * \brief          Perform a CAMELLIA-CBC buffer encryption/decryption operation.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -132,15 +152,22 @@
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      CAMELLIA context
- * \param mode     MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
- * \param length   length of the input data
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param length   The length in Bytes of the input data \p input.
+ *                 This must be a multiple of \c 16 Bytes.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 16 Bytes. It is updated to allow streaming
+ *                 use as explained above.
+ * \param input    The buffer holding the input data. This must point to a
+ *                 readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must point to a
+ *                 writable buffer of length \p length Bytes.
  *
- * \return         0 if successful, or
- *                 MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
                     int mode,
@@ -152,11 +179,14 @@
 
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
 /**
- * \brief          CAMELLIA-CFB128 buffer encryption/decryption
+ * \brief          Perform a CAMELLIA-CFB128 buffer encryption/decryption
+ *                 operation.
  *
- * Note: Due to the nature of CFB you should use the same key schedule for
- * both encryption and decryption. So a context initialized with
- * mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT.
+ * \note           Due to the nature of CFB mode, you should use the same
+ *                 key for both encryption and decryption. In particular, calls
+ *                 to this function should be preceded by a key-schedule via
+ *                 mbedtls_camellia_setkey_enc() regardless of whether \p mode
+ *                 is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -166,16 +196,24 @@
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      CAMELLIA context
- * \param mode     MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
- * \param length   length of the input data
- * \param iv_off   offset in IV (updated after use)
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param length   The length of the input data \p input. Any value is allowed.
+ * \param iv_off   The current offset in the IV. This must be smaller
+ *                 than \c 16 Bytes. It is updated after this call to allow
+ *                 the aforementioned streaming usage.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 16 Bytes. It is updated after this call to
+ *                 allow the aforementioned streaming usage.
+ * \param input    The buffer holding the input data. This must be a readable
+ *                 buffer of size \p length Bytes.
+ * \param output   The buffer to hold the output data. This must be a writable
+ *                 buffer of length \p length Bytes.
  *
- * \return         0 if successful, or
- *                 MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
                        int mode,
@@ -188,11 +226,13 @@
 
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /**
- * \brief               CAMELLIA-CTR buffer encryption/decryption
+ * \brief      Perform a CAMELLIA-CTR buffer encryption/decryption operation.
  *
- * Note: Due to the nature of CTR you should use the same key schedule for
- * both encryption and decryption. So a context initialized with
- * mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and MBEDTLS_CAMELLIA_DECRYPT.
+ * *note       Due to the nature of CTR mode, you should use the same
+ *             key for both encryption and decryption. In particular, calls
+ *             to this function should be preceded by a key-schedule via
+ *             mbedtls_camellia_setkey_enc() regardless of whether \p mode
+ *             is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
  *
  * \warning    You must never reuse a nonce value with the same key. Doing so
  *             would void the encryption for the two messages encrypted with
@@ -215,41 +255,49 @@
  *             per-message nonce, handled by yourself, and the second one
  *             updated by this function internally.
  *
- *             For example, you might reserve the first 12 bytes for the
- *             per-message nonce, and the last 4 bytes for internal use. In that
- *             case, before calling this function on a new message you need to
- *             set the first 12 bytes of \p nonce_counter to your chosen nonce
- *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
- *             stream_block to be ignored). That way, you can encrypt at most
- *             2**96 messages of up to 2**32 blocks each with the same key.
+ *             For example, you might reserve the first \c 12 Bytes for the
+ *             per-message nonce, and the last \c 4 Bytes for internal use.
+ *             In that case, before calling this function on a new message you
+ *             need to set the first \c 12 Bytes of \p nonce_counter to your
+ *             chosen nonce value, the last four to \c 0, and \p nc_off to \c 0
+ *             (which will cause \p stream_block to be ignored). That way, you
+ *             can encrypt at most \c 2**96 messages of up to \c 2**32 blocks
+ *             each  with the same key.
  *
  *             The per-message nonce (or information sufficient to reconstruct
- *             it) needs to be communicated with the ciphertext and must be unique.
- *             The recommended way to ensure uniqueness is to use a message
- *             counter. An alternative is to generate random nonces, but this
- *             limits the number of messages that can be securely encrypted:
- *             for example, with 96-bit random nonces, you should not encrypt
- *             more than 2**32 messages with the same key.
+ *             it) needs to be communicated with the ciphertext and must be
+ *             unique. The recommended way to ensure uniqueness is to use a
+ *             message counter. An alternative is to generate random nonces,
+ *             but this limits the number of messages that can be securely
+ *             encrypted: for example, with 96-bit random nonces, you should
+ *             not encrypt more than 2**32 messages with the same key.
  *
  *             Note that for both stategies, sizes are measured in blocks and
- *             that a CAMELLIA block is 16 bytes.
+ *             that a CAMELLIA block is \c 16 Bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
  *             content must not be written to insecure storage and should be
  *             securely discarded as soon as it's no longer needed.
  *
- * \param ctx           CAMELLIA context
- * \param length        The length of the data
- * \param nc_off        The offset in the current stream_block (for resuming
+ * \param ctx           The CAMELLIA context to use. This must be initialized
+ *                      and bound to a key.
+ * \param length        The length of the input data \p input in Bytes.
+ *                      Any value is allowed.
+ * \param nc_off        The offset in the current \p stream_block (for resuming
  *                      within current cipher stream). The offset pointer to
- *                      should be 0 at the start of a stream.
- * \param nonce_counter The 128-bit nonce and counter.
- * \param stream_block  The saved stream-block for resuming. Is overwritten
- *                      by the function.
- * \param input         The input data stream
- * \param output        The output data stream
+ *                      should be \c 0 at the start of a stream. It is updated
+ *                      at the end of this call.
+ * \param nonce_counter The 128-bit nonce and counter. This must be a read/write
+ *                      buffer of length \c 16 Bytes.
+ * \param stream_block  The saved stream-block for resuming. This must be a
+ *                      read/write buffer of length \c 16 Bytes.
+ * \param input         The input data stream. This must be a readable buffer of
+ *                      size \p length Bytes.
+ * \param output        The output data stream. This must be a writable buffer
+ *                      of size \p length Bytes.
  *
- * \return         0 if successful
+ * \return              \c 0 if successful.
+ * \return              A negative error code on failure.
  */
 int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
                        size_t length,
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index dfb1b5e..3f6b8f6 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -57,7 +57,6 @@
 /* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -85,7 +84,7 @@
  *                  to make references valid, and prepare the context
  *                  for mbedtls_ccm_setkey() or mbedtls_ccm_free().
  *
- * \param ctx       The CCM context to initialize.
+ * \param ctx       The CCM context to initialize. This must not be \c NULL.
  */
 void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
 
@@ -93,9 +92,10 @@
  * \brief           This function initializes the CCM context set in the
  *                  \p ctx parameter and sets the encryption key.
  *
- * \param ctx       The CCM context to initialize.
+ * \param ctx       The CCM context to initialize. This must be an initialized
+ *                  context.
  * \param cipher    The 128-bit block cipher to use.
- * \param key       The encryption key.
+ * \param key       The encryption key. This must not be \c NULL.
  * \param keybits   The key size in bits. This must be acceptable by the cipher.
  *
  * \return          \c 0 on success.
@@ -110,7 +110,8 @@
  * \brief   This function releases and clears the specified CCM context
  *          and underlying cipher sub-context.
  *
- * \param ctx       The CCM context to clear.
+ * \param ctx       The CCM context to clear. If this is \c NULL, the function
+ *                  has no effect. Otherwise, this must be initialized.
  */
 void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
 
@@ -123,19 +124,27 @@
  *                  \p tag = \p output + \p length, and make sure that the
  *                  output buffer is at least \p length + \p tag_len wide.
  *
- * \param ctx       The CCM context to use for encryption.
+ * \param ctx       The CCM context to use for encryption. This must be
+ *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
- * \param iv        Initialization vector (nonce).
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
  * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
  *                  or 13. The length L of the message length field is
  *                  15 - \p iv_len.
- * \param add       The additional data field.
+ * \param add       The additional data field. If \p add_len is greater than
+ *                  zero, \p add must be a readable buffer of at least that
+ *                  length.
  * \param add_len   The length of additional data in Bytes.
- *                  Must be less than 2^16 - 2^8.
- * \param input     The buffer holding the input data.
- * \param output    The buffer holding the output data.
- *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the authentication field.
+ *                  This must be less than `2^16 - 2^8`.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  4, 6, 8, 10, 12, 14 or 16.
  *
@@ -161,23 +170,30 @@
  *                  the tag length has to be encoded into the \p iv passed to
  *                  this function.
  *
- * \param ctx       The CCM context to use for encryption.
+ * \param ctx       The CCM context to use for encryption. This must be
+ *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
- * \param iv        Initialization vector (nonce).
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
  * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
  *                  or 13. The length L of the message length field is
  *                  15 - \p iv_len.
- * \param add       The additional data field.
+ * \param add       The additional data field. This must be a readable buffer of
+ *                  at least \p add_len Bytes.
  * \param add_len   The length of additional data in Bytes.
- *                  Must be less than 2^16 - 2^8.
- * \param input     The buffer holding the input data.
- * \param output    The buffer holding the output data.
- *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the authentication field.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  0, 4, 6, 8, 10, 12, 14 or 16.
  *
- * \warning         Passing 0 as \p tag_len means that the message is no
+ * \warning         Passing \c 0 as \p tag_len means that the message is no
  *                  longer authenticated.
  *
  * \return          \c 0 on success.
@@ -193,20 +209,27 @@
  * \brief           This function performs a CCM authenticated decryption of a
  *                  buffer.
  *
- * \param ctx       The CCM context to use for decryption.
+ * \param ctx       The CCM context to use for decryption. This must be
+ *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
- * \param iv        Initialization vector (nonce).
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
  * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
  *                  or 13. The length L of the message length field is
  *                  15 - \p iv_len.
- * \param add       The additional data field.
+ * \param add       The additional data field. This must be a readable buffer
+ *                  of at least that \p add_len Bytes..
  * \param add_len   The length of additional data in Bytes.
- *                  Must be less than 2^16 - 2^8.
- * \param input     The buffer holding the input data.
- * \param output    The buffer holding the output data.
- *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the authentication field.
- * \param tag_len   The length of the authentication field in Bytes.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  4, 6, 8, 10, 12, 14 or 16.
  *
  * \return          \c 0 on success. This indicates that the message is authentic.
@@ -228,23 +251,30 @@
  *                  this function as \p tag_len. (\p tag needs to be adjusted
  *                  accordingly.)
  *
- * \param ctx       The CCM context to use for decryption.
+ * \param ctx       The CCM context to use for decryption. This must be
+ *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
- * \param iv        Initialization vector (nonce).
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
  * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
  *                  or 13. The length L of the message length field is
  *                  15 - \p iv_len.
- * \param add       The additional data field.
+ * \param add       The additional data field. This must be a readable buffer of
+ *                  at least that \p add_len Bytes.
  * \param add_len   The length of additional data in Bytes.
- *                  Must be less than 2^16 - 2^8.
- * \param input     The buffer holding the input data.
- * \param output    The buffer holding the output data.
- *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the authentication field.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the authentication field in Bytes.
  *                  0, 4, 6, 8, 10, 12, 14 or 16.
  *
- * \warning         Passing 0 as \p tag_len means that the message is no
+ * \warning         Passing \c 0 as \p tag_len means that the message is nos
  *                  longer authenticated.
  *
  * \return          \c 0 on success.
diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h
index 529f22d..2ae5e6e 100644
--- a/include/mbedtls/chacha20.h
+++ b/include/mbedtls/chacha20.h
@@ -83,13 +83,18 @@
  *                  \c mbedtls_chacha20_free().
  *
  * \param ctx       The ChaCha20 context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx );
 
 /**
- * \brief           This function releases and clears the specified ChaCha20 context.
+ * \brief           This function releases and clears the specified
+ *                  ChaCha20 context.
  *
- * \param ctx       The ChaCha20 context to clear.
+ * \param ctx       The ChaCha20 context to clear. This may be \c NULL,
+ *                  in which case this function is a no-op. If it is not
+ *                  \c NULL, it must point to an initialized context.
+ *
  */
 void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx );
 
@@ -102,7 +107,9 @@
  *                  \c mbedtls_chacha_update().
  *
  * \param ctx       The ChaCha20 context to which the key should be bound.
- * \param key       The encryption/decryption key. Must be 32 bytes in length.
+ *                  It must be initialized.
+ * \param key       The encryption/decryption key. This must be \c 32 Bytes
+ *                  in length.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL.
@@ -121,8 +128,9 @@
  *                  messages encrypted with the same nonce and key.
  *
  * \param ctx       The ChaCha20 context to which the nonce should be bound.
- * \param nonce     The nonce. Must be 12 bytes in size.
- * \param counter   The initial counter value. This is usually 0.
+ *                  It must be initialized and bound to a key.
+ * \param nonce     The nonce. This must be \c 12 Bytes in size.
+ * \param counter   The initial counter value. This is usually \c 0.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is
@@ -150,16 +158,16 @@
  *                  key and nonce.
  *
  * \param ctx       The ChaCha20 context to use for encryption or decryption.
- * \param size      The length of the input data in bytes.
+ *                  It must be initialized and bound to a key and nonce.
+ * \param size      The length of the input data in Bytes.
  * \param input     The buffer holding the input data.
- *                  This pointer can be NULL if size == 0.
+ *                  This pointer can be \c NULL if `size == 0`.
  * \param output    The buffer holding the output data.
- *                  Must be able to hold \p size bytes.
- *                  This pointer can be NULL if size == 0.
+ *                  This must be able to hold \p size Bytes.
+ *                  This pointer can be \c NULL if `size == 0`.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if the ctx, input, or
- *                  output pointers are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
                              size_t size,
@@ -180,19 +188,19 @@
  * \note            The \p input and \p output pointers must either be equal or
  *                  point to non-overlapping buffers.
  *
- * \param key       The encryption/decryption key. Must be 32 bytes in length.
- * \param nonce     The nonce. Must be 12 bytes in size.
- * \param counter   The initial counter value. This is usually 0.
- * \param size      The length of the input data in bytes.
+ * \param key       The encryption/decryption key.
+ *                  This must be \c 32 Bytes in length.
+ * \param nonce     The nonce. This must be \c 12 Bytes in size.
+ * \param counter   The initial counter value. This is usually \c 0.
+ * \param size      The length of the input data in Bytes.
  * \param input     The buffer holding the input data.
- *                  This pointer can be NULL if size == 0.
+ *                  This pointer can be \c NULL if `size == 0`.
  * \param output    The buffer holding the output data.
- *                  Must be able to hold \p size bytes.
- *                  This pointer can be NULL if size == 0.
+ *                  This must be able to hold \p size Bytes.
+ *                  This pointer can be \c NULL if `size == 0`.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if key, nonce, input,
- *                  or output is NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_chacha20_crypt( const unsigned char key[32],
                             const unsigned char nonce[12],
diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h
index 7de6f4e..49e615d 100644
--- a/include/mbedtls/chachapoly.h
+++ b/include/mbedtls/chachapoly.h
@@ -115,27 +115,29 @@
  *                  all previous outputs of \c mbedtls_chachapoly_update(),
  *                  otherwise you can now safely use the plaintext.
  *
- * \param ctx       The ChachaPoly context to initialize.
+ * \param ctx       The ChachaPoly context to initialize. Must not be \c NULL.
  */
 void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx );
 
 /**
- * \brief           This function releases and clears the specified ChaCha20-Poly1305 context.
+ * \brief           This function releases and clears the specified
+ *                  ChaCha20-Poly1305 context.
  *
- * \param ctx       The ChachaPoly context to clear.
+ * \param ctx       The ChachaPoly context to clear. This may be \c NULL, in which
+ *                  case this function is a no-op.
  */
 void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx );
 
 /**
- * \brief           This function sets the ChaCha20-Poly1305 symmetric encryption key.
+ * \brief           This function sets the ChaCha20-Poly1305
+ *                  symmetric encryption key.
  *
  * \param ctx       The ChaCha20-Poly1305 context to which the key should be
- *                  bound.
- * \param key       The 256-bit (32 bytes) key.
+ *                  bound. This must be initialized.
+ * \param key       The \c 256 Bit (\c 32 Bytes) key.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if \p ctx or \p key are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
                                const unsigned char key[32] );
@@ -155,14 +157,15 @@
  * \warning         Decryption with the piecewise API is discouraged, see the
  *                  warning on \c mbedtls_chachapoly_init().
  *
- * \param ctx       The ChaCha20-Poly1305 context.
- * \param nonce     The nonce/IV to use for the message. Must be 12 bytes.
+ * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
+ *                  and bound to a key.
+ * \param nonce     The nonce/IV to use for the message.
+ *                  This must be a redable buffer of length \c 12 Bytes.
  * \param mode      The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
  *                  #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if \p ctx or \p mac are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
                                const unsigned char nonce[12],
@@ -193,11 +196,12 @@
  * \warning         Decryption with the piecewise API is discouraged, see the
  *                  warning on \c mbedtls_chachapoly_init().
  *
- * \param ctx       The ChaCha20-Poly1305 context to use.
- * \param aad_len   The length (in bytes) of the AAD. The length has no
+ * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
+ *                  and bound to a key.
+ * \param aad_len   The length in Bytes of the AAD. The length has no
  *                  restrictions.
  * \param aad       Buffer containing the AAD.
- *                  This pointer can be NULL if aad_len == 0.
+ *                  This pointer can be \c NULL if `aad_len == 0`.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
@@ -227,20 +231,19 @@
  * \warning         Decryption with the piecewise API is discouraged, see the
  *                  warning on \c mbedtls_chachapoly_init().
  *
- * \param ctx       The ChaCha20-Poly1305 context to use.
+ * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
  * \param len       The length (in bytes) of the data to encrypt or decrypt.
  * \param input     The buffer containing the data to encrypt or decrypt.
- *                  This pointer can be NULL if len == 0.
- * \param output    The buffer to where the encrypted or decrypted data is written.
- *                  Must be able to hold \p len bytes.
- *                  This pointer can be NULL if len == 0.
+ *                  This pointer can be \c NULL if `len == 0`.
+ * \param output    The buffer to where the encrypted or decrypted data is
+ *                  written. This must be able to hold \p len bytes.
+ *                  This pointer can be \c NULL if `len == 0`.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if \p ctx, \p input, or \p output are NULL.
  * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
  *                  if the operation has not been started or has been
  *                  finished.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
                                size_t len,
@@ -251,18 +254,17 @@
  * \brief           This function finished the ChaCha20-Poly1305 operation and
  *                  generates the MAC (authentication tag).
  *
- * \param ctx       The ChaCha20-Poly1305 context to use.
+ * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
  * \param mac       The buffer to where the 128-bit (16 bytes) MAC is written.
  *
  * \warning         Decryption with the piecewise API is discouraged, see the
  *                  warning on \c mbedtls_chachapoly_init().
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if \p ctx or \p mac are NULL.
  * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
  *                  if the operation has not been started or has been
  *                  finished.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
                                unsigned char mac[16] );
@@ -280,20 +282,21 @@
  *                  and key.
  *
  * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
+ *                  This must be initialized.
  * \param length    The length (in bytes) of the data to encrypt or decrypt.
  * \param nonce     The 96-bit (12 bytes) nonce/IV to use.
- * \param aad       The buffer containing the additional authenticated data (AAD).
- *                  This pointer can be NULL if aad_len == 0.
+ * \param aad       The buffer containing the additional authenticated
+ *                  data (AAD). This pointer can be \c NULL if `aad_len == 0`.
  * \param aad_len   The length (in bytes) of the AAD data to process.
  * \param input     The buffer containing the data to encrypt or decrypt.
- *                  This pointer can be NULL if ilen == 0.
- * \param output    The buffer to where the encrypted or decrypted data is written.
- *                  This pointer can be NULL if ilen == 0.
- * \param tag       The buffer to where the computed 128-bit (16 bytes) MAC is written.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param output    The buffer to where the encrypted or decrypted data
+ *                  is written. This pointer can be \c NULL if `ilen == 0`.
+ * \param tag       The buffer to where the computed 128-bit (16 bytes) MAC
+ *                  is written. This must not be \c NULL.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if one or more of the required parameters are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
                                         size_t length,
@@ -312,22 +315,22 @@
  *                  \c mbedtls_chachapoly_setkey().
  *
  * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
- * \param length    The length (in bytes) of the data to decrypt.
- * \param nonce     The 96-bit (12 bytes) nonce/IV to use.
+ * \param length    The length (in Bytes) of the data to decrypt.
+ * \param nonce     The \c 96 Bit (\c 12 bytes) nonce/IV to use.
  * \param aad       The buffer containing the additional authenticated data (AAD).
- *                  This pointer can be NULL if aad_len == 0.
+ *                  This pointer can be \c NULL if `aad_len == 0`.
  * \param aad_len   The length (in bytes) of the AAD data to process.
  * \param tag       The buffer holding the authentication tag.
+ *                  This must be a readable buffer of length \c 16 Bytes.
  * \param input     The buffer containing the data to decrypt.
- *                  This pointer can be NULL if ilen == 0.
+ *                  This pointer can be \c NULL if `ilen == 0`.
  * \param output    The buffer to where the decrypted data is written.
- *                  This pointer can be NULL if ilen == 0.
+ *                  This pointer can be \c NULL if `ilen == 0`.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if one or more of the required parameters are NULL.
  * \return          #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
  *                  if the data was not authentic.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
                                      size_t length,
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 425e3ea..b86e580 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -114,6 +114,7 @@
       defined(MBEDTLS_ECDSA_SIGN_ALT)          || \
       defined(MBEDTLS_ECDSA_VERIFY_ALT)        || \
       defined(MBEDTLS_ECDSA_GENKEY_ALT)        || \
+      defined(MBEDTLS_ECP_INTERNAL_ALT)        || \
       defined(MBEDTLS_ECP_ALT) )
 #error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
 #endif
@@ -137,6 +138,10 @@
 #error "MBEDTLS_ECP_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
+#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
+#endif
+
 #if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) &&      \
                                     !defined(MBEDTLS_SHA256_C))
 #error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 58a5d63..922b6c3 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -36,6 +36,7 @@
 #endif
 
 #include <stddef.h>
+#include "mbedtls/platform_util.h"
 
 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 #define MBEDTLS_CIPHER_MODE_AEAD
@@ -336,11 +337,12 @@
  * \brief               This function retrieves the cipher-information
  *                      structure associated with the given cipher name.
  *
- * \param cipher_name   Name of the cipher to search for.
+ * \param cipher_name   Name of the cipher to search for. This must not be
+ *                      \c NULL.
  *
  * \return              The cipher information structure associated with the
  *                      given \p cipher_name.
- * \return              NULL if the associated cipher information is not found.
+ * \return              \c NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
 
@@ -352,7 +354,7 @@
  *
  * \return              The cipher information structure associated with the
  *                      given \p cipher_type.
- * \return              NULL if the associated cipher information is not found.
+ * \return              \c NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
 
@@ -368,7 +370,7 @@
  *
  * \return              The cipher information structure associated with the
  *                      given \p cipher_id.
- * \return              NULL if the associated cipher information is not found.
+ * \return              \c NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
                                               int key_bitlen,
@@ -376,6 +378,8 @@
 
 /**
  * \brief               This function initializes a \p cipher_context as NONE.
+ *
+ * \param ctx           The context to be initialized. This must not be \c NULL.
  */
 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
 
@@ -383,6 +387,10 @@
  * \brief               This function frees and clears the cipher-specific
  *                      context of \p ctx. Freeing \p ctx itself remains the
  *                      responsibility of the caller.
+ *
+ * \param ctx           The context to be freed. If this is \c NULL, the
+ *                      function has no effect, otherwise this must point to an
+ *                      initialized context.
  */
 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
 
@@ -392,7 +400,7 @@
  *                      structure with the appropriate values. It also clears
  *                      the structure.
  *
- * \param ctx           The context to initialize. May not be NULL.
+ * \param ctx           The context to initialize. This must be initialized.
  * \param cipher_info   The cipher to use.
  *
  * \return              \c 0 on success.
@@ -405,19 +413,22 @@
  * In future versions, the caller will be required to call
  * mbedtls_cipher_init() on the structure first.
  */
-int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info );
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
+                          const mbedtls_cipher_info_t *cipher_info );
 
 /**
  * \brief        This function returns the block size of the given cipher.
  *
- * \param ctx    The context of the cipher. Must be initialized.
+ * \param ctx    The context of the cipher. This must be initialized.
  *
- * \return       The size of the blocks of the cipher.
- * \return       0 if \p ctx has not been initialized.
+ * \return       The block size of the underlying cipher.
+ * \return       \c 0 if \p ctx has not been initialized.
  */
-static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
+static inline unsigned int mbedtls_cipher_get_block_size(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
         return 0;
 
     return ctx->cipher_info->block_size;
@@ -427,14 +438,16 @@
  * \brief        This function returns the mode of operation for
  *               the cipher. For example, MBEDTLS_MODE_CBC.
  *
- * \param ctx    The context of the cipher. Must be initialized.
+ * \param ctx    The context of the cipher. This must be initialized.
  *
  * \return       The mode of operation.
  * \return       #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
  */
-static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx )
+static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_MODE_NONE;
 
     return ctx->cipher_info->mode;
@@ -444,15 +457,17 @@
  * \brief       This function returns the size of the IV or nonce
  *              of the cipher, in Bytes.
  *
- * \param ctx   The context of the cipher. Must be initialized.
+ * \param ctx   The context of the cipher. This must be initialized.
  *
  * \return      The recommended IV size if no IV has been set.
  * \return      \c 0 for ciphers not using an IV or a nonce.
  * \return      The actual size if an IV has been set.
  */
-static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx )
+static inline int mbedtls_cipher_get_iv_size(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
         return 0;
 
     if( ctx->iv_size != 0 )
@@ -464,14 +479,17 @@
 /**
  * \brief               This function returns the type of the given cipher.
  *
- * \param ctx           The context of the cipher. Must be initialized.
+ * \param ctx           The context of the cipher. This must be initialized.
  *
  * \return              The type of the cipher.
  * \return              #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
  */
-static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx )
+static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_CIPHER_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_CIPHER_NONE;
 
     return ctx->cipher_info->type;
@@ -481,14 +499,16 @@
  * \brief               This function returns the name of the given cipher
  *                      as a string.
  *
- * \param ctx           The context of the cipher. Must be initialized.
+ * \param ctx           The context of the cipher. This must be initialized.
  *
  * \return              The name of the cipher.
  * \return              NULL if \p ctx has not been not initialized.
  */
-static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx )
+static inline const char *mbedtls_cipher_get_name(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
         return 0;
 
     return ctx->cipher_info->name;
@@ -497,15 +517,18 @@
 /**
  * \brief               This function returns the key length of the cipher.
  *
- * \param ctx           The context of the cipher. Must be initialized.
+ * \param ctx           The context of the cipher. This must be initialized.
  *
  * \return              The key length of the cipher in bits.
  * \return              #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
  *                      initialized.
  */
-static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx )
+static inline int mbedtls_cipher_get_key_bitlen(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_KEY_LENGTH_NONE;
 
     return (int) ctx->cipher_info->key_bitlen;
@@ -514,14 +537,17 @@
 /**
  * \brief          This function returns the operation of the given cipher.
  *
- * \param ctx      The context of the cipher. Must be initialized.
+ * \param ctx      The context of the cipher. This must be initialized.
  *
  * \return         The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
  * \return         #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
  */
-static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx )
+static inline mbedtls_operation_t mbedtls_cipher_get_operation(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_OPERATION_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_OPERATION_NONE;
 
     return ctx->operation;
@@ -530,11 +556,11 @@
 /**
  * \brief               This function sets the key to use with the given context.
  *
- * \param ctx           The generic cipher context. May not be NULL. Must have
- *                      been initialized using mbedtls_cipher_info_from_type()
- *                      or mbedtls_cipher_info_from_string().
- * \param key           The key to use.
- * \param key_bitlen    The key length to use, in bits.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a cipher information structure.
+ * \param key           The key to use. This must be a readable buffer of at
+ *                      least \p key_bitlen Bits.
+ * \param key_bitlen    The key length to use, in Bits.
  * \param operation     The operation that the key will be used for:
  *                      #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
  *
@@ -543,8 +569,10 @@
  *                      parameter-verification failure.
  * \return              A cipher-specific error code on failure.
  */
-int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
-                   int key_bitlen, const mbedtls_operation_t operation );
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *key,
+                           int key_bitlen,
+                           const mbedtls_operation_t operation );
 
 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
 /**
@@ -553,7 +581,8 @@
  *
  *                      The default passing mode is PKCS7 padding.
  *
- * \param ctx           The generic cipher context.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a cipher information structure.
  * \param mode          The padding mode.
  *
  * \return              \c 0 on success.
@@ -562,7 +591,8 @@
  * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
  *                      does not support padding.
  */
-int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode );
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+                                     mbedtls_cipher_padding_t mode );
 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
 
 /**
@@ -572,8 +602,10 @@
  * \note            Some ciphers do not use IVs nor nonce. For these
  *                  ciphers, this function has no effect.
  *
- * \param ctx       The generic cipher context.
- * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \param ctx       The generic cipher context. This must be initialized and
+ *                  bound to a cipher information structure.
+ * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
+ *                  must be a readable buffer of at least \p iv_len Bytes.
  * \param iv_len    The IV length for ciphers with variable-size IV.
  *                  This parameter is discarded by ciphers with fixed-size IV.
  *
@@ -582,12 +614,13 @@
  *                  parameter-verification failure.
  */
 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
-                   const unsigned char *iv, size_t iv_len );
+                           const unsigned char *iv,
+                           size_t iv_len );
 
 /**
  * \brief         This function resets the cipher state.
  *
- * \param ctx     The generic cipher context.
+ * \param ctx     The generic cipher context. This must be initialized.
  *
  * \return        \c 0 on success.
  * \return        #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -599,11 +632,13 @@
 /**
  * \brief               This function adds additional data for AEAD ciphers.
  *                      Currently supported with GCM and ChaCha20+Poly1305.
- *                      Must be called exactly once, after mbedtls_cipher_reset().
+ *                      This must be called exactly once, after
+ *                      mbedtls_cipher_reset().
  *
- * \param ctx           The generic cipher context.
- * \param ad            The additional data to use.
- * \param ad_len        the Length of \p ad.
+ * \param ctx           The generic cipher context. This must be initialized.
+ * \param ad            The additional data to use. This must be a readable
+ *                      buffer of at least \p ad_len Bytes.
+ * \param ad_len        the Length of \p ad Bytes.
  *
  * \return              \c 0 on success.
  * \return              A specific error code on failure.
@@ -627,14 +662,17 @@
  *                      mbedtls_cipher_finish(), must have \p ilen as a
  *                      multiple of the block size of the cipher.
  *
- * \param ctx           The generic cipher context.
- * \param input         The buffer holding the input data.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
  * \param ilen          The length of the input data.
- * \param output        The buffer for the output data. Must be able to hold at
- *                      least \p ilen + block_size. Must not be the same buffer
- *                      as input.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least `ilen + block_size`. This must not be the
+ *                      same buffer as \p input.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
  *
  * \return              \c 0 on success.
  * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -652,9 +690,12 @@
  *                      contained in it is padded to the size of
  *                      the last block, and written to the \p output buffer.
  *
- * \param ctx           The generic cipher context.
- * \param output        The buffer to write data to. Needs block_size available.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
+ * \param output        The buffer to write data to. This needs to be a writable
+ *                      buffer of at least \p block_size Bytes.
  * \param olen          The length of the data written to the \p output buffer.
+ *                      This may not be \c NULL.
  *
  * \return              \c 0 on success.
  * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -672,10 +713,14 @@
 /**
  * \brief               This function writes a tag for AEAD ciphers.
  *                      Currently supported with GCM and ChaCha20+Poly1305.
- *                      Must be called after mbedtls_cipher_finish().
+ *                      This must be called after mbedtls_cipher_finish().
  *
- * \param ctx           The generic cipher context.
- * \param tag           The buffer to write the tag to.
+ * \param ctx           The generic cipher context. This must be initialized,
+ *                      bound to a key, and have just completed a cipher
+ *                      operation through mbedtls_cipher_finish() the tag for
+ *                      which should be written.
+ * \param tag           The buffer to write the tag to. This must be a writable
+ *                      buffer of at least \p tag_len Bytes.
  * \param tag_len       The length of the tag to write.
  *
  * \return              \c 0 on success.
@@ -687,10 +732,11 @@
 /**
  * \brief               This function checks the tag for AEAD ciphers.
  *                      Currently supported with GCM and ChaCha20+Poly1305.
- *                      Must be called after mbedtls_cipher_finish().
+ *                      This must be called after mbedtls_cipher_finish().
  *
- * \param ctx           The generic cipher context.
- * \param tag           The buffer holding the tag.
+ * \param ctx           The generic cipher context. This must be initialized.
+ * \param tag           The buffer holding the tag. This must be a readable
+ *                      buffer of at least \p tag_len Bytes.
  * \param tag_len       The length of the tag to check.
  *
  * \return              \c 0 on success.
@@ -704,18 +750,22 @@
  * \brief               The generic all-in-one encryption/decryption function,
  *                      for all ciphers except AEAD constructs.
  *
- * \param ctx           The generic cipher context.
+ * \param ctx           The generic cipher context. This must be initialized.
  * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
  * \param iv_len        The IV length for ciphers with variable-size IV.
  *                      This parameter is discarded by ciphers with fixed-size
  *                      IV.
- * \param input         The buffer holding the input data.
- * \param ilen          The length of the input data.
- * \param output        The buffer for the output data. Must be able to hold at
- *                      least \p ilen + block_size. Must not be the same buffer
- *                      as input.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
+ * \param ilen          The length of the input data in Bytes.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least `ilen + block_size`. This must not be the
+ *                      same buffer as \p input.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
  *
  * \note                Some ciphers do not use IVs nor nonce. For these
  *                      ciphers, use \p iv = NULL and \p iv_len = 0.
@@ -738,19 +788,26 @@
 /**
  * \brief               The generic autenticated encryption (AEAD) function.
  *
- * \param ctx           The generic cipher context.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
  * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
  * \param iv_len        The IV length for ciphers with variable-size IV.
  *                      This parameter is discarded by ciphers with fixed-size IV.
- * \param ad            The additional data to authenticate.
+ * \param ad            The additional data to authenticate. This must be a
+ *                      readable buffer of at least \p ad_len Bytes.
  * \param ad_len        The length of \p ad.
- * \param input         The buffer holding the input data.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
  * \param ilen          The length of the input data.
- * \param output        The buffer for the output data.
- *                      Must be able to hold at least \p ilen.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least \p ilen Bytes.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
- * \param tag           The buffer for the authentication tag.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ * \param tag           The buffer for the authentication tag. This must be a
+ *                      writable buffer of at least \p tag_len Bytes.
  * \param tag_len       The desired length of the authentication tag.
  *
  * \return              \c 0 on success.
@@ -772,19 +829,26 @@
  *                      is zeroed out to prevent the unauthentic plaintext being
  *                      used, making this interface safer.
  *
- * \param ctx           The generic cipher context.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      and bound to a key.
  * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
  * \param iv_len        The IV length for ciphers with variable-size IV.
  *                      This parameter is discarded by ciphers with fixed-size IV.
- * \param ad            The additional data to be authenticated.
+ * \param ad            The additional data to be authenticated. This must be a
+ *                      readable buffer of at least \p ad_len Bytes.
  * \param ad_len        The length of \p ad.
- * \param input         The buffer holding the input data.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
  * \param ilen          The length of the input data.
  * \param output        The buffer for the output data.
- *                      Must be able to hold at least \p ilen.
+ *                      This must be able to hold at least \p ilen Bytes.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
- * \param tag           The buffer holding the authentication tag.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ * \param tag           The buffer holding the authentication tag. This must be
+ *                      a readable buffer of at least \p tag_len Bytes.
  * \param tag_len       The length of the authentication tag.
  *
  * \return              \c 0 on success.
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 16ed503..91cc5bd 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -256,6 +256,48 @@
  */
 //#define MBEDTLS_DEPRECATED_REMOVED
 
+/**
+ * \def MBEDTLS_CHECK_PARAMS
+ *
+ * This configuration option controls whether the library validates more of
+ * the parameters passed to it.
+ *
+ * When this flag is not defined, the library only attempts to validate an
+ * input parameter if: (1) they may come from the outside world (such as the
+ * network, the filesystem, etc.) or (2) not validating them could result in
+ * internal memory errors such as overflowing a buffer controlled by the
+ * library. On the other hand, it doesn't attempt to validate parameters whose
+ * values are fully controlled by the application (such as pointers).
+ *
+ * When this flag is defined, the library additionally attempts to validate
+ * parameters that are fully controlled by the application, and should always
+ * be valid if the application code is fully correct and trusted.
+ *
+ * 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
+ *
+ * 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).
+ *
+ * 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.
+ *
+ * Uncomment to enable validation of application-controlled parameters.
+ */
+//#define MBEDTLS_CHECK_PARAMS
+
 /* \} name SECTION: System support */
 
 /**
@@ -414,11 +456,11 @@
  *      unsigned char mbedtls_internal_ecp_grp_capable(
  *          const mbedtls_ecp_group *grp )
  *      int  mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
- *      void mbedtls_internal_ecp_deinit( const mbedtls_ecp_group *grp )
+ *      void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp )
  * The mbedtls_internal_ecp_grp_capable function should return 1 if the
  * replacement functions implement arithmetic for the given group and 0
  * otherwise.
- * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_deinit are
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are
  * called before and after each point operation and provide an opportunity to
  * implement optimized set up and tear down instructions.
  *
@@ -2996,6 +3038,36 @@
 //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
 //#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, a default definition is
+ *              provided that invokes the function mbedtls_param_failed(),
+ *              which is declared in platform_util.h for the benefit of the
+ *              library, but that 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).
+ *
+ *              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 )
+
 /* SSL Cache options */
 //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
 //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
@@ -3004,31 +3076,65 @@
 
 /** \def MBEDTLS_SSL_MAX_CONTENT_LEN
  *
- * Maximum fragment length in bytes.
+ * Maximum length (in bytes) of incoming and outgoing plaintext fragments.
  *
- * Determines the size of both the incoming and outgoing TLS I/O buffers.
+ * This determines the size of both the incoming and outgoing TLS I/O buffers
+ * in such a way that both are capable of holding the specified amount of
+ * plaintext data, regardless of the protection mechanism used.
  *
- * Uncommenting MBEDTLS_SSL_IN_CONTENT_LEN and/or MBEDTLS_SSL_OUT_CONTENT_LEN
- * will override this length by setting maximum incoming and/or outgoing
- * fragment length, respectively.
+ * To configure incoming and outgoing I/O buffers separately, use
+ * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN,
+ * which overwrite the value set by this option.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of both
+ * incoming and outgoing I/O buffers.
  */
 //#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384
 
 /** \def MBEDTLS_SSL_IN_CONTENT_LEN
  *
- * Maximum incoming fragment length in bytes.
+ * Maximum length (in bytes) of incoming plaintext fragments.
  *
- * Uncomment to set the size of the inward TLS buffer independently of the
- * outward buffer.
+ * This determines the size of the incoming TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option is undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of the incoming I/O buffer
+ * independently of the outgoing I/O buffer.
  */
 //#define MBEDTLS_SSL_IN_CONTENT_LEN              16384
 
 /** \def MBEDTLS_SSL_OUT_CONTENT_LEN
  *
- * Maximum outgoing fragment length in bytes.
+ * Maximum length (in bytes) of outgoing plaintext fragments.
  *
- * Uncomment to set the size of the outward TLS buffer independently of the
- * inward buffer.
+ * This determines the size of the outgoing TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
  *
  * It is possible to save RAM by setting a smaller outward buffer, while keeping
  * the default inward 16384 byte buffer to conform to the TLS specification.
@@ -3038,11 +3144,8 @@
  * The specific size requirement depends on the configured ciphers and any
  * certificate data which is sent during the handshake.
  *
- * For absolute minimum RAM usage, it's best to enable
- * MBEDTLS_SSL_MAX_FRAGMENT_LENGTH and reduce MBEDTLS_SSL_MAX_CONTENT_LEN. This
- * reduces both incoming and outgoing buffer sizes. However this is only
- * guaranteed if the other end of the connection also supports the TLS
- * max_fragment_len extension. Otherwise the connection may fail.
+ * Uncomment to set the maximum plaintext size of the outgoing I/O buffer
+ * independently of the incoming I/O buffer.
  */
 //#define MBEDTLS_SSL_OUT_CONTENT_LEN             16384
 
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index c91ca58..10f9389 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -239,18 +239,20 @@
 /**
  * \brief              This function updates the state of the CTR_DRBG context.
  *
- * \note               If \p add_len is greater than
- *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
- *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
- *                     The remaining Bytes are silently discarded.
- *
  * \param ctx          The CTR_DRBG context.
  * \param additional   The data to update the state with.
- * \param add_len      Length of \p additional data.
+ * \param add_len      Length of \p additional in bytes. This must be at
+ *                     most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
  *
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
+ *                     \p add_len is more than
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ * \return             An error from the underlying AES cipher on failure.
  */
-void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
-                      const unsigned char *additional, size_t add_len );
+int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
+                                 const unsigned char *additional,
+                                 size_t add_len );
 
 /**
  * \brief   This function updates a CTR_DRBG instance with additional
@@ -290,6 +292,35 @@
 int mbedtls_ctr_drbg_random( void *p_rng,
                      unsigned char *output, size_t output_len );
 
+
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief              This function updates the state of the CTR_DRBG context.
+ *
+ * \deprecated         Superseded by mbedtls_ctr_drbg_update_ret()
+ *                     in 2.16.0.
+ *
+ * \note               If \p add_len is greater than
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
+ *                     The remaining Bytes are silently discarded.
+ *
+ * \param ctx          The CTR_DRBG context.
+ * \param additional   The data to update the state with.
+ * \param add_len      Length of \p additional data.
+ */
+MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
+    mbedtls_ctr_drbg_context *ctx,
+    const unsigned char *additional,
+    size_t add_len );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
 #if defined(MBEDTLS_FS_IO)
 /**
  * \brief               This function writes a seed file.
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index ef8db67..736444b 100644
--- a/include/mbedtls/debug.h
+++ b/include/mbedtls/debug.h
@@ -65,6 +65,11 @@
     mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt )
 #endif
 
+#if defined(MBEDTLS_ECDH_C)
+#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr )               \
+    mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr )
+#endif
+
 #else /* MBEDTLS_DEBUG_C */
 
 #define MBEDTLS_SSL_DEBUG_MSG( level, args )            do { } while( 0 )
@@ -73,6 +78,7 @@
 #define MBEDTLS_SSL_DEBUG_MPI( level, text, X )         do { } while( 0 )
 #define MBEDTLS_SSL_DEBUG_ECP( level, text, X )         do { } while( 0 )
 #define MBEDTLS_SSL_DEBUG_CRT( level, text, crt )       do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr )     do { } while( 0 )
 
 #endif /* MBEDTLS_DEBUG_C */
 
@@ -221,6 +227,36 @@
                       const char *text, const mbedtls_x509_crt *crt );
 #endif
 
+#if defined(MBEDTLS_ECDH_C)
+typedef enum
+{
+    MBEDTLS_DEBUG_ECDH_Q,
+    MBEDTLS_DEBUG_ECDH_QP,
+    MBEDTLS_DEBUG_ECDH_Z,
+} mbedtls_debug_ecdh_attr;
+
+/**
+ * \brief   Print a field of the ECDH structure in the SSL context to the debug
+ *          output. This function is always used through the
+ *          MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
+ *          and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param ecdh      the ECDH context
+ * \param attr      the identifier of the attribute being output
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
+                                const char *file, int line,
+                                const mbedtls_ecdh_context *ecdh,
+                                mbedtls_debug_ecdh_attr attr );
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index 8e2d020..a5452c1 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -127,9 +127,15 @@
 void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
 
 /**
- * \brief          This function parses the ServerKeyExchange parameters.
+ * \brief          This function parses the DHM parameters in a
+ *                 TLS ServerKeyExchange handshake message
+ *                 (DHM modulus, generator, and public key).
  *
- * \param ctx      The DHM context.
+ * \note           In a TLS handshake, this is the how the client
+ *                 sets up its DHM context from the server's public
+ *                 DHM key material.
+ *
+ * \param ctx      The DHM context to use. This must be initialized.
  * \param p        On input, *p must be the start of the input buffer.
  *                 On output, *p is updated to point to the end of the data
  *                 that has been read. On success, this is the first byte
@@ -143,31 +149,37 @@
  * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
-                     unsigned char **p,
-                     const unsigned char *end );
+                             unsigned char **p,
+                             const unsigned char *end );
 
 /**
- * \brief          This function sets up and writes the ServerKeyExchange
- *                 parameters.
+ * \brief          This function generates a DHM key pair and exports its
+ *                 public part together with the DHM parameters in the format
+ *                 used in a TLS ServerKeyExchange handshake message.
  *
- * \note           The destination buffer must be large enough to hold
- *                 the reduced binary presentation of the modulus, the generator
- *                 and the public key, each wrapped with a 2-byte length field.
- *                 It is the responsibility of the caller to ensure that enough
- *                 space is available. Refer to \c mbedtls_mpi_size to computing
- *                 the byte-size of an MPI.
- *
- * \note           This function assumes that \c ctx->P and \c ctx->G
- *                 have already been properly set. For that, use
+ * \note           This function assumes that the DHM parameters \c ctx->P
+ *                 and \c ctx->G have already been properly set. For that, use
  *                 mbedtls_dhm_set_group() below in conjunction with
  *                 mbedtls_mpi_read_binary() and mbedtls_mpi_read_string().
  *
- * \param ctx      The DHM context.
+ * \note           In a TLS handshake, this is the how the server generates
+ *                 and exports its DHM key material.
+ *
+ * \param ctx      The DHM context to use. This must be initialized
+ *                 and have the DHM parameters set. It may or may not
+ *                 already have imported the peer's public key.
  * \param x_size   The private key size in Bytes.
- * \param olen     The number of characters written.
- * \param output   The destination buffer.
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG context.
+ * \param olen     The address at which to store the number of Bytes
+ *                 written on success. This must not be \c NULL.
+ * \param output   The destination buffer. This must be a writable buffer of
+ *                 sufficient size to hold the reduced binary presentation of
+ *                 the modulus, the generator and the public key, each wrapped
+ *                 with a 2-byte length field. It is the responsibility of the
+ *                 caller to ensure that enough space is available. Refer to
+ *                 mbedtls_mpi_size() to computing the byte-size of an MPI.
+ * \param f_rng    The RNG function. Must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context parameter.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
@@ -180,12 +192,14 @@
 /**
  * \brief          This function sets the prime modulus and generator.
  *
- * \note           This function can be used to set \p P, \p G
+ * \note           This function can be used to set \c ctx->P, \c ctx->G
  *                 in preparation for mbedtls_dhm_make_params().
  *
- * \param ctx      The DHM context.
- * \param P        The MPI holding the DHM prime modulus.
- * \param G        The MPI holding the DHM generator.
+ * \param ctx      The DHM context to configure. This must be initialized.
+ * \param P        The MPI holding the DHM prime modulus. This must be
+ *                 an initialized MPI.
+ * \param G        The MPI holding the DHM generator. This must be an
+ *                 initialized MPI.
  *
  * \return         \c 0 if successful.
  * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
@@ -195,11 +209,17 @@
                            const mbedtls_mpi *G );
 
 /**
- * \brief          This function imports the public value of the peer, G^Y.
+ * \brief          This function imports the raw public value of the peer.
  *
- * \param ctx      The DHM context.
- * \param input    The input buffer containing the G^Y value of the peer.
- * \param ilen     The size of the input buffer.
+ * \note           In a TLS handshake, this is the how the server imports
+ *                 the Client's public DHM key.
+ *
+ * \param ctx      The DHM context to use. This must be initialized and have
+ *                 its DHM parameters set, e.g. via mbedtls_dhm_set_group().
+ *                 It may or may not already have generated its own private key.
+ * \param input    The input buffer containing the \c G^Y value of the peer.
+ *                 This must be a readable buffer of size \p ilen Bytes.
+ * \param ilen     The size of the input buffer \p input in Bytes.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
@@ -208,21 +228,25 @@
                      const unsigned char *input, size_t ilen );
 
 /**
- * \brief          This function creates its own private key, \c X, and
- *                 exports \c G^X.
+ * \brief          This function creates a DHM key pair and exports
+ *                 the raw public key in big-endian format.
  *
  * \note           The destination buffer is always fully written
  *                 so as to contain a big-endian representation of G^X mod P.
- *                 If it is larger than ctx->len, it is padded accordingly
+ *                 If it is larger than \c ctx->len, it is padded accordingly
  *                 with zero-bytes at the beginning.
  *
- * \param ctx      The DHM context.
+ * \param ctx      The DHM context to use. This must be initialized and
+ *                 have the DHM parameters set. It may or may not already
+ *                 have imported the peer's public key.
  * \param x_size   The private key size in Bytes.
- * \param output   The destination buffer.
- * \param olen     The length of the destination buffer. Must be at least
- *                  equal to ctx->len (the size of \c P).
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG context.
+ * \param output   The destination buffer. This must be a writable buffer of
+ *                 size \p olen Bytes.
+ * \param olen     The length of the destination buffer. This must be at least
+ *                 equal to `ctx->len` (the size of \c P).
+ * \param f_rng    The RNG function. This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng doesn't need a context argument.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
@@ -233,22 +257,27 @@
                      void *p_rng );
 
 /**
- * \brief               This function derives and exports the shared secret
- *                      \c (G^Y)^X mod \c P.
+ * \brief          This function derives and exports the shared secret
+ *                 \c (G^Y)^X mod \c P.
  *
- * \note                If \p f_rng is not NULL, it is used to blind the input as
- *                      a countermeasure against timing attacks. Blinding is used
- *                      only if our private key \c X is re-used, and not used
- *                      otherwise. We recommend always passing a non-NULL
- *                      \p f_rng argument.
+ * \note           If \p f_rng is not \c NULL, it is used to blind the input as
+ *                 a countermeasure against timing attacks. Blinding is used
+ *                 only if our private key \c X is re-used, and not used
+ *                 otherwise. We recommend always passing a non-NULL
+ *                 \p f_rng argument.
  *
- * \param ctx           The DHM context.
- * \param output        The destination buffer.
- * \param output_size   The size of the destination buffer. Must be at least
- *                      the size of ctx->len (the size of \c P).
+ * \param ctx           The DHM context to use. This must be initialized
+ *                      and have its own private key generated and the peer's
+ *                      public key imported.
+ * \param output        The buffer to write the generated shared key to. This
+ *                      must be a writable buffer of size \p output_size Bytes.
+ * \param output_size   The size of the destination buffer. This must be at
+ *                      least the size of \c ctx->len (the size of \c P).
  * \param olen          On exit, holds the actual number of Bytes written.
- * \param f_rng         The RNG function, for blinding purposes.
- * \param p_rng         The RNG context.
+ * \param f_rng         The RNG function, for blinding purposes. This may
+ *                      b \c NULL if blinding isn't needed.
+ * \param p_rng         The RNG context. This may be \c NULL if \p f_rng
+ *                      doesn't need a context argument.
  *
  * \return              \c 0 on success.
  * \return              An \c MBEDTLS_ERR_DHM_XXX error code on failure.
@@ -259,9 +288,12 @@
                      void *p_rng );
 
 /**
- * \brief          This function frees and clears the components of a DHM context.
+ * \brief          This function frees and clears the components
+ *                 of a DHM context.
  *
- * \param ctx      The DHM context to free and clear.
+ * \param ctx      The DHM context to free and clear. This may be \c NULL,
+ *                 in which case this function is a no-op. If it is not \c NULL,
+ *                 it must point to an initialized DHM context.
  */
 void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
 
@@ -270,17 +302,19 @@
 /**
  * \brief             This function parses DHM parameters in PEM or DER format.
  *
- * \param dhm         The DHM context to initialize.
- * \param dhmin       The input buffer.
- * \param dhminlen    The size of the buffer, including the terminating null
- *                    Byte for PEM data.
+ * \param dhm         The DHM context to import the DHM parameters into.
+ *                    This must be initialized.
+ * \param dhmin       The input buffer. This must be a readable buffer of
+ *                    length \p dhminlen Bytes.
+ * \param dhminlen    The size of the input buffer \p dhmin, including the
+ *                    terminating \c NULL Byte for PEM data.
  *
  * \return            \c 0 on success.
- * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error code
- *                    error code on failure.
+ * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error
+ *                    code on failure.
  */
 int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
-                   size_t dhminlen );
+                           size_t dhminlen );
 
 #if defined(MBEDTLS_FS_IO)
 /** \ingroup x509_module */
@@ -288,11 +322,13 @@
  * \brief          This function loads and parses DHM parameters from a file.
  *
  * \param dhm      The DHM context to load the parameters to.
+ *                 This must be initialized.
  * \param path     The filename to read the DHM parameters from.
+ *                 This must not be \c NULL.
  *
  * \return         \c 0 on success.
- * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error code
- *                    error code on failure.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX
+ *                 error code on failure.
  */
 int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path );
 #endif /* MBEDTLS_FS_IO */
@@ -353,15 +389,6 @@
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-#define MBEDTLS_DEPRECATED __attribute__((deprecated))
-MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_constant_t;
-#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL )       \
-    ( (mbedtls_deprecated_constant_t) ( VAL ) )
-#else
-#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
-#endif /* ! MBEDTLS_DEPRECATED_WARNING */
-
 /**
  * \warning The origin of the primes in RFC 5114 is not documented and
  *          their use therefore constitutes a security risk!
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 27f2ffc..05b2b03 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -36,6 +36,18 @@
 
 #include "ecp.h"
 
+/*
+ * Use a backward compatible ECDH context.
+ *
+ * This flag is always enabled for now and future versions might add a
+ * configuration option that conditionally undefines this flag.
+ * The configuration option in question may have a different name.
+ *
+ * Features undefining this flag, must have a warning in their description in
+ * config.h stating that the feature breaks backward compatibility.
+ */
+#define MBEDTLS_ECDH_LEGACY_CONTEXT
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -49,6 +61,39 @@
     MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
 } mbedtls_ecdh_side;
 
+#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+/**
+ * Defines the ECDH implementation used.
+ *
+ * Later versions of the library may add new variants, therefore users should
+ * not make any assumptions about them.
+ */
+typedef enum
+{
+    MBEDTLS_ECDH_VARIANT_NONE = 0,   /*!< Implementation not defined. */
+    MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
+} mbedtls_ecdh_variant;
+
+/**
+ * The context used by the default ECDH implementation.
+ *
+ * Later versions might change the structure of this context, therefore users
+ * should not make any assumptions about the structure of
+ * mbedtls_ecdh_context_mbed.
+ */
+typedef struct mbedtls_ecdh_context_mbed
+{
+    mbedtls_ecp_group grp;   /*!< The elliptic curve used. */
+    mbedtls_mpi d;           /*!< The private key. */
+    mbedtls_ecp_point Q;     /*!< The public key. */
+    mbedtls_ecp_point Qp;    /*!< The value of the public key of the peer. */
+    mbedtls_mpi z;           /*!< The shared secret. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
+#endif
+} mbedtls_ecdh_context_mbed;
+#endif
+
 /**
  *
  * \warning         Performing multiple operations concurrently on the same
@@ -58,6 +103,7 @@
  */
 typedef struct mbedtls_ecdh_context
 {
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     mbedtls_ecp_group grp;   /*!< The elliptic curve used. */
     mbedtls_mpi d;           /*!< The private key. */
     mbedtls_ecp_point Q;     /*!< The public key. */
@@ -70,7 +116,26 @@
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     int restart_enabled;        /*!< The flag for restartable mode. */
     mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
-#endif
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#else
+    uint8_t point_format;       /*!< The format of point export in TLS messages
+                                  as defined in RFC 4492. */
+    mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */
+    mbedtls_ecdh_variant var;   /*!< The ECDH implementation/structure used. */
+    union
+    {
+        mbedtls_ecdh_context_mbed   mbed_ecdh;
+    } ctx;                      /*!< Implementation-specific context. The
+                                  context in use is specified by the \c var
+                                  field. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    uint8_t restart_enabled;    /*!< The flag for restartable mode. Functions of
+                                  an alternative implementation not supporting
+                                  restartable mode must return
+                                  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error
+                                  if this flag is set. */
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
 }
 mbedtls_ecdh_context;
 
@@ -84,11 +149,16 @@
  *
  * \see             ecp.h
  *
- * \param grp       The ECP group.
+ * \param grp       The ECP group to use. This must be initialized and have
+ *                  domain parameters loaded, for example through
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
  * \param d         The destination MPI (private key).
+ *                  This must be initialized.
  * \param Q         The destination point (public key).
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ *                  This must be initialized.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          Another \c MBEDTLS_ERR_ECP_XXX or
@@ -111,12 +181,22 @@
  *                  countermeasures against side-channel attacks.
  *                  For more information, see mbedtls_ecp_mul().
  *
- * \param grp       The ECP group.
+ * \param grp       The ECP group to use. This must be initialized and have
+ *                  domain parameters loaded, for example through
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
  * \param z         The destination MPI (shared secret).
+ *                  This must be initialized.
  * \param Q         The public key from another party.
+ *                  This must be initialized.
  * \param d         Our secret exponent (private key).
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ *                  This must be initialized.
+ * \param f_rng     The RNG function. This may be \c NULL if randomization
+ *                  of intermediate results during the ECP computations is
+ *                  not needed (discouraged). See the documentation of
+ *                  mbedtls_ecp_mul() for more.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't need a
+ *                  context argument.
  *
  * \return          \c 0 on success.
  * \return          Another \c MBEDTLS_ERR_ECP_XXX or
@@ -130,36 +210,57 @@
 /**
  * \brief           This function initializes an ECDH context.
  *
- * \param ctx       The ECDH context to initialize.
+ * \param ctx       The ECDH context to initialize. This must not be \c NULL.
  */
 void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
 
 /**
- * \brief           This function frees a context.
+ * \brief           This function sets up the ECDH context with the information
+ *                  given.
  *
- * \param ctx       The context to free.
- */
-void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
-
-/**
- * \brief           This function generates a public key and a TLS
- *                  ServerKeyExchange payload.
+ *                  This function should be called after mbedtls_ecdh_init() but
+ *                  before mbedtls_ecdh_make_params(). There is no need to call
+ *                  this function before mbedtls_ecdh_read_params().
  *
  *                  This is the first function used by a TLS server for ECDHE
  *                  ciphersuites.
  *
- * \note            This function assumes that the ECP group (grp) of the
- *                  \p ctx context has already been properly set,
- *                  for example, using mbedtls_ecp_group_load().
+ * \param ctx       The ECDH context to set up. This must be initialized.
+ * \param grp_id    The group id of the group to set up the context for.
+ *
+ * \return          \c 0 on success.
+ */
+int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx,
+                        mbedtls_ecp_group_id grp_id );
+
+/**
+ * \brief           This function frees a context.
+ *
+ * \param ctx       The context to free. This may be \c NULL, in which
+ *                  case this function does nothing. If it is not \c NULL,
+ *                  it must point to an initialized ECDH context.
+ */
+void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
+
+/**
+ * \brief           This function generates an EC key pair and exports its
+ *                  in the format used in a TLS ServerKeyExchange handshake
+ *                  message.
+ *
+ *                  This is the second function used by a TLS server for ECDHE
+ *                  ciphersuites. (It is called after mbedtls_ecdh_setup().)
  *
  * \see             ecp.h
  *
- * \param ctx       The ECDH context.
- * \param olen      The number of characters written.
- * \param buf       The destination buffer.
- * \param blen      The length of the destination buffer.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and bound to a group, for example via mbedtls_ecdh_setup().
+ * \param olen      The address at which to store the number of Bytes written.
+ * \param buf       The destination buffer. This must be a writable buffer of
+ *                  length \p blen Bytes.
+ * \param blen      The length of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
@@ -172,24 +273,32 @@
                       void *p_rng );
 
 /**
- * \brief           This function parses and processes a TLS ServerKeyExhange
- *                  payload.
+ * \brief           This function parses the ECDHE parameters in a
+ *                  TLS ServerKeyExchange handshake message.
  *
- *                  This is the first function used by a TLS client for ECDHE
- *                  ciphersuites.
+ * \note            In a TLS handshake, this is the how the client
+ *                  sets up its ECDHE context from the server's public
+ *                  ECDHE key material.
  *
  * \see             ecp.h
  *
- * \param ctx       The ECDH context.
- * \param buf       The pointer to the start of the input buffer.
- * \param end       The address for one Byte past the end of the buffer.
+ * \param ctx       The ECDHE context to use. This must be initialized.
+ * \param buf       On input, \c *buf must be the start of the input buffer.
+ *                  On output, \c *buf is updated to point to the end of the
+ *                  data that has been read. On success, this is the first byte
+ *                  past the end of the ServerKeyExchange parameters.
+ *                  On error, this is the point at which an error has been
+ *                  detected, which is usually not useful except to debug
+ *                  failures.
+ * \param end       The end of the input buffer.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  *
  */
 int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
-                      const unsigned char **buf, const unsigned char *end );
+                              const unsigned char **buf,
+                              const unsigned char *end );
 
 /**
  * \brief           This function sets up an ECDH context from an EC key.
@@ -200,33 +309,40 @@
  *
  * \see             ecp.h
  *
- * \param ctx       The ECDH context to set up.
- * \param key       The EC key to use.
- * \param side      Defines the source of the key: 1: Our key, or
- *                  0: The key of the peer.
+ * \param ctx       The ECDH context to set up. This must be initialized.
+ * \param key       The EC key to use. This must be initialized.
+ * \param side      Defines the source of the key. Possible values are:
+ *                  - #MBEDTLS_ECDH_OURS: The key is ours.
+ *                  - #MBEDTLS_ECDH_THEIRS: The key is that of the peer.
  *
  * \return          \c 0 on success.
  * \return          Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
  *
  */
-int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
-                     mbedtls_ecdh_side side );
+int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
+                             const mbedtls_ecp_keypair *key,
+                             mbedtls_ecdh_side side );
 
 /**
- * \brief           This function generates a public key and a TLS
- *                  ClientKeyExchange payload.
+ * \brief           This function generates a public key and exports it
+ *                  as a TLS ClientKeyExchange payload.
  *
  *                  This is the second function used by a TLS client for ECDH(E)
  *                  ciphersuites.
  *
  * \see             ecp.h
  *
- * \param ctx       The ECDH context.
- * \param olen      The number of Bytes written.
- * \param buf       The destination buffer.
- * \param blen      The size of the destination buffer.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and bound to a group, the latter usually by
+ *                  mbedtls_ecdh_read_params().
+ * \param olen      The address at which to store the number of Bytes written.
+ *                  This must not be \c NULL.
+ * \param buf       The destination buffer. This must be a writable buffer
+ *                  of length \p blen Bytes.
+ * \param blen      The size of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
@@ -239,23 +355,26 @@
                       void *p_rng );
 
 /**
- * \brief       This function parses and processes a TLS ClientKeyExchange
- *              payload.
+ * \brief       This function parses and processes the ECDHE payload of a
+ *              TLS ClientKeyExchange message.
  *
- *              This is the second function used by a TLS server for ECDH(E)
- *              ciphersuites.
+ *              This is the third function used by a TLS server for ECDH(E)
+ *              ciphersuites. (It is called after mbedtls_ecdh_setup() and
+ *              mbedtls_ecdh_make_params().)
  *
  * \see         ecp.h
  *
- * \param ctx   The ECDH context.
- * \param buf   The start of the input buffer.
- * \param blen  The length of the input buffer.
+ * \param ctx   The ECDH context to use. This must be initialized
+ *              and bound to a group, for example via mbedtls_ecdh_setup().
+ * \param buf   The pointer to the ClientKeyExchange payload. This must
+ *              be a readable buffer of length \p blen Bytes.
+ * \param blen  The length of the input buffer \p buf in Bytes.
  *
  * \return      \c 0 on success.
  * \return      An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
-                      const unsigned char *buf, size_t blen );
+                              const unsigned char *buf, size_t blen );
 
 /**
  * \brief           This function derives and exports the shared secret.
@@ -268,13 +387,19 @@
  *                  For more information, see mbedtls_ecp_mul().
  *
  * \see             ecp.h
- *
- * \param ctx       The ECDH context.
- * \param olen      The number of Bytes written.
- * \param buf       The destination buffer.
- * \param blen      The length of the destination buffer.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and have its own private key generated and the peer's
+ *                  public key imported.
+ * \param olen      The address at which to store the total number of
+ *                  Bytes written on success. This must not be \c NULL.
+ * \param buf       The buffer to write the generated shared key to. This
+ *                  must be a writable buffer of size \p blen Bytes.
+ * \param blen      The length of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function, for blinding purposes. This may
+ *                  b \c NULL if blinding isn't needed.
+ * \param p_rng     The RNG context. This may be \c NULL if \p f_rng
+ *                  doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
@@ -297,7 +422,7 @@
  *                  computations once enabled, except by free-ing the context,
  *                  which cancels possible in-progress operations.
  *
- * \param ctx       The ECDH context.
+ * \param ctx       The ECDH context to use. This must be initialized.
  */
 void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx );
 #endif /* MBEDTLS_ECP_RESTARTABLE */
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index 4057828..40fdab3 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -118,7 +118,8 @@
  * \brief           This function computes the ECDSA signature of a
  *                  previously-hashed message.
  *
- * \note            The deterministic version is usually preferred.
+ * \note            The deterministic version implemented in
+ *                  mbedtls_ecdsa_sign_det() is usually preferred.
  *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated
@@ -128,14 +129,22 @@
  *
  * \see             ecp.h
  *
- * \param grp       The ECP group.
- * \param r         The first output integer.
- * \param s         The second output integer.
- * \param d         The private signing key.
- * \param buf       The message hash.
- * \param blen      The length of \p buf.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ * \param grp       The context for the elliptic curve to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param r         The MPI context in which to store the first part
+ *                  the signature. This must be initialized.
+ * \param s         The MPI context in which to store the second part
+ *                  the signature. This must be initialized.
+ * \param d         The private signing key. This must be initialized.
+ * \param buf       The content to be signed. This is usually the hash of
+ *                  the original data to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng doesn't need a context parameter.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX
@@ -162,21 +171,29 @@
  *
  * \see             ecp.h
  *
- * \param grp       The ECP group.
- * \param r         The first output integer.
- * \param s         The second output integer.
- * \param d         The private signing key.
- * \param buf       The message hash.
- * \param blen      The length of \p buf.
- * \param md_alg    The MD algorithm used to hash the message.
+ * \param grp       The context for the elliptic curve to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param r         The MPI context in which to store the first part
+ *                  the signature. This must be initialized.
+ * \param s         The MPI context in which to store the second part
+ *                  the signature. This must be initialized.
+ * \param d         The private signing key. This must be initialized
+ *                  and setup, for example through mbedtls_ecp_gen_privkey().
+ * \param buf       The hashed content to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param md_alg    The hash algorithm used to hash the original data.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
  *                  error code on failure.
  */
-int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
-                    const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
-                    mbedtls_md_type_t md_alg );
+int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+                            mbedtls_mpi *s, const mbedtls_mpi *d,
+                            const unsigned char *buf, size_t blen,
+                            mbedtls_md_type_t md_alg );
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
 /**
@@ -191,12 +208,19 @@
  *
  * \see             ecp.h
  *
- * \param grp       The ECP group.
- * \param buf       The message hash.
- * \param blen      The length of \p buf.
- * \param Q         The public key to use for verification.
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param buf       The hashed content that was signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param Q         The public key to use for verification. This must be
+ *                  initialized and setup.
  * \param r         The first integer of the signature.
+ *                  This must be initialized.
  * \param s         The second integer of the signature.
+ *                  This must be initialized.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
@@ -205,8 +229,9 @@
  *                  error code on failure for any other reason.
  */
 int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
-                  const unsigned char *buf, size_t blen,
-                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s);
+                          const unsigned char *buf, size_t blen,
+                          const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
+                          const mbedtls_mpi *s);
 
 /**
  * \brief           This function computes the ECDSA signature and writes it
@@ -223,11 +248,6 @@
  *                  of the Digital Signature Algorithm (DSA) and Elliptic
  *                  Curve Digital Signature Algorithm (ECDSA)</em>.
  *
- * \note            The \p sig buffer must be at least twice as large as the
- *                  size of the curve used, plus 9. For example, 73 Bytes if
- *                  a 256-bit curve is used. A buffer length of
- *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
- *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
  *                  defined in <em>Standards for Efficient Cryptography Group
@@ -236,20 +256,32 @@
  *
  * \see             ecp.h
  *
- * \param ctx       The ECDSA context.
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
  * \param md_alg    The message digest that was used to hash the message.
- * \param hash      The message hash.
- * \param hlen      The length of the hash.
- * \param sig       The buffer that holds the signature.
- * \param slen      The length of the signature written.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param f_rng     The RNG function. This must not be \c NULL if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ *                  it is unused and may be set to \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
  *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
-int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
+int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
+                                   mbedtls_md_type_t md_alg,
                            const unsigned char *hash, size_t hlen,
                            unsigned char *sig, size_t *slen,
                            int (*f_rng)(void *, unsigned char *, size_t),
@@ -265,15 +297,28 @@
  *                  but it can return early and restart according to the limit
  *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
  *
- * \param ctx       The ECDSA context.
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
  * \param md_alg    The message digest that was used to hash the message.
- * \param hash      The message hash.
- * \param hlen      The length of the hash.
- * \param sig       The buffer that holds the signature.
- * \param slen      The length of the signature written.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
- * \param rs_ctx    The restart context (NULL disables restart).
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param f_rng     The RNG function. This must not be \c NULL if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ *                  it is unused and may be set to \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
+ * \param rs_ctx    The restart context to use. This may be \c NULL to disable
+ *                  restarting. If it is not \c NULL, it must point to an
+ *                  initialized restart context.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
@@ -309,11 +354,6 @@
  * \warning         It is not thread-safe to use the same context in
  *                  multiple threads.
  *
- * \note            The \p sig buffer must be at least twice as large as the
- *                  size of the curve used, plus 9. For example, 73 Bytes if a
- *                  256-bit curve is used. A buffer length of
- *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
- *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
  *                  defined in <em>Standards for Efficient Cryptography Group
@@ -325,12 +365,20 @@
  * \deprecated      Superseded by mbedtls_ecdsa_write_signature() in
  *                  Mbed TLS version 2.0 and later.
  *
- * \param ctx       The ECDSA context.
- * \param hash      The message hash.
- * \param hlen      The length of the hash.
- * \param sig       The buffer that holds the signature.
- * \param slen      The length of the signature written.
- * \param md_alg    The MD algorithm used to hash the message.
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param md_alg    The message digest that was used to hash the message.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
@@ -355,11 +403,14 @@
  *
  * \see             ecp.h
  *
- * \param ctx       The ECDSA context.
- * \param hash      The message hash.
- * \param hlen      The size of the hash.
- * \param sig       The signature to read and verify.
- * \param slen      The size of \p sig.
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and public key bound to it.
+ * \param hash      The message hash that was signed. This must be a readable
+ *                  buffer of length \p size Bytes.
+ * \param hlen      The size of the hash \p hash.
+ * \param sig       The signature to read and verify. This must be a readable
+ *                  buffer of length \p slen Bytes.
+ * \param slen      The size of \p sig in Bytes.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
@@ -382,12 +433,17 @@
  *                  but it can return early and restart according to the limit
  *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
  *
- * \param ctx       The ECDSA context.
- * \param hash      The message hash.
- * \param hlen      The size of the hash.
- * \param sig       The signature to read and verify.
- * \param slen      The size of \p sig.
- * \param rs_ctx    The restart context (NULL disables restart).
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and public key bound to it.
+ * \param hash      The message hash that was signed. This must be a readable
+ *                  buffer of length \p size Bytes.
+ * \param hlen      The size of the hash \p hash.
+ * \param sig       The signature to read and verify. This must be a readable
+ *                  buffer of length \p slen Bytes.
+ * \param slen      The size of \p sig in Bytes.
+ * \param rs_ctx    The restart context to use. This may be \c NULL to disable
+ *                  restarting. If it is not \c NULL, it must point to an
+ *                  initialized restart context.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
@@ -409,10 +465,12 @@
  * \see            ecp.h
  *
  * \param ctx      The ECDSA context to store the keypair in.
+ *                 This must be initialized.
  * \param gid      The elliptic curve to use. One of the various
  *                 \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG context.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context argument.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_ECP_XXX code on failure.
@@ -421,40 +479,55 @@
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 /**
- * \brief           This function sets an ECDSA context from an EC key pair.
+ * \brief           This function sets up an ECDSA context from an EC key pair.
  *
  * \see             ecp.h
  *
- * \param ctx       The ECDSA context to set.
- * \param key       The EC key to use.
+ * \param ctx       The ECDSA context to setup. This must be initialized.
+ * \param key       The EC key to use. This must be initialized and hold
+ *                  a private-public key pair or a public key. In the former
+ *                  case, the ECDSA context may be used for signature creation
+ *                  and verification after this call. In the latter case, it
+ *                  may be used for signature verification.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX code on failure.
  */
-int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
+int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
+                                const mbedtls_ecp_keypair *key );
 
 /**
  * \brief           This function initializes an ECDSA context.
  *
  * \param ctx       The ECDSA context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
 
 /**
  * \brief           This function frees an ECDSA context.
  *
- * \param ctx       The ECDSA context to free.
+ * \param ctx       The ECDSA context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it
+ *                  is not \c NULL, it must be initialized.
  */
 void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
 /**
- * \brief           Initialize a restart context
+ * \brief           Initialize a restart context.
+ *
+ * \param ctx       The restart context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
 
 /**
- * \brief           Free the components of a restart context
+ * \brief           Free the components of a restart context.
+ *
+ * \param ctx       The restart context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it
+ *                  is not \c NULL, it must be initialized.
  */
 void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
 #endif /* MBEDTLS_ECP_RESTARTABLE */
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index 59d12f0..b967af8 100644
--- a/include/mbedtls/ecjpake.h
+++ b/include/mbedtls/ecjpake.h
@@ -92,28 +92,33 @@
 #endif /* MBEDTLS_ECJPAKE_ALT */
 
 /**
- * \brief           Initialize a context
- *                  (just makes it ready for setup() or free()).
+ * \brief           Initialize an ECJPAKE context.
  *
- * \param ctx       context to initialize
+ * \param ctx       The ECJPAKE context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
 
 /**
- * \brief           Set up a context for use
+ * \brief           Set up an ECJPAKE context for use.
  *
  * \note            Currently the only values for hash/curve allowed by the
- *                  standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1.
+ *                  standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
  *
- * \param ctx       context to set up
- * \param role      Our role: client or server
- * \param hash      hash function to use (MBEDTLS_MD_XXX)
- * \param curve     elliptic curve identifier (MBEDTLS_ECP_DP_XXX)
- * \param secret    pre-shared secret (passphrase)
- * \param len       length of the shared secret
+ * \param ctx       The ECJPAKE context to set up. This must be initialized.
+ * \param role      The role of the caller. This must be either
+ *                  #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
+ * \param hash      The identifier of the hash function to use,
+ *                  for example #MBEDTLS_MD_SHA256.
+ * \param curve     The identifier of the elliptic curve to use,
+ *                  for example #MBEDTLS_ECP_DP_SECP256R1.
+ * \param secret    The pre-shared secret (passphrase). This must be
+ *                  a readable buffer of length \p len Bytes. It need
+ *                  only be valid for the duration of this call.
+ * \param len       The length of the pre-shared secret \p secret.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
                            mbedtls_ecjpake_role role,
@@ -123,29 +128,34 @@
                            size_t len );
 
 /**
- * \brief           Check if a context is ready for use
+ * \brief           Check if an ECJPAKE context is ready for use.
  *
- * \param ctx       Context to check
+ * \param ctx       The ECJPAKE context to check. This must be
+ *                  initialized.
  *
- * \return          0 if the context is ready for use,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
+ * \return          \c 0 if the context is ready for use.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
  */
 int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
 
 /**
  * \brief           Generate and write the first round message
  *                  (TLS: contents of the Client/ServerHello extension,
- *                  excluding extension type and length bytes)
+ *                  excluding extension type and length bytes).
  *
- * \param ctx       Context to use
- * \param buf       Buffer to write the contents to
- * \param len       Buffer size
- * \param olen      Will be updated with the number of bytes written
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param ctx       The ECJPAKE context to use. This must be
+ *                  initialized and set up.
+ * \param buf       The buffer to write the contents to. This must be a
+ *                  writable buffer of length \p len Bytes.
+ * \param len       The length of \p buf in Bytes.
+ * \param olen      The address at which to store the total number
+ *                  of Bytes written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
                             unsigned char *buf, size_t len, size_t *olen,
@@ -155,14 +165,16 @@
 /**
  * \brief           Read and process the first round message
  *                  (TLS: contents of the Client/ServerHello extension,
- *                  excluding extension type and length bytes)
+ *                  excluding extension type and length bytes).
  *
- * \param ctx       Context to use
- * \param buf       Pointer to extension contents
- * \param len       Extension length
+ * \param ctx       The ECJPAKE context to use. This must be initialized
+ *                  and set up.
+ * \param buf       The buffer holding the first round message. This must
+ *                  be a readable buffer of length \p len Bytes.
+ * \param len       The length in Bytes of \p buf.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
                                     const unsigned char *buf,
@@ -170,17 +182,21 @@
 
 /**
  * \brief           Generate and write the second round message
- *                  (TLS: contents of the Client/ServerKeyExchange)
+ *                  (TLS: contents of the Client/ServerKeyExchange).
  *
- * \param ctx       Context to use
- * \param buf       Buffer to write the contents to
- * \param len       Buffer size
- * \param olen      Will be updated with the number of bytes written
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param ctx       The ECJPAKE context to use. This must be initialized,
+ *                  set up, and already have performed round one.
+ * \param buf       The buffer to write the round two contents to.
+ *                  This must be a writable buffer of length \p len Bytes.
+ * \param len       The size of \p buf in Bytes.
+ * \param olen      The address at which to store the total number of Bytes
+ *                  written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
                             unsigned char *buf, size_t len, size_t *olen,
@@ -189,14 +205,16 @@
 
 /**
  * \brief           Read and process the second round message
- *                  (TLS: contents of the Client/ServerKeyExchange)
+ *                  (TLS: contents of the Client/ServerKeyExchange).
  *
- * \param ctx       Context to use
- * \param buf       Pointer to the message
- * \param len       Message length
+ * \param ctx       The ECJPAKE context to use. This must be initialized
+ *                  and set up and already have performed round one.
+ * \param buf       The buffer holding the second round message. This must
+ *                  be a readable buffer of length \p len Bytes.
+ * \param len       The length in Bytes of \p buf.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
                                     const unsigned char *buf,
@@ -204,17 +222,21 @@
 
 /**
  * \brief           Derive the shared secret
- *                  (TLS: Pre-Master Secret)
+ *                  (TLS: Pre-Master Secret).
  *
- * \param ctx       Context to use
- * \param buf       Buffer to write the contents to
- * \param len       Buffer size
- * \param olen      Will be updated with the number of bytes written
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param ctx       The ECJPAKE context to use. This must be initialized,
+ *                  set up and have performed both round one and two.
+ * \param buf       The buffer to write the derived secret to. This must
+ *                  be a writable buffer of length \p len Bytes.
+ * \param len       The length of \p buf in Bytes.
+ * \param olen      The address at which to store the total number of Bytes
+ *                  written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
                             unsigned char *buf, size_t len, size_t *olen,
@@ -222,14 +244,15 @@
                             void *p_rng );
 
 /**
- * \brief           Free a context's content
+ * \brief           This clears an ECJPAKE context and frees any
+ *                  embedded data structure.
  *
- * \param ctx       context to free
+ * \param ctx       The ECJPAKE context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it is not
+ *                  \c NULL, it must point to an initialized ECJPAKE context.
  */
 void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
 
-
-
 #if defined(MBEDTLS_SELF_TEST)
 
 /**
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 2fb1af4..de3a343 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -159,6 +159,10 @@
  * additions or subtractions. Therefore, it is only an approximative modular
  * reduction. It must return 0 on success and non-zero on failure.
  *
+ * \note        Alternative implementations must keep the group IDs distinct. If
+ *              two group structures have the same ID, then they must be
+ *              identical.
+ *
  */
 typedef struct mbedtls_ecp_group
 {
@@ -493,24 +497,37 @@
 
 /**
  * \brief           This function frees the components of an ECP group.
- * \param grp       The group to free.
+ *
+ * \param grp       The group to free. This may be \c NULL, in which
+ *                  case this function returns immediately. If it is not
+ *                  \c NULL, it must point to an initialized ECP group.
  */
 void mbedtls_ecp_group_free( mbedtls_ecp_group *grp );
 
 /**
  * \brief           This function frees the components of a key pair.
- * \param key       The key pair to free.
+ *
+ * \param key       The key pair to free. This may be \c NULL, in which
+ *                  case this function returns immediately. If it is not
+ *                  \c NULL, it must point to an initialized ECP key pair.
  */
 void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
 /**
- * \brief           Initialize a restart context
+ * \brief           Initialize a restart context.
+ *
+ * \param ctx       The restart context to initialize. This must
+ *                  not be \c NULL.
  */
 void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx );
 
 /**
- * \brief           Free the components of a restart context
+ * \brief           Free the components of a restart context.
+ *
+ * \param ctx       The restart context to free. This may be \c NULL, in which
+ *                  case this function returns immediately. If it is not
+ *                  \c NULL, it must point to an initialized restart context.
  */
 void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx );
 #endif /* MBEDTLS_ECP_RESTARTABLE */
@@ -519,11 +536,12 @@
  * \brief           This function copies the contents of point \p Q into
  *                  point \p P.
  *
- * \param P         The destination point.
- * \param Q         The source point.
+ * \param P         The destination point. This must be initialized.
+ * \param Q         The source point. This must be initialized.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code for other kinds of failure.
  */
 int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q );
 
@@ -531,31 +549,35 @@
  * \brief           This function copies the contents of group \p src into
  *                  group \p dst.
  *
- * \param dst       The destination group.
- * \param src       The source group.
+ * \param dst       The destination group. This must be initialized.
+ * \param src       The source group. This must be initialized.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
  */
-int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src );
+int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst,
+                            const mbedtls_ecp_group *src );
 
 /**
- * \brief           This function sets a point to zero.
+ * \brief           This function sets a point to the point at infinity.
  *
- * \param pt        The point to set.
+ * \param pt        The point to set. This must be initialized.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
 
 /**
- * \brief           This function checks if a point is zero.
+ * \brief           This function checks if a point is the point at infinity.
  *
- * \param pt        The point to test.
+ * \param pt        The point to test. This must be initialized.
  *
  * \return          \c 1 if the point is zero.
  * \return          \c 0 if the point is non-zero.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
 
@@ -565,8 +587,8 @@
  * \note            This assumes that the points are normalized. Otherwise,
  *                  they may compare as "not equal" even if they are.
  *
- * \param P         The first point to compare.
- * \param Q         The second point to compare.
+ * \param P         The first point to compare. This must be initialized.
+ * \param Q         The second point to compare. This must be initialized.
  *
  * \return          \c 0 if the points are equal.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal.
@@ -578,7 +600,7 @@
  * \brief           This function imports a non-zero point from two ASCII
  *                  strings.
  *
- * \param P         The destination point.
+ * \param P         The destination point. This must be initialized.
  * \param radix     The numeric base of the input.
  * \param x         The first affine coordinate, as a null-terminated string.
  * \param y         The second affine coordinate, as a null-terminated string.
@@ -593,15 +615,21 @@
  * \brief           This function exports a point into unsigned binary data.
  *
  * \param grp       The group to which the point should belong.
- * \param P         The point to export.
- * \param format    The point format. Should be an \c MBEDTLS_ECP_PF_XXX macro.
- * \param olen      The length of the output.
- * \param buf       The output buffer.
- * \param buflen    The length of the output buffer.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param P         The point to export. This must be initialized.
+ * \param format    The point format. This must be either
+ *                  #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * \param olen      The address at which to store the length of
+ *                  the output in Bytes. This must not be \c NULL.
+ * \param buf       The output buffer. This must be a writable buffer
+ *                  of length \p buflen Bytes.
+ * \param buflen    The length of the output buffer \p buf in Bytes.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA
- *                  or #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
+ *                  is too small to hold the point.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
                             int format, size_t *olen,
@@ -615,108 +643,158 @@
  *                  for that.
  *
  * \param grp       The group to which the point should belong.
- * \param P         The point to import.
- * \param buf       The input buffer.
- * \param ilen      The length of the input.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param P         The destination context to import the point to.
+ *                  This must be initialized.
+ * \param buf       The input buffer. This must be a readable buffer
+ *                  of length \p ilen Bytes.
+ * \param ilen      The length of the input buffer \p buf in Bytes.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
  *                  is not implemented.
- *
  */
-int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
-                           const unsigned char *buf, size_t ilen );
+int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
+                                   mbedtls_ecp_point *P,
+                                   const unsigned char *buf, size_t ilen );
 
 /**
  * \brief           This function imports a point from a TLS ECPoint record.
  *
- * \note            On function return, \p buf is updated to point to immediately
+ * \note            On function return, \p *buf is updated to point immediately
  *                  after the ECPoint record.
  *
- * \param grp       The ECP group used.
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
  * \param pt        The destination point.
  * \param buf       The address of the pointer to the start of the input buffer.
  * \param len       The length of the buffer.
  *
  * \return          \c 0 on success.
- * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization
+ *                  failure.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
  */
-int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
-                        const unsigned char **buf, size_t len );
+int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp,
+                                mbedtls_ecp_point *pt,
+                                const unsigned char **buf, size_t len );
 
 /**
- * \brief           This function exports a point as a TLS ECPoint record.
+ * \brief           This function exports a point as a TLS ECPoint record
+ *                  defined in RFC 4492, Section 5.4.
  *
- * \param grp       The ECP group used.
- * \param pt        The point format to export to. The point format is an
- *                  \c MBEDTLS_ECP_PF_XXX constant.
- * \param format    The export format.
- * \param olen      The length of the data written.
- * \param buf       The buffer to write to.
- * \param blen      The length of the buffer.
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param pt        The point to be exported. This must be initialized.
+ * \param format    The point format to use. This must be either
+ *                  #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * \param olen      The address at which to store the length in Bytes
+ *                  of the data written.
+ * \param buf       The target buffer. This must be a writable buffer of
+ *                  length \p blen Bytes.
+ * \param blen      The length of the target buffer \p buf in Bytes.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA or
- *                  #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer
+ *                  is too small to hold the exported point.
+ * \return          Another negative error code on other kinds of failure.
  */
-int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
-                         int format, size_t *olen,
-                         unsigned char *buf, size_t blen );
+int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp,
+                                 const mbedtls_ecp_point *pt,
+                                 int format, size_t *olen,
+                                 unsigned char *buf, size_t blen );
 
 /**
- * \brief           This function sets a group using standardized domain parameters.
+ * \brief           This function sets up an ECP group context
+ *                  from a standardized set of domain parameters.
  *
  * \note            The index should be a value of the NamedCurve enum,
  *                  as defined in <em>RFC-4492: Elliptic Curve Cryptography
  *                  (ECC) Cipher Suites for Transport Layer Security (TLS)</em>,
  *                  usually in the form of an \c MBEDTLS_ECP_DP_XXX macro.
  *
- * \param grp       The destination group.
+ * \param grp       The group context to setup. This must be initialized.
  * \param id        The identifier of the domain parameter set to load.
  *
- * \return          \c 0 on success,
- * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
- * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups.
-
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't
+ *                  correspond to a known group.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id );
 
 /**
- * \brief           This function sets a group from a TLS ECParameters record.
+ * \brief           This function sets up an ECP group context from a TLS
+ *                  ECParameters record as defined in RFC 4492, Section 5.4.
  *
- * \note            \p buf is updated to point right after the ECParameters record
- *                  on exit.
+ * \note            The read pointer \p buf is updated to point right after
+ *                  the ECParameters record on exit.
  *
- * \param grp       The destination group.
+ * \param grp       The group context to setup. This must be initialized.
  * \param buf       The address of the pointer to the start of the input buffer.
- * \param len       The length of the buffer.
+ * \param len       The length of the input buffer \c *buf in Bytes.
  *
  * \return          \c 0 on success.
- * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
+ *                  recognized.
+ * \return          Another negative error code on other kinds of failure.
  */
-int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len );
+int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
+                                const unsigned char **buf, size_t len );
 
 /**
- * \brief           This function writes the TLS ECParameters record for a group.
+ * \brief           This function extracts an elliptic curve group ID from a
+ *                  TLS ECParameters record as defined in RFC 4492, Section 5.4.
  *
- * \param grp       The ECP group used.
- * \param olen      The number of Bytes written.
- * \param buf       The buffer to write to.
- * \param blen      The length of the buffer.
+ * \note            The read pointer \p buf is updated to point right after
+ *                  the ECParameters record on exit.
+ *
+ * \param grp       The address at which to store the group id.
+ *                  This must not be \c NULL.
+ * \param buf       The address of the pointer to the start of the input buffer.
+ * \param len       The length of the input buffer \c *buf in Bytes.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
+ *                  recognized.
+ * \return          Another negative error code on other kinds of failure.
  */
-int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
-                         unsigned char *buf, size_t blen );
+int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp,
+                                   const unsigned char **buf,
+                                   size_t len );
+/**
+ * \brief           This function exports an elliptic curve as a TLS
+ *                  ECParameters record as defined in RFC 4492, Section 5.4.
+ *
+ * \param grp       The ECP group to be exported.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param olen      The address at which to store the number of Bytes written.
+ *                  This must not be \c NULL.
+ * \param buf       The buffer to write to. This must be a writable buffer
+ *                  of length \p blen Bytes.
+ * \param blen      The length of the output buffer \p buf in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output
+ *                  buffer is too small to hold the exported group.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp,
+                                 size_t *olen,
+                                 unsigned char *buf, size_t blen );
 
 /**
- * \brief           This function performs multiplication of a point by
- *                  an integer: \p R = \p m * \p P.
+ * \brief           This function performs a scalar multiplication of a point
+ *                  by an integer: \p R = \p m * \p P.
  *
  *                  It is not thread-safe to use same group in multiple threads.
  *
@@ -730,17 +808,22 @@
  *                  targeting these results. We recommend always providing
  *                  a non-NULL \p f_rng. The overhead is negligible.
  *
- * \param grp       The ECP group.
- * \param R         The destination point.
- * \param m         The integer by which to multiply.
- * \param P         The point to multiply.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
+ * \param m         The integer by which to multiply. This must be initialized.
+ * \param P         The point to multiply. This must be initialized.
+ * \param f_rng     The RNG function. This may be \c NULL if randomization
+ *                  of intermediate results isn't desired (discouraged).
+ * \param p_rng     The RNG context to be passed to \p p_rng.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private
  *                  key, or \p P is not a valid public key.
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
@@ -756,12 +839,16 @@
  *                  it can return early and restart according to the limit set
  *                  with \c mbedtls_ecp_set_max_ops() to reduce blocking.
  *
- * \param grp       The ECP group.
- * \param R         The destination point.
- * \param m         The integer by which to multiply.
- * \param P         The point to multiply.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
+ * \param m         The integer by which to multiply. This must be initialized.
+ * \param P         The point to multiply. This must be initialized.
+ * \param f_rng     The RNG function. This may be \c NULL if randomization
+ *                  of intermediate results isn't desired (discouraged).
+ * \param p_rng     The RNG context to be passed to \p p_rng.
  * \param rs_ctx    The restart context (NULL disables restart).
  *
  * \return          \c 0 on success.
@@ -770,6 +857,7 @@
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
  *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
@@ -785,18 +873,25 @@
  * \note            In contrast to mbedtls_ecp_mul(), this function does not
  *                  guarantee a constant execution flow and timing.
  *
- * \param grp       The ECP group.
- * \param R         The destination point.
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
  * \param m         The integer by which to multiply \p P.
- * \param P         The point to multiply by \p m.
+ *                  This must be initialized.
+ * \param P         The point to multiply by \p m. This must be initialized.
  * \param n         The integer by which to multiply \p Q.
+ *                  This must be initialized.
  * \param Q         The point to be multiplied by \p n.
+ *                  This must be initialized.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not
  *                  valid private keys, or \p P or \p Q are not valid public
  *                  keys.
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
@@ -813,12 +908,18 @@
  *                  but it can return early and restart according to the limit
  *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
  *
- * \param grp       The ECP group.
- * \param R         The destination point.
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
  * \param m         The integer by which to multiply \p P.
- * \param P         The point to multiply by \p m.
+ *                  This must be initialized.
+ * \param P         The point to multiply by \p m. This must be initialized.
  * \param n         The integer by which to multiply \p Q.
+ *                  This must be initialized.
  * \param Q         The point to be multiplied by \p n.
+ *                  This must be initialized.
  * \param rs_ctx    The restart context (NULL disables restart).
  *
  * \return          \c 0 on success.
@@ -828,6 +929,7 @@
  * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
  *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another negative error code on other kinds of failure.
  */
 int mbedtls_ecp_muladd_restartable(
              mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
@@ -852,38 +954,51 @@
  *                  structures, such as ::mbedtls_ecdh_context or
  *                  ::mbedtls_ecdsa_context.
  *
- * \param grp       The curve the point should lie on.
- * \param pt        The point to check.
+ * \param grp       The ECP group the point should belong to.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param pt        The point to check. This must be initialized.
  *
  * \return          \c 0 if the point is a valid public key.
- * \return          #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not
+ *                  a valid public key for the given curve.
+ * \return          Another negative error code on other kinds of failure.
  */
-int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt );
+int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
+                              const mbedtls_ecp_point *pt );
 
 /**
- * \brief           This function checks that an \p mbedtls_mpi is a valid private
- *                  key for this curve.
+ * \brief           This function checks that an \p mbedtls_mpi is a
+ *                  valid private key for this curve.
  *
  * \note            This function uses bare components rather than an
  *                  ::mbedtls_ecp_keypair structure to ease use with other
  *                  structures, such as ::mbedtls_ecdh_context or
  *                  ::mbedtls_ecdsa_context.
  *
- * \param grp       The group used.
- * \param d         The integer to check.
+ * \param grp       The ECP group the private key should belong to.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param d         The integer to check. This must be initialized.
  *
  * \return          \c 0 if the point is a valid private key.
- * \return          #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid
+ *                  private key for the given curve.
+ * \return          Another negative error code on other kinds of failure.
  */
-int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
+int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
+                               const mbedtls_mpi *d );
 
 /**
  * \brief           This function generates a private key.
  *
- * \param grp       The ECP group.
- * \param d         The destination MPI (secret part).
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \param grp       The ECP group to generate a private key for.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param d         The destination MPI (secret part). This must be initialized.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
@@ -903,22 +1018,29 @@
  *                  structures, such as ::mbedtls_ecdh_context or
  *                  ::mbedtls_ecdsa_context.
  *
- * \param grp       The ECP group.
- * \param G         The chosen base point.
+ * \param grp       The ECP group to generate a key pair for.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param G         The base point to use. This must be initialized
+ *                  and belong to \p grp. It replaces the default base
+ *                  point \c grp->G used by mbedtls_ecp_gen_keypair().
  * \param d         The destination MPI (secret part).
+ *                  This must be initialized.
  * \param Q         The destination point (public part).
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ *                  This must be initialized.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may
+ *                  be \c NULL if \p f_rng doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
  *                  on failure.
  */
 int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
-                     const mbedtls_ecp_point *G,
-                     mbedtls_mpi *d, mbedtls_ecp_point *Q,
-                     int (*f_rng)(void *, unsigned char *, size_t),
-                     void *p_rng );
+                                  const mbedtls_ecp_point *G,
+                                  mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  void *p_rng );
 
 /**
  * \brief           This function generates an ECP keypair.
@@ -928,34 +1050,42 @@
  *                  structures, such as ::mbedtls_ecdh_context or
  *                  ::mbedtls_ecdsa_context.
  *
- * \param grp       The ECP group.
+ * \param grp       The ECP group to generate a key pair for.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
  * \param d         The destination MPI (secret part).
+ *                  This must be initialized.
  * \param Q         The destination point (public part).
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ *                  This must be initialized.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may
+ *                  be \c NULL if \p f_rng doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
  *                  on failure.
  */
-int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
-                     int (*f_rng)(void *, unsigned char *, size_t),
-                     void *p_rng );
+int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d,
+                             mbedtls_ecp_point *Q,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng );
 
 /**
  * \brief           This function generates an ECP key.
  *
  * \param grp_id    The ECP group identifier.
- * \param key       The destination key.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG context.
+ * \param key       The destination key. This must be initialized.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may
+ *                  be \c NULL if \p f_rng doesn't need a context argument.
  *
  * \return          \c 0 on success.
  * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
  *                  on failure.
  */
 int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
-                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng );
 
 /**
  * \brief           This function checks that the keypair objects
@@ -963,16 +1093,19 @@
  *                  same public point, and that the private key in
  *                  \p prv is consistent with the public key.
  *
- * \param pub       The keypair structure holding the public key.
- *                  If it contains a private key, that part is ignored.
+ * \param pub       The keypair structure holding the public key. This
+ *                  must be initialized. If it contains a private key, that
+ *                  part is ignored.
  * \param prv       The keypair structure holding the full keypair.
+ *                  This must be initialized.
  *
  * \return          \c 0 on success, meaning that the keys are valid and match.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match.
  * \return          An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
  *                  error code on calculation failure.
  */
-int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv );
+int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub,
+                                const mbedtls_ecp_keypair *prv );
 
 #if defined(MBEDTLS_SELF_TEST)
 
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 0c38889..647a11a 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -74,9 +74,9 @@
  * MD4       1                  0x002D-0x002D
  * MD5       1                  0x002F-0x002F
  * RIPEMD160 1                  0x0031-0x0031
- * SHA1      1                  0x0035-0x0035
- * SHA256    1                  0x0037-0x0037
- * SHA512    1                  0x0039-0x0039
+ * SHA1      1                  0x0035-0x0035 0x0073-0x0073
+ * SHA256    1                  0x0037-0x0037 0x0074-0x0074
+ * SHA512    1                  0x0039-0x0039 0x0075-0x0075
  * CHACHA20  3                  0x0051-0x0055
  * POLY1305  3                  0x0057-0x005B
  * CHACHAPOLY 2 0x0054-0x0056
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index 93d15ee..fccabb0 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -85,7 +85,7 @@
  *                  cipher, nor set the key. For this purpose, use
  *                  mbedtls_gcm_setkey().
  *
- * \param ctx       The GCM context to initialize.
+ * \param ctx       The GCM context to initialize. This must not be \c NULL.
  */
 void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
 
@@ -93,9 +93,10 @@
  * \brief           This function associates a GCM context with a
  *                  cipher algorithm and a key.
  *
- * \param ctx       The GCM context to initialize.
+ * \param ctx       The GCM context. This must be initialized.
  * \param cipher    The 128-bit block cipher to use.
- * \param key       The encryption key.
+ * \param key       The encryption key. This must be a readable buffer of at
+ *                  least \p keybits bits.
  * \param keybits   The key size in bits. Valid options are:
  *                  <ul><li>128 bits</li>
  *                  <li>192 bits</li>
@@ -122,7 +123,8 @@
  *                  authentic. You should use this function to perform encryption
  *                  only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
  *
- * \param ctx       The GCM context to use for encryption or decryption.
+ * \param ctx       The GCM context to use for encryption or decryption. This
+ *                  must be initialized.
  * \param mode      The operation to perform:
  *                  - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
  *                    The ciphertext is written to \p output and the
@@ -136,21 +138,27 @@
  *                    calling this function in decryption mode.
  * \param length    The length of the input data, which is equal to the length
  *                  of the output data.
- * \param iv        The initialization vector.
+ * \param iv        The initialization vector. This must be a readable buffer of
+ *                  at least \p iv_len Bytes.
  * \param iv_len    The length of the IV.
- * \param add       The buffer holding the additional data.
+ * \param add       The buffer holding the additional data. This must be of at
+ *                  least that size in Bytes.
  * \param add_len   The length of the additional data.
- * \param input     The buffer holding the input data. Its size is \b length.
- * \param output    The buffer for holding the output data. It must have room
- *                  for \b length bytes.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size in Bytes.
+ * \param output    The buffer for holding the output data. If \p length is greater
+ *                  than zero, this must be a writable buffer of at least that
+ *                  size in Bytes.
  * \param tag_len   The length of the tag to generate.
- * \param tag       The buffer for holding the tag.
+ * \param tag       The buffer for holding the tag. This must be a readable
+ *                  buffer of at least \p tag_len Bytes.
  *
  * \return          \c 0 if the encryption or decryption was performed
  *                  successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
  *                  this does not indicate that the data is authentic.
- * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid or
- *                  a cipher-specific error code if the encryption
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ *                  not valid or a cipher-specific error code if the encryption
  *                  or decryption failed.
  */
 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
@@ -173,23 +181,30 @@
  *                  input buffer. If the buffers overlap, the output buffer
  *                  must trail at least 8 Bytes behind the input buffer.
  *
- * \param ctx       The GCM context.
+ * \param ctx       The GCM context. This must be initialized.
  * \param length    The length of the ciphertext to decrypt, which is also
  *                  the length of the decrypted plaintext.
- * \param iv        The initialization vector.
+ * \param iv        The initialization vector. This must be a readable buffer
+ *                  of at least \p iv_len Bytes.
  * \param iv_len    The length of the IV.
- * \param add       The buffer holding the additional data.
+ * \param add       The buffer holding the additional data. This must be of at
+ *                  least that size in Bytes.
  * \param add_len   The length of the additional data.
- * \param tag       The buffer holding the tag to verify.
+ * \param tag       The buffer holding the tag to verify. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the tag to verify.
- * \param input     The buffer holding the ciphertext. Its size is \b length.
- * \param output    The buffer for holding the decrypted plaintext. It must
- *                  have room for \b length bytes.
+ * \param input     The buffer holding the ciphertext. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size.
+ * \param output    The buffer for holding the decrypted plaintext. If \p length
+ *                  is greater than zero, this must be a writable buffer of at
+ *                  least that size.
  *
  * \return          \c 0 if successful and authenticated.
  * \return          #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
- * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid or
- *                  a cipher-specific error code if the decryption failed.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ *                  not valid or a cipher-specific error code if the decryption
+ *                  failed.
  */
 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
                       size_t length,
@@ -206,15 +221,16 @@
  * \brief           This function starts a GCM encryption or decryption
  *                  operation.
  *
- * \param ctx       The GCM context.
+ * \param ctx       The GCM context. This must be initialized.
  * \param mode      The operation to perform: #MBEDTLS_GCM_ENCRYPT or
  *                  #MBEDTLS_GCM_DECRYPT.
- * \param iv        The initialization vector.
+ * \param iv        The initialization vector. This must be a readable buffer of
+ *                  at least \p iv_len Bytes.
  * \param iv_len    The length of the IV.
- * \param add       The buffer holding the additional data, or NULL
- *                  if \p add_len is 0.
- * \param add_len   The length of the additional data. If 0,
- *                  \p add is NULL.
+ * \param add       The buffer holding the additional data, or \c NULL
+ *                  if \p add_len is \c 0.
+ * \param add_len   The length of the additional data. If \c 0,
+ *                  \p add may be \c NULL.
  *
  * \return          \c 0 on success.
  */
@@ -237,11 +253,15 @@
  *                  input buffer. If the buffers overlap, the output buffer
  *                  must trail at least 8 Bytes behind the input buffer.
  *
- * \param ctx       The GCM context.
+ * \param ctx       The GCM context. This must be initialized.
  * \param length    The length of the input data. This must be a multiple of
  *                  16 except in the last call before mbedtls_gcm_finish().
- * \param input     The buffer holding the input data.
- * \param output    The buffer for holding the output data.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size in Bytes.
+ * \param output    The buffer for holding the output data. If \p length is
+ *                  greater than zero, this must be a writable buffer of at
+ *                  least that size in Bytes.
  *
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
@@ -258,9 +278,11 @@
  *                  It wraps up the GCM stream, and generates the
  *                  tag. The tag can have a maximum length of 16 Bytes.
  *
- * \param ctx       The GCM context.
- * \param tag       The buffer for holding the tag.
- * \param tag_len   The length of the tag to generate. Must be at least four.
+ * \param ctx       The GCM context. This must be initialized.
+ * \param tag       The buffer for holding the tag. This must be a readable
+ *                  buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the tag to generate. This must be at least
+ *                  four.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
@@ -273,7 +295,8 @@
  * \brief           This function clears a GCM context and the underlying
  *                  cipher sub-context.
  *
- * \param ctx       The GCM context to clear.
+ * \param ctx       The GCM context to clear. If this is \c NULL, the call has
+ *                  no effect. Otherwise, this must be initialized.
  */
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
 
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 3bc675e..146367b 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -195,10 +195,13 @@
  * \param additional    Additional data to update state with, or NULL
  * \param add_len       Length of additional data, or 0
  *
+ * \return              \c 0 on success, or an error from the underlying
+ *                      hash calculation.
+ *
  * \note                Additional data is optional, pass NULL and 0 as second
  *                      third argument if no additional data is being used.
  */
-void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
                        const unsigned char *additional, size_t add_len );
 
 /**
@@ -257,6 +260,31 @@
  */
 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
 
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief               HMAC_DRBG update state
+ *
+ * \deprecated          Superseded by mbedtls_hmac_drbg_update_ret()
+ *                      in 2.16.0.
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param additional    Additional data to update state with, or NULL
+ * \param add_len       Length of additional data, or 0
+ *
+ * \note                Additional data is optional, pass NULL and 0 as second
+ *                      third argument if no additional data is being used.
+ */
+MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
+    mbedtls_hmac_drbg_context *ctx,
+    const unsigned char *additional, size_t add_len );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
 #if defined(MBEDTLS_FS_IO)
 /**
  * \brief               Write a seed file
diff --git a/include/mbedtls/padlock.h b/include/mbedtls/padlock.h
index 677936e..7a5d083 100644
--- a/include/mbedtls/padlock.h
+++ b/include/mbedtls/padlock.h
@@ -3,6 +3,9 @@
  *
  * \brief VIA PadLock ACE for HW encryption/decryption supported by some
  *        processors
+ *
+ * \warning These functions are only for internal use by other library
+ *          functions; you must not call them directly.
  */
 /*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@@ -57,7 +60,10 @@
 #endif
 
 /**
- * \brief          PadLock detection routine
+ * \brief          Internal PadLock detection routine
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param feature  The feature to detect
  *
@@ -66,7 +72,10 @@
 int mbedtls_padlock_has_support( int feature );
 
 /**
- * \brief          PadLock AES-ECB block en(de)cryption
+ * \brief          Internal PadLock AES-ECB block en(de)cryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param ctx      AES context
  * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@@ -76,12 +85,15 @@
  * \return         0 if success, 1 if operation failed
  */
 int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
-                       int mode,
-                       const unsigned char input[16],
-                       unsigned char output[16] );
+                               int mode,
+                               const unsigned char input[16],
+                               unsigned char output[16] );
 
 /**
- * \brief          PadLock AES-CBC buffer en(de)cryption
+ * \brief          Internal PadLock AES-CBC buffer en(de)cryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param ctx      AES context
  * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@@ -93,11 +105,11 @@
  * \return         0 if success, 1 if operation failed
  */
 int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
-                       int mode,
-                       size_t length,
-                       unsigned char iv[16],
-                       const unsigned char *input,
-                       unsigned char *output );
+                               int mode,
+                               size_t length,
+                               unsigned char iv[16],
+                               const unsigned char *input,
+                               unsigned char *output );
 
 #ifdef __cplusplus
 }
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index df3a03c..91950f9 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -197,23 +197,35 @@
 const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type );
 
 /**
- * \brief           Initialize a mbedtls_pk_context (as NONE)
+ * \brief           Initialize a #mbedtls_pk_context (as NONE).
+ *
+ * \param ctx       The context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_pk_init( mbedtls_pk_context *ctx );
 
 /**
- * \brief           Free a mbedtls_pk_context
+ * \brief           Free the components of a #mbedtls_pk_context.
+ *
+ * \param ctx       The context to clear. It must have been initialized.
+ *                  If this is \c NULL, this function does nothing.
  */
 void mbedtls_pk_free( mbedtls_pk_context *ctx );
 
 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
 /**
  * \brief           Initialize a restart context
+ *
+ * \param ctx       The context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx );
 
 /**
  * \brief           Free the components of a restart context
+ *
+ * \param ctx       The context to clear. It must have been initialized.
+ *                  If this is \c NULL, this function does nothing.
  */
 void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
@@ -222,7 +234,8 @@
  * \brief           Initialize a PK context with the information given
  *                  and allocates the type-specific PK subcontext.
  *
- * \param ctx       Context to initialize. Must be empty (type NONE).
+ * \param ctx       Context to initialize. It must not have been set
+ *                  up yet (type #MBEDTLS_PK_NONE).
  * \param info      Information to use
  *
  * \return          0 on success,
@@ -238,7 +251,8 @@
 /**
  * \brief           Initialize an RSA-alt context
  *
- * \param ctx       Context to initialize. Must be empty (type NONE).
+ * \param ctx       Context to initialize. It must not have been set
+ *                  up yet (type #MBEDTLS_PK_NONE).
  * \param key       RSA key pointer
  * \param decrypt_func  Decryption function
  * \param sign_func     Signing function
@@ -258,7 +272,7 @@
 /**
  * \brief           Get the size in bits of the underlying key
  *
- * \param ctx       Context to use
+ * \param ctx       The context to query. It must have been initialized.
  *
  * \return          Key size in bits, or 0 on error
  */
@@ -266,7 +280,8 @@
 
 /**
  * \brief           Get the length in bytes of the underlying key
- * \param ctx       Context to use
+ *
+ * \param ctx       The context to query. It must have been initialized.
  *
  * \return          Key length in bytes, or 0 on error
  */
@@ -278,18 +293,21 @@
 /**
  * \brief           Tell if a context can do the operation given by type
  *
- * \param ctx       Context to test
- * \param type      Target type
+ * \param ctx       The context to query. It must have been initialized.
+ * \param type      The desired type.
  *
- * \return          0 if context can't do the operations,
- *                  1 otherwise.
+ * \return          1 if the context can do operations on the given type.
+ * \return          0 if the context cannot do the operations on the given
+ *                  type. This is always the case for a context that has
+ *                  been initialized but not set up, or that has been
+ *                  cleared with mbedtls_pk_free().
  */
 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
 
 /**
  * \brief           Verify signature (including padding if relevant).
  *
- * \param ctx       PK context to use
+ * \param ctx       The PK context to use. It must have been set up.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -322,7 +340,7 @@
  *                  \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
  *                  operations. For RSA, same as \c mbedtls_pk_verify().
  *
- * \param ctx       PK context to use
+ * \param ctx       The PK context to use. It must have been set up.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -346,7 +364,7 @@
  *
  * \param type      Signature type (inc. possible padding type) to verify
  * \param options   Pointer to type-specific options, or NULL
- * \param ctx       PK context to use
+ * \param ctx       The PK context to use. It must have been set up.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -377,7 +395,8 @@
 /**
  * \brief           Make signature, including padding if relevant.
  *
- * \param ctx       PK context to use - must hold a private key
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -411,7 +430,8 @@
  *                  \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
  *                  operations. For RSA, same as \c mbedtls_pk_sign().
  *
- * \param ctx       PK context to use - must hold a private key
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -435,7 +455,8 @@
 /**
  * \brief           Decrypt message (including padding if relevant).
  *
- * \param ctx       PK context to use - must hold a private key
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
  * \param input     Input to decrypt
  * \param ilen      Input size
  * \param output    Decrypted output
@@ -456,7 +477,7 @@
 /**
  * \brief           Encrypt message (including padding if relevant).
  *
- * \param ctx       PK context to use
+ * \param ctx       The PK context to use. It must have been set up.
  * \param input     Message to encrypt
  * \param ilen      Message size
  * \param output    Encrypted output
@@ -487,7 +508,7 @@
 /**
  * \brief           Export debug information
  *
- * \param ctx       Context to use
+ * \param ctx       The PK context to use. It must have been initialized.
  * \param items     Place to write debug items
  *
  * \return          0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
@@ -497,7 +518,7 @@
 /**
  * \brief           Access the type name
  *
- * \param ctx       Context to use
+ * \param ctx       The PK context to use. It must have been initialized.
  *
  * \return          Type name on success, or "invalid PK"
  */
@@ -506,9 +527,10 @@
 /**
  * \brief           Get the key type
  *
- * \param ctx       Context to use
+ * \param ctx       The PK context to use. It must have been initialized.
  *
- * \return          Type on success, or MBEDTLS_PK_NONE
+ * \return          Type on success.
+ * \return          #MBEDTLS_PK_NONE for a context that has not been set up.
  */
 mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
 
@@ -517,12 +539,22 @@
 /**
  * \brief           Parse a private key in PEM or DER format
  *
- * \param ctx       key to be initialized
- * \param key       input buffer
- * \param keylen    size of the buffer
- *                  (including the terminating null byte for PEM data)
- * \param pwd       password for decryption (optional)
- * \param pwdlen    size of the password
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param key       Input buffer to parse.
+ *                  The buffer must contain the input exactly, with no
+ *                  extra trailing material. For PEM, the buffer must
+ *                  contain a null-terminated string.
+ * \param keylen    Size of \b key in bytes.
+ *                  For PEM data, this includes the terminating null byte,
+ *                  so \p keylen must be equal to `strlen(key) + 1`.
+ * \param pwd       Optional password for decryption.
+ *                  Pass \c NULL if expecting a non-encrypted key.
+ *                  Pass a string of \p pwdlen bytes if expecting an encrypted
+ *                  key; a non-encrypted key will also be accepted.
+ *                  The empty password is not supported.
+ * \param pwdlen    Size of the password in bytes.
+ *                  Ignored if \p pwd is \c NULL.
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -540,10 +572,15 @@
 /**
  * \brief           Parse a public key in PEM or DER format
  *
- * \param ctx       key to be initialized
- * \param key       input buffer
- * \param keylen    size of the buffer
- *                  (including the terminating null byte for PEM data)
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param key       Input buffer to parse.
+ *                  The buffer must contain the input exactly, with no
+ *                  extra trailing material. For PEM, the buffer must
+ *                  contain a null-terminated string.
+ * \param keylen    Size of \b key in bytes.
+ *                  For PEM data, this includes the terminating null byte,
+ *                  so \p keylen must be equal to `strlen(key) + 1`.
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -561,9 +598,14 @@
 /**
  * \brief           Load and parse a private key
  *
- * \param ctx       key to be initialized
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
  * \param path      filename to read the private key from
- * \param password  password to decrypt the file (can be NULL)
+ * \param password  Optional password to decrypt the file.
+ *                  Pass \c NULL if expecting a non-encrypted key.
+ *                  Pass a null-terminated string if expecting an encrypted
+ *                  key; a non-encrypted key will also be accepted.
+ *                  The empty password is not supported.
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -580,7 +622,8 @@
 /**
  * \brief           Load and parse a public key
  *
- * \param ctx       key to be initialized
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
  * \param path      filename to read the public key from
  *
  * \note            On entry, ctx must be empty, either freshly initialised
@@ -603,7 +646,7 @@
  *                        return value to determine where you should start
  *                        using the buffer
  *
- * \param ctx       private to write away
+ * \param ctx       PK context which must contain a valid private key.
  * \param buf       buffer to write to
  * \param size      size of the buffer
  *
@@ -618,7 +661,7 @@
  *                        return value to determine where you should start
  *                        using the buffer
  *
- * \param ctx       public key to write away
+ * \param ctx       PK context which must contain a valid public or private key.
  * \param buf       buffer to write to
  * \param size      size of the buffer
  *
@@ -631,9 +674,10 @@
 /**
  * \brief           Write a public key to a PEM string
  *
- * \param ctx       public key to write away
- * \param buf       buffer to write to
- * \param size      size of the buffer
+ * \param ctx       PK context which must contain a valid public or private key.
+ * \param buf       Buffer to write to. The output includes a
+ *                  terminating null byte.
+ * \param size      Size of the buffer in bytes.
  *
  * \return          0 if successful, or a specific error code
  */
@@ -642,9 +686,10 @@
 /**
  * \brief           Write a private key to a PKCS#1 or SEC1 PEM string
  *
- * \param ctx       private to write away
- * \param buf       buffer to write to
- * \param size      size of the buffer
+ * \param ctx       PK context which must contain a valid private key.
+ * \param buf       Buffer to write to. The output includes a
+ *                  terminating null byte.
+ * \param size      Size of the buffer in bytes.
  *
  * \return          0 if successful, or a specific error code
  */
@@ -663,7 +708,8 @@
  *
  * \param p         the position in the ASN.1 data
  * \param end       end of the buffer
- * \param pk        the key to fill
+ * \param pk        The PK context to fill. It must have been initialized
+ *                  but not set up.
  *
  * \return          0 if successful, or a specific PK error code
  */
@@ -678,7 +724,7 @@
  *
  * \param p         reference to current position pointer
  * \param start     start of the buffer (for bounds-checking)
- * \param key       public key to write away
+ * \param key       PK context which must contain a valid public or private key.
  *
  * \return          the length written or a negative error code
  */
diff --git a/include/mbedtls/pkcs12.h b/include/mbedtls/pkcs12.h
index a621ef5..69f0417 100644
--- a/include/mbedtls/pkcs12.h
+++ b/include/mbedtls/pkcs12.h
@@ -46,6 +46,8 @@
 extern "C" {
 #endif
 
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
 /**
  * \brief            PKCS12 Password Based function (encryption / decryption)
  *                   for pbeWithSHAAnd128BitRC4
@@ -87,6 +89,8 @@
                 const unsigned char *input, size_t len,
                 unsigned char *output );
 
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
 /**
  * \brief            The PKCS#12 derivation function uses a password and a salt
  *                   to produce pseudo-random bits for a particular "purpose".
diff --git a/include/mbedtls/pkcs5.h b/include/mbedtls/pkcs5.h
index 9a3c9fd..d4bb36d 100644
--- a/include/mbedtls/pkcs5.h
+++ b/include/mbedtls/pkcs5.h
@@ -44,6 +44,8 @@
 extern "C" {
 #endif
 
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
 /**
  * \brief          PKCS#5 PBES2 function
  *
@@ -62,6 +64,8 @@
                  const unsigned char *data, size_t datalen,
                  unsigned char *output );
 
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
 /**
  * \brief          PKCS#5 PBKDF2 using HMAC
  *
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 164a1a0..b0e72ad 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -41,6 +41,88 @@
 extern "C" {
 #endif
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+
+#if defined(MBEDTLS_PARAM_FAILED)
+/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
+ *
+ * This flag can be used to check whether it is safe to assume that
+ * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
+ */
+#define MBEDTLS_PARAM_FAILED_ALT
+#else /* MBEDTLS_PARAM_FAILED */
+#define MBEDTLS_PARAM_FAILED( cond ) \
+    mbedtls_param_failed( #cond, __FILE__, __LINE__ )
+
+/**
+ * \brief       User supplied callback function for parameter validation failure.
+ *              See #MBEDTLS_CHECK_PARAMS for context.
+ *
+ *              This function will be called unless an alternative treatement
+ *              is defined through the #MBEDTLS_PARAM_FAILED macro.
+ *
+ *              This function can return, and the operation will be aborted, or
+ *              alternatively, through use of setjmp()/longjmp() can resume
+ *              execution in the application code.
+ *
+ * \param failure_condition The assertion that didn't hold.
+ * \param file  The file where the assertion failed.
+ * \param line  The line in the file where the assertion failed.
+ */
+void mbedtls_param_failed( const char *failure_condition,
+                           const char *file,
+                           int line );
+#endif /* MBEDTLS_PARAM_FAILED */
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret )  \
+    do {                                            \
+        if( !(cond) )                               \
+        {                                           \
+            MBEDTLS_PARAM_FAILED( cond );           \
+            return( ret );                          \
+        }                                           \
+    } while( 0 )
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE( cond )           \
+    do {                                            \
+        if( !(cond) )                               \
+        {                                           \
+            MBEDTLS_PARAM_FAILED( cond );           \
+            return;                                 \
+        }                                           \
+    } while( 0 )
+
+#else /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal macros meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret )  do { } while( 0 )
+#define MBEDTLS_INTERNAL_VALIDATE( cond )           do { } while( 0 )
+
+#endif /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal helper macros for deprecating API constants. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here
+ * to avoid conflict with other headers which define and use
+ * it, too. We might want to move all these definitions here at
+ * some point for uniformity. */
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t;
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL )       \
+    ( (mbedtls_deprecated_string_constant_t) ( VAL ) )
+MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL )       \
+    ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) )
+#undef MBEDTLS_DEPRECATED
+#else /* MBEDTLS_DEPRECATED_WARNING */
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
 /**
  * \brief       Securely zeroize a buffer
  *
diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h
index b02f968..05866a2 100644
--- a/include/mbedtls/poly1305.h
+++ b/include/mbedtls/poly1305.h
@@ -84,14 +84,18 @@
  *                  \c mbedtls_poly1305_finish(), then finally
  *                  \c mbedtls_poly1305_free().
  *
- * \param ctx       The Poly1305 context to initialize.
+ * \param ctx       The Poly1305 context to initialize. This must
+ *                  not be \c NULL.
  */
 void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx );
 
 /**
- * \brief           This function releases and clears the specified Poly1305 context.
+ * \brief           This function releases and clears the specified
+ *                  Poly1305 context.
  *
- * \param ctx       The Poly1305 context to clear.
+ * \param ctx       The Poly1305 context to clear. This may be \c NULL, in which
+ *                  case this function is a no-op. If it is not \c NULL, it must
+ *                  point to an initialized Poly1305 context.
  */
 void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx );
 
@@ -102,11 +106,11 @@
  *                  invocation of Poly1305.
  *
  * \param ctx       The Poly1305 context to which the key should be bound.
- * \param key       The buffer containing the 256-bit key.
+ *                  This must be initialized.
+ * \param key       The buffer containing the \c 32 Byte (\c 256 Bit) key.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if ctx or key are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
                              const unsigned char key[32] );
@@ -120,13 +124,14 @@
  *                  It can be called repeatedly to process a stream of data.
  *
  * \param ctx       The Poly1305 context to use for the Poly1305 operation.
- * \param ilen      The length of the input data (in bytes). Any value is accepted.
+ *                  This must be initialized and bound to a key.
+ * \param ilen      The length of the input data in Bytes.
+ *                  Any value is accepted.
  * \param input     The buffer holding the input data.
- *                  This pointer can be NULL if ilen == 0.
+ *                  This pointer can be \c NULL if `ilen == 0`.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if ctx or input are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
                              const unsigned char *input,
@@ -137,12 +142,12 @@
  *                  Authentication Code (MAC).
  *
  * \param ctx       The Poly1305 context to use for the Poly1305 operation.
- * \param mac       The buffer to where the MAC is written. Must be big enough
- *                  to hold the 16-byte MAC.
+ *                  This must be initialized and bound to a key.
+ * \param mac       The buffer to where the MAC is written. This must
+ *                  be a writable buffer of length \c 16 Bytes.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if ctx or mac are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
                              unsigned char mac[16] );
@@ -154,16 +159,16 @@
  * \warning         The key must be unique and unpredictable for each
  *                  invocation of Poly1305.
  *
- * \param key       The buffer containing the 256-bit key.
- * \param ilen      The length of the input data (in bytes). Any value is accepted.
+ * \param key       The buffer containing the \c 32 Byte (\c 256 Bit) key.
+ * \param ilen      The length of the input data in Bytes.
+ *                  Any value is accepted.
  * \param input     The buffer holding the input data.
- *                  This pointer can be NULL if ilen == 0.
- * \param mac       The buffer to where the MAC is written. Must be big enough
- *                  to hold the 16-byte MAC.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param mac       The buffer to where the MAC is written. This must be
+ *                  a writable buffer of length \c 16 Bytes.
  *
  * \return          \c 0 on success.
- * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
- *                  if key, input, or mac are NULL.
+ * \return          A negative error code on failure.
  */
 int mbedtls_poly1305_mac( const unsigned char key[32],
                           const unsigned char *input,
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index 406a317..ed65a34 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -158,15 +158,16 @@
  *                 making signatures, but can be overriden for verifying them.
  *                 If set to #MBEDTLS_MD_NONE, it is always overriden.
  *
- * \param ctx      The RSA context to initialize.
- * \param padding  Selects padding mode: #MBEDTLS_RSA_PKCS_V15 or
- *                 #MBEDTLS_RSA_PKCS_V21.
- * \param hash_id  The hash identifier of #mbedtls_md_type_t type, if
- *                 \p padding is #MBEDTLS_RSA_PKCS_V21.
+ * \param ctx      The RSA context to initialize. This must not be \c NULL.
+ * \param padding  The padding mode to use. This must be either
+ *                 #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21.
+ * \param hash_id  The hash identifier of ::mbedtls_md_type_t type, if
+ *                 \p padding is #MBEDTLS_RSA_PKCS_V21. It is unused
+ *                 otherwise.
  */
 void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
                        int padding,
-                       int hash_id);
+                       int hash_id );
 
 /**
  * \brief          This function imports a set of core parameters into an
@@ -188,11 +189,11 @@
  *                 for the lifetime of the RSA context being set up.
  *
  * \param ctx      The initialized RSA context to store the parameters in.
- * \param N        The RSA modulus, or NULL.
- * \param P        The first prime factor of \p N, or NULL.
- * \param Q        The second prime factor of \p N, or NULL.
- * \param D        The private exponent, or NULL.
- * \param E        The public exponent, or NULL.
+ * \param N        The RSA modulus. This may be \c NULL.
+ * \param P        The first prime factor of \p N. This may be \c NULL.
+ * \param Q        The second prime factor of \p N. This may be \c NULL.
+ * \param D        The private exponent. This may be \c NULL.
+ * \param E        The public exponent. This may be \c NULL.
  *
  * \return         \c 0 on success.
  * \return         A non-zero error code on failure.
@@ -222,16 +223,16 @@
  *                 for the lifetime of the RSA context being set up.
  *
  * \param ctx      The initialized RSA context to store the parameters in.
- * \param N        The RSA modulus, or NULL.
- * \param N_len    The Byte length of \p N, ignored if \p N == NULL.
- * \param P        The first prime factor of \p N, or NULL.
- * \param P_len    The Byte length of \p P, ignored if \p P == NULL.
- * \param Q        The second prime factor of \p N, or NULL.
- * \param Q_len    The Byte length of \p Q, ignored if \p Q == NULL.
- * \param D        The private exponent, or NULL.
- * \param D_len    The Byte length of \p D, ignored if \p D == NULL.
- * \param E        The public exponent, or NULL.
- * \param E_len    The Byte length of \p E, ignored if \p E == NULL.
+ * \param N        The RSA modulus. This may be \c NULL.
+ * \param N_len    The Byte length of \p N; it is ignored if \p N == NULL.
+ * \param P        The first prime factor of \p N. This may be \c NULL.
+ * \param P_len    The Byte length of \p P; it ns ignored if \p P == NULL.
+ * \param Q        The second prime factor of \p N. This may be \c NULL.
+ * \param Q_len    The Byte length of \p Q; it is ignored if \p Q == NULL.
+ * \param D        The private exponent. This may be \c NULL.
+ * \param D_len    The Byte length of \p D; it is ignored if \p D == NULL.
+ * \param E        The public exponent. This may be \c NULL.
+ * \param E_len    The Byte length of \p E; it is ignored if \p E == NULL.
  *
  * \return         \c 0 on success.
  * \return         A non-zero error code on failure.
@@ -299,11 +300,16 @@
  *                 the RSA context stays intact and remains usable.
  *
  * \param ctx      The initialized RSA context.
- * \param N        The MPI to hold the RSA modulus, or NULL.
- * \param P        The MPI to hold the first prime factor of \p N, or NULL.
- * \param Q        The MPI to hold the second prime factor of \p N, or NULL.
- * \param D        The MPI to hold the private exponent, or NULL.
- * \param E        The MPI to hold the public exponent, or NULL.
+ * \param N        The MPI to hold the RSA modulus.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param P        The MPI to hold the first prime factor of \p N.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param Q        The MPI to hold the second prime factor of \p N.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param D        The MPI to hold the private exponent.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param E        The MPI to hold the public exponent.
+ *                 This may be \c NULL if this field need not be exported.
  *
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the
@@ -341,17 +347,20 @@
  *                 buffer pointers are NULL.
  *
  * \param ctx      The initialized RSA context.
- * \param N        The Byte array to store the RSA modulus, or NULL.
+ * \param N        The Byte array to store the RSA modulus,
+ *                 or \c NULL if this field need not be exported.
  * \param N_len    The size of the buffer for the modulus.
- * \param P        The Byte array to hold the first prime factor of \p N, or
- *                 NULL.
+ * \param P        The Byte array to hold the first prime factor of \p N,
+ *                 or \c NULL if this field need not be exported.
  * \param P_len    The size of the buffer for the first prime factor.
- * \param Q        The Byte array to hold the second prime factor of \p N, or
- *                 NULL.
+ * \param Q        The Byte array to hold the second prime factor of \p N,
+ *                 or \c NULL if this field need not be exported.
  * \param Q_len    The size of the buffer for the second prime factor.
- * \param D        The Byte array to hold the private exponent, or NULL.
+ * \param D        The Byte array to hold the private exponent,
+ *                 or \c NULL if this field need not be exported.
  * \param D_len    The size of the buffer for the private exponent.
- * \param E        The Byte array to hold the public exponent, or NULL.
+ * \param E        The Byte array to hold the public exponent,
+ *                 or \c NULL if this field need not be exported.
  * \param E_len    The size of the buffer for the public exponent.
  *
  * \return         \c 0 on success.
@@ -375,9 +384,12 @@
  *                 mbedtls_rsa_deduce_opt().
  *
  * \param ctx      The initialized RSA context.
- * \param DP       The MPI to hold D modulo P-1, or NULL.
- * \param DQ       The MPI to hold D modulo Q-1, or NULL.
- * \param QP       The MPI to hold modular inverse of Q modulo P, or NULL.
+ * \param DP       The MPI to hold \c D modulo `P-1`,
+ *                 or \c NULL if it need not be exported.
+ * \param DQ       The MPI to hold \c D modulo `Q-1`,
+ *                 or \c NULL if it need not be exported.
+ * \param QP       The MPI to hold modular inverse of \c Q modulo \c P,
+ *                 or \c NULL if it need not be exported.
  *
  * \return         \c 0 on success.
  * \return         A non-zero error code on failure.
@@ -390,13 +402,13 @@
  * \brief          This function sets padding for an already initialized RSA
  *                 context. See mbedtls_rsa_init() for details.
  *
- * \param ctx      The RSA context to be set.
- * \param padding  Selects padding mode: #MBEDTLS_RSA_PKCS_V15 or
- *                 #MBEDTLS_RSA_PKCS_V21.
+ * \param ctx      The initialized RSA context to be configured.
+ * \param padding  The padding mode to use. This must be either
+ *                 #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21.
  * \param hash_id  The #MBEDTLS_RSA_PKCS_V21 hash identifier.
  */
 void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
-                              int hash_id);
+                              int hash_id );
 
 /**
  * \brief          This function retrieves the length of RSA modulus in Bytes.
@@ -414,11 +426,14 @@
  * \note           mbedtls_rsa_init() must be called before this function,
  *                 to set up the RSA context.
  *
- * \param ctx      The RSA context used to hold the key.
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG context.
+ * \param ctx      The initialized RSA context used to hold the key.
+ * \param f_rng    The RNG function to be used for key generation.
+ *                 This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't need a context.
  * \param nbits    The size of the public key in bits.
- * \param exponent The public exponent. For example, 65537.
+ * \param exponent The public exponent to use. For example, \c 65537.
+ *                 This must be odd and greater than \c 1.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -436,7 +451,7 @@
  *                 enough information is present to perform an RSA public key
  *                 operation using mbedtls_rsa_public().
  *
- * \param ctx      The RSA context to check.
+ * \param ctx      The initialized RSA context to check.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -475,7 +490,7 @@
  *             parameters, which goes beyond what is effectively checkable
  *             by the library.</li></ul>
  *
- * \param ctx  The RSA context to check.
+ * \param ctx  The initialized RSA context to check.
  *
  * \return     \c 0 on success.
  * \return     An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -487,8 +502,8 @@
  *
  *                 It checks each of the contexts, and makes sure they match.
  *
- * \param pub      The RSA context holding the public key.
- * \param prv      The RSA context holding the private key.
+ * \param pub      The initialized RSA context holding the public key.
+ * \param prv      The initialized RSA context holding the private key.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -499,18 +514,19 @@
 /**
  * \brief          This function performs an RSA public key operation.
  *
+ * \param ctx      The initialized RSA context to use.
+ * \param input    The input buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
  * \note           This function does not handle message padding.
  *
  * \note           Make sure to set \p input[0] = 0 or ensure that
  *                 input is smaller than \p N.
  *
- * \note           The input and output buffers must be large
- *                 enough. For example, 128 Bytes if RSA-1024 is used.
- *
- * \param ctx      The RSA context.
- * \param input    The input buffer.
- * \param output   The output buffer.
- *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
@@ -521,9 +537,6 @@
 /**
  * \brief          This function performs an RSA private key operation.
  *
- * \note           The input and output buffers must be large
- *                 enough. For example, 128 Bytes if RSA-1024 is used.
- *
  * \note           Blinding is used if and only if a PRNG is provided.
  *
  * \note           If blinding is used, both the base of exponentation
@@ -535,11 +548,18 @@
  *                 Future versions of the library may enforce the presence
  *                 of a PRNG.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for blinding.
- * \param p_rng    The RNG context.
- * \param input    The input buffer.
- * \param output   The output buffer.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function, used for blinding. It is discouraged
+ *                 and deprecated to pass \c NULL here, in which case
+ *                 blinding will be omitted.
+ * \param p_rng    The RNG context to pass to \p f_rng. This may be \c NULL
+ *                 if \p f_rng is \c NULL or if \p f_rng doesn't need a context.
+ * \param input    The input buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -558,9 +578,6 @@
  *                 It is the generic wrapper for performing a PKCS#1 encryption
  *                 operation using the \p mode from the context.
  *
- * \note           The input and output buffers must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
  *                 are likely to remove the \p mode argument and have it
@@ -570,14 +587,24 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for padding, PKCS#1 v2.1
- *                 encoding, and #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param ilen     The length of the plaintext.
- * \param input    The buffer holding the data to encrypt.
- * \param output   The buffer used to hold the ciphertext.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG to use. It is mandatory for PKCS#1 v2.1 padding
+ *                 encoding, and for PKCS#1 v1.5 padding encoding when used
+ *                 with \p mode set to #MBEDTLS_RSA_PUBLIC. For PKCS#1 v1.5
+ *                 padding encoding and \p mode set to #MBEDTLS_RSA_PRIVATE,
+ *                 it is used for blinding and should be provided in this
+ *                 case; see mbedtls_rsa_private() for more.
+ * \param p_rng    The RNG context to be passed to \p f_rng. May be
+ *                 \c NULL if \p f_rng is \c NULL or if \p f_rng doesn't
+ *                 need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param ilen     The length of the plaintext in Bytes.
+ * \param input    The input data to encrypt. This must be a readable
+ *                 buffer of size \p ilen Bytes. This must not be \c NULL.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -593,9 +620,6 @@
  * \brief          This function performs a PKCS#1 v1.5 encryption operation
  *                 (RSAES-PKCS1-v1_5-ENCRYPT).
  *
- * \note           The output buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
  *                 are likely to remove the \p mode argument and have it
@@ -605,14 +629,22 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for padding and
- *                 #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param ilen     The length of the plaintext.
- * \param input    The buffer holding the data to encrypt.
- * \param output   The buffer used to hold the ciphertext.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function to use. It is needed for padding generation
+ *                 if \p mode is #MBEDTLS_RSA_PUBLIC. If \p mode is
+ *                 #MBEDTLS_RSA_PRIVATE (discouraged), it is used for
+ *                 blinding and should be provided; see mbedtls_rsa_private().
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may
+ *                 be \c NULL if \p f_rng is \c NULL or if \p f_rng
+ *                 doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param ilen     The length of the plaintext in Bytes.
+ * \param input    The input data to encrypt. This must be a readable
+ *                 buffer of size \p ilen Bytes. This must not be \c NULL.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -640,16 +672,23 @@
  *                   mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                   return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx        The RSA context.
- * \param f_rng      The RNG function. Needed for padding and PKCS#1 v2.1
- *                   encoding and #MBEDTLS_RSA_PRIVATE.
- * \param p_rng      The RNG context.
- * \param mode       #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx        The initnialized RSA context to use.
+ * \param f_rng      The RNG function to use. This is needed for padding
+ *                   generation and must be provided.
+ * \param p_rng      The RNG context to be passed to \p f_rng. This may
+ *                   be \c NULL if \p f_rng doesn't need a context argument.
+ * \param mode       The mode of operation. This must be either
+ *                   #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
  * \param label      The buffer holding the custom label to use.
- * \param label_len  The length of the label.
- * \param ilen       The length of the plaintext.
- * \param input      The buffer holding the data to encrypt.
- * \param output     The buffer used to hold the ciphertext.
+ *                   This must be a readable buffer of length \p label_len
+ *                   Bytes. It may be \c NULL if \p label_len is \c 0.
+ * \param label_len  The length of the label in Bytes.
+ * \param ilen       The length of the plaintext buffer \p input in Bytes.
+ * \param input      The input data to encrypt. This must be a readable
+ *                   buffer of size \p ilen Bytes. This must not be \c NULL.
+ * \param output     The output buffer. This must be a writable buffer
+ *                   of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                   for an 2048-bit RSA modulus.
  *
  * \return           \c 0 on success.
  * \return           An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -677,9 +716,6 @@
  *                 hold the decryption of the particular ciphertext provided,
  *                 the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
  *
- * \note           The input buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
  *                 are likely to remove the \p mode argument and have it
@@ -689,14 +725,23 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param olen     The length of the plaintext.
- * \param input    The buffer holding the encrypted data.
- * \param output   The buffer used to hold the plaintext.
- * \param output_max_len    The maximum length of the output buffer.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. If \p mode is
+ *                 #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param olen     The address at which to store the length of
+ *                 the plaintext. This must not be \c NULL.
+ * \param input    The ciphertext buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The buffer used to hold the plaintext. This must
+ *                 be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -720,9 +765,6 @@
  *                 hold the decryption of the particular ciphertext provided,
  *                 the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
  *
- * \note           The input buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
  *                 are likely to remove the \p mode argument and have it
@@ -732,14 +774,23 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param olen     The length of the plaintext.
- * \param input    The buffer holding the encrypted data.
- * \param output   The buffer to hold the plaintext.
- * \param output_max_len    The maximum length of the output buffer.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. If \p mode is
+ *                 #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param olen     The address at which to store the length of
+ *                 the plaintext. This must not be \c NULL.
+ * \param input    The ciphertext buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The buffer used to hold the plaintext. This must
+ *                 be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -765,9 +816,6 @@
  *                   ciphertext provided, the function returns
  *                   #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
  *
- * \note             The input buffer must be as large as the size
- *                   of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \deprecated       It is deprecated and discouraged to call this function
  *                   in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
  *                   are likely to remove the \p mode argument and have it
@@ -777,16 +825,27 @@
  *                   mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                   return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx        The RSA context.
- * \param f_rng      The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng      The RNG context.
- * \param mode       #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx        The initialized RSA context to use.
+ * \param f_rng      The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                   this is used for blinding and should be provided; see
+ *                   mbedtls_rsa_private() for more. If \p mode is
+ *                   #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng      The RNG context to be passed to \p f_rng. This may be
+ *                   \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode       The mode of operation. This must be either
+ *                   #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
  * \param label      The buffer holding the custom label to use.
- * \param label_len  The length of the label.
- * \param olen       The length of the plaintext.
- * \param input      The buffer holding the encrypted data.
- * \param output     The buffer to hold the plaintext.
- * \param output_max_len    The maximum length of the output buffer.
+ *                   This must be a readable buffer of length \p label_len
+ *                   Bytes. It may be \c NULL if \p label_len is \c 0.
+ * \param label_len  The length of the label in Bytes.
+ * \param olen       The address at which to store the length of
+ *                   the plaintext. This must not be \c NULL.
+ * \param input      The ciphertext buffer. This must be a readable buffer
+ *                   of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                   for an 2048-bit RSA modulus.
+ * \param output     The buffer used to hold the plaintext. This must
+ *                   be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
  *
  * \return         \c 0 on success.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -824,16 +883,28 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for PKCS#1 v2.1 encoding and for
- *                 #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function to use. If the padding mode is PKCS#1 v2.1,
+ *                 this must be provided. If the padding mode is PKCS#1 v1.5 and
+ *                 \p mode is #MBEDTLS_RSA_PRIVATE, it is used for blinding
+ *                 and should be provided; see mbedtls_rsa_private() for more
+ *                 more. It is ignored otherwise.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng is \c NULL or doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer to hold the ciphertext.
+ * \param hashlen  The length of the message digest.
+ *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer to hold the signature. This must be a writable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 if the signing operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -851,9 +922,6 @@
  * \brief          This function performs a PKCS#1 v1.5 signature
  *                 operation (RSASSA-PKCS1-v1_5-SIGN).
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
  *                 are likely to remove the \p mode argument and have it
@@ -863,15 +931,27 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. If \p mode is
+ *                 #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng is \c NULL or doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer to hold the ciphertext.
+ * \param hashlen  The length of the message digest.
+ *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer to hold the signature. This must be a writable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 if the signing operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -889,9 +969,6 @@
  * \brief          This function performs a PKCS#1 v2.1 PSS signature
  *                 operation (RSASSA-PSS-SIGN).
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \note           The \p hash_id in the RSA context is the one used for the
  *                 encoding. \p md_alg in the function call is the type of hash
  *                 that is encoded. According to <em>RFC-3447: Public-Key
@@ -918,16 +995,24 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for PKCS#1 v2.1 encoding and for
- *                 #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. It must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer to hold the ciphertext.
+ * \param hashlen  The length of the message digest.
+ *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer to hold the signature. This must be a writable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 if the signing operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -948,9 +1033,6 @@
  *                 This is the generic wrapper for performing a PKCS#1
  *                 verification using the mode from the context.
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \note           For PKCS#1 v2.1 encoding, see comments on
  *                 mbedtls_rsa_rsassa_pss_verify() about \p md_alg and
  *                 \p hash_id.
@@ -964,15 +1046,26 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer holding the ciphertext.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 if the verify operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -990,9 +1083,6 @@
  * \brief          This function performs a PKCS#1 v1.5 verification
  *                 operation (RSASSA-PKCS1-v1_5-VERIFY).
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
  *                 are likely to remove the \p mode argument and have it
@@ -1002,15 +1092,26 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer holding the ciphertext.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 if the verify operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -1031,9 +1132,6 @@
  *                 The hash function for the MGF mask generating function
  *                 is that specified in the RSA context.
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
  * \note           The \p hash_id in the RSA context is the one used for the
  *                 verification. \p md_alg in the function call is the type of
  *                 hash that is verified. According to <em>RFC-3447: Public-Key
@@ -1051,15 +1149,26 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer holding the ciphertext.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 if the verify operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -1085,19 +1194,29 @@
  *
  * \note           The \p hash_id in the RSA context is ignored.
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG context.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is
- *                 #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param mgf1_hash_id       The message digest used for mask generation.
- * \param expected_salt_len  The length of the salt used in padding. Use
- *                           #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
- * \param sig      The buffer holding the ciphertext.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param mgf1_hash_id      The message digest used for mask generation.
+ * \param expected_salt_len The length of the salt used in padding. Use
+ *                          #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
  *
  * \return         \c 0 if the verify operation was successful.
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@@ -1116,8 +1235,8 @@
 /**
  * \brief          This function copies the components of an RSA context.
  *
- * \param dst      The destination context.
- * \param src      The source context.
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The source context. This must be initialized.
  *
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure.
@@ -1127,7 +1246,9 @@
 /**
  * \brief          This function frees the components of an RSA key.
  *
- * \param ctx      The RSA Context to free.
+ * \param ctx      The RSA context to free. May be \c NULL, in which case
+ *                 this function is a no-op. If it is not \c NULL, it must
+ *                 point to an initialized RSA context.
  */
 void mbedtls_rsa_free( mbedtls_rsa_context *ctx );
 
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index bcaeab5..38ea10b 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -42,6 +42,7 @@
 
 /* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA                   -0x0073  /**< SHA-1 input data was malformed. */
 
 #ifdef __cplusplus
 extern "C" {
@@ -79,6 +80,7 @@
  *                 stronger message digests instead.
  *
  * \param ctx      The SHA-1 context to initialize.
+ *                 This must not be \c NULL.
  *
  */
 void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
@@ -90,7 +92,10 @@
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
- * \param ctx      The SHA-1 context to clear.
+ * \param ctx      The SHA-1 context to clear. This may be \c NULL,
+ *                 in which case this function does nothing. If it is
+ *                 not \c NULL, it must point to an initialized
+ *                 SHA-1 context.
  *
  */
 void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
@@ -102,8 +107,8 @@
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
- * \param dst      The SHA-1 context to clone to.
- * \param src      The SHA-1 context to clone from.
+ * \param dst      The SHA-1 context to clone to. This must be initialized.
+ * \param src      The SHA-1 context to clone from. This must be initialized.
  *
  */
 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
@@ -116,9 +121,10 @@
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
- * \param ctx      The SHA-1 context to initialize.
+ * \param ctx      The SHA-1 context to initialize. This must be initialized.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  *
  */
 int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
@@ -131,11 +137,14 @@
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
- * \param ctx      The SHA-1 context.
+ * \param ctx      The SHA-1 context. This must be initialized
+ *                 and have a hash operation started.
  * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
                              const unsigned char *input,
@@ -149,10 +158,13 @@
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
- * \param ctx      The SHA-1 context.
- * \param output   The SHA-1 checksum result.
+ * \param ctx      The SHA-1 context to use. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-1 checksum result. This must be a writable
+ *                 buffer of length \c 20 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
                              unsigned char output[20] );
@@ -164,10 +176,12 @@
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
- * \param ctx      The SHA-1 context.
- * \param data     The data block being processed.
+ * \param ctx      The SHA-1 context to use. This must be initialized.
+ * \param data     The data block being processed. This must be a
+ *                 readable buffer of length \c 64 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  *
  */
 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
@@ -188,7 +202,7 @@
  *
  * \deprecated     Superseded by mbedtls_sha1_starts_ret() in 2.7.0.
  *
- * \param ctx      The SHA-1 context to initialize.
+ * \param ctx      The SHA-1 context to initialize. This must be initialized.
  *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
@@ -203,9 +217,11 @@
  *
  * \deprecated     Superseded by mbedtls_sha1_update_ret() in 2.7.0.
  *
- * \param ctx      The SHA-1 context.
+ * \param ctx      The SHA-1 context. This must be initialized and
+ *                 have a hash operation started.
  * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
  *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
@@ -222,9 +238,10 @@
  *
  * \deprecated     Superseded by mbedtls_sha1_finish_ret() in 2.7.0.
  *
- * \param ctx      The SHA-1 context.
+ * \param ctx      The SHA-1 context. This must be initialized and
+ *                 have a hash operation started.
  * \param output   The SHA-1 checksum result.
- *
+ *                 This must be a writable buffer of length \c 20 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
                                              unsigned char output[20] );
@@ -238,8 +255,9 @@
  *
  * \deprecated     Superseded by mbedtls_internal_sha1_process() in 2.7.0.
  *
- * \param ctx      The SHA-1 context.
+ * \param ctx      The SHA-1 context. This must be initialized.
  * \param data     The data block being processed.
+ *                 This must be a readable buffer of length \c 64 bytes.
  *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
@@ -262,10 +280,13 @@
  *                 stronger message digests instead.
  *
  * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
  * \param output   The SHA-1 checksum result.
+ *                 This must be a writable buffer of length \c 20 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  *
  */
 int mbedtls_sha1_ret( const unsigned char *input,
@@ -294,8 +315,10 @@
  * \deprecated     Superseded by mbedtls_sha1_ret() in 2.7.0
  *
  * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-1 checksum result.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ * \param output   The SHA-1 checksum result. This must be a writable
+ *                 buffer of size \c 20 Bytes.
  *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input,
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index 47a31e8..0e42f0a 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -38,6 +38,7 @@
 
 /* MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA                 -0x0074  /**< SHA-256 input data was malformed. */
 
 #ifdef __cplusplus
 extern "C" {
@@ -71,22 +72,24 @@
 /**
  * \brief          This function initializes a SHA-256 context.
  *
- * \param ctx      The SHA-256 context to initialize.
+ * \param ctx      The SHA-256 context to initialize. This must not be \c NULL.
  */
 void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
 
 /**
  * \brief          This function clears a SHA-256 context.
  *
- * \param ctx      The SHA-256 context to clear.
+ * \param ctx      The SHA-256 context to clear. This may be \c NULL, in which
+ *                 case this function returns immediately. If it is not \c NULL,
+ *                 it must point to an initialized SHA-256 context.
  */
 void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
 
 /**
  * \brief          This function clones the state of a SHA-256 context.
  *
- * \param dst      The destination context.
- * \param src      The context to clone.
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The context to clone. This must be initialized.
  */
 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
                            const mbedtls_sha256_context *src );
@@ -95,11 +98,12 @@
  * \brief          This function starts a SHA-224 or SHA-256 checksum
  *                 calculation.
  *
- * \param ctx      The context to initialize.
- * \param is224    Determines which function to use:
- *                 0: Use SHA-256, or 1: Use SHA-224.
+ * \param ctx      The context to use. This must be initialized.
+ * \param is224    This determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 );
 
@@ -107,11 +111,14 @@
  * \brief          This function feeds an input buffer into an ongoing
  *                 SHA-256 checksum calculation.
  *
- * \param ctx      The SHA-256 context.
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
+ * \param ctx      The SHA-256 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
                                const unsigned char *input,
@@ -121,10 +128,13 @@
  * \brief          This function finishes the SHA-256 operation, and writes
  *                 the result to the output buffer.
  *
- * \param ctx      The SHA-256 context.
+ * \param ctx      The SHA-256 context. This must be initialized
+ *                 and have a hash operation started.
  * \param output   The SHA-224 or SHA-256 checksum result.
+ *                 This must be a writable buffer of length \c 32 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
                                unsigned char output[32] );
@@ -134,10 +144,12 @@
  *                 the ongoing SHA-256 computation. This function is for
  *                 internal use only.
  *
- * \param ctx      The SHA-256 context.
- * \param data     The buffer holding one block of data.
+ * \param ctx      The SHA-256 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must
+ *                 be a readable buffer of length \c 64 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
                                      const unsigned char data[64] );
@@ -152,12 +164,11 @@
  * \brief          This function starts a SHA-224 or SHA-256 checksum
  *                 calculation.
  *
- *
  * \deprecated     Superseded by mbedtls_sha256_starts_ret() in 2.7.0.
  *
- * \param ctx      The context to initialize.
- * \param is224    Determines which function to use:
- *                 0: Use SHA-256, or 1: Use SHA-224.
+ * \param ctx      The context to use. This must be initialized.
+ * \param is224    Determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
                                                int is224 );
@@ -168,9 +179,11 @@
  *
  * \deprecated     Superseded by mbedtls_sha256_update_ret() in 2.7.0.
  *
- * \param ctx      The SHA-256 context to initialize.
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
+ * \param ctx      The SHA-256 context to use. This must be
+ *                 initialized and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
                                                const unsigned char *input,
@@ -182,8 +195,10 @@
  *
  * \deprecated     Superseded by mbedtls_sha256_finish_ret() in 2.7.0.
  *
- * \param ctx      The SHA-256 context.
- * \param output   The SHA-224 or SHA-256 checksum result.
+ * \param ctx      The SHA-256 context. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must be
+ *                 a writable buffer of length \c 32 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
                                                unsigned char output[32] );
@@ -195,8 +210,9 @@
  *
  * \deprecated     Superseded by mbedtls_internal_sha256_process() in 2.7.0.
  *
- * \param ctx      The SHA-256 context.
- * \param data     The buffer holding one block of data.
+ * \param ctx      The SHA-256 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must be
+ *                 a readable buffer of size \c 64 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
                                                 const unsigned char data[64] );
@@ -214,11 +230,13 @@
  *                 The SHA-256 result is calculated as
  *                 output = SHA-256(input buffer).
  *
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-224 or SHA-256 checksum result.
- * \param is224    Determines which function to use:
- *                 0: Use SHA-256, or 1: Use SHA-224.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must
+ *                 be a writable buffer of length \c 32 Bytes.
+ * \param is224    Determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
  */
 int mbedtls_sha256_ret( const unsigned char *input,
                         size_t ilen,
@@ -244,11 +262,13 @@
  *
  * \deprecated     Superseded by mbedtls_sha256_ret() in 2.7.0.
  *
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-224 or SHA-256 checksum result.
- * \param is224    Determines which function to use:
- *                 0: Use SHA-256, or 1: Use SHA-224.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must be
+ *                 a writable buffer of length \c 32 Bytes.
+ * \param is224    Determines which function to use. This must be either
+ *                 \c 0 for SHA-256, or \c 1 for SHA-224.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input,
                                         size_t ilen,
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 020f95d..7b26cf5 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -37,6 +37,7 @@
 
 /* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA                 -0x0075  /**< SHA-512 input data was malformed. */
 
 #ifdef __cplusplus
 extern "C" {
@@ -70,22 +71,26 @@
 /**
  * \brief          This function initializes a SHA-512 context.
  *
- * \param ctx      The SHA-512 context to initialize.
+ * \param ctx      The SHA-512 context to initialize. This must
+ *                 not be \c NULL.
  */
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
 
 /**
  * \brief          This function clears a SHA-512 context.
  *
- * \param ctx      The SHA-512 context to clear.
+ * \param ctx      The SHA-512 context to clear. This may be \c NULL,
+ *                 in which case this function does nothing. If it
+ *                 is not \c NULL, it must point to an initialized
+ *                 SHA-512 context.
  */
 void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
 
 /**
  * \brief          This function clones the state of a SHA-512 context.
  *
- * \param dst      The destination context.
- * \param src      The context to clone.
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The context to clone. This must be initialized.
  */
 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
                            const mbedtls_sha512_context *src );
@@ -94,11 +99,12 @@
  * \brief          This function starts a SHA-384 or SHA-512 checksum
  *                 calculation.
  *
- * \param ctx      The SHA-512 context to initialize.
- * \param is384    Determines which function to use:
- *                 0: Use SHA-512, or 1: Use SHA-384.
+ * \param ctx      The SHA-512 context to use. This must be initialized.
+ * \param is384    Determines which function to use. This must be
+ *                 either \c for SHA-512, or \c 1 for SHA-384.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 );
 
@@ -106,11 +112,14 @@
  * \brief          This function feeds an input buffer into an ongoing
  *                 SHA-512 checksum calculation.
  *
- * \param ctx      The SHA-512 context.
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
                     const unsigned char *input,
@@ -121,10 +130,13 @@
  *                 the result to the output buffer. This function is for
  *                 internal use only.
  *
- * \param ctx      The SHA-512 context.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
  * \param output   The SHA-384 or SHA-512 checksum result.
+ *                 This must be a writable buffer of length \c 64 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
                                unsigned char output[64] );
@@ -133,10 +145,12 @@
  * \brief          This function processes a single data block within
  *                 the ongoing SHA-512 computation.
  *
- * \param ctx      The SHA-512 context.
- * \param data     The buffer holding one block of data.
+ * \param ctx      The SHA-512 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This
+ *                 must be a readable buffer of length \c 128 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
                                      const unsigned char data[128] );
@@ -152,9 +166,9 @@
  *
  * \deprecated     Superseded by mbedtls_sha512_starts_ret() in 2.7.0
  *
- * \param ctx      The SHA-512 context to initialize.
- * \param is384    Determines which function to use:
- *                 0: Use SHA-512, or 1: Use SHA-384.
+ * \param ctx      The SHA-512 context to use. This must be initialized.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512 or \c 1 for SHA-384.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
                                                int is384 );
@@ -165,9 +179,11 @@
  *
  * \deprecated     Superseded by mbedtls_sha512_update_ret() in 2.7.0.
  *
- * \param ctx      The SHA-512 context.
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
                                                const unsigned char *input,
@@ -179,8 +195,10 @@
  *
  * \deprecated     Superseded by mbedtls_sha512_finish_ret() in 2.7.0.
  *
- * \param ctx      The SHA-512 context.
- * \param output   The SHA-384 or SHA-512 checksum result.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param output   The SHA-384 or SHA-512 checksum result. This must
+ *                 be a writable buffer of size \c 64 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
                                                unsigned char output[64] );
@@ -192,8 +210,9 @@
  *
  * \deprecated     Superseded by mbedtls_internal_sha512_process() in 2.7.0.
  *
- * \param ctx      The SHA-512 context.
- * \param data     The buffer holding one block of data.
+ * \param ctx      The SHA-512 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must be
+ *                 a readable buffer of length \c 128 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_process(
                                             mbedtls_sha512_context *ctx,
@@ -212,13 +231,16 @@
  *                 The SHA-512 result is calculated as
  *                 output = SHA-512(input buffer).
  *
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ * \param input    The buffer holding the input data. This must be
+ *                 a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  * \param output   The SHA-384 or SHA-512 checksum result.
- * \param is384    Determines which function to use:
- *                 0: Use SHA-512, or 1: Use SHA-384.
+ *                 This must be a writable buffer of length \c 64 Bytes.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512, or \c 1 for SHA-384.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_ret( const unsigned char *input,
                         size_t ilen,
@@ -243,11 +265,13 @@
  *
  * \deprecated     Superseded by mbedtls_sha512_ret() in 2.7.0
  *
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-384 or SHA-512 checksum result.
- * \param is384    Determines which function to use:
- *                 0: Use SHA-512, or 1: Use SHA-384.
+ * \param input    The buffer holding the data. This must be a
+ *                 readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-384 or SHA-512 checksum result. This must
+ *                 be a writable buffer of length \c 64 Bytes.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512, or \c 1 for SHA-384.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input,
                                         size_t ilen,
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 55b206f..8106bb4 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -2044,6 +2044,14 @@
  *                 whether it matches those preferences - the server can then
  *                 decide what it wants to do with it.
  *
+ * \note           The provided \p pk_key needs to match the public key in the
+ *                 first certificate in \p own_cert, or all handshakes using
+ *                 that certificate will fail. It is your responsibility
+ *                 to ensure that; this function will not perform any check.
+ *                 You may use mbedtls_pk_check_pair() in order to perform
+ *                 this check yourself, but be aware that this function can
+ *                 be computationally expensive on some key types.
+ *
  * \param conf     SSL configuration
  * \param own_cert own public certificate chain
  * \param pk_key   own private key
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 492fde3..56e7398 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -39,7 +39,7 @@
  * Major, Minor, Patchlevel
  */
 #define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  14
+#define MBEDTLS_VERSION_MINOR  16
 #define MBEDTLS_VERSION_PATCH  0
 
 /**
@@ -47,9 +47,9 @@
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x020E0000
-#define MBEDTLS_VERSION_STRING         "2.14.0"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.14.0"
+#define MBEDTLS_VERSION_NUMBER         0x02100000
+#define MBEDTLS_VERSION_STRING         "2.16.0"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.0"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index afeefca..3dd5922 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -232,19 +232,34 @@
                         size_t buflen );
 
 /**
- * \brief          Parse one or more certificates and add them
- *                 to the chained list. Parses permissively. If some
- *                 certificates can be parsed, the result is the number
- *                 of failed certificates it encountered. If none complete
- *                 correctly, the first error is returned.
+ * \brief          Parse one DER-encoded or one or more concatenated PEM-encoded
+ *                 certificates and add them to the chained list.
  *
- * \param chain    points to the start of the chain
- * \param buf      buffer holding the certificate data in PEM or DER format
- * \param buflen   size of the buffer
- *                 (including the terminating null byte for PEM data)
+ *                 For CRTs in PEM encoding, the function parses permissively:
+ *                 if at least one certificate can be parsed, the function
+ *                 returns the number of certificates for which parsing failed
+ *                 (hence \c 0 if all certificates were parsed successfully).
+ *                 If no certificate could be parsed, the function returns
+ *                 the first (negative) error encountered during parsing.
  *
- * \return         0 if all certificates parsed successfully, a positive number
- *                 if partly successful or a specific X509 or PEM error code
+ *                 PEM encoded certificates may be interleaved by other data
+ *                 such as human readable descriptions of their content, as
+ *                 long as the certificates are enclosed in the PEM specific
+ *                 '-----{BEGIN/END} CERTIFICATE-----' delimiters.
+ *
+ * \param chain    The chain to which to add the parsed certificates.
+ * \param buf      The buffer holding the certificate data in PEM or DER format.
+ *                 For certificates in PEM encoding, this may be a concatenation
+ *                 of multiple certificates; for DER encoding, the buffer must
+ *                 comprise exactly one certificate.
+ * \param buflen   The size of \p buf, including the terminating \c NULL byte
+ *                 in case of PEM encoded data.
+ *
+ * \return         \c 0 if all certificates were parsed successfully.
+ * \return         The (positive) number of certificates that couldn't
+ *                 be parsed if parsing was partly successful (see above).
+ * \return         A negative X509 or PEM error code otherwise.
+ *
  */
 int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen );
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index ea51363..c33c1cd 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -159,15 +159,15 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.14.0 SOVERSION 3)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.0 SOVERSION 3)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.14.0 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.0 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.14.0 SOVERSION 12)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.16.0 SOVERSION 12)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/aes.c b/library/aes.c
index 3de571e..0543cd7 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -56,6 +56,12 @@
 
 #if !defined(MBEDTLS_AES_ALT)
 
+/* Parameter validation macros based on platform_util.h */
+#define AES_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
+#define AES_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * 32-bit integer manipulation macros (little endian)
  */
@@ -511,6 +517,8 @@
 
 void mbedtls_aes_init( mbedtls_aes_context *ctx )
 {
+    AES_VALIDATE( ctx != NULL );
+
     memset( ctx, 0, sizeof( mbedtls_aes_context ) );
 }
 
@@ -525,12 +533,17 @@
 #if defined(MBEDTLS_CIPHER_MODE_XTS)
 void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
 {
+    AES_VALIDATE( ctx != NULL );
+
     mbedtls_aes_init( &ctx->crypt );
     mbedtls_aes_init( &ctx->tweak );
 }
 
 void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
 {
+    if( ctx == NULL )
+        return;
+
     mbedtls_aes_free( &ctx->crypt );
     mbedtls_aes_free( &ctx->tweak );
 }
@@ -546,14 +559,8 @@
     unsigned int i;
     uint32_t *RK;
 
-#if !defined(MBEDTLS_AES_ROM_TABLES)
-    if( aes_init_done == 0 )
-    {
-        aes_gen_tables();
-        aes_init_done = 1;
-
-    }
-#endif
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
 
     switch( keybits )
     {
@@ -563,6 +570,14 @@
         default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
     }
 
+#if !defined(MBEDTLS_AES_ROM_TABLES)
+    if( aes_init_done == 0 )
+    {
+        aes_gen_tables();
+        aes_init_done = 1;
+    }
+#endif
+
 #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
     if( aes_padlock_ace == -1 )
         aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
@@ -662,6 +677,9 @@
     uint32_t *RK;
     uint32_t *SK;
 
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
+
     mbedtls_aes_init( &cty );
 
 #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
@@ -752,6 +770,9 @@
     const unsigned char *key1, *key2;
     unsigned int key1bits, key2bits;
 
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
+
     ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
                                        &key2, &key2bits );
     if( ret != 0 )
@@ -774,6 +795,9 @@
     const unsigned char *key1, *key2;
     unsigned int key1bits, key2bits;
 
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
+
     ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
                                        &key2, &key2bits );
     if( ret != 0 )
@@ -977,10 +1001,16 @@
  * AES-ECB block encryption/decryption
  */
 int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
-                    int mode,
-                    const unsigned char input[16],
-                    unsigned char output[16] )
+                           int mode,
+                           const unsigned char input[16],
+                           unsigned char output[16] )
 {
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+
 #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
     if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
         return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
@@ -1018,6 +1048,13 @@
     int i;
     unsigned char temp[16];
 
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
     if( length % 16 )
         return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
 
@@ -1143,6 +1180,13 @@
     unsigned char prev_tweak[16];
     unsigned char tmp[16];
 
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( data_unit != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
     /* Data units must be at least 16 bytes long. */
     if( length < 16 )
         return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
@@ -1242,7 +1286,20 @@
                        unsigned char *output )
 {
     int c;
-    size_t n = *iv_off;
+    size_t n;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( iv_off != NULL );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    n = *iv_off;
+
+    if( n > 15 )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
 
     if( mode == MBEDTLS_AES_DECRYPT )
     {
@@ -1280,15 +1337,21 @@
  * AES-CFB8 buffer encryption/decryption
  */
 int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
-                       int mode,
-                       size_t length,
-                       unsigned char iv[16],
-                       const unsigned char *input,
-                       unsigned char *output )
+                            int mode,
+                            size_t length,
+                            unsigned char iv[16],
+                            const unsigned char *input,
+                            unsigned char *output )
 {
     unsigned char c;
     unsigned char ov[17];
 
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
     while( length-- )
     {
         memcpy( ov, iv, 16 );
@@ -1321,7 +1384,18 @@
                            unsigned char *output )
 {
     int ret = 0;
-    size_t n = *iv_off;
+    size_t n;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( iv_off != NULL );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    n = *iv_off;
+
+    if( n > 15 )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
 
     while( length-- )
     {
@@ -1356,7 +1430,16 @@
                        unsigned char *output )
 {
     int c, i;
-    size_t n = *nc_off;
+    size_t n;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( nc_off != NULL );
+    AES_VALIDATE_RET( nonce_counter != NULL );
+    AES_VALIDATE_RET( stream_block != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    n = *nc_off;
 
     if ( n > 0x0F )
         return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
diff --git a/library/aria.c b/library/aria.c
index ca9e147..aff66d6 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -55,6 +55,12 @@
 #define inline __inline
 #endif
 
+/* Parameter validation macros */
+#define ARIA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA )
+#define ARIA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * 32-bit integer manipulation macros (little endian)
  */
@@ -449,9 +455,11 @@
 
     int i;
     uint32_t w[4][4], *w2;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( key != NULL );
 
     if( keybits != 128 && keybits != 192 && keybits != 256 )
-        return( MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH );
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
 
     /* Copy key to W0 (and potential remainder to W1) */
     GET_UINT32_LE( w[0][0], key,  0 );
@@ -503,6 +511,8 @@
                              const unsigned char *key, unsigned int keybits )
 {
     int i, j, k, ret;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( key != NULL );
 
     ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
     if( ret != 0 )
@@ -539,6 +549,9 @@
     int i;
 
     uint32_t a, b, c, d;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( input != NULL );
+    ARIA_VALIDATE_RET( output != NULL );
 
     GET_UINT32_LE( a, input,  0 );
     GET_UINT32_LE( b, input,  4 );
@@ -586,6 +599,7 @@
 /* Initialize context */
 void mbedtls_aria_init( mbedtls_aria_context *ctx )
 {
+    ARIA_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_aria_context ) );
 }
 
@@ -612,6 +626,13 @@
     int i;
     unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
 
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+                       mode == MBEDTLS_ARIA_DECRYPT );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( iv != NULL );
+
     if( length % MBEDTLS_ARIA_BLOCKSIZE )
         return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
 
@@ -665,7 +686,23 @@
                                unsigned char *output )
 {
     unsigned char c;
-    size_t n = *iv_off;
+    size_t n;
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+                       mode == MBEDTLS_ARIA_DECRYPT );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( iv != NULL );
+    ARIA_VALIDATE_RET( iv_off != NULL );
+
+    n = *iv_off;
+
+    /* An overly large value of n can lead to an unlimited
+     * buffer overflow. Therefore, guard against this
+     * outside of parameter validation. */
+    if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
 
     if( mode == MBEDTLS_ARIA_DECRYPT )
     {
@@ -713,7 +750,21 @@
                             unsigned char *output )
 {
     int c, i;
-    size_t n = *nc_off;
+    size_t n;
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( nonce_counter != NULL );
+    ARIA_VALIDATE_RET( stream_block  != NULL );
+    ARIA_VALIDATE_RET( nc_off != NULL );
+
+    n = *nc_off;
+    /* An overly large value of n can lead to an unlimited
+     * buffer overflow. Therefore, guard against this
+     * outside of parameter validation. */
+    if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
 
     while( length-- )
     {
diff --git a/library/asn1write.c b/library/asn1write.c
index d617de5..a4d23f6 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -331,14 +331,36 @@
     return( (int) len );
 }
 
-mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head,
+
+/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(),
+ * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */
+static mbedtls_asn1_named_data *asn1_find_named_data(
+                                               mbedtls_asn1_named_data *list,
+                                               const char *oid, size_t len )
+{
+    while( list != NULL )
+    {
+        if( list->oid.len == len &&
+            memcmp( list->oid.p, oid, len ) == 0 )
+        {
+            break;
+        }
+
+        list = list->next;
+    }
+
+    return( list );
+}
+
+mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
+                                        mbedtls_asn1_named_data **head,
                                         const char *oid, size_t oid_len,
                                         const unsigned char *val,
                                         size_t val_len )
 {
     mbedtls_asn1_named_data *cur;
 
-    if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
+    if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
     {
         // Add new entry if not present yet based on OID
         //
diff --git a/library/bignum.c b/library/bignum.c
index ae5e7cf..f968a0a 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -59,6 +59,11 @@
 #define mbedtls_free       free
 #endif
 
+#define MPI_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+#define MPI_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #define ciL    (sizeof(mbedtls_mpi_uint))         /* chars in limb  */
 #define biL    (ciL << 3)               /* bits  in limb  */
 #define biH    (ciL << 2)               /* half limb size */
@@ -83,8 +88,7 @@
  */
 void mbedtls_mpi_init( mbedtls_mpi *X )
 {
-    if( X == NULL )
-        return;
+    MPI_VALIDATE( X != NULL );
 
     X->s = 1;
     X->n = 0;
@@ -116,6 +120,7 @@
 int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
 {
     mbedtls_mpi_uint *p;
+    MPI_VALIDATE_RET( X != NULL );
 
     if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
         return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
@@ -147,6 +152,10 @@
 {
     mbedtls_mpi_uint *p;
     size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
+        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
 
     /* Actually resize up in this case */
     if( X->n <= nblimbs )
@@ -183,6 +192,8 @@
 {
     int ret = 0;
     size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     if( X == Y )
         return( 0 );
@@ -222,6 +233,8 @@
 void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
 {
     mbedtls_mpi T;
+    MPI_VALIDATE( X != NULL );
+    MPI_VALIDATE( Y != NULL );
 
     memcpy( &T,  X, sizeof( mbedtls_mpi ) );
     memcpy(  X,  Y, sizeof( mbedtls_mpi ) );
@@ -237,6 +250,8 @@
 {
     int ret = 0;
     size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     /* make sure assign is 0 or 1 in a time-constant manner */
     assign = (assign | (unsigned char)-assign) >> 7;
@@ -266,6 +281,8 @@
     int ret, s;
     size_t i;
     mbedtls_mpi_uint tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     if( X == Y )
         return( 0 );
@@ -298,6 +315,7 @@
 int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
 {
     int ret;
+    MPI_VALIDATE_RET( X != NULL );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
     memset( X->p, 0, X->n * ciL );
@@ -315,12 +333,18 @@
  */
 int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
 {
+    MPI_VALIDATE_RET( X != NULL );
+
     if( X->n * biL <= pos )
         return( 0 );
 
     return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
 }
 
+/* Get a specific byte, without range checks. */
+#define GET_BYTE( X, i )                                \
+    ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
+
 /*
  * Set a bit to a specific value of 0 or 1
  */
@@ -329,6 +353,7 @@
     int ret = 0;
     size_t off = pos / biL;
     size_t idx = pos % biL;
+    MPI_VALIDATE_RET( X != NULL );
 
     if( val != 0 && val != 1 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -355,6 +380,7 @@
 size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
 {
     size_t i, j, count = 0;
+    MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
 
     for( i = 0; i < X->n; i++ )
         for( j = 0; j < biL; j++, count++ )
@@ -435,6 +461,8 @@
     size_t i, j, slen, n;
     mbedtls_mpi_uint d;
     mbedtls_mpi T;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( s != NULL );
 
     if( radix < 2 || radix > 16 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -535,6 +563,9 @@
     size_t n;
     char *p;
     mbedtls_mpi T;
+    MPI_VALIDATE_RET( X    != NULL );
+    MPI_VALIDATE_RET( olen != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
 
     if( radix < 2 || radix > 16 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -616,6 +647,12 @@
      */
     char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
 
+    MPI_VALIDATE_RET( X   != NULL );
+    MPI_VALIDATE_RET( fin != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
     memset( s, 0, sizeof( s ) );
     if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
         return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
@@ -647,6 +684,10 @@
      * newline characters and '\0'
      */
     char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
     memset( s, 0, sizeof( s ) );
 
@@ -683,6 +724,9 @@
     size_t i, j;
     size_t const limbs = CHARS_TO_LIMBS( buflen );
 
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
+
     /* Ensure that target MPI has exactly the necessary number of limbs */
     if( X->n != limbs )
     {
@@ -704,19 +748,45 @@
 /*
  * Export X into unsigned binary data, big endian
  */
-int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen )
+int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
+                              unsigned char *buf, size_t buflen )
 {
-    size_t i, j, n;
+    size_t stored_bytes;
+    size_t bytes_to_copy;
+    unsigned char *p;
+    size_t i;
 
-    n = mbedtls_mpi_size( X );
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
 
-    if( buflen < n )
-        return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+    stored_bytes = X->n * ciL;
 
-    memset( buf, 0, buflen );
+    if( stored_bytes < buflen )
+    {
+        /* There is enough space in the output buffer. Write initial
+         * null bytes and record the position at which to start
+         * writing the significant bytes. In this case, the execution
+         * trace of this function does not depend on the value of the
+         * number. */
+        bytes_to_copy = stored_bytes;
+        p = buf + buflen - stored_bytes;
+        memset( buf, 0, buflen - stored_bytes );
+    }
+    else
+    {
+        /* The output buffer is smaller than the allocated size of X.
+         * However X may fit if its leading bytes are zero. */
+        bytes_to_copy = buflen;
+        p = buf;
+        for( i = bytes_to_copy; i < stored_bytes; i++ )
+        {
+            if( GET_BYTE( X, i ) != 0 )
+                return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+        }
+    }
 
-    for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
-        buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
+    for( i = 0; i < bytes_to_copy; i++ )
+        p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
 
     return( 0 );
 }
@@ -729,6 +799,7 @@
     int ret;
     size_t i, v0, t1;
     mbedtls_mpi_uint r0 = 0, r1;
+    MPI_VALIDATE_RET( X != NULL );
 
     v0 = count / (biL    );
     t1 = count & (biL - 1);
@@ -778,6 +849,7 @@
 {
     size_t i, v0, v1;
     mbedtls_mpi_uint r0 = 0, r1;
+    MPI_VALIDATE_RET( X != NULL );
 
     v0 = count /  biL;
     v1 = count & (biL - 1);
@@ -820,6 +892,8 @@
 int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
     size_t i, j;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     for( i = X->n; i > 0; i-- )
         if( X->p[i - 1] != 0 )
@@ -850,6 +924,8 @@
 int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
     size_t i, j;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     for( i = X->n; i > 0; i-- )
         if( X->p[i - 1] != 0 )
@@ -884,6 +960,7 @@
 {
     mbedtls_mpi Y;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
 
     *p  = ( z < 0 ) ? -z : z;
     Y.s = ( z < 0 ) ? -1 : 1;
@@ -901,6 +978,9 @@
     int ret;
     size_t i, j;
     mbedtls_mpi_uint *o, *p, c, tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( X == B )
     {
@@ -978,6 +1058,9 @@
     mbedtls_mpi TB;
     int ret;
     size_t n;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
         return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
@@ -1018,8 +1101,12 @@
  */
 int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
 {
-    int ret, s = A->s;
+    int ret, s;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
+    s = A->s;
     if( A->s * B->s < 0 )
     {
         if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
@@ -1049,8 +1136,12 @@
  */
 int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
 {
-    int ret, s = A->s;
+    int ret, s;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
+    s = A->s;
     if( A->s * B->s > 0 )
     {
         if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
@@ -1082,6 +1173,8 @@
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
     _B.s = ( b < 0 ) ? -1 : 1;
@@ -1098,6 +1191,8 @@
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
     _B.s = ( b < 0 ) ? -1 : 1;
@@ -1187,6 +1282,9 @@
     int ret;
     size_t i, j;
     mbedtls_mpi TA, TB;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
 
@@ -1223,6 +1321,8 @@
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     _B.s = 1;
     _B.n = 1;
@@ -1331,11 +1431,14 @@
 /*
  * Division by mbedtls_mpi: A = Q * B + R  (HAC 14.20)
  */
-int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
+int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B )
 {
     int ret;
     size_t i, n, t, k;
     mbedtls_mpi X, Y, Z, T1, T2;
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
         return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
@@ -1446,10 +1549,13 @@
 /*
  * Division by int: A = Q * b + R
  */
-int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b )
+int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
+                         const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b )
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
     _B.s = ( b < 0 ) ? -1 : 1;
@@ -1465,6 +1571,9 @@
 int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
 {
     int ret;
+    MPI_VALIDATE_RET( R != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
         return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
@@ -1489,6 +1598,8 @@
 {
     size_t i;
     mbedtls_mpi_uint x, y, z;
+    MPI_VALIDATE_RET( r != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     if( b == 0 )
         return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
@@ -1602,7 +1713,8 @@
 /*
  * Montgomery reduction: A = A * R^-1 mod N
  */
-static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
+static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
+                        mbedtls_mpi_uint mm, const mbedtls_mpi *T )
 {
     mbedtls_mpi_uint z = 1;
     mbedtls_mpi U;
@@ -1616,7 +1728,9 @@
 /*
  * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
  */
-int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR )
+int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *E, const mbedtls_mpi *N,
+                         mbedtls_mpi *_RR )
 {
     int ret;
     size_t wbits, wsize, one = 1;
@@ -1626,6 +1740,11 @@
     mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
     int neg;
 
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( E != NULL );
+    MPI_VALIDATE_RET( N != NULL );
+
     if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
@@ -1830,6 +1949,10 @@
     size_t lz, lzt;
     mbedtls_mpi TG, TA, TB;
 
+    MPI_VALIDATE_RET( G != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
     mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
@@ -1886,6 +2009,8 @@
 {
     int ret;
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
 
     if( size > MBEDTLS_MPI_MAX_SIZE )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -1905,6 +2030,9 @@
 {
     int ret;
     mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( N != NULL );
 
     if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -2064,7 +2192,11 @@
     size_t i, j, k, s;
     mbedtls_mpi W, R, T, A, RR;
 
-    mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R );
+    mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
     mbedtls_mpi_init( &RR );
 
     /*
@@ -2136,7 +2268,8 @@
     }
 
 cleanup:
-    mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
+    mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
     mbedtls_mpi_free( &RR );
 
     return( ret );
@@ -2151,6 +2284,8 @@
 {
     int ret;
     mbedtls_mpi XX;
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
 
     XX.s = 1;
     XX.n = X->n;
@@ -2182,12 +2317,15 @@
                   int (*f_rng)(void *, unsigned char *, size_t),
                   void *p_rng )
 {
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
     /*
      * In the past our key generation aimed for an error rate of at most
      * 2^-80. Since this function is deprecated, aim for the same certainty
      * here as well.
      */
-    return mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng );
+    return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
 }
 #endif
 
@@ -2215,6 +2353,9 @@
     mbedtls_mpi_uint r;
     mbedtls_mpi Y;
 
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
     if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
diff --git a/library/blowfish.c b/library/blowfish.c
index 5b6bb98..cbf9238 100644
--- a/library/blowfish.c
+++ b/library/blowfish.c
@@ -40,6 +40,12 @@
 
 #if !defined(MBEDTLS_BLOWFISH_ALT)
 
+/* Parameter validation macros */
+#define BLOWFISH_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA )
+#define BLOWFISH_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -153,6 +159,7 @@
 
 void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
 {
+    BLOWFISH_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
 }
 
@@ -167,16 +174,20 @@
 /*
  * Blowfish key schedule
  */
-int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
-                     unsigned int keybits )
+int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx,
+                             const unsigned char *key,
+                             unsigned int keybits )
 {
     unsigned int i, j, k;
     uint32_t data, datal, datar;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( key != NULL );
 
-    if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
-        ( keybits % 8 ) )
+    if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS    ||
+        keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS    ||
+        keybits % 8 != 0 )
     {
-        return( MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH );
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
     }
 
     keybits >>= 3;
@@ -231,6 +242,11 @@
                     unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
 {
     uint32_t X0, X1;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( input  != NULL );
+    BLOWFISH_VALIDATE_RET( output != NULL );
 
     GET_UINT32_BE( X0, input,  0 );
     GET_UINT32_BE( X1, input,  4 );
@@ -263,6 +279,12 @@
 {
     int i;
     unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( iv != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
 
     if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
         return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
@@ -317,7 +339,19 @@
                        unsigned char *output )
 {
     int c;
-    size_t n = *iv_off;
+    size_t n;
+
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( iv     != NULL );
+    BLOWFISH_VALIDATE_RET( iv_off != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *iv_off;
+    if( n >= 8 )
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
 
     if( mode == MBEDTLS_BLOWFISH_DECRYPT )
     {
@@ -365,7 +399,17 @@
                        unsigned char *output )
 {
     int c, i;
-    size_t n = *nc_off;
+    size_t n;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( nonce_counter != NULL );
+    BLOWFISH_VALIDATE_RET( stream_block  != NULL );
+    BLOWFISH_VALIDATE_RET( nc_off != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *nc_off;
+    if( n >= 8 )
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
 
     while( length-- )
     {
diff --git a/library/camellia.c b/library/camellia.c
index 41b7da0..22262b8 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -49,6 +49,12 @@
 
 #if !defined(MBEDTLS_CAMELLIA_ALT)
 
+/* Parameter validation macros */
+#define CAMELLIA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA )
+#define CAMELLIA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -321,6 +327,7 @@
 
 void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
 {
+    CAMELLIA_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
 }
 
@@ -335,8 +342,9 @@
 /*
  * Camellia key schedule (encryption)
  */
-int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits )
+int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits )
 {
     int idx;
     size_t i;
@@ -346,6 +354,9 @@
     uint32_t KC[16];
     uint32_t TK[20];
 
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( key != NULL );
+
     RK = ctx->rk;
 
     memset( t, 0, 64 );
@@ -356,7 +367,7 @@
         case 128: ctx->nr = 3; idx = 0; break;
         case 192:
         case 256: ctx->nr = 4; idx = 1; break;
-        default : return( MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH );
+        default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
     }
 
     for( i = 0; i < keybits / 8; ++i )
@@ -440,14 +451,17 @@
 /*
  * Camellia key schedule (decryption)
  */
-int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits )
+int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits )
 {
     int idx, ret;
     size_t i;
     mbedtls_camellia_context cty;
     uint32_t *RK;
     uint32_t *SK;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( key != NULL );
 
     mbedtls_camellia_init( &cty );
 
@@ -495,6 +509,11 @@
 {
     int NR;
     uint32_t *RK, X[4];
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( input  != NULL );
+    CAMELLIA_VALIDATE_RET( output != NULL );
 
     ( (void) mode );
 
@@ -552,14 +571,20 @@
  * Camellia-CBC buffer encryption/decryption
  */
 int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
-                    int mode,
-                    size_t length,
-                    unsigned char iv[16],
-                    const unsigned char *input,
-                    unsigned char *output )
+                                int mode,
+                                size_t length,
+                                unsigned char iv[16],
+                                const unsigned char *input,
+                                unsigned char *output )
 {
     int i;
     unsigned char temp[16];
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( iv != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
 
     if( length % 16 )
         return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
@@ -614,7 +639,18 @@
                        unsigned char *output )
 {
     int c;
-    size_t n = *iv_off;
+    size_t n;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( iv     != NULL );
+    CAMELLIA_VALIDATE_RET( iv_off != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *iv_off;
+    if( n >= 16 )
+        return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
 
     if( mode == MBEDTLS_CAMELLIA_DECRYPT )
     {
@@ -662,7 +698,17 @@
                        unsigned char *output )
 {
     int c, i;
-    size_t n = *nc_off;
+    size_t n;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( nonce_counter != NULL );
+    CAMELLIA_VALIDATE_RET( stream_block  != NULL );
+    CAMELLIA_VALIDATE_RET( nc_off != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *nc_off;
+    if( n >= 16 )
+        return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
 
     while( length-- )
     {
diff --git a/library/ccm.c b/library/ccm.c
index 90cab8e..01e58b0 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -52,6 +52,11 @@
 
 #if !defined(MBEDTLS_CCM_ALT)
 
+#define CCM_VALIDATE_RET( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
+#define CCM_VALIDATE( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #define CCM_ENCRYPT 0
 #define CCM_DECRYPT 1
 
@@ -60,6 +65,7 @@
  */
 void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
 {
+    CCM_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
 }
 
@@ -71,6 +77,9 @@
     int ret;
     const mbedtls_cipher_info_t *cipher_info;
 
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( key != NULL );
+
     cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
     if( cipher_info == NULL )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -97,6 +106,8 @@
  */
 void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
 {
+    if( ctx == NULL )
+        return;
     mbedtls_cipher_free( &ctx->cipher_ctx );
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
 }
@@ -310,6 +321,12 @@
                          const unsigned char *input, unsigned char *output,
                          unsigned char *tag, size_t tag_len )
 {
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
     return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
                             add, add_len, input, output, tag, tag_len ) );
 }
@@ -320,6 +337,12 @@
                          const unsigned char *input, unsigned char *output,
                          unsigned char *tag, size_t tag_len )
 {
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
     if( tag_len == 0 )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
 
@@ -341,6 +364,13 @@
     unsigned char i;
     int diff;
 
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
     if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
                                 iv, iv_len, add, add_len,
                                 input, output, check_tag, tag_len ) ) != 0 )
@@ -367,6 +397,13 @@
                       const unsigned char *input, unsigned char *output,
                       const unsigned char *tag, size_t tag_len )
 {
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
     if( tag_len == 0 )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
 
diff --git a/library/chacha20.c b/library/chacha20.c
index d14a51e..0757163 100644
--- a/library/chacha20.c
+++ b/library/chacha20.c
@@ -53,6 +53,12 @@
 #define inline __inline
 #endif
 
+/* Parameter validation macros */
+#define CHACHA20_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
+#define CHACHA20_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #define BYTES_TO_U32_LE( data, offset )                           \
     ( (uint32_t) data[offset]                                     \
           | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 )   \
@@ -181,14 +187,13 @@
 
 void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
 {
-    if( ctx != NULL )
-    {
-        mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
-        mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+    CHACHA20_VALIDATE( ctx != NULL );
 
-        /* Initially, there's no keystream bytes available */
-        ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
-    }
+    mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
+    mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+
+    /* Initially, there's no keystream bytes available */
+    ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
 }
 
 void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
@@ -202,10 +207,8 @@
 int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
                             const unsigned char key[32] )
 {
-    if( ( ctx == NULL ) || ( key == NULL ) )
-    {
-        return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    }
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( key != NULL );
 
     /* ChaCha20 constants - the string "expand 32-byte k" */
     ctx->state[0] = 0x61707865;
@@ -230,10 +233,8 @@
                              const unsigned char nonce[12],
                              uint32_t counter )
 {
-    if( ( ctx == NULL ) || ( nonce == NULL ) )
-    {
-        return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    }
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( nonce != NULL );
 
     /* Counter */
     ctx->state[12] = counter;
@@ -259,15 +260,9 @@
     size_t offset = 0U;
     size_t i;
 
-    if( ctx == NULL )
-    {
-        return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    }
-    else if( ( size > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) )
-    {
-        /* input and output pointers are allowed to be NULL only if size == 0 */
-        return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    }
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( size == 0 || input  != NULL );
+    CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
 
     /* Use leftover keystream bytes, if available */
     while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
@@ -332,6 +327,11 @@
     mbedtls_chacha20_context ctx;
     int ret;
 
+    CHACHA20_VALIDATE_RET( key != NULL );
+    CHACHA20_VALIDATE_RET( nonce != NULL );
+    CHACHA20_VALIDATE_RET( data_len == 0 || input  != NULL );
+    CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
+
     mbedtls_chacha20_init( &ctx );
 
     ret = mbedtls_chacha20_setkey( &ctx, key );
diff --git a/library/chachapoly.c b/library/chachapoly.c
index 860f877..dc643dd 100644
--- a/library/chachapoly.c
+++ b/library/chachapoly.c
@@ -44,6 +44,12 @@
 
 #if !defined(MBEDTLS_CHACHAPOLY_ALT)
 
+/* Parameter validation macros */
+#define CHACHAPOLY_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
+#define CHACHAPOLY_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #define CHACHAPOLY_STATE_INIT       ( 0 )
 #define CHACHAPOLY_STATE_AAD        ( 1 )
 #define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
@@ -90,39 +96,35 @@
 
 void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
 {
-    if( ctx != NULL )
-    {
-        mbedtls_chacha20_init( &ctx->chacha20_ctx );
-        mbedtls_poly1305_init( &ctx->poly1305_ctx );
-        ctx->aad_len        = 0U;
-        ctx->ciphertext_len = 0U;
-        ctx->state          = CHACHAPOLY_STATE_INIT;
-        ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
-    }
+    CHACHAPOLY_VALIDATE( ctx != NULL );
+
+    mbedtls_chacha20_init( &ctx->chacha20_ctx );
+    mbedtls_poly1305_init( &ctx->poly1305_ctx );
+    ctx->aad_len        = 0U;
+    ctx->ciphertext_len = 0U;
+    ctx->state          = CHACHAPOLY_STATE_INIT;
+    ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
 }
 
 void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
 {
-    if( ctx != NULL )
-    {
-        mbedtls_chacha20_free( &ctx->chacha20_ctx );
-        mbedtls_poly1305_free( &ctx->poly1305_ctx );
-        ctx->aad_len        = 0U;
-        ctx->ciphertext_len = 0U;
-        ctx->state          = CHACHAPOLY_STATE_INIT;
-        ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
-    }
+    if( ctx == NULL )
+        return;
+
+    mbedtls_chacha20_free( &ctx->chacha20_ctx );
+    mbedtls_poly1305_free( &ctx->poly1305_ctx );
+    ctx->aad_len        = 0U;
+    ctx->ciphertext_len = 0U;
+    ctx->state          = CHACHAPOLY_STATE_INIT;
+    ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
 }
 
 int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
                                const unsigned char key[32] )
 {
     int ret;
-
-    if( ( ctx == NULL ) || ( key == NULL ) )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( key != NULL );
 
     ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
 
@@ -135,11 +137,8 @@
 {
     int ret;
     unsigned char poly1305_key[64];
-
-    if( ( ctx == NULL ) || ( nonce == NULL ) )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
 
     /* Set counter = 0, will be update to 1 when generating Poly1305 key */
     ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
@@ -176,19 +175,11 @@
                                    const unsigned char *aad,
                                    size_t aad_len )
 {
-    if( ctx == NULL )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
-    else if( ( aad_len > 0U ) && ( aad == NULL ) )
-    {
-        /* aad pointer is allowed to be NULL if aad_len == 0 */
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
-    else if( ctx->state != CHACHAPOLY_STATE_AAD )
-    {
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
+
+    if( ctx->state != CHACHAPOLY_STATE_AAD )
         return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
-    }
 
     ctx->aad_len += aad_len;
 
@@ -201,18 +192,12 @@
                                unsigned char *output )
 {
     int ret;
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
+    CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
 
-    if( ctx == NULL )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
-    else if( ( len > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) )
-    {
-        /* input and output pointers are allowed to be NULL if len == 0 */
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
-    else if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
-              ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
+    if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
+        ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
     {
         return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
     }
@@ -257,12 +242,10 @@
 {
     int ret;
     unsigned char len_block[16];
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( mac != NULL );
 
-    if( ( ctx == NULL ) || ( mac == NULL ) )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
-    else if( ctx->state == CHACHAPOLY_STATE_INIT )
+    if( ctx->state == CHACHAPOLY_STATE_INIT )
     {
         return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
     }
@@ -350,6 +333,13 @@
                                         unsigned char *output,
                                         unsigned char tag[16] )
 {
+    CHACHAPOLY_VALIDATE_RET( ctx   != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+    CHACHAPOLY_VALIDATE_RET( tag   != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );
+
     return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
                                       length, nonce, aad, aad_len,
                                       input, output, tag ) );
@@ -368,9 +358,12 @@
     unsigned char check_tag[16];
     size_t i;
     int diff;
-
-    if( tag == NULL )
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+    CHACHAPOLY_VALIDATE_RET( ctx   != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+    CHACHAPOLY_VALIDATE_RET( tag   != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );
 
     if( ( ret = chachapoly_crypt_and_tag( ctx,
                         MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
diff --git a/library/cipher.c b/library/cipher.c
index d7acf34..2739975 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -65,6 +65,11 @@
 #define mbedtls_free   free
 #endif
 
+#define CIPHER_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
+#define CIPHER_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 /* Compare the contents of two buffers in constant time.
  * Returns 0 if the contents are bitwise identical, otherwise returns
@@ -81,7 +86,7 @@
     for( diff = 0, i = 0; i < len; i++ )
         diff |= p1[i] ^ p2[i];
 
-    return (int)diff;
+    return( (int)diff );
 }
 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
 
@@ -150,6 +155,7 @@
 
 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
 {
+    CIPHER_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
 }
 
@@ -175,7 +181,8 @@
 
 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
 {
-    if( NULL == cipher_info || NULL == ctx )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    if( cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
@@ -199,10 +206,16 @@
     return( 0 );
 }
 
-int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
-        int key_bitlen, const mbedtls_operation_t operation )
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *key,
+                           int key_bitlen,
+                           const mbedtls_operation_t operation )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( key != NULL );
+    CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
+                         operation == MBEDTLS_DECRYPT );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
@@ -222,28 +235,27 @@
         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
         MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
     {
-        return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
-                ctx->key_bitlen );
+        return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
+                                                         ctx->key_bitlen ) );
     }
 
     if( MBEDTLS_DECRYPT == operation )
-        return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
-                ctx->key_bitlen );
+        return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
+                                                         ctx->key_bitlen ) );
 
     return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 }
 
 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
-                   const unsigned char *iv, size_t iv_len )
+                           const unsigned char *iv,
+                           size_t iv_len )
 {
     size_t actual_iv_size;
-    if( NULL == ctx || NULL == ctx->cipher_info )
-        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    else if( NULL == iv && iv_len != 0  )
-        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-    if( NULL == iv && iv_len == 0 )
-        ctx->iv_size = 0;
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     /* avoid buffer overflow in ctx->iv */
     if( iv_len > MBEDTLS_MAX_IV_LENGTH )
@@ -283,7 +295,8 @@
 
 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     ctx->unprocessed_len = 0;
@@ -295,14 +308,16 @@
 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
                       const unsigned char *ad, size_t ad_len )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
-        return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
-                           ctx->iv, ctx->iv_size, ad, ad_len );
+        return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
+                                    ctx->iv, ctx->iv_size, ad, ad_len ) );
     }
 #endif
 
@@ -322,8 +337,8 @@
         if ( result != 0 )
             return( result );
 
-        return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
-                                                          ad, ad_len );
+        return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                               ad, ad_len ) );
     }
 #endif
 
@@ -335,12 +350,14 @@
                    size_t ilen, unsigned char *output, size_t *olen )
 {
     int ret;
-    size_t block_size = 0;
+    size_t block_size;
 
-    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
-    {
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    }
 
     *olen = 0;
     block_size = mbedtls_cipher_get_block_size( ctx );
@@ -365,8 +382,8 @@
     if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
     {
         *olen = ilen;
-        return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
-                           output );
+        return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
+                                    output ) );
     }
 #endif
 
@@ -374,14 +391,14 @@
     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
     {
         *olen = ilen;
-        return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
-                                                      ilen, input, output );
+        return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                           ilen, input, output ) );
     }
 #endif
 
     if ( 0 == block_size )
     {
-        return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+        return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
     }
 
     if( input == output &&
@@ -444,7 +461,7 @@
         {
             if( 0 == block_size )
             {
-                return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+                return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
             }
 
             /* Encryption: only cache partial blocks
@@ -745,7 +762,10 @@
 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
                    unsigned char *output, size_t *olen )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     *olen = 0;
@@ -815,8 +835,8 @@
 
         /* Set output size for decryption */
         if( MBEDTLS_DECRYPT == ctx->operation )
-            return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
-                                     olen );
+            return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
+                                      olen ) );
 
         /* Set output size for encryption */
         *olen = mbedtls_cipher_get_block_size( ctx );
@@ -830,10 +850,12 @@
 }
 
 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
-int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode )
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+                                     mbedtls_cipher_padding_t mode )
 {
-    if( NULL == ctx ||
-        MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+
+    if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
     {
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
@@ -881,7 +903,9 @@
 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
                       unsigned char *tag, size_t tag_len )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     if( MBEDTLS_ENCRYPT != ctx->operation )
@@ -889,7 +913,8 @@
 
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
-        return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len );
+        return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
+                                    tag, tag_len ) );
 #endif
 
 #if defined(MBEDTLS_CHACHAPOLY_C)
@@ -899,8 +924,8 @@
         if ( tag_len != 16U )
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-        return mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
-                                                      tag );
+        return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                           tag ) );
     }
 #endif
 
@@ -913,8 +938,12 @@
     unsigned char check_tag[16];
     int ret;
 
-    if( NULL == ctx || NULL == ctx->cipher_info ||
-        MBEDTLS_DECRYPT != ctx->operation )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if( MBEDTLS_DECRYPT != ctx->operation )
     {
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
@@ -976,6 +1005,12 @@
     int ret;
     size_t finish_olen;
 
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+
     if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
         return( ret );
 
@@ -1004,6 +1039,14 @@
                          unsigned char *output, size_t *olen,
                          unsigned char *tag, size_t tag_len )
 {
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
@@ -1051,6 +1094,14 @@
                          unsigned char *output, size_t *olen,
                          const unsigned char *tag, size_t tag_len )
 {
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index fead18f..fb12157 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -299,9 +299,7 @@
          * Crypt counter block
          */
         if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
-        {
-            return( ret );
-        }
+            goto exit;
 
         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
     }
@@ -313,12 +311,12 @@
      * Update key and counter
      */
     if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
-    {
-        return( ret );
-    }
+        goto exit;
     memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
 
-    return( 0 );
+exit:
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    return( ret );
 }
 
 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
@@ -333,23 +331,39 @@
  * and with outputs
  *   ctx = initial_working_state
  */
-void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
-                      const unsigned char *additional, size_t add_len )
+int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
+                                 const unsigned char *additional,
+                                 size_t add_len )
 {
     unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
+    int ret;
 
-    if( add_len > 0 )
-    {
-        /* MAX_INPUT would be more logical here, but we have to match
-         * block_cipher_df()'s limits since we can't propagate errors */
-        if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
-            add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
+    if( add_len == 0 )
+        return( 0 );
 
-        block_cipher_df( add_input, additional, add_len );
-        ctr_drbg_update_internal( ctx, add_input );
-    }
+    if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
+        goto exit;
+    if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
+    return( ret );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
+                              const unsigned char *additional,
+                              size_t add_len )
+{
+    /* MAX_INPUT would be more logical here, but we have to match
+     * block_cipher_df()'s limits since we can't propagate errors */
+    if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+        add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
+    (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
 /* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
  * mbedtls_ctr_drbg_reseed(ctx, additional, len)
  * implements
@@ -399,20 +413,18 @@
      * Reduce to 384 bits
      */
     if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
-    {
-        return( ret );
-    }
+        goto exit;
 
     /*
      * Update state
      */
     if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
-    {
-        return( ret );
-    }
+        goto exit;
     ctx->reseed_counter = 1;
 
-    return( 0 );
+exit:
+    mbedtls_platform_zeroize( seed, sizeof( seed ) );
+    return( ret );
 }
 
 /* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
@@ -467,13 +479,9 @@
     if( add_len > 0 )
     {
         if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
-        {
-            return( ret );
-        }
+            goto exit;
         if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
-        {
-            return( ret );
-        }
+            goto exit;
     }
 
     while( output_len > 0 )
@@ -489,9 +497,7 @@
          * Crypt counter block
          */
         if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
-        {
-            return( ret );
-        }
+            goto exit;
 
         use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
                                                        output_len;
@@ -504,12 +510,13 @@
     }
 
     if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
-    {
-        return( ret );
-    }
+        goto exit;
 
     ctx->reseed_counter++;
 
+exit:
+    mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
     return( 0 );
 }
 
@@ -561,35 +568,36 @@
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
 {
     int ret = 0;
-    FILE *f;
+    FILE *f = NULL;
     size_t n;
     unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
+    unsigned char c;
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
         return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
 
-    fseek( f, 0, SEEK_END );
-    n = (size_t) ftell( f );
-    fseek( f, 0, SEEK_SET );
-
-    if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
+    n = fread( buf, 1, sizeof( buf ), f );
+    if( fread( &c, 1, 1, f ) != 0 )
     {
-        fclose( f );
-        return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+        ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
+        goto exit;
     }
-
-    if( fread( buf, 1, n, f ) != n )
+    if( n == 0 || ferror( f ) )
+    {
         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
-    else
-        mbedtls_ctr_drbg_update( ctx, buf, n );
-
+        goto exit;
+    }
     fclose( f );
+    f = NULL;
 
+    ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
+
+exit:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
-
+    if( f != NULL )
+        fclose( f );
     if( ret != 0 )
         return( ret );
-
     return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
 }
 #endif /* MBEDTLS_FS_IO */
diff --git a/library/debug.c b/library/debug.c
index db3924a..824cd02 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -365,4 +365,54 @@
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if defined(MBEDTLS_ECDH_C)
+static void mbedtls_debug_printf_ecdh_internal( const mbedtls_ssl_context *ssl,
+                                                int level, const char *file,
+                                                int line,
+                                                const mbedtls_ecdh_context *ecdh,
+                                                mbedtls_debug_ecdh_attr attr )
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    const mbedtls_ecdh_context* ctx = ecdh;
+#else
+    const mbedtls_ecdh_context_mbed* ctx = &ecdh->ctx.mbed_ecdh;
+#endif
+
+    switch( attr )
+    {
+        case MBEDTLS_DEBUG_ECDH_Q:
+            mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Q",
+                                     &ctx->Q );
+            break;
+        case MBEDTLS_DEBUG_ECDH_QP:
+            mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Qp",
+                                     &ctx->Qp );
+            break;
+        case MBEDTLS_DEBUG_ECDH_Z:
+            mbedtls_debug_print_mpi( ssl, level, file, line, "ECDH: z",
+                                     &ctx->z );
+            break;
+        default:
+            break;
+    }
+}
+
+void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
+                                const char *file, int line,
+                                const mbedtls_ecdh_context *ecdh,
+                                mbedtls_debug_ecdh_attr attr )
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, attr );
+#else
+    switch( ecdh->var )
+    {
+        default:
+            mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh,
+                                                attr );
+    }
+#endif
+}
+#endif /* MBEDTLS_ECDH_C */
+
 #endif /* MBEDTLS_DEBUG_C */
diff --git a/library/dhm.c b/library/dhm.c
index 82cbb0c..fb6937e 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -60,6 +60,11 @@
 
 #if !defined(MBEDTLS_DHM_ALT)
 
+#define DHM_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
+#define DHM_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * helper to validate the mbedtls_mpi size and import it
  */
@@ -121,6 +126,7 @@
 
 void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
 {
+    DHM_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
 }
 
@@ -132,6 +138,9 @@
                      const unsigned char *end )
 {
     int ret;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( p != NULL && *p != NULL );
+    DHM_VALIDATE_RET( end != NULL );
 
     if( ( ret = dhm_read_bignum( &ctx->P,  p, end ) ) != 0 ||
         ( ret = dhm_read_bignum( &ctx->G,  p, end ) ) != 0 ||
@@ -157,6 +166,10 @@
     int ret, count = 0;
     size_t n1, n2, n3;
     unsigned char *p;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( olen != NULL );
+    DHM_VALIDATE_RET( f_rng != NULL );
 
     if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
@@ -227,9 +240,9 @@
                            const mbedtls_mpi *G )
 {
     int ret;
-
-    if( ctx == NULL || P == NULL || G == NULL )
-        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( P != NULL );
+    DHM_VALIDATE_RET( G != NULL );
 
     if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
         ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
@@ -248,8 +261,10 @@
                      const unsigned char *input, size_t ilen )
 {
     int ret;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( input != NULL );
 
-    if( ctx == NULL || ilen < 1 || ilen > ctx->len )
+    if( ilen < 1 || ilen > ctx->len )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
     if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
@@ -267,8 +282,11 @@
                      void *p_rng )
 {
     int ret, count = 0;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( f_rng != NULL );
 
-    if( ctx == NULL || olen < 1 || olen > ctx->len )
+    if( olen < 1 || olen > ctx->len )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
     if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
@@ -380,8 +398,11 @@
 {
     int ret;
     mbedtls_mpi GYb;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( olen != NULL );
 
-    if( ctx == NULL || output_size < ctx->len )
+    if( output_size < ctx->len )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
     if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
@@ -428,11 +449,19 @@
  */
 void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
 {
-    mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf );
-    mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP );
-    mbedtls_mpi_free( &ctx->K  ); mbedtls_mpi_free( &ctx->GY );
-    mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X  );
-    mbedtls_mpi_free( &ctx->G  ); mbedtls_mpi_free( &ctx->P  );
+    if( ctx == NULL )
+        return;
+
+    mbedtls_mpi_free( &ctx->pX );
+    mbedtls_mpi_free( &ctx->Vf );
+    mbedtls_mpi_free( &ctx->Vi );
+    mbedtls_mpi_free( &ctx->RP );
+    mbedtls_mpi_free( &ctx->K  );
+    mbedtls_mpi_free( &ctx->GY );
+    mbedtls_mpi_free( &ctx->GX );
+    mbedtls_mpi_free( &ctx->X  );
+    mbedtls_mpi_free( &ctx->G  );
+    mbedtls_mpi_free( &ctx->P  );
 
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
 }
@@ -449,7 +478,12 @@
     unsigned char *p, *end;
 #if defined(MBEDTLS_PEM_PARSE_C)
     mbedtls_pem_context pem;
+#endif /* MBEDTLS_PEM_PARSE_C */
 
+    DHM_VALIDATE_RET( dhm != NULL );
+    DHM_VALIDATE_RET( dhmin != NULL );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
     mbedtls_pem_init( &pem );
 
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
@@ -596,6 +630,8 @@
     int ret;
     size_t n;
     unsigned char *buf;
+    DHM_VALIDATE_RET( dhm != NULL );
+    DHM_VALIDATE_RET( path != NULL );
 
     if( ( ret = load_file( path, &buf, &n ) ) != 0 )
         return( ret );
diff --git a/library/ecdh.c b/library/ecdh.c
index e6ae999..da95c60 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -35,9 +35,20 @@
 #if defined(MBEDTLS_ECDH_C)
 
 #include "mbedtls/ecdh.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
+/* Parameter validation macros based on platform_util.h */
+#define ECDH_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECDH_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
+#endif
+
 #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
 /*
  * Generate public key (restartable version)
@@ -74,6 +85,10 @@
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng )
 {
+    ECDH_VALIDATE_RET( grp != NULL );
+    ECDH_VALIDATE_RET( d != NULL );
+    ECDH_VALIDATE_RET( Q != NULL );
+    ECDH_VALIDATE_RET( f_rng != NULL );
     return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
 }
 #endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
@@ -119,48 +134,94 @@
                          int (*f_rng)(void *, unsigned char *, size_t),
                          void *p_rng )
 {
+    ECDH_VALIDATE_RET( grp != NULL );
+    ECDH_VALIDATE_RET( Q != NULL );
+    ECDH_VALIDATE_RET( d != NULL );
+    ECDH_VALIDATE_RET( z != NULL );
     return( ecdh_compute_shared_restartable( grp, z, Q, d,
                                              f_rng, p_rng, NULL ) );
 }
 #endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
 
-/*
- * Initialize context
- */
-void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
+static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx )
 {
     mbedtls_ecp_group_init( &ctx->grp );
     mbedtls_mpi_init( &ctx->d  );
     mbedtls_ecp_point_init( &ctx->Q   );
     mbedtls_ecp_point_init( &ctx->Qp  );
     mbedtls_mpi_init( &ctx->z  );
-    ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
-    mbedtls_ecp_point_init( &ctx->Vi  );
-    mbedtls_ecp_point_init( &ctx->Vf  );
-    mbedtls_mpi_init( &ctx->_d );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
-    ctx->restart_enabled = 0;
     mbedtls_ecp_restart_init( &ctx->rs );
 #endif
 }
 
 /*
- * Free context
+ * Initialize context
  */
-void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
+void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
 {
-    if( ctx == NULL )
-        return;
+    ECDH_VALIDATE( ctx != NULL );
 
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    ecdh_init_internal( ctx );
+    mbedtls_ecp_point_init( &ctx->Vi  );
+    mbedtls_ecp_point_init( &ctx->Vf  );
+    mbedtls_mpi_init( &ctx->_d );
+#else
+    memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
+
+    ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
+#endif
+    ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    ctx->restart_enabled = 0;
+#endif
+}
+
+static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx,
+                                mbedtls_ecp_group_id grp_id )
+{
+    int ret;
+
+    ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Setup context
+ */
+int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
+{
+    ECDH_VALIDATE_RET( ctx != NULL );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_setup_internal( ctx, grp_id ) );
+#else
+    switch( grp_id )
+    {
+        default:
+            ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+            ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
+            ctx->grp_id = grp_id;
+            ecdh_init_internal( &ctx->ctx.mbed_ecdh );
+            return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) );
+    }
+#endif
+}
+
+static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx )
+{
     mbedtls_ecp_group_free( &ctx->grp );
     mbedtls_mpi_free( &ctx->d  );
     mbedtls_ecp_point_free( &ctx->Q   );
     mbedtls_ecp_point_free( &ctx->Qp  );
     mbedtls_mpi_free( &ctx->z  );
-    mbedtls_ecp_point_free( &ctx->Vi  );
-    mbedtls_ecp_point_free( &ctx->Vf  );
-    mbedtls_mpi_free( &ctx->_d );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     mbedtls_ecp_restart_free( &ctx->rs );
@@ -173,21 +234,49 @@
  */
 void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
 {
+    ECDH_VALIDATE( ctx != NULL );
+
     ctx->restart_enabled = 1;
 }
 #endif
 
 /*
- * Setup and write the ServerKeyExhange parameters (RFC 4492)
- *      struct {
- *          ECParameters    curve_params;
- *          ECPoint         public;
- *      } ServerECDHParams;
+ * Free context
  */
-int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
-                      unsigned char *buf, size_t blen,
-                      int (*f_rng)(void *, unsigned char *, size_t),
-                      void *p_rng )
+void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    mbedtls_ecp_point_free( &ctx->Vi );
+    mbedtls_ecp_point_free( &ctx->Vf );
+    mbedtls_mpi_free( &ctx->_d );
+    ecdh_free_internal( ctx );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            ecdh_free_internal( &ctx->ctx.mbed_ecdh );
+            break;
+        default:
+            break;
+    }
+
+    ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+    ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
+    ctx->grp_id = MBEDTLS_ECP_DP_NONE;
+#endif
+}
+
+static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      size_t *olen, int point_format,
+                                      unsigned char *buf, size_t blen,
+                                      int (*f_rng)(void *,
+                                                   unsigned char *,
+                                                   size_t),
+                                      void *p_rng,
+                                      int restart_enabled )
 {
     int ret;
     size_t grp_len, pt_len;
@@ -195,12 +284,14 @@
     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
 #endif
 
-    if( ctx == NULL || ctx->grp.pbits == 0 )
+    if( ctx->grp.pbits == 0 )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
-    if( ctx->restart_enabled )
+    if( restart_enabled )
         rs_ctx = &ctx->rs;
+#else
+    (void) restart_enabled;
 #endif
 
 
@@ -214,14 +305,14 @@
         return( ret );
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
-    if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
-                != 0 )
+    if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf,
+                                             blen ) ) != 0 )
         return( ret );
 
     buf += grp_len;
     blen -= grp_len;
 
-    if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
+    if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format,
                                              &pt_len, buf, blen ) ) != 0 )
         return( ret );
 
@@ -230,6 +321,55 @@
 }
 
 /*
+ * Setup and write the ServerKeyExhange parameters (RFC 4492)
+ *      struct {
+ *          ECParameters    curve_params;
+ *          ECPoint         public;
+ *      } ServerECDHParams;
+ */
+int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
+                              unsigned char *buf, size_t blen,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int restart_enabled = 0;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( olen != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+    ECDH_VALIDATE_RET( f_rng != NULL );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    restart_enabled = ctx->restart_enabled;
+#else
+    (void) restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen,
+                                       f_rng, p_rng, restart_enabled ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
+                                               ctx->point_format, buf, blen,
+                                               f_rng, p_rng,
+                                               restart_enabled ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      const unsigned char **buf,
+                                      const unsigned char *end )
+{
+    return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf,
+                                        end - *buf ) );
+}
+
+/*
  * Read the ServerKeyExhange parameters (RFC 4492)
  *      struct {
  *          ECParameters    curve_params;
@@ -237,31 +377,43 @@
  *      } ServerECDHParams;
  */
 int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
-                      const unsigned char **buf, const unsigned char *end )
+                              const unsigned char **buf,
+                              const unsigned char *end )
 {
     int ret;
+    mbedtls_ecp_group_id grp_id;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+    ECDH_VALIDATE_RET( *buf != NULL );
+    ECDH_VALIDATE_RET( end != NULL );
 
-    if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
+    if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
+            != 0 )
         return( ret );
 
-    if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
-                != 0 )
+    if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 )
         return( ret );
 
-    return( 0 );
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_read_params_internal( ctx, buf, end ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
+                                               buf, end ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
 }
 
-/*
- * Get parameters from a keypair
- */
-int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
-                     mbedtls_ecdh_side side )
+static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
+                                     const mbedtls_ecp_keypair *key,
+                                     mbedtls_ecdh_side side )
 {
     int ret;
 
-    if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
-        return( ret );
-
     /* If it's not our key, just import the public part as Qp */
     if( side == MBEDTLS_ECDH_THEIRS )
         return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) );
@@ -278,29 +430,62 @@
 }
 
 /*
- * Setup and export the client public value
+ * Get parameters from a keypair
  */
-int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
-                      unsigned char *buf, size_t blen,
-                      int (*f_rng)(void *, unsigned char *, size_t),
-                      void *p_rng )
+int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
+                             const mbedtls_ecp_keypair *key,
+                             mbedtls_ecdh_side side )
+{
+    int ret;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( key != NULL );
+    ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
+                       side == MBEDTLS_ECDH_THEIRS );
+
+    if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_get_params_internal( ctx, key, side ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
+                                              key, side ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      size_t *olen, int point_format,
+                                      unsigned char *buf, size_t blen,
+                                      int (*f_rng)(void *,
+                                                   unsigned char *,
+                                                   size_t),
+                                      void *p_rng,
+                                      int restart_enabled )
 {
     int ret;
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
 #endif
 
-    if( ctx == NULL || ctx->grp.pbits == 0 )
+    if( ctx->grp.pbits == 0 )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
-    if( ctx->restart_enabled )
+    if( restart_enabled )
         rs_ctx = &ctx->rs;
+#else
+    (void) restart_enabled;
 #endif
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
-                    f_rng, p_rng, rs_ctx ) ) != 0 )
+                                             f_rng, p_rng, rs_ctx ) ) != 0 )
         return( ret );
 #else
     if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
@@ -308,23 +493,53 @@
         return( ret );
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
-    return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
-                                olen, buf, blen );
+    return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen,
+                                        buf, blen );
 }
 
 /*
- * Parse and import the client's public value
+ * Setup and export the client public value
  */
-int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
-                      const unsigned char *buf, size_t blen )
+int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
+                              unsigned char *buf, size_t blen,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int restart_enabled = 0;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( olen != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+    ECDH_VALIDATE_RET( f_rng != NULL );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    restart_enabled = ctx->restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen,
+                                       f_rng, p_rng, restart_enabled ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
+                                               ctx->point_format, buf, blen,
+                                               f_rng, p_rng,
+                                               restart_enabled ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      const unsigned char *buf, size_t blen )
 {
     int ret;
     const unsigned char *p = buf;
 
-    if( ctx == NULL )
-        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
-
-    if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 )
+    if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p,
+                                            blen ) ) != 0 )
         return( ret );
 
     if( (size_t)( p - buf ) != blen )
@@ -334,12 +549,36 @@
 }
 
 /*
- * Derive and export the shared secret
+ * Parse and import the client's public value
  */
-int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
-                      unsigned char *buf, size_t blen,
-                      int (*f_rng)(void *, unsigned char *, size_t),
-                      void *p_rng )
+int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
+                              const unsigned char *buf, size_t blen )
+{
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_read_public_internal( ctx, buf, blen ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
+                                                       buf, blen ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      size_t *olen, unsigned char *buf,
+                                      size_t blen,
+                                      int (*f_rng)(void *,
+                                                   unsigned char *,
+                                                   size_t),
+                                      void *p_rng,
+                                      int restart_enabled )
 {
     int ret;
 #if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -350,13 +589,16 @@
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
-    if( ctx->restart_enabled )
+    if( restart_enabled )
         rs_ctx = &ctx->rs;
+#else
+    (void) restart_enabled;
 #endif
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
-    if( ( ret = ecdh_compute_shared_restartable( &ctx->grp,
-                    &ctx->z, &ctx->Qp, &ctx->d, f_rng, p_rng, rs_ctx ) ) != 0 )
+    if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp,
+                                                 &ctx->d, f_rng, p_rng,
+                                                 rs_ctx ) ) != 0 )
     {
         return( ret );
     }
@@ -375,4 +617,37 @@
     return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
 }
 
+/*
+ * Derive and export the shared secret
+ */
+int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
+                              unsigned char *buf, size_t blen,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int restart_enabled = 0;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( olen != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    restart_enabled = ctx->restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng,
+                                       restart_enabled ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
+                                               blen, f_rng, p_rng,
+                                               restart_enabled ) );
+        default:
+            return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+#endif
+}
+
 #endif /* MBEDTLS_ECDH_C */
diff --git a/library/ecdsa.c b/library/ecdsa.c
index a62c14c..1204ef9 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -50,6 +50,14 @@
 #define mbedtls_free       free
 #endif
 
+#include "mbedtls/platform_util.h"
+
+/* Parameter validation macros based on platform_util.h */
+#define ECDSA_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECDSA_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if defined(MBEDTLS_ECP_RESTARTABLE)
 
 /*
@@ -377,6 +385,13 @@
                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
+    ECDSA_VALIDATE_RET( grp   != NULL );
+    ECDSA_VALIDATE_RET( r     != NULL );
+    ECDSA_VALIDATE_RET( s     != NULL );
+    ECDSA_VALIDATE_RET( d     != NULL );
+    ECDSA_VALIDATE_RET( f_rng != NULL );
+    ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
+
     return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
                                     f_rng, p_rng, NULL ) );
 }
@@ -456,6 +471,12 @@
                     const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
                     mbedtls_md_type_t md_alg )
 {
+    ECDSA_VALIDATE_RET( grp   != NULL );
+    ECDSA_VALIDATE_RET( r     != NULL );
+    ECDSA_VALIDATE_RET( s     != NULL );
+    ECDSA_VALIDATE_RET( d     != NULL );
+    ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
+
     return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) );
 }
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -574,9 +595,17 @@
  * Verify ECDSA signature of hashed message
  */
 int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
-                  const unsigned char *buf, size_t blen,
-                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
+                          const unsigned char *buf, size_t blen,
+                          const mbedtls_ecp_point *Q,
+                          const mbedtls_mpi *r,
+                          const mbedtls_mpi *s)
 {
+    ECDSA_VALIDATE_RET( grp != NULL );
+    ECDSA_VALIDATE_RET( Q   != NULL );
+    ECDSA_VALIDATE_RET( r   != NULL );
+    ECDSA_VALIDATE_RET( s   != NULL );
+    ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+
     return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
 }
 #endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
@@ -618,6 +647,10 @@
 {
     int ret;
     mbedtls_mpi r, s;
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+    ECDSA_VALIDATE_RET( slen != NULL );
 
     mbedtls_mpi_init( &r );
     mbedtls_mpi_init( &s );
@@ -652,12 +685,17 @@
 /*
  * Compute and write signature
  */
-int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
-                           const unsigned char *hash, size_t hlen,
-                           unsigned char *sig, size_t *slen,
-                           int (*f_rng)(void *, unsigned char *, size_t),
-                           void *p_rng )
+int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
+                                 mbedtls_md_type_t md_alg,
+                                 const unsigned char *hash, size_t hlen,
+                                 unsigned char *sig, size_t *slen,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng )
 {
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+    ECDSA_VALIDATE_RET( slen != NULL );
     return( mbedtls_ecdsa_write_signature_restartable(
                 ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
 }
@@ -669,6 +707,10 @@
                                unsigned char *sig, size_t *slen,
                                mbedtls_md_type_t md_alg )
 {
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+    ECDSA_VALIDATE_RET( slen != NULL );
     return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen,
                                    NULL, NULL ) );
 }
@@ -681,6 +723,9 @@
                           const unsigned char *hash, size_t hlen,
                           const unsigned char *sig, size_t slen )
 {
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
     return( mbedtls_ecdsa_read_signature_restartable(
                 ctx, hash, hlen, sig, slen, NULL ) );
 }
@@ -698,6 +743,9 @@
     const unsigned char *end = sig + slen;
     size_t len;
     mbedtls_mpi r, s;
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
 
     mbedtls_mpi_init( &r );
     mbedtls_mpi_init( &s );
@@ -752,6 +800,9 @@
 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
+    ECDSA_VALIDATE_RET( ctx   != NULL );
+    ECDSA_VALIDATE_RET( f_rng != NULL );
+
     return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
             mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
 }
@@ -763,6 +814,8 @@
 int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
 {
     int ret;
+    ECDSA_VALIDATE_RET( ctx != NULL );
+    ECDSA_VALIDATE_RET( key != NULL );
 
     if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
         ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
@@ -779,6 +832,8 @@
  */
 void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
 {
+    ECDSA_VALIDATE( ctx != NULL );
+
     mbedtls_ecp_keypair_init( ctx );
 }
 
@@ -787,6 +842,9 @@
  */
 void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
 {
+    if( ctx == NULL )
+        return;
+
     mbedtls_ecp_keypair_free( ctx );
 }
 
@@ -796,6 +854,8 @@
  */
 void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
 {
+    ECDSA_VALIDATE( ctx != NULL );
+
     mbedtls_ecp_restart_init( &ctx->ecp );
 
     ctx->ver = NULL;
@@ -810,6 +870,9 @@
  */
 void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
 {
+    if( ctx == NULL )
+        return;
+
     mbedtls_ecp_restart_free( &ctx->ecp );
 
     ecdsa_restart_ver_free( ctx->ver );
diff --git a/library/ecjpake.c b/library/ecjpake.c
index ec5a400..be941b1 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -33,11 +33,18 @@
 #if defined(MBEDTLS_ECJPAKE_C)
 
 #include "mbedtls/ecjpake.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
 #if !defined(MBEDTLS_ECJPAKE_ALT)
 
+/* Parameter validation macros based on platform_util.h */
+#define ECJPAKE_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECJPAKE_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * Convert a mbedtls_ecjpake_role to identifier string
  */
@@ -54,8 +61,7 @@
  */
 void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
 {
-    if( ctx == NULL )
-        return;
+    ECJPAKE_VALIDATE( ctx != NULL );
 
     ctx->md_info = NULL;
     mbedtls_ecp_group_init( &ctx->grp );
@@ -106,6 +112,11 @@
 {
     int ret;
 
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+    ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT ||
+                          role == MBEDTLS_ECJPAKE_SERVER );
+    ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 );
+
     ctx->role = role;
 
     if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
@@ -127,6 +138,8 @@
  */
 int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
 {
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+
     if( ctx->md_info == NULL ||
         ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
         ctx->s.p == NULL )
@@ -504,6 +517,9 @@
                                     const unsigned char *buf,
                                     size_t len )
 {
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+    ECJPAKE_VALIDATE_RET( buf != NULL );
+
     return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
                                &ctx->grp.G,
                                &ctx->Xp1, &ctx->Xp2, ID_PEER,
@@ -518,6 +534,11 @@
                             int (*f_rng)(void *, unsigned char *, size_t),
                             void *p_rng )
 {
+    ECJPAKE_VALIDATE_RET( ctx   != NULL );
+    ECJPAKE_VALIDATE_RET( buf   != NULL );
+    ECJPAKE_VALIDATE_RET( olen  != NULL );
+    ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
     return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
                                 &ctx->grp.G,
                                 &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
@@ -560,6 +581,9 @@
     mbedtls_ecp_group grp;
     mbedtls_ecp_point G;    /* C: GB, S: GA */
 
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+    ECJPAKE_VALIDATE_RET( buf != NULL );
+
     mbedtls_ecp_group_init( &grp );
     mbedtls_ecp_point_init( &G );
 
@@ -652,6 +676,11 @@
     const unsigned char *end = buf + len;
     size_t ec_len;
 
+    ECJPAKE_VALIDATE_RET( ctx   != NULL );
+    ECJPAKE_VALIDATE_RET( buf   != NULL );
+    ECJPAKE_VALIDATE_RET( olen  != NULL );
+    ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
     mbedtls_ecp_point_init( &G );
     mbedtls_ecp_point_init( &Xm );
     mbedtls_mpi_init( &xm );
@@ -727,6 +756,11 @@
     unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
     size_t x_bytes;
 
+    ECJPAKE_VALIDATE_RET( ctx   != NULL );
+    ECJPAKE_VALIDATE_RET( buf   != NULL );
+    ECJPAKE_VALIDATE_RET( olen  != NULL );
+    ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
     *olen = mbedtls_md_get_size( ctx->md_info );
     if( len < *olen )
         return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
diff --git a/library/ecp.c b/library/ecp.c
index de5725c..ecea591 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -47,6 +47,35 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
+/**
+ * \brief Function level alternative implementation.
+ *
+ * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to
+ * replace certain functions in this module. The alternative implementations are
+ * typically hardware accelerators and need to activate the hardware before the
+ * computation starts and deactivate it after it finishes. The
+ * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve
+ * this purpose.
+ *
+ * To preserve the correct functionality the following conditions must hold:
+ *
+ * - The alternative implementation must be activated by
+ *   mbedtls_internal_ecp_init() before any of the replaceable functions is
+ *   called.
+ * - mbedtls_internal_ecp_free() must \b only be called when the alternative
+ *   implementation is activated.
+ * - mbedtls_internal_ecp_init() must \b not be called when the alternative
+ *   implementation is activated.
+ * - Public functions must not return while the alternative implementation is
+ *   activated.
+ * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and
+ *   before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) )
+ *   \endcode ensures that the alternative implementation supports the current
+ *   group.
+ */
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+#endif
+
 #if defined(MBEDTLS_ECP_C)
 
 #include "mbedtls/ecp.h"
@@ -57,6 +86,12 @@
 
 #if !defined(MBEDTLS_ECP_ALT)
 
+/* Parameter validation macros based on platform_util.h */
+#define ECP_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECP_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
@@ -209,6 +244,7 @@
  */
 void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx )
 {
+    ECP_VALIDATE( ctx != NULL );
     ctx->ops_done = 0;
     ctx->depth = 0;
     ctx->rsm = NULL;
@@ -239,6 +275,8 @@
                               mbedtls_ecp_restart_ctx *rs_ctx,
                               unsigned ops )
 {
+    ECP_VALIDATE_RET( grp != NULL );
+
     if( rs_ctx != NULL && ecp_max_ops != 0 )
     {
         /* scale depending on curve size: the chosen reference is 256-bit,
@@ -467,6 +505,9 @@
 {
     const mbedtls_ecp_curve_info *curve_info;
 
+    if( name == NULL )
+        return( NULL );
+
     for( curve_info = mbedtls_ecp_curve_list();
          curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
          curve_info++ )
@@ -497,8 +538,7 @@
  */
 void mbedtls_ecp_point_init( mbedtls_ecp_point *pt )
 {
-    if( pt == NULL )
-        return;
+    ECP_VALIDATE( pt != NULL );
 
     mbedtls_mpi_init( &pt->X );
     mbedtls_mpi_init( &pt->Y );
@@ -510,8 +550,7 @@
  */
 void mbedtls_ecp_group_init( mbedtls_ecp_group *grp )
 {
-    if( grp == NULL )
-        return;
+    ECP_VALIDATE( grp != NULL );
 
     grp->id = MBEDTLS_ECP_DP_NONE;
     mbedtls_mpi_init( &grp->P );
@@ -535,8 +574,7 @@
  */
 void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key )
 {
-    if( key == NULL )
-        return;
+    ECP_VALIDATE( key != NULL );
 
     mbedtls_ecp_group_init( &key->grp );
     mbedtls_mpi_init( &key->d );
@@ -604,6 +642,8 @@
 int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
 {
     int ret;
+    ECP_VALIDATE_RET( P != NULL );
+    ECP_VALIDATE_RET( Q != NULL );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) );
@@ -618,7 +658,10 @@
  */
 int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src )
 {
-    return mbedtls_ecp_group_load( dst, src->id );
+    ECP_VALIDATE_RET( dst != NULL );
+    ECP_VALIDATE_RET( src != NULL );
+
+    return( mbedtls_ecp_group_load( dst, src->id ) );
 }
 
 /*
@@ -627,6 +670,7 @@
 int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt )
 {
     int ret;
+    ECP_VALIDATE_RET( pt != NULL );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) );
@@ -641,15 +685,20 @@
  */
 int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
 {
+    ECP_VALIDATE_RET( pt != NULL );
+
     return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 );
 }
 
 /*
- * Compare two points lazyly
+ * Compare two points lazily
  */
 int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
                            const mbedtls_ecp_point *Q )
 {
+    ECP_VALIDATE_RET( P != NULL );
+    ECP_VALIDATE_RET( Q != NULL );
+
     if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 &&
         mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 &&
         mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 )
@@ -667,6 +716,9 @@
                            const char *x, const char *y )
 {
     int ret;
+    ECP_VALIDATE_RET( P != NULL );
+    ECP_VALIDATE_RET( x != NULL );
+    ECP_VALIDATE_RET( y != NULL );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) );
@@ -679,16 +731,19 @@
 /*
  * Export a point into unsigned binary data (SEC1 2.3.3)
  */
-int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
-                            int format, size_t *olen,
-                            unsigned char *buf, size_t buflen )
+int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
+                                    const mbedtls_ecp_point *P,
+                                    int format, size_t *olen,
+                                    unsigned char *buf, size_t buflen )
 {
     int ret = 0;
     size_t plen;
-
-    if( format != MBEDTLS_ECP_PF_UNCOMPRESSED &&
-        format != MBEDTLS_ECP_PF_COMPRESSED )
-        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( P    != NULL );
+    ECP_VALIDATE_RET( olen != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+                      format == MBEDTLS_ECP_PF_COMPRESSED );
 
     /*
      * Common case: P == 0
@@ -735,11 +790,15 @@
 /*
  * Import a point from unsigned binary data (SEC1 2.3.4)
  */
-int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
-                           const unsigned char *buf, size_t ilen )
+int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
+                                   mbedtls_ecp_point *pt,
+                                   const unsigned char *buf, size_t ilen )
 {
     int ret;
     size_t plen;
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( pt  != NULL );
+    ECP_VALIDATE_RET( buf != NULL );
 
     if( ilen < 1 )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -774,11 +833,16 @@
  *          opaque point <1..2^8-1>;
  *      } ECPoint;
  */
-int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
-                        const unsigned char **buf, size_t buf_len )
+int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp,
+                                mbedtls_ecp_point *pt,
+                                const unsigned char **buf, size_t buf_len )
 {
     unsigned char data_len;
     const unsigned char *buf_start;
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( pt  != NULL );
+    ECP_VALIDATE_RET( buf != NULL );
+    ECP_VALIDATE_RET( *buf != NULL );
 
     /*
      * We must have at least two bytes (1 for length, at least one for data)
@@ -796,7 +860,7 @@
     buf_start = *buf;
     *buf += data_len;
 
-    return mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len );
+    return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) );
 }
 
 /*
@@ -810,6 +874,12 @@
                          unsigned char *buf, size_t blen )
 {
     int ret;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( pt   != NULL );
+    ECP_VALIDATE_RET( olen != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+                      format == MBEDTLS_ECP_PF_COMPRESSED );
 
     /*
      * buffer length must be at least one, for our length byte
@@ -833,10 +903,33 @@
 /*
  * Set a group from an ECParameters record (RFC 4492)
  */
-int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len )
+int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
+                                const unsigned char **buf, size_t len )
+{
+    int ret;
+    mbedtls_ecp_group_id grp_id;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( *buf != NULL );
+
+    if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 )
+        return( ret );
+
+    return( mbedtls_ecp_group_load( grp, grp_id ) );
+}
+
+/*
+ * Read a group id from an ECParameters record (RFC 4492) and convert it to
+ * mbedtls_ecp_group_id.
+ */
+int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp,
+                                   const unsigned char **buf, size_t len )
 {
     uint16_t tls_id;
     const mbedtls_ecp_curve_info *curve_info;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( *buf != NULL );
 
     /*
      * We expect at least three bytes (see below)
@@ -860,7 +953,9 @@
     if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL )
         return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 
-    return mbedtls_ecp_group_load( grp, curve_info->grp_id );
+    *grp = curve_info->grp_id;
+
+    return( 0 );
 }
 
 /*
@@ -870,6 +965,9 @@
                          unsigned char *buf, size_t blen )
 {
     const mbedtls_ecp_curve_info *curve_info;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( olen != NULL );
 
     if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -2228,6 +2326,10 @@
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
     char is_grp_capable = 0;
 #endif
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     /* reset ops count for this call if top-level */
@@ -2285,6 +2387,10 @@
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
     return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) );
 }
 
@@ -2387,17 +2493,18 @@
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
     char is_grp_capable = 0;
 #endif
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+    ECP_VALIDATE_RET( n   != NULL );
+    ECP_VALIDATE_RET( Q   != NULL );
 
     if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
         return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 
     mbedtls_ecp_point_init( &mP );
 
-#if defined(MBEDTLS_ECP_INTERNAL_ALT)
-    if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) )
-        MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
-#endif /* MBEDTLS_ECP_INTERNAL_ALT */
-
     ECP_RS_ENTER( ma );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -2425,6 +2532,12 @@
 mul2:
 #endif
     MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR,  n, Q, rs_ctx ) );
+
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) )
+        MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if( rs_ctx != NULL && rs_ctx->ma != NULL )
         rs_ctx->ma->state = ecp_rsma_add;
@@ -2468,6 +2581,12 @@
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
              const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
 {
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+    ECP_VALIDATE_RET( n   != NULL );
+    ECP_VALIDATE_RET( Q   != NULL );
     return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
 }
 
@@ -2490,8 +2609,12 @@
 /*
  * Check that a point is valid as a public key
  */
-int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
+int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
+                              const mbedtls_ecp_point *pt )
 {
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( pt  != NULL );
+
     /* Must use affine coordinates */
     if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
         return( MBEDTLS_ERR_ECP_INVALID_KEY );
@@ -2510,8 +2633,12 @@
 /*
  * Check that an mbedtls_mpi is valid as a private key
  */
-int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d )
+int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
+                               const mbedtls_mpi *d )
 {
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( d   != NULL );
+
 #if defined(ECP_MONTGOMERY)
     if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
     {
@@ -2552,7 +2679,13 @@
                      void *p_rng )
 {
     int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-    size_t n_size = ( grp->nbits + 7 ) / 8;
+    size_t n_size;
+
+    ECP_VALIDATE_RET( grp   != NULL );
+    ECP_VALIDATE_RET( d     != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
+
+    n_size = ( grp->nbits + 7 ) / 8;
 
 #if defined(ECP_MONTGOMERY)
     if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
@@ -2631,6 +2764,11 @@
                      void *p_rng )
 {
     int ret;
+    ECP_VALIDATE_RET( grp   != NULL );
+    ECP_VALIDATE_RET( d     != NULL );
+    ECP_VALIDATE_RET( G     != NULL );
+    ECP_VALIDATE_RET( Q     != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
 
     MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
@@ -2647,6 +2785,11 @@
                              int (*f_rng)(void *, unsigned char *, size_t),
                              void *p_rng )
 {
+    ECP_VALIDATE_RET( grp   != NULL );
+    ECP_VALIDATE_RET( d     != NULL );
+    ECP_VALIDATE_RET( Q     != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
+
     return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
 }
 
@@ -2657,6 +2800,8 @@
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret;
+    ECP_VALIDATE_RET( key   != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
 
     if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
         return( ret );
@@ -2672,6 +2817,8 @@
     int ret;
     mbedtls_ecp_point Q;
     mbedtls_ecp_group grp;
+    ECP_VALIDATE_RET( pub != NULL );
+    ECP_VALIDATE_RET( prv != NULL );
 
     if( pub->grp.id == MBEDTLS_ECP_DP_NONE ||
         pub->grp.id != prv->grp.id ||
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 68e2441..731621d 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -28,11 +28,18 @@
 #if defined(MBEDTLS_ECP_C)
 
 #include "mbedtls/ecp.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
 #if !defined(MBEDTLS_ECP_ALT)
 
+/* Parameter validation macros based on platform_util.h */
+#define ECP_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECP_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
 #define inline __inline
@@ -746,6 +753,7 @@
  */
 int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
 {
+    ECP_VALIDATE_RET( grp != NULL );
     mbedtls_ecp_group_free( grp );
 
     grp->id = id;
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 040aa11..4556f88 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -99,6 +99,7 @@
 #include <sys/syscall.h>
 #if defined(SYS_getrandom)
 #define HAVE_GETRANDOM
+#include <errno.h>
 
 static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
 {
@@ -108,47 +109,8 @@
     memset( buf, 0, buflen );
 #endif
 #endif
-
     return( syscall( SYS_getrandom, buf, buflen, flags ) );
 }
-
-#include <sys/utsname.h>
-/* Check if version is at least 3.17.0 */
-static int check_version_3_17_plus( void )
-{
-    int minor;
-    struct utsname un;
-    const char *ver;
-
-    /* Get version information */
-    uname(&un);
-    ver = un.release;
-
-    /* Check major version; assume a single digit */
-    if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
-        return( -1 );
-
-    if( ver[0] - '0' > 3 )
-        return( 0 );
-
-    /* Ok, so now we know major == 3, check minor.
-     * Assume 1 or 2 digits. */
-    if( ver[2] < '0' || ver[2] > '9' )
-        return( -1 );
-
-    minor = ver[2] - '0';
-
-    if( ver[3] >= '0' && ver[3] <= '9' )
-        minor = 10 * minor + ver[3] - '0';
-    else if( ver [3] != '.' )
-        return( -1 );
-
-    if( minor < 17 )
-        return( -1 );
-
-    return( 0 );
-}
-static int has_getrandom = -1;
 #endif /* SYS_getrandom */
 #endif /* __linux__ */
 
@@ -159,22 +121,21 @@
 {
     FILE *file;
     size_t read_len;
+    int ret;
     ((void) data);
 
 #if defined(HAVE_GETRANDOM)
-    if( has_getrandom == -1 )
-        has_getrandom = ( check_version_3_17_plus() == 0 );
-
-    if( has_getrandom )
+    ret = getrandom_wrapper( output, len, 0 );
+    if( ret >= 0 )
     {
-        int ret;
-
-        if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
-            return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
-
         *olen = ret;
         return( 0 );
     }
+    else if( errno != ENOSYS )
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+    /* Fall through if the system call isn't known. */
+#else
+    ((void) ret);
 #endif /* HAVE_GETRANDOM */
 
     *olen = 0;
diff --git a/library/error.c b/library/error.c
index eabee9e..12312a0 100644
--- a/library/error.c
+++ b/library/error.c
@@ -618,8 +618,8 @@
 #endif /* MBEDTLS_ARC4_C */
 
 #if defined(MBEDTLS_ARIA_C)
-    if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH) )
-        mbedtls_snprintf( buf, buflen, "ARIA - Invalid key length" );
+    if( use_ret == -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "ARIA - Bad input data" );
     if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" );
     if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) )
@@ -672,17 +672,17 @@
 #endif /* MBEDTLS_BIGNUM_C */
 
 #if defined(MBEDTLS_BLOWFISH_C)
-    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
-        mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
-    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
-        mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "BLOWFISH - Bad input data" );
     if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
 #endif /* MBEDTLS_BLOWFISH_C */
 
 #if defined(MBEDTLS_CAMELLIA_C)
-    if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH) )
-        mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
+    if( use_ret == -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "CAMELLIA - Bad input data" );
     if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
     if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) )
@@ -855,16 +855,22 @@
 #if defined(MBEDTLS_SHA1_C)
     if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
         mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 input data was malformed" );
 #endif /* MBEDTLS_SHA1_C */
 
 #if defined(MBEDTLS_SHA256_C)
     if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) )
         mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 input data was malformed" );
 #endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA512_C)
     if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) )
         mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 input data was malformed" );
 #endif /* MBEDTLS_SHA512_C */
 
 #if defined(MBEDTLS_THREADING_C)
diff --git a/library/gcm.c b/library/gcm.c
index c486ef7..675926a 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -57,6 +57,12 @@
 
 #if !defined(MBEDTLS_GCM_ALT)
 
+/* Parameter validation macros */
+#define GCM_VALIDATE_RET( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
+#define GCM_VALIDATE( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -85,6 +91,7 @@
  */
 void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
 {
+    GCM_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
 }
 
@@ -164,6 +171,10 @@
     int ret;
     const mbedtls_cipher_info_t *cipher_info;
 
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( key != NULL );
+    GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
+
     cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
     if( cipher_info == NULL )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -274,6 +285,10 @@
     const unsigned char *p;
     size_t use_len, olen = 0;
 
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( iv != NULL );
+    GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+
     /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
     /* IV is not allowed to be zero length */
     if( iv_len == 0 ||
@@ -356,6 +371,10 @@
     unsigned char *out_p = output;
     size_t use_len, olen = 0;
 
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( length == 0 || input != NULL );
+    GCM_VALIDATE_RET( length == 0 || output != NULL );
+
     if( output > input && (size_t) ( output - input ) < length )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
 
@@ -409,8 +428,14 @@
 {
     unsigned char work_buf[16];
     size_t i;
-    uint64_t orig_len = ctx->len * 8;
-    uint64_t orig_add_len = ctx->add_len * 8;
+    uint64_t orig_len;
+    uint64_t orig_add_len;
+
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( tag != NULL );
+
+    orig_len = ctx->len * 8;
+    orig_add_len = ctx->add_len * 8;
 
     if( tag_len > 16 || tag_len < 4 )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -452,6 +477,13 @@
 {
     int ret;
 
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( iv != NULL );
+    GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    GCM_VALIDATE_RET( length == 0 || input != NULL );
+    GCM_VALIDATE_RET( length == 0 || output != NULL );
+    GCM_VALIDATE_RET( tag != NULL );
+
     if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
         return( ret );
 
@@ -480,6 +512,13 @@
     size_t i;
     int diff;
 
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( iv != NULL );
+    GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    GCM_VALIDATE_RET( tag != NULL );
+    GCM_VALIDATE_RET( length == 0 || input != NULL );
+    GCM_VALIDATE_RET( length == 0 || output != NULL );
+
     if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
                                    iv, iv_len, add, add_len,
                                    input, output, tag_len, check_tag ) ) != 0 )
@@ -502,6 +541,8 @@
 
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
 {
+    if( ctx == NULL )
+        return;
     mbedtls_cipher_free( &ctx->cipher_ctx );
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
 }
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index dad55ff..c50330e 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -66,31 +66,60 @@
 /*
  * HMAC_DRBG update, using optional additional data (10.1.2.2)
  */
-void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
-                       const unsigned char *additional, size_t add_len )
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
+                                  const unsigned char *additional,
+                                  size_t add_len )
 {
     size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
     unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
     unsigned char sep[1];
     unsigned char K[MBEDTLS_MD_MAX_SIZE];
+    int ret;
 
     for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
     {
         /* Step 1 or 4 */
-        mbedtls_md_hmac_reset( &ctx->md_ctx );
-        mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
-        mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 );
+        if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            ctx->V, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            sep, 1 ) ) != 0 )
+            goto exit;
         if( rounds == 2 )
-            mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len );
-        mbedtls_md_hmac_finish( &ctx->md_ctx, K );
+        {
+            if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                                additional, add_len ) ) != 0 )
+            goto exit;
+        }
+        if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
+            goto exit;
 
         /* Step 2 or 5 */
-        mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len );
-        mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
-        mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
+        if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            ctx->V, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
+            goto exit;
     }
+
+exit:
+    mbedtls_platform_zeroize( K, sizeof( K ) );
+    return( ret );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+                               const unsigned char *additional,
+                               size_t add_len )
+{
+    (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
 /*
  * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
  */
@@ -108,10 +137,13 @@
      * Use the V memory location, which is currently all 0, to initialize the
      * MD context with an all-zero key. Then set V to its initial value.
      */
-    mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) );
+    if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
+                                        mbedtls_md_get_size( md_info ) ) ) != 0 )
+        return( ret );
     memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
 
-    mbedtls_hmac_drbg_update( ctx, data, data_len );
+    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
+        return( ret );
 
     return( 0 );
 }
@@ -124,6 +156,7 @@
 {
     unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
     size_t seedlen;
+    int ret;
 
     /* III. Check input length */
     if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
@@ -135,7 +168,8 @@
     memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
 
     /* IV. Gather entropy_len bytes of entropy for the seed */
-    if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
+    if( ( ret = ctx->f_entropy( ctx->p_entropy,
+                                seed, ctx->entropy_len ) ) != 0 )
         return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
 
     seedlen = ctx->entropy_len;
@@ -148,13 +182,16 @@
     }
 
     /* 2. Update state */
-    mbedtls_hmac_drbg_update( ctx, seed, seedlen );
+    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
+        goto exit;
 
     /* 3. Reset reseed_counter */
     ctx->reseed_counter = 1;
 
+exit:
     /* 4. Done */
-    return( 0 );
+    mbedtls_platform_zeroize( seed, seedlen );
+    return( ret );
 }
 
 /*
@@ -180,7 +217,8 @@
      * Use the V memory location, which is currently all 0, to initialize the
      * MD context with an all-zero key. Then set V to its initial value.
      */
-    mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size );
+    if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
+        return( ret );
     memset( ctx->V, 0x01, md_size );
 
     ctx->f_entropy = f_entropy;
@@ -273,16 +311,24 @@
 
     /* 2. Use additional data if any */
     if( additional != NULL && add_len != 0 )
-        mbedtls_hmac_drbg_update( ctx, additional, add_len );
+    {
+        if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+                                                  additional, add_len ) ) != 0 )
+            goto exit;
+    }
 
     /* 3, 4, 5. Generate bytes */
     while( left != 0 )
     {
         size_t use_len = left > md_len ? md_len : left;
 
-        mbedtls_md_hmac_reset( &ctx->md_ctx );
-        mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
-        mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
+        if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            ctx->V, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
+            goto exit;
 
         memcpy( out, ctx->V, use_len );
         out += use_len;
@@ -290,13 +336,16 @@
     }
 
     /* 6. Update */
-    mbedtls_hmac_drbg_update( ctx, additional, add_len );
+    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+                                              additional, add_len ) ) != 0 )
+        goto exit;
 
     /* 7. Update reseed counter */
     ctx->reseed_counter++;
 
+exit:
     /* 8. Done */
-    return( 0 );
+    return( ret );
 }
 
 /*
@@ -368,35 +417,36 @@
 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
 {
     int ret = 0;
-    FILE *f;
+    FILE *f = NULL;
     size_t n;
     unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
+    unsigned char c;
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
         return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
 
-    fseek( f, 0, SEEK_END );
-    n = (size_t) ftell( f );
-    fseek( f, 0, SEEK_SET );
-
-    if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
+    n = fread( buf, 1, sizeof( buf ), f );
+    if( fread( &c, 1, 1, f ) != 0 )
     {
-        fclose( f );
-        return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
+        ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
+        goto exit;
     }
-
-    if( fread( buf, 1, n, f ) != n )
+    if( n == 0 || ferror( f ) )
+    {
         ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
-    else
-        mbedtls_hmac_drbg_update( ctx, buf, n );
-
+        goto exit;
+    }
     fclose( f );
+    f = NULL;
 
+    ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
+
+exit:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
-
+    if( f != NULL )
+        fclose( f );
     if( ret != 0 )
         return( ret );
-
     return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
 }
 #endif /* MBEDTLS_FS_IO */
diff --git a/library/nist_kw.c b/library/nist_kw.c
index 176af9f..317a242 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -311,7 +311,7 @@
     }
     mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 );
     mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 );
-    mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen );
+
     return( ret );
 }
 
@@ -528,7 +528,7 @@
     mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) );
     mbedtls_platform_zeroize( &diff, sizeof( diff ) );
     mbedtls_platform_zeroize( A, sizeof( A ) );
-    mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen );
+
     return( ret );
 }
 
diff --git a/library/pem.c b/library/pem.c
index 6069a23..897c8a0 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -423,9 +423,11 @@
 
 void mbedtls_pem_free( mbedtls_pem_context *ctx )
 {
-    if( ctx->buf != NULL )
+    if ( ctx->buf != NULL )
+    {
         mbedtls_platform_zeroize( ctx->buf, ctx->buflen );
-    mbedtls_free( ctx->buf );
+        mbedtls_free( ctx->buf );
+    }
     mbedtls_free( ctx->info );
 
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) );
diff --git a/library/pk.c b/library/pk.c
index e0e8dba..bac685d 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -44,13 +44,18 @@
 #include <limits.h>
 #include <stdint.h>
 
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 /*
  * Initialise a mbedtls_pk_context
  */
 void mbedtls_pk_init( mbedtls_pk_context *ctx )
 {
-    if( ctx == NULL )
-        return;
+    PK_VALIDATE( ctx != NULL );
 
     ctx->pk_info = NULL;
     ctx->pk_ctx = NULL;
@@ -61,10 +66,11 @@
  */
 void mbedtls_pk_free( mbedtls_pk_context *ctx )
 {
-    if( ctx == NULL || ctx->pk_info == NULL )
+    if( ctx == NULL )
         return;
 
-    ctx->pk_info->ctx_free_func( ctx->pk_ctx );
+    if ( ctx->pk_info != NULL )
+        ctx->pk_info->ctx_free_func( ctx->pk_ctx );
 
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
 }
@@ -75,6 +81,7 @@
  */
 void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
 {
+    PK_VALIDATE( ctx != NULL );
     ctx->pk_info = NULL;
     ctx->rs_ctx = NULL;
 }
@@ -128,7 +135,8 @@
  */
 int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
 {
-    if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
+    PK_VALIDATE_RET( ctx != NULL );
+    if( info == NULL || ctx->pk_info != NULL )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
     if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
@@ -151,7 +159,8 @@
     mbedtls_rsa_alt_context *rsa_alt;
     const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
 
-    if( ctx == NULL || ctx->pk_info != NULL )
+    PK_VALIDATE_RET( ctx != NULL );
+    if( ctx->pk_info != NULL )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
     if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
@@ -175,7 +184,9 @@
  */
 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
 {
-    /* null or NONE context can't do anything */
+    /* A context with null pk_info is not set up yet and can't do anything.
+     * For backward compatibility, also accept NULL instead of a context
+     * pointer. */
     if( ctx == NULL || ctx->pk_info == NULL )
         return( 0 );
 
@@ -232,7 +243,12 @@
                const unsigned char *sig, size_t sig_len,
                mbedtls_pk_restart_ctx *rs_ctx )
 {
-    if( ctx == NULL || ctx->pk_info == NULL ||
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+                     hash != NULL );
+    PK_VALIDATE_RET( sig != NULL );
+
+    if( ctx->pk_info == NULL ||
         pk_hashlen_helper( md_alg, &hash_len ) != 0 )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
@@ -285,7 +301,12 @@
                    const unsigned char *hash, size_t hash_len,
                    const unsigned char *sig, size_t sig_len )
 {
-    if( ctx == NULL || ctx->pk_info == NULL )
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+                     hash != NULL );
+    PK_VALIDATE_RET( sig != NULL );
+
+    if( ctx->pk_info == NULL )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
     if( ! mbedtls_pk_can_do( ctx, type ) )
@@ -345,7 +366,12 @@
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
              mbedtls_pk_restart_ctx *rs_ctx )
 {
-    if( ctx == NULL || ctx->pk_info == NULL ||
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+                     hash != NULL );
+    PK_VALIDATE_RET( sig != NULL );
+
+    if( ctx->pk_info == NULL ||
         pk_hashlen_helper( md_alg, &hash_len ) != 0 )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
@@ -399,7 +425,12 @@
                 unsigned char *output, size_t *olen, size_t osize,
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-    if( ctx == NULL || ctx->pk_info == NULL )
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( input != NULL || ilen == 0 );
+    PK_VALIDATE_RET( output != NULL || osize == 0 );
+    PK_VALIDATE_RET( olen != NULL );
+
+    if( ctx->pk_info == NULL )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
     if( ctx->pk_info->decrypt_func == NULL )
@@ -417,7 +448,12 @@
                 unsigned char *output, size_t *olen, size_t osize,
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-    if( ctx == NULL || ctx->pk_info == NULL )
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( input != NULL || ilen == 0 );
+    PK_VALIDATE_RET( output != NULL || osize == 0 );
+    PK_VALIDATE_RET( olen != NULL );
+
+    if( ctx->pk_info == NULL )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
     if( ctx->pk_info->encrypt_func == NULL )
@@ -432,8 +468,11 @@
  */
 int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
 {
-    if( pub == NULL || pub->pk_info == NULL ||
-        prv == NULL || prv->pk_info == NULL ||
+    PK_VALIDATE_RET( pub != NULL );
+    PK_VALIDATE_RET( prv != NULL );
+
+    if( pub->pk_info == NULL ||
+        prv->pk_info == NULL ||
         prv->pk_info->check_pair_func == NULL )
     {
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -458,6 +497,8 @@
  */
 size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
 {
+    /* For backward compatibility, accept NULL or a context that
+     * isn't set up yet, and return a fake value that should be safe. */
     if( ctx == NULL || ctx->pk_info == NULL )
         return( 0 );
 
@@ -469,7 +510,8 @@
  */
 int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
 {
-    if( ctx == NULL || ctx->pk_info == NULL )
+    PK_VALIDATE_RET( ctx != NULL );
+    if( ctx->pk_info == NULL )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
     if( ctx->pk_info->debug_func == NULL )
diff --git a/library/pkcs12.c b/library/pkcs12.c
index 16a15cb..7edf064 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -48,6 +48,8 @@
 #include "mbedtls/des.h"
 #endif
 
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
                                     mbedtls_asn1_buf *salt, int *iterations )
 {
@@ -226,6 +228,8 @@
     return( ret );
 }
 
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
                                 const unsigned char *filler, size_t fill_len )
 {
diff --git a/library/pkcs5.c b/library/pkcs5.c
index f04f0ab..5013343 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -54,22 +54,7 @@
 #define mbedtls_printf printf
 #endif
 
-#if !defined(MBEDTLS_ASN1_PARSE_C)
-int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
-                 const unsigned char *pwd,  size_t pwdlen,
-                 const unsigned char *data, size_t datalen,
-                 unsigned char *output )
-{
-    ((void) pbe_params);
-    ((void) mode);
-    ((void) pwd);
-    ((void) pwdlen);
-    ((void) data);
-    ((void) datalen);
-    ((void) output);
-    return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
-}
-#else
+#if defined(MBEDTLS_ASN1_PARSE_C)
 static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
                                       mbedtls_asn1_buf *salt, int *iterations,
                                       int *keylen, mbedtls_md_type_t *md_type )
diff --git a/library/pkparse.c b/library/pkparse.c
index 86d9fb0..ae210bc 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -61,6 +61,12 @@
 #define mbedtls_free       free
 #endif
 
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if defined(MBEDTLS_FS_IO)
 /*
  * Load all data from a file into a given buffer.
@@ -74,6 +80,10 @@
     FILE *f;
     long size;
 
+    PK_VALIDATE_RET( path != NULL );
+    PK_VALIDATE_RET( buf != NULL );
+    PK_VALIDATE_RET( n != NULL );
+
     if( ( f = fopen( path, "rb" ) ) == NULL )
         return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
 
@@ -124,6 +134,9 @@
     size_t n;
     unsigned char *buf;
 
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( path != NULL );
+
     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
@@ -148,6 +161,9 @@
     size_t n;
     unsigned char *buf;
 
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( path != NULL );
+
     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
@@ -605,6 +621,11 @@
     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
     const mbedtls_pk_info_t *pk_info;
 
+    PK_VALIDATE_RET( p != NULL );
+    PK_VALIDATE_RET( *p != NULL );
+    PK_VALIDATE_RET( end != NULL );
+    PK_VALIDATE_RET( pk != NULL );
+
     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
     {
@@ -1145,16 +1166,22 @@
 {
     int ret;
     const mbedtls_pk_info_t *pk_info;
-
 #if defined(MBEDTLS_PEM_PARSE_C)
     size_t len;
     mbedtls_pem_context pem;
+#endif
 
-    mbedtls_pem_init( &pem );
+    PK_VALIDATE_RET( pk != NULL );
+    if( keylen == 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+    PK_VALIDATE_RET( key != NULL );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+   mbedtls_pem_init( &pem );
 
 #if defined(MBEDTLS_RSA_C)
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( keylen == 0 || key[keylen - 1] != '\0' )
+    if( key[keylen - 1] != '\0' )
         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     else
         ret = mbedtls_pem_read_buffer( &pem,
@@ -1185,7 +1212,7 @@
 
 #if defined(MBEDTLS_ECP_C)
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( keylen == 0 || key[keylen - 1] != '\0' )
+    if( key[keylen - 1] != '\0' )
         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     else
         ret = mbedtls_pem_read_buffer( &pem,
@@ -1215,7 +1242,7 @@
 #endif /* MBEDTLS_ECP_C */
 
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( keylen == 0 || key[keylen - 1] != '\0' )
+    if( key[keylen - 1] != '\0' )
         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     else
         ret = mbedtls_pem_read_buffer( &pem,
@@ -1238,7 +1265,7 @@
 
 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( keylen == 0 || key[keylen - 1] != '\0' )
+    if( key[keylen - 1] != '\0' )
         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     else
         ret = mbedtls_pem_read_buffer( &pem,
@@ -1276,9 +1303,6 @@
     {
         unsigned char *key_copy;
 
-        if( keylen == 0 )
-            return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
-
         if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
             return( MBEDTLS_ERR_PK_ALLOC_FAILED );
 
@@ -1360,11 +1384,18 @@
 #if defined(MBEDTLS_PEM_PARSE_C)
     size_t len;
     mbedtls_pem_context pem;
+#endif
 
+    PK_VALIDATE_RET( ctx != NULL );
+    if( keylen == 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+    PK_VALIDATE_RET( key != NULL || keylen == 0 );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
     mbedtls_pem_init( &pem );
 #if defined(MBEDTLS_RSA_C)
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( keylen == 0 || key[keylen - 1] != '\0' )
+    if( key[keylen - 1] != '\0' )
         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     else
         ret = mbedtls_pem_read_buffer( &pem,
@@ -1395,7 +1426,7 @@
 #endif /* MBEDTLS_RSA_C */
 
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
-    if( keylen == 0 || key[keylen - 1] != '\0' )
+    if( key[keylen - 1] != '\0' )
         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     else
         ret = mbedtls_pem_read_buffer( &pem,
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 8eabd88..8d1da2f 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -30,6 +30,7 @@
 #include "mbedtls/pk.h"
 #include "mbedtls/asn1write.h"
 #include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -54,6 +55,12 @@
 #define mbedtls_free       free
 #endif
 
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if defined(MBEDTLS_RSA_C)
 /*
  *  RSAPublicKey ::= SEQUENCE {
@@ -151,6 +158,11 @@
     int ret;
     size_t len = 0;
 
+    PK_VALIDATE_RET( p != NULL );
+    PK_VALIDATE_RET( *p != NULL );
+    PK_VALIDATE_RET( start != NULL );
+    PK_VALIDATE_RET( key != NULL );
+
 #if defined(MBEDTLS_RSA_C)
     if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
         MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
@@ -173,6 +185,11 @@
     size_t len = 0, par_len = 0, oid_len;
     const char *oid;
 
+    PK_VALIDATE_RET( key != NULL );
+    if( size == 0 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+    PK_VALIDATE_RET( buf != NULL );
+
     c = buf + size;
 
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
@@ -217,9 +234,16 @@
 int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
 {
     int ret;
-    unsigned char *c = buf + size;
+    unsigned char *c;
     size_t len = 0;
 
+    PK_VALIDATE_RET( key != NULL );
+    if( size == 0 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+    PK_VALIDATE_RET( buf != NULL );
+
+    c = buf + size;
+
 #if defined(MBEDTLS_RSA_C)
     if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
     {
@@ -457,6 +481,9 @@
     unsigned char output_buf[PUB_DER_MAX_BYTES];
     size_t olen = 0;
 
+    PK_VALIDATE_RET( key != NULL );
+    PK_VALIDATE_RET( buf != NULL || size == 0 );
+
     if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
                                      sizeof(output_buf) ) ) < 0 )
     {
@@ -480,6 +507,9 @@
     const char *begin, *end;
     size_t olen = 0;
 
+    PK_VALIDATE_RET( key != NULL );
+    PK_VALIDATE_RET( buf != NULL || size == 0 );
+
     if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
         return( ret );
 
diff --git a/library/platform_util.c b/library/platform_util.c
index ca5fe4f..756e226 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -35,6 +35,7 @@
 #endif
 
 #include "mbedtls/platform_util.h"
+#include "mbedtls/platform.h"
 #include "mbedtls/threading.h"
 
 #include <stddef.h>
diff --git a/library/poly1305.c b/library/poly1305.c
index e22d3af..b274119 100644
--- a/library/poly1305.c
+++ b/library/poly1305.c
@@ -49,6 +49,12 @@
 #define inline __inline
 #endif
 
+/* Parameter validation macros */
+#define POLY1305_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
+#define POLY1305_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #define POLY1305_BLOCK_SIZE_BYTES ( 16U )
 
 #define BYTES_TO_U32_LE( data, offset )                           \
@@ -276,27 +282,24 @@
 
 void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
 {
-    if( ctx != NULL )
-    {
-        mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
-    }
+    POLY1305_VALIDATE( ctx != NULL );
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
 }
 
 void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
 {
-    if( ctx != NULL )
-    {
-        mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
-    }
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
 }
 
 int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
                              const unsigned char key[32] )
 {
-    if( ctx == NULL || key == NULL )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
+    POLY1305_VALIDATE_RET( ctx != NULL );
+    POLY1305_VALIDATE_RET( key != NULL );
 
     /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
     ctx->r[0] = BYTES_TO_U32_LE( key, 0 )  & 0x0FFFFFFFU;
@@ -331,16 +334,8 @@
     size_t remaining = ilen;
     size_t queue_free_len;
     size_t nblocks;
-
-    if( ctx == NULL )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
-    else if( ( ilen > 0U ) && ( input == NULL ) )
-    {
-        /* input pointer is allowed to be NULL only if ilen == 0 */
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
+    POLY1305_VALIDATE_RET( ctx != NULL );
+    POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
 
     if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
     {
@@ -398,10 +393,8 @@
 int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
                              unsigned char mac[16] )
 {
-    if( ( ctx == NULL ) || ( mac == NULL ) )
-    {
-        return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    }
+    POLY1305_VALIDATE_RET( ctx != NULL );
+    POLY1305_VALIDATE_RET( mac != NULL );
 
     /* Process any leftover data */
     if( ctx->queue_len > 0U )
@@ -431,6 +424,9 @@
 {
     mbedtls_poly1305_context ctx;
     int ret;
+    POLY1305_VALIDATE_RET( key != NULL );
+    POLY1305_VALIDATE_RET( mac != NULL );
+    POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
 
     mbedtls_poly1305_init( &ctx );
 
diff --git a/library/rsa.c b/library/rsa.c
index 7615e1e..af1a878 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -71,6 +71,12 @@
 
 #if !defined(MBEDTLS_RSA_ALT)
 
+/* Parameter validation macros */
+#define RSA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
+#define RSA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if defined(MBEDTLS_PKCS1_V15)
 /* constant-time buffer comparison */
 static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
@@ -93,6 +99,7 @@
                         const mbedtls_mpi *D, const mbedtls_mpi *E )
 {
     int ret;
+    RSA_VALIDATE_RET( ctx != NULL );
 
     if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
         ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
@@ -117,6 +124,7 @@
                             unsigned char const *E, size_t E_len )
 {
     int ret = 0;
+    RSA_VALIDATE_RET( ctx != NULL );
 
     if( N != NULL )
     {
@@ -240,12 +248,16 @@
 int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
 {
     int ret = 0;
+    int have_N, have_P, have_Q, have_D, have_E;
+    int n_missing, pq_missing, d_missing, is_pub, is_priv;
 
-    const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
-    const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
-    const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
-    const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
-    const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
+    have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
+    have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
+    have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
+    have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
 
     /*
      * Check whether provided parameters are enough
@@ -257,13 +269,13 @@
      *
      */
 
-    const int n_missing  =              have_P &&  have_Q &&  have_D && have_E;
-    const int pq_missing =   have_N && !have_P && !have_Q &&  have_D && have_E;
-    const int d_missing  =              have_P &&  have_Q && !have_D && have_E;
-    const int is_pub     =   have_N && !have_P && !have_Q && !have_D && have_E;
+    n_missing  =              have_P &&  have_Q &&  have_D && have_E;
+    pq_missing =   have_N && !have_P && !have_Q &&  have_D && have_E;
+    d_missing  =              have_P &&  have_Q && !have_D && have_E;
+    is_pub     =   have_N && !have_P && !have_Q && !have_D && have_E;
 
     /* These three alternatives are mutually exclusive */
-    const int is_priv = n_missing || pq_missing || d_missing;
+    is_priv = n_missing || pq_missing || d_missing;
 
     if( !is_priv && !is_pub )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -336,9 +348,11 @@
                             unsigned char *E, size_t E_len )
 {
     int ret = 0;
+    int is_priv;
+    RSA_VALIDATE_RET( ctx != NULL );
 
     /* Check if key is private or public */
-    const int is_priv =
+    is_priv =
         mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
         mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
         mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@@ -379,9 +393,11 @@
                         mbedtls_mpi *D, mbedtls_mpi *E )
 {
     int ret;
+    int is_priv;
+    RSA_VALIDATE_RET( ctx != NULL );
 
     /* Check if key is private or public */
-    int is_priv =
+    is_priv =
         mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
         mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
         mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@@ -421,9 +437,11 @@
                             mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
 {
     int ret;
+    int is_priv;
+    RSA_VALIDATE_RET( ctx != NULL );
 
     /* Check if key is private or public */
-    int is_priv =
+    is_priv =
         mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
         mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
         mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@@ -459,6 +477,10 @@
                int padding,
                int hash_id )
 {
+    RSA_VALIDATE( ctx != NULL );
+    RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
+                  padding == MBEDTLS_RSA_PKCS_V21 );
+
     memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
 
     mbedtls_rsa_set_padding( ctx, padding, hash_id );
@@ -471,8 +493,13 @@
 /*
  * Set padding for an existing RSA context
  */
-void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
+void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+                              int hash_id )
 {
+    RSA_VALIDATE( ctx != NULL );
+    RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
+                  padding == MBEDTLS_RSA_PKCS_V21 );
+
     ctx->padding = padding;
     ctx->hash_id = hash_id;
 }
@@ -503,11 +530,10 @@
     int ret;
     mbedtls_mpi H, G, L;
     int prime_quality = 0;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( f_rng != NULL );
 
-    if( f_rng == NULL || nbits < 128 || exponent < 3 )
-        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
-
-    if( nbits % 2 )
+    if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
     /*
@@ -612,6 +638,8 @@
  */
 int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
 {
+    RSA_VALIDATE_RET( ctx != NULL );
+
     if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
         return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
 
@@ -635,6 +663,8 @@
  */
 int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
 {
+    RSA_VALIDATE_RET( ctx != NULL );
+
     if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
         rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
     {
@@ -664,6 +694,9 @@
 int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
                                 const mbedtls_rsa_context *prv )
 {
+    RSA_VALIDATE_RET( pub != NULL );
+    RSA_VALIDATE_RET( prv != NULL );
+
     if( mbedtls_rsa_check_pubkey( pub )  != 0 ||
         mbedtls_rsa_check_privkey( prv ) != 0 )
     {
@@ -689,6 +722,9 @@
     int ret;
     size_t olen;
     mbedtls_mpi T;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( output != NULL );
 
     if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -831,6 +867,10 @@
      * checked result; should be the same in the end. */
     mbedtls_mpi I, C;
 
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( input  != NULL );
+    RSA_VALIDATE_RET( output != NULL );
+
     if( rsa_check_context( ctx, 1             /* private key checks */,
                                 f_rng != NULL /* blinding y/n       */ ) != 0 )
     {
@@ -1091,6 +1131,13 @@
     const mbedtls_md_info_t *md_info;
     mbedtls_md_context_t md_ctx;
 
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( label_len == 0 || label != NULL );
+
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
@@ -1167,11 +1214,13 @@
     int ret;
     unsigned char *p = output;
 
-    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
-        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
 
-    // We don't check p_rng because it won't be dereferenced here
-    if( f_rng == NULL || input == NULL || output == NULL )
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
     olen = ctx->len;
@@ -1185,6 +1234,9 @@
     *p++ = 0;
     if( mode == MBEDTLS_RSA_PUBLIC )
     {
+        if( f_rng == NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
         *p++ = MBEDTLS_RSA_CRYPT;
 
         while( nb_pad-- > 0 )
@@ -1229,6 +1281,12 @@
                        const unsigned char *input,
                        unsigned char *output )
 {
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+
     switch( ctx->padding )
     {
 #if defined(MBEDTLS_PKCS1_V15)
@@ -1271,6 +1329,14 @@
     const mbedtls_md_info_t *md_info;
     mbedtls_md_context_t md_ctx;
 
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+    RSA_VALIDATE_RET( label_len == 0 || label != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( olen != NULL );
+
     /*
      * Parameters sanity checks
      */
@@ -1387,6 +1453,97 @@
 #endif /* MBEDTLS_PKCS1_V21 */
 
 #if defined(MBEDTLS_PKCS1_V15)
+/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
+ *
+ * \param value     The value to analyze.
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+static unsigned all_or_nothing_int( unsigned value )
+{
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+/** Check whether a size is out of bounds, without branches.
+ *
+ * This is equivalent to `size > max`, but is likely to be compiled to
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param size      Size to check.
+ * \param max       Maximum desired value for \p size.
+ * \return          \c 0 if `size <= max`.
+ * \return          \c 1 if `size > max`.
+ */
+static unsigned size_greater_than( size_t size, size_t max )
+{
+    /* Return the sign bit (1 for negative) of (max - size). */
+    return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
+}
+
+/** Choose between two integer values, without branches.
+ *
+ * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param cond      Condition to test.
+ * \param if1       Value to use if \p cond is nonzero.
+ * \param if0       Value to use if \p cond is zero.
+ * \return          \c if1 if \p cond is nonzero, otherwise \c if0.
+ */
+static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
+{
+    unsigned mask = all_or_nothing_int( cond );
+    return( ( mask & if1 ) | (~mask & if0 ) );
+}
+
+/** Shift some data towards the left inside a buffer without leaking
+ * the length of the data through side channels.
+ *
+ * `mem_move_to_left(start, total, offset)` is functionally equivalent to
+ * ```
+ * memmove(start, start + offset, total - offset);
+ * memset(start + offset, 0, total - offset);
+ * ```
+ * but it strives to use a memory access pattern (and thus total timing)
+ * that does not depend on \p offset. This timing independence comes at
+ * the expense of performance.
+ *
+ * \param start     Pointer to the start of the buffer.
+ * \param total     Total size of the buffer.
+ * \param offset    Offset from which to copy \p total - \p offset bytes.
+ */
+static void mem_move_to_left( void *start,
+                              size_t total,
+                              size_t offset )
+{
+    volatile unsigned char *buf = start;
+    size_t i, n;
+    if( total == 0 )
+        return;
+    for( i = 0; i < total; i++ )
+    {
+        unsigned no_op = size_greater_than( total - offset, i );
+        /* The first `total - offset` passes are a no-op. The last
+         * `offset` passes shift the data one byte to the left and
+         * zero out the last byte. */
+        for( n = 0; n < total - 1; n++ )
+        {
+            unsigned char current = buf[n];
+            unsigned char next = buf[n+1];
+            buf[n] = if_int( no_op, current, next );
+        }
+        buf[total-1] = if_int( no_op, buf[total-1], 0 );
+    }
+}
+
 /*
  * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
  */
@@ -1396,18 +1553,42 @@
                                  int mode, size_t *olen,
                                  const unsigned char *input,
                                  unsigned char *output,
-                                 size_t output_max_len)
+                                 size_t output_max_len )
 {
     int ret;
-    size_t ilen, pad_count = 0, i;
-    unsigned char *p, bad, pad_done = 0;
+    size_t ilen, i, plaintext_max_size;
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    /* The following variables take sensitive values: their value must
+     * not leak into the observable behavior of the function other than
+     * the designated outputs (output, olen, return value). Otherwise
+     * this would open the execution of the function to
+     * side-channel-based variants of the Bleichenbacher padding oracle
+     * attack. Potential side channels include overall timing, memory
+     * access patterns (especially visible to an adversary who has access
+     * to a shared memory cache), and branches (especially visible to
+     * an adversary who has access to a shared code cache or to a shared
+     * branch predictor). */
+    size_t pad_count = 0;
+    unsigned bad = 0;
+    unsigned char pad_done = 0;
+    size_t plaintext_size = 0;
+    unsigned output_too_large;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( olen != NULL );
+
+    ilen = ctx->len;
+    plaintext_max_size = ( output_max_len > ilen - 11 ?
+                           ilen - 11 :
+                           output_max_len );
 
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-    ilen = ctx->len;
-
     if( ilen < 16 || ilen > sizeof( buf ) )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
@@ -1418,63 +1599,109 @@
     if( ret != 0 )
         goto cleanup;
 
-    p = buf;
-    bad = 0;
+    /* Check and get padding length in constant time and constant
+     * memory trace. The first byte must be 0. */
+    bad |= buf[0];
 
-    /*
-     * Check and get padding len in "constant-time"
-     */
-    bad |= *p++; /* First byte must be 0 */
-
-    /* This test does not depend on secret data */
     if( mode == MBEDTLS_RSA_PRIVATE )
     {
-        bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
+        /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
+         * where PS must be at least 8 nonzero bytes. */
+        bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
 
-        /* Get padding len, but always read till end of buffer
-         * (minus one, for the 00 byte) */
-        for( i = 0; i < ilen - 3; i++ )
+        /* Read the whole buffer. Set pad_done to nonzero if we find
+         * the 0x00 byte and remember the padding length in pad_count. */
+        for( i = 2; i < ilen; i++ )
         {
-            pad_done  |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
+            pad_done  |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
             pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
         }
-
-        p += pad_count;
-        bad |= *p++; /* Must be zero */
     }
     else
     {
-        bad |= *p++ ^ MBEDTLS_RSA_SIGN;
+        /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
+         * where PS must be at least 8 bytes with the value 0xFF. */
+        bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
 
-        /* Get padding len, but always read till end of buffer
-         * (minus one, for the 00 byte) */
-        for( i = 0; i < ilen - 3; i++ )
+        /* Read the whole buffer. Set pad_done to nonzero if we find
+         * the 0x00 byte and remember the padding length in pad_count.
+         * If there's a non-0xff byte in the padding, the padding is bad. */
+        for( i = 2; i < ilen; i++ )
         {
-            pad_done |= ( p[i] != 0xFF );
-            pad_count += ( pad_done == 0 );
+            pad_done |= if_int( buf[i], 0, 1 );
+            pad_count += if_int( pad_done, 0, 1 );
+            bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
         }
-
-        p += pad_count;
-        bad |= *p++; /* Must be zero */
     }
 
-    bad |= ( pad_count < 8 );
+    /* If pad_done is still zero, there's no data, only unfinished padding. */
+    bad |= if_int( pad_done, 0, 1 );
 
-    if( bad )
-    {
-        ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
-        goto cleanup;
-    }
+    /* There must be at least 8 bytes of padding. */
+    bad |= size_greater_than( 8, pad_count );
 
-    if( ilen - ( p - buf ) > output_max_len )
-    {
-        ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
-        goto cleanup;
-    }
+    /* If the padding is valid, set plaintext_size to the number of
+     * remaining bytes after stripping the padding. If the padding
+     * is invalid, avoid leaking this fact through the size of the
+     * output: use the maximum message size that fits in the output
+     * buffer. Do it without branches to avoid leaking the padding
+     * validity through timing. RSA keys are small enough that all the
+     * size_t values involved fit in unsigned int. */
+    plaintext_size = if_int( bad,
+                             (unsigned) plaintext_max_size,
+                             (unsigned) ( ilen - pad_count - 3 ) );
 
-    *olen = ilen - (p - buf);
-    memcpy( output, p, *olen );
-    ret = 0;
+    /* Set output_too_large to 0 if the plaintext fits in the output
+     * buffer and to 1 otherwise. */
+    output_too_large = size_greater_than( plaintext_size,
+                                          plaintext_max_size );
+
+    /* Set ret without branches to avoid timing attacks. Return:
+     * - INVALID_PADDING if the padding is bad (bad != 0).
+     * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
+     *   plaintext does not fit in the output buffer.
+     * - 0 if the padding is correct. */
+    ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
+                  if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
+                          0 ) );
+
+    /* If the padding is bad or the plaintext is too large, zero the
+     * data that we're about to copy to the output buffer.
+     * We need to copy the same amount of data
+     * from the same buffer whether the padding is good or not to
+     * avoid leaking the padding validity through overall timing or
+     * through memory or cache access patterns. */
+    bad = all_or_nothing_int( bad | output_too_large );
+    for( i = 11; i < ilen; i++ )
+        buf[i] &= ~bad;
+
+    /* If the plaintext is too large, truncate it to the buffer size.
+     * Copy anyway to avoid revealing the length through timing, because
+     * revealing the length is as bad as revealing the padding validity
+     * for a Bleichenbacher attack. */
+    plaintext_size = if_int( output_too_large,
+                             (unsigned) plaintext_max_size,
+                             (unsigned) plaintext_size );
+
+    /* Move the plaintext to the leftmost position where it can start in
+     * the working buffer, i.e. make it start plaintext_max_size from
+     * the end of the buffer. Do this with a memory access trace that
+     * does not depend on the plaintext size. After this move, the
+     * starting location of the plaintext is no longer sensitive
+     * information. */
+    mem_move_to_left( buf + ilen - plaintext_max_size,
+                      plaintext_max_size,
+                      plaintext_max_size - plaintext_size );
+
+    /* Finally copy the decrypted plaintext plus trailing zeros
+     * into the output buffer. */
+    memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
+
+    /* Report the amount of data we copied to the output buffer. In case
+     * of errors (bad padding or output too large), the value of *olen
+     * when this function returns is not specified. Making it equivalent
+     * to the good case limits the risks of leaking the padding validity. */
+    *olen = plaintext_size;
 
 cleanup:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -1494,6 +1721,13 @@
                        unsigned char *output,
                        size_t output_max_len)
 {
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( olen != NULL );
+
     switch( ctx->padding )
     {
 #if defined(MBEDTLS_PKCS1_V15)
@@ -1535,6 +1769,13 @@
     size_t msb;
     const mbedtls_md_info_t *md_info;
     mbedtls_md_context_t md_ctx;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+    RSA_VALIDATE_RET( sig != NULL );
 
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1782,6 +2023,14 @@
     int ret;
     unsigned char *sig_try = NULL, *verif = NULL;
 
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+    RSA_VALIDATE_RET( sig != NULL );
+
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
@@ -1851,6 +2100,14 @@
                     const unsigned char *hash,
                     unsigned char *sig )
 {
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+    RSA_VALIDATE_RET( sig != NULL );
+
     switch( ctx->padding )
     {
 #if defined(MBEDTLS_PKCS1_V15)
@@ -1897,6 +2154,14 @@
     mbedtls_md_context_t md_ctx;
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
 
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
@@ -2025,7 +2290,16 @@
                            const unsigned char *hash,
                            const unsigned char *sig )
 {
-    mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
+    mbedtls_md_type_t mgf1_hash_id;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
+    mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
                              ? (mbedtls_md_type_t) ctx->hash_id
                              : md_alg;
 
@@ -2051,9 +2325,19 @@
                                  const unsigned char *sig )
 {
     int ret = 0;
-    const size_t sig_len = ctx->len;
+    size_t sig_len;
     unsigned char *encoded = NULL, *encoded_expected = NULL;
 
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
+    sig_len = ctx->len;
+
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
@@ -2123,6 +2407,14 @@
                       const unsigned char *hash,
                       const unsigned char *sig )
 {
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
     switch( ctx->padding )
     {
 #if defined(MBEDTLS_PKCS1_V15)
@@ -2148,6 +2440,8 @@
 int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
 {
     int ret;
+    RSA_VALIDATE_RET( dst != NULL );
+    RSA_VALIDATE_RET( src != NULL );
 
     dst->ver = src->ver;
     dst->len = src->len;
@@ -2187,14 +2481,23 @@
  */
 void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
 {
-    mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
-    mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D  );
-    mbedtls_mpi_free( &ctx->Q  ); mbedtls_mpi_free( &ctx->P  );
-    mbedtls_mpi_free( &ctx->E  ); mbedtls_mpi_free( &ctx->N  );
+    if( ctx == NULL )
+        return;
+
+    mbedtls_mpi_free( &ctx->Vi );
+    mbedtls_mpi_free( &ctx->Vf );
+    mbedtls_mpi_free( &ctx->RN );
+    mbedtls_mpi_free( &ctx->D  );
+    mbedtls_mpi_free( &ctx->Q  );
+    mbedtls_mpi_free( &ctx->P  );
+    mbedtls_mpi_free( &ctx->E  );
+    mbedtls_mpi_free( &ctx->N  );
 
 #if !defined(MBEDTLS_RSA_NO_CRT)
-    mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
-    mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
+    mbedtls_mpi_free( &ctx->RQ );
+    mbedtls_mpi_free( &ctx->RP );
+    mbedtls_mpi_free( &ctx->QP );
+    mbedtls_mpi_free( &ctx->DQ );
     mbedtls_mpi_free( &ctx->DP );
 #endif /* MBEDTLS_RSA_NO_CRT */
 
diff --git a/library/sha1.c b/library/sha1.c
index bab6087..e8d4096 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -46,6 +46,11 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
+#define SHA1_VALIDATE_RET(cond)                             \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA )
+
+#define SHA1_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if !defined(MBEDTLS_SHA1_ALT)
 
 /*
@@ -73,6 +78,8 @@
 
 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
 {
+    SHA1_VALIDATE( ctx != NULL );
+
     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
 }
 
@@ -87,6 +94,9 @@
 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
                          const mbedtls_sha1_context *src )
 {
+    SHA1_VALIDATE( dst != NULL );
+    SHA1_VALIDATE( src != NULL );
+
     *dst = *src;
 }
 
@@ -95,6 +105,8 @@
  */
 int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
 {
+    SHA1_VALIDATE_RET( ctx != NULL );
+
     ctx->total[0] = 0;
     ctx->total[1] = 0;
 
@@ -120,6 +132,9 @@
 {
     uint32_t temp, W[16], A, B, C, D, E;
 
+    SHA1_VALIDATE_RET( ctx != NULL );
+    SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
+
     GET_UINT32_BE( W[ 0], data,  0 );
     GET_UINT32_BE( W[ 1], data,  4 );
     GET_UINT32_BE( W[ 2], data,  8 );
@@ -294,6 +309,9 @@
     size_t fill;
     uint32_t left;
 
+    SHA1_VALIDATE_RET( ctx != NULL );
+    SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
+
     if( ilen == 0 )
         return( 0 );
 
@@ -352,6 +370,9 @@
     uint32_t used;
     uint32_t high, low;
 
+    SHA1_VALIDATE_RET( ctx != NULL );
+    SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
+
     /*
      * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
      */
@@ -420,6 +441,9 @@
     int ret;
     mbedtls_sha1_context ctx;
 
+    SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
+    SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
+
     mbedtls_sha1_init( &ctx );
 
     if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
diff --git a/library/sha256.c b/library/sha256.c
index dbb4a89..8a540ad 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -49,6 +49,10 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
+#define SHA256_VALIDATE_RET(cond)                           \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
+#define SHA256_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if !defined(MBEDTLS_SHA256_ALT)
 
 /*
@@ -76,6 +80,8 @@
 
 void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
 {
+    SHA256_VALIDATE( ctx != NULL );
+
     memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
 }
 
@@ -90,6 +96,9 @@
 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
                            const mbedtls_sha256_context *src )
 {
+    SHA256_VALIDATE( dst != NULL );
+    SHA256_VALIDATE( src != NULL );
+
     *dst = *src;
 }
 
@@ -98,6 +107,9 @@
  */
 int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
 {
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
+
     ctx->total[0] = 0;
     ctx->total[1] = 0;
 
@@ -192,6 +204,9 @@
     uint32_t A[8];
     unsigned int i;
 
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
+
     for( i = 0; i < 8; i++ )
         A[i] = ctx->state[i];
 
@@ -263,6 +278,9 @@
     size_t fill;
     uint32_t left;
 
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
+
     if( ilen == 0 )
         return( 0 );
 
@@ -321,6 +339,9 @@
     uint32_t used;
     uint32_t high, low;
 
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
+
     /*
      * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
      */
@@ -395,6 +416,10 @@
     int ret;
     mbedtls_sha256_context ctx;
 
+    SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
+    SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
+    SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
+
     mbedtls_sha256_init( &ctx );
 
     if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
diff --git a/library/sha512.c b/library/sha512.c
index a9440e8..941ecda 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -55,6 +55,10 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
+#define SHA512_VALIDATE_RET(cond)                           \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
+#define SHA512_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
+
 #if !defined(MBEDTLS_SHA512_ALT)
 
 /*
@@ -90,6 +94,8 @@
 
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
 {
+    SHA512_VALIDATE( ctx != NULL );
+
     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
 }
 
@@ -104,6 +110,9 @@
 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
                            const mbedtls_sha512_context *src )
 {
+    SHA512_VALIDATE( dst != NULL );
+    SHA512_VALIDATE( src != NULL );
+
     *dst = *src;
 }
 
@@ -112,6 +121,9 @@
  */
 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
 {
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+
     ctx->total[0] = 0;
     ctx->total[1] = 0;
 
@@ -209,6 +221,9 @@
     uint64_t temp1, temp2, W[80];
     uint64_t A, B, C, D, E, F, G, H;
 
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
+
 #define  SHR(x,n) (x >> n)
 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
 
@@ -294,6 +309,9 @@
     size_t fill;
     unsigned int left;
 
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
+
     if( ilen == 0 )
         return( 0 );
 
@@ -351,6 +369,9 @@
     unsigned used;
     uint64_t high, low;
 
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
     /*
      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
      */
@@ -427,6 +448,10 @@
     int ret;
     mbedtls_sha512_context ctx;
 
+    SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+    SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
+    SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
     mbedtls_sha512_init( &ctx );
 
     if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index ff576f3..afced7a 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -2027,8 +2027,14 @@
 static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
 {
     const mbedtls_ecp_curve_info *curve_info;
+    mbedtls_ecp_group_id grp_id;
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    grp_id = ssl->handshake->ecdh_ctx.grp.id;
+#else
+    grp_id = ssl->handshake->ecdh_ctx.grp_id;
+#endif
 
-    curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
+    curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id );
     if( curve_info == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
@@ -2038,14 +2044,15 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
 
 #if defined(MBEDTLS_ECP_C)
-    if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
+    if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 )
 #else
     if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
         ssl->handshake->ecdh_ctx.grp.nbits > 521 )
 #endif
         return( -1 );
 
-    MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
+    MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                            MBEDTLS_DEBUG_ECDH_QP );
 
     return( 0 );
 }
@@ -2967,7 +2974,8 @@
             return( ret );
         }
 
-        MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Q );
 
 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
         if( ssl->handshake->ecrs_enabled )
@@ -2994,7 +3002,8 @@
             return( ret );
         }
 
-        MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Z );
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
@@ -3089,7 +3098,8 @@
                 return( ret );
             }
 
-            MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
+            MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                    MBEDTLS_DEBUG_ECDH_Q );
         }
         else
 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 36ca0d6..bc77f80 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3048,8 +3048,8 @@
 
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
 
-        if( ( ret = mbedtls_ecp_group_load( &ssl->handshake->ecdh_ctx.grp,
-                                       (*curve)->grp_id ) ) != 0 )
+        if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx,
+                                        (*curve)->grp_id ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret );
             return( ret );
@@ -3071,7 +3071,8 @@
 
         ssl->out_msglen += len;
 
-        MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Q );
     }
 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
 
@@ -3794,7 +3795,8 @@
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
         }
 
-        MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_QP );
 
         if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
                                       &ssl->handshake->pmslen,
@@ -3806,7 +3808,8 @@
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
         }
 
-        MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z  ", &ssl->handshake->ecdh_ctx.z );
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Z );
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
@@ -3919,7 +3922,8 @@
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
         }
 
-        MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_QP );
 
         if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
                         ciphersuite_info->key_exchange ) ) != 0 )
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 985b7cd..8492c19 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -188,9 +188,9 @@
     if( left < 3 + cert_len )
         return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
 
-    *p++ = (unsigned char)( cert_len >> 16 & 0xFF );
-    *p++ = (unsigned char)( cert_len >>  8 & 0xFF );
-    *p++ = (unsigned char)( cert_len       & 0xFF );
+    *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
+    *p++ = (unsigned char)( ( cert_len >>  8 ) & 0xFF );
+    *p++ = (unsigned char)( ( cert_len       ) & 0xFF );
 
     if( session->peer_cert != NULL )
         memcpy( p, session->peer_cert->raw.p, cert_len );
@@ -215,14 +215,14 @@
     size_t cert_len;
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-    if( p + sizeof( mbedtls_ssl_session ) > end )
+    if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
     memcpy( session, p, sizeof( mbedtls_ssl_session ) );
     p += sizeof( mbedtls_ssl_session );
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
-    if( p + 3 > end )
+    if( 3 > (size_t)( end - p ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
     cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
@@ -236,7 +236,7 @@
     {
         int ret;
 
-        if( p + cert_len > end )
+        if( cert_len > (size_t)( end - p ) )
             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
         session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
@@ -247,7 +247,7 @@
         mbedtls_x509_crt_init( session->peer_cert );
 
         if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
-                                        p, cert_len ) ) != 0 )
+                                                p, cert_len ) ) != 0 )
         {
             mbedtls_x509_crt_free( session->peer_cert );
             mbedtls_free( session->peer_cert );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 82e6525..38690fa 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1333,7 +1333,8 @@
         *(p++) = (unsigned char)( zlen      );
         p += zlen;
 
-        MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Z );
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
@@ -3200,8 +3201,10 @@
         }
     }
 
-    if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
-        hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST &&
+    /* Whenever we send anything different from a
+     * HelloRequest we should be in a handshake - double check. */
+    if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+            hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
         ssl->handshake == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
@@ -3295,8 +3298,8 @@
     /* Either send now, or just save to be sent (and resent) later */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-        ( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
-          hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) )
+        ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+            hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
     {
         if( ( ret = ssl_flight_append( ssl ) ) != 0 )
         {
diff --git a/library/version_features.c b/library/version_features.c
index f1798a7..4c36d3c 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -84,6 +84,9 @@
 #if defined(MBEDTLS_DEPRECATED_REMOVED)
     "MBEDTLS_DEPRECATED_REMOVED",
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
+#if defined(MBEDTLS_CHECK_PARAMS)
+    "MBEDTLS_CHECK_PARAMS",
+#endif /* MBEDTLS_CHECK_PARAMS */
 #if defined(MBEDTLS_TIMING_ALT)
     "MBEDTLS_TIMING_ALT",
 #endif /* MBEDTLS_TIMING_ALT */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 3e505e2..7655834 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -2179,7 +2179,7 @@
     }
 
     /* extra precaution against mistakes in the caller */
-    if( parent == NULL )
+    if( *parent == NULL )
     {
         *parent_is_trusted = 0;
         *signature_is_good = 0;
diff --git a/programs/aes/aescrypt2.c b/programs/aes/aescrypt2.c
index 5725eb0..bdeac3a 100644
--- a/programs/aes/aescrypt2.c
+++ b/programs/aes/aescrypt2.c
@@ -37,6 +37,7 @@
 #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 */
@@ -78,6 +79,19 @@
     return( 0 );
 }
 #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[] )
 {
     int ret = 0;
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index 88b852b..f58e616 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -38,6 +38,7 @@
 #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 */
@@ -80,6 +81,19 @@
     return( 0 );
 }
 #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[] )
 {
     int ret = 1, i, n;
diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c
index bbe8d92..4b7fe37 100644
--- a/programs/hash/generic_sum.c
+++ b/programs/hash/generic_sum.c
@@ -32,6 +32,7 @@
 #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 */
@@ -50,6 +51,19 @@
     return( 0 );
 }
 #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 )
 {
     int ret = mbedtls_md_file( md_info, filename, sum );
diff --git a/programs/hash/hello.c b/programs/hash/hello.c
index 2e8c224..6046f86 100644
--- a/programs/hash/hello.c
+++ b/programs/hash/hello.c
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #define mbedtls_printf       printf
+#define mbedtls_exit         exit
 #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
 #endif
@@ -46,6 +47,19 @@
     return( 0 );
 }
 #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 )
 {
     int i, ret;
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index 3dadf48..1dce31a 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_printf          printf
 #define mbedtls_time_t          time_t
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -70,6 +71,19 @@
     return( 0 );
 }
 #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 )
 {
     FILE *f;
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index 360e355..cca43ca 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_printf          printf
 #define mbedtls_time_t          time_t
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -68,6 +69,18 @@
  */
 #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 )
 {
     int ret = 1;
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index c4e2c39..a797e60 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_printf          printf
 #define mbedtls_time_t          time_t
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -70,6 +71,19 @@
     return( 0 );
 }
 #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 )
 {
     FILE *f;
diff --git a/programs/pkey/ecdh_curve25519.c b/programs/pkey/ecdh_curve25519.c
index 5db0408..9267c7e 100644
--- a/programs/pkey/ecdh_curve25519.c
+++ b/programs/pkey/ecdh_curve25519.c
@@ -31,16 +31,17 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
 
-#if !defined(MBEDTLS_ECDH_C) || \
+#if !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) || \
     !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
 int main( void )
 {
-    mbedtls_printf( "MBEDTLS_ECDH_C and/or "
+    mbedtls_printf( "MBEDTLS_ECDH_C and/or MBEDTLS_ECDH_LEGACY_CONTEXT and/or "
                     "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
                     "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
                     "not defined\n" );
@@ -52,6 +53,18 @@
 #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[] )
 {
     int ret = 1;
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index c653df9..4471a20 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -99,6 +100,18 @@
 #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[] )
 {
     int ret = 1;
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index f01bf5f..35fc149 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -135,6 +136,19 @@
     return( 0 );
 }
 #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
  */
@@ -322,7 +336,8 @@
     mbedtls_printf( "\n  . Generating the private key ..." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_pk_setup( &key, mbedtls_pk_info_from_type( opt.type ) ) ) != 0 )
+    if( ( ret = mbedtls_pk_setup( &key,
+            mbedtls_pk_info_from_type( (mbedtls_pk_type_t) opt.type ) ) ) != 0 )
     {
         mbedtls_printf( " failed\n  !  mbedtls_pk_setup returned -0x%04x", -ret );
         goto exit;
@@ -344,7 +359,8 @@
 #if defined(MBEDTLS_ECP_C)
     if( opt.type == MBEDTLS_PK_ECKEY )
     {
-        ret = mbedtls_ecp_gen_key( opt.ec_curve, mbedtls_pk_ec( key ),
+        ret = mbedtls_ecp_gen_key( (mbedtls_ecp_group_id) opt.ec_curve,
+                                   mbedtls_pk_ec( key ),
                                    mbedtls_ctr_drbg_random, &ctr_drbg );
         if( ret != 0 )
         {
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index 027b95f..0bd61e4 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -73,6 +74,19 @@
     return( 0 );
 }
 #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 13602c2..500e258 100644
--- a/programs/pkey/key_app_writer.c
+++ b/programs/pkey/key_app_writer.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -87,13 +88,28 @@
     USAGE_OUT                                           \
     "\n"
 
-#if !defined(MBEDTLS_PK_WRITE_C) || !defined(MBEDTLS_FS_IO)
+#if !defined(MBEDTLS_PK_PARSE_C) || \
+    !defined(MBEDTLS_PK_WRITE_C) || \
+    !defined(MBEDTLS_FS_IO)
 int main( void )
 {
-    mbedtls_printf( "MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO not defined.\n" );
+    mbedtls_printf( "MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO not defined.\n" );
     return( 0 );
 }
 #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
  */
@@ -433,4 +449,4 @@
 
     return( exit_code );
 }
-#endif /* MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO */
+#endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO */
diff --git a/programs/pkey/mpi_demo.c b/programs/pkey/mpi_demo.c
index 365bdc4..80573c0 100644
--- a/programs/pkey/mpi_demo.c
+++ b/programs/pkey/mpi_demo.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -48,6 +49,19 @@
     return( 0 );
 }
 #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 )
 {
     int ret = 1;
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index 1d8c959..978f39e 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -59,6 +60,19 @@
     return( 0 );
 }
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c
index 22dedba..806c59a 100644
--- a/programs/pkey/pk_encrypt.c
+++ b/programs/pkey/pk_encrypt.c
@@ -32,6 +32,7 @@
 #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 */
@@ -59,6 +60,19 @@
     return( 0 );
 }
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 7ec4675..7354082 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_snprintf        snprintf
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -59,6 +60,18 @@
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/pk_verify.c b/programs/pkey/pk_verify.c
index 3c7709f..9fcf029 100644
--- a/programs/pkey/pk_verify.c
+++ b/programs/pkey/pk_verify.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_snprintf        snprintf
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -55,6 +56,18 @@
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index 0a252d2..dc8a920 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -58,6 +58,19 @@
     return( 0 );
 }
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index 411657a..e9effe8 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -58,6 +58,19 @@
     return( 0 );
 }
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c
index 3359e14..81867ee 100644
--- a/programs/pkey/rsa_genkey.c
+++ b/programs/pkey/rsa_genkey.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -62,6 +63,19 @@
     return( 0 );
 }
 #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 )
 {
     int ret = 1;
diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c
index b16fe5d..f014872 100644
--- a/programs/pkey/rsa_sign.c
+++ b/programs/pkey/rsa_sign.c
@@ -33,6 +33,7 @@
 #define mbedtls_fprintf         fprintf
 #define mbedtls_printf          printf
 #define mbedtls_snprintf        snprintf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -55,6 +56,18 @@
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index b0b0f7e..ad03a91 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_snprintf        snprintf
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -60,6 +61,18 @@
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c
index 6f88345..5d1c085 100644
--- a/programs/pkey/rsa_verify.c
+++ b/programs/pkey/rsa_verify.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_printf          printf
 #define mbedtls_snprintf        snprintf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -54,6 +55,18 @@
 #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[] )
 {
     FILE *f;
diff --git a/programs/pkey/rsa_verify_pss.c b/programs/pkey/rsa_verify_pss.c
index 7c9c68f..34122ca 100644
--- a/programs/pkey/rsa_verify_pss.c
+++ b/programs/pkey/rsa_verify_pss.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_snprintf        snprintf
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -59,6 +60,18 @@
 #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[] )
 {
     FILE *f;
diff --git a/programs/random/gen_entropy.c b/programs/random/gen_entropy.c
index a1eb386..3b350ed 100644
--- a/programs/random/gen_entropy.c
+++ b/programs/random/gen_entropy.c
@@ -32,6 +32,7 @@
 #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 */
@@ -49,6 +50,19 @@
     return( 0 );
 }
 #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[] )
 {
     FILE *f;
diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c
index 5ade946..a50402f 100644
--- a/programs/random/gen_random_ctr_drbg.c
+++ b/programs/random/gen_random_ctr_drbg.c
@@ -32,6 +32,7 @@
 #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 */
@@ -52,6 +53,19 @@
     return( 0 );
 }
 #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[] )
 {
     FILE *f;
diff --git a/programs/random/gen_random_havege.c b/programs/random/gen_random_havege.c
index 3fb3f01..ef888ff 100644
--- a/programs/random/gen_random_havege.c
+++ b/programs/random/gen_random_havege.c
@@ -32,6 +32,7 @@
 #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 */
@@ -50,6 +51,19 @@
     return( 0 );
 }
 #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[] )
 {
     FILE *f;
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index c29ab34..90db06c 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -31,6 +31,9 @@
 #include <stdio.h>
 #define mbedtls_printf     printf
 #define mbedtls_fprintf    fprintf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif
 
 #if !defined(MBEDTLS_SSL_CLI_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||    \
@@ -79,6 +82,18 @@
 
 #define DEBUG_LEVEL 0
 
+#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 void my_debug( void *ctx, int level,
                       const char *file, int line,
                       const char *str )
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index b4ad6b5..dd21fbf 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -32,6 +32,9 @@
 #define mbedtls_printf     printf
 #define mbedtls_fprintf    fprintf
 #define mbedtls_time_t     time_t
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif
 
 /* Uncomment out the following line to default to IPv4 and disable IPv6 */
@@ -88,6 +91,18 @@
 #define READ_TIMEOUT_MS 10000   /* 5 seconds */
 #define DEBUG_LEVEL 0
 
+#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 void my_debug( void *ctx, int level,
                       const char *file, int line,
                       const char *str )
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 290455e..ff36128 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -26,6 +26,17 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf          printf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
+#endif
+
 /*
  * We're creating and connecting the socket "manually" rather than using the
  * NET module, in order to avoid the overhead of getaddrinfo() which tends to
@@ -44,13 +55,6 @@
     !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_CLI_C) || \
     !defined(UNIX)
 
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif
-
 int main( void )
 {
     mbedtls_printf( "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_ENTROPY_C and/or "
@@ -60,12 +64,6 @@
 }
 #else
 
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#endif
-
 #include <string.h>
 
 #include "mbedtls/net_sockets.h"
@@ -168,6 +166,18 @@
     ssl_write_failed,
 };
 
+#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 )
 {
     int ret = exit_ok;
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index bf7c013..646909f 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -34,6 +34,7 @@
 #define mbedtls_time_t          time_t
 #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 */
@@ -70,6 +71,18 @@
 
 #define DEBUG_LEVEL 1
 
+#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 void my_debug( void *ctx, int level,
                       const char *file, int line,
                       const char *str )
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 15c778d..1ce10b6 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -35,6 +35,9 @@
 #define mbedtls_printf     printf
 #define mbedtls_fprintf    fprintf
 #define mbedtls_snprintf   snprintf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif
 
 #if !defined(MBEDTLS_ENTROPY_C) || \
@@ -314,6 +317,18 @@
 #define ALPN_LIST_SIZE  10
 #define CURVE_LIST_SIZE 20
 
+#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/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 1c3a806..b6f1cc4 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -33,6 +33,7 @@
 #define mbedtls_fprintf         fprintf
 #define mbedtls_printf          printf
 #define mbedtls_time_t          time_t
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -86,6 +87,18 @@
 
 #define DEBUG_LEVEL 0
 
+#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 void my_debug( void *ctx, int level,
                       const char *file, int line,
                       const char *str )
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 16cedfe..bbe4c70 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -39,6 +39,7 @@
 #define mbedtls_time_t          time_t
 #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 */
@@ -141,6 +142,18 @@
     "    force_ciphersuite=<name>    default: all enabled\n"\
     " acceptable ciphersuite names:\n"
 
+#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/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index 9a05ad8..b502695 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -30,9 +30,13 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #define mbedtls_snprintf   snprintf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif
 
 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_CERTS_C) ||            \
@@ -77,6 +81,18 @@
 #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
+
 #define HTTP_RESPONSE \
     "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
     "<h2>mbed TLS Test Server</h2>\r\n" \
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index dcdafbb..1852b2b 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -34,6 +34,9 @@
 #define mbedtls_time_t     time_t
 #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
 
 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_CERTS_C) ||    \
@@ -80,6 +83,18 @@
 
 #define DEBUG_LEVEL 0
 
+#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 void my_debug( void *ctx, int level,
                       const char *file, int line,
                       const char *str )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index efda65d..d23a55e 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -36,6 +36,9 @@
 #define mbedtls_calloc    calloc
 #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
 
 #if !defined(MBEDTLS_ENTROPY_C) || \
@@ -426,6 +429,18 @@
     (out_be)[(i) + 7] = (unsigned char)( ( (in_le) >> 0  ) & 0xFF );    \
 }
 
+#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/test/benchmark.c b/programs/test/benchmark.c
index e7d29c3..8d7ecf7 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -29,10 +29,14 @@
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
+#include <stdlib.h>
 #define mbedtls_exit       exit
 #define mbedtls_printf     printf
 #define mbedtls_snprintf   snprintf
 #define mbedtls_free       free
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif
 
 #if !defined(MBEDTLS_TIMING_C)
@@ -254,6 +258,18 @@
          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[] )
 {
     int i;
@@ -862,7 +878,7 @@
     }
 #endif
 
-#if defined(MBEDTLS_ECDH_C)
+#if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     if( todo.ecdh )
     {
         mbedtls_ecdh_context ecdh;
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index f923a43..9d3ea7e 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -77,6 +77,18 @@
 #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 )
 {
     int ret;
diff --git a/programs/test/ssl_cert_test.c b/programs/test/ssl_cert_test.c
index fd3526f..fdf30ef 100644
--- a/programs/test/ssl_cert_test.c
+++ b/programs/test/ssl_cert_test.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #define mbedtls_snprintf        snprintf
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -81,6 +82,18 @@
     "cert_digest.key"
 };
 
+#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 )
 {
     int ret = 1, i;
diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c
index 73a9fb5..0cc9d06 100644
--- a/programs/util/pem2der.c
+++ b/programs/util/pem2der.c
@@ -33,6 +33,7 @@
 #define mbedtls_free            free
 #define mbedtls_calloc          calloc
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -63,6 +64,19 @@
     return( 0 );
 }
 #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/programs/x509/cert_app.c b/programs/x509/cert_app.c
index c57ecca..626c4d1 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -34,6 +34,7 @@
 #define mbedtls_time_t          time_t
 #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 */
@@ -99,6 +100,18 @@
     "    permissive=%%d       default: 0 (disabled)\n"  \
     "\n"
 
+#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/programs/x509/cert_req.c b/programs/x509/cert_req.c
index 8c56287..027050c 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -100,6 +101,17 @@
     "                          SHA384, SHA512\n"       \
     "\n"
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+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/x509/cert_write.c b/programs/x509/cert_write.c
index 3842ebc..cd39108 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -153,6 +154,18 @@
     "                            object_signing_ca\n"     \
     "\n"
 
+#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/programs/x509/crl_app.c b/programs/x509/crl_app.c
index f831683..a951570 100644
--- a/programs/x509/crl_app.c
+++ b/programs/x509/crl_app.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -60,6 +61,18 @@
     "    filename=%%s         default: crl.pem\n"      \
     "\n"
 
+#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/programs/x509/req_app.c b/programs/x509/req_app.c
index 0f20c85..04ad119 100644
--- a/programs/x509/req_app.c
+++ b/programs/x509/req_app.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_printf          printf
+#define mbedtls_exit            exit
 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
@@ -60,6 +61,18 @@
     "    filename=%%s         default: cert.req\n"      \
     "\n"
 
+#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/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 58126be..eae1f57 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -72,6 +72,7 @@
 add_test_suite(cipher cipher.chachapoly)
 add_test_suite(cipher cipher.des)
 add_test_suite(cipher cipher.gcm)
+add_test_suite(cipher cipher.misc)
 add_test_suite(cipher cipher.null)
 add_test_suite(cipher cipher.padding)
 add_test_suite(cmac)
@@ -92,6 +93,7 @@
 add_test_suite(gcm gcm.aes192_de)
 add_test_suite(gcm gcm.aes256_de)
 add_test_suite(gcm gcm.camellia)
+add_test_suite(gcm gcm.misc)
 add_test_suite(hkdf)
 add_test_suite(hmac_drbg hmac_drbg.misc)
 add_test_suite(hmac_drbg hmac_drbg.no_reseed)
diff --git a/tests/git-scripts/pre-push.sh b/tests/git-scripts/pre-push.sh
index 7407f44..86edf5a 100755
--- a/tests/git-scripts/pre-push.sh
+++ b/tests/git-scripts/pre-push.sh
@@ -46,3 +46,4 @@
 run_test ./tests/scripts/check-names.sh
 run_test ./tests/scripts/check-generated-files.sh
 run_test ./tests/scripts/check-files.py
+run_test ./tests/scripts/doxygen.sh
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index d63a948..3bac81a 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -685,6 +685,30 @@
     make TEST_CPP=1
 }
 
+component_test_check_params_without_platform () {
+    msg "build+test: MBEDTLS_CHECK_PARAMS without MBEDTLS_PLATFORM_C"
+    scripts/config.pl full # includes CHECK_PARAMS
+    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
+    scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT
+    scripts/config.pl unset MBEDTLS_PLATFORM_FPRINTF_ALT
+    scripts/config.pl unset MBEDTLS_PLATFORM_MEMORY
+    scripts/config.pl unset MBEDTLS_PLATFORM_PRINTF_ALT
+    scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT
+    scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
+    scripts/config.pl unset MBEDTLS_PLATFORM_C
+    make CC=gcc CFLAGS='-Werror -O1' all test
+}
+
+component_test_check_params_silent () {
+    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
+    sed -i 's/.*\(#define MBEDTLS_PARAM_FAILED( cond )\).*/\1/' "$CONFIG_H"
+    make CC=gcc CFLAGS='-Werror -O1' all test
+}
+
 component_test_no_platform () {
     # Full configuration build, without platform support, file IO and net sockets.
     # This should catch missing mbedtls_printf definitions, and by disabling file
@@ -1159,6 +1183,8 @@
     run_component component_test_depends_pkalgs
     run_component component_build_key_exchanges
     run_component component_build_default_make_gcc_and_cxx
+    run_component component_test_check_params_without_platform
+    run_component component_test_check_params_silent
     run_component component_test_no_platform
     run_component component_build_no_std_function
     run_component component_build_no_ssl_srv
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index b405871..28fc687 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -76,7 +76,7 @@
 cd tests
 
 # Step 2a - Unit Tests
-perl scripts/run-test-suites.pl -v |tee unit-test-$TEST_OUTPUT
+perl scripts/run-test-suites.pl -v 2 |tee unit-test-$TEST_OUTPUT
 echo
 
 # Step 2b - System Tests
@@ -93,6 +93,9 @@
     GNUTLS_SERV="$GNUTLS_LEGACY_SERV"                               \
     sh compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR' | \
     tee -a compat-test-$TEST_OUTPUT
+OPENSSL_CMD="$OPENSSL_NEXT"                     \
+    sh compat.sh -e '^$' -f 'ARIA\|CHACHA' |    \
+    tee -a compat-test-$TEST_OUTPUT
 echo
 
 # Step 3 - Process the coverage report
diff --git a/tests/scripts/check-files.py b/tests/scripts/check-files.py
index ed67872..005a077 100755
--- a/tests/scripts/check-files.py
+++ b/tests/scripts/check-files.py
@@ -43,11 +43,14 @@
             for i, line in enumerate(iter(f.readline, b"")):
                 self.check_file_line(filepath, line, i + 1)
 
+    def record_issue(self, filepath, line_number):
+        if filepath not in self.files_with_issues.keys():
+            self.files_with_issues[filepath] = []
+        self.files_with_issues[filepath].append(line_number)
+
     def check_file_line(self, filepath, line, line_number):
         if self.issue_with_line(line):
-            if filepath not in self.files_with_issues.keys():
-                self.files_with_issues[filepath] = []
-            self.files_with_issues[filepath].append(line_number)
+            self.record_issue(filepath, line_number)
 
     def output_file_issues(self, logger):
         if self.files_with_issues.values():
@@ -132,13 +135,36 @@
         return b"\t" in line
 
 
+class MergeArtifactIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "Merge artifact:"
+
+    def issue_with_line(self, filepath, line):
+        # Detect leftover git conflict markers.
+        if line.startswith(b'<<<<<<< ') or line.startswith(b'>>>>>>> '):
+            return True
+        if line.startswith(b'||||||| '): # from merge.conflictStyle=diff3
+            return True
+        if line.rstrip(b'\r\n') == b'=======' and \
+           not filepath.endswith('.md'):
+            return True
+        return False
+
+    def check_file_line(self, filepath, line, line_number):
+        if self.issue_with_line(filepath, line):
+            self.record_issue(filepath, line_number)
+
 class TodoIssueTracker(IssueTracker):
 
     def __init__(self):
         super().__init__()
         self.heading = "TODO present:"
         self.files_exemptions = [
-            __file__, "benchmark.c", "pull_request_template.md"
+            os.path.basename(__file__),
+            "benchmark.c",
+            "pull_request_template.md",
         ]
 
     def issue_with_line(self, line):
@@ -167,6 +193,7 @@
             LineEndingIssueTracker(),
             TrailingWhitespaceIssueTracker(),
             TabIssueTracker(),
+            MergeArtifactIssueTracker(),
             TodoIssueTracker(),
         ]
 
diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py
index 8e8a89b..f9e88cf 100755
--- a/tests/scripts/mbedtls_test.py
+++ b/tests/scripts/mbedtls_test.py
@@ -185,7 +185,7 @@
         binary_path = self.get_config_item('image_path')
         script_dir = os.path.split(os.path.abspath(__file__))[0]
         suite_name = os.path.splitext(os.path.basename(binary_path))[0]
-        data_file = ".".join((suite_name, 'data'))
+        data_file = ".".join((suite_name, 'datax'))
         data_file = os.path.join(script_dir, '..', 'mbedtls',
                                  suite_name, data_file)
         if os.path.exists(data_file):
diff --git a/tests/scripts/run-test-suites.pl b/tests/scripts/run-test-suites.pl
index 6fe6abf..d0d4046 100755
--- a/tests/scripts/run-test-suites.pl
+++ b/tests/scripts/run-test-suites.pl
@@ -24,14 +24,10 @@
 use utf8;
 use open qw(:std utf8);
 
-use constant FALSE => 0;
-use constant TRUE => 1;
+use Getopt::Long;
 
-my $verbose;
-my $switch = shift;
-if ( defined($switch) && ( $switch eq "-v" || $switch eq "--verbose" ) ) {
-    $verbose = TRUE;
-}
+my $verbose = 0;
+GetOptions( "verbose|v:1" => \$verbose );
 
 # All test suites = executable files, excluding source files, debug
 # and profiling information, etc. We can't just grep {! /\./} because
@@ -50,10 +46,20 @@
     $suite_cases_failed, $suite_cases_skipped, $total_cases_passed,
     $total_cases_failed, $total_cases_skipped );
 
+sub pad_print_center {
+    my( $width, $padchar, $string ) = @_;
+    my $padlen = ( $width - length( $string ) - 2 ) / 2;
+    print $padchar x( $padlen ), " $string ", $padchar x( $padlen ), "\n";
+}
+
 for my $suite (@suites)
 {
     print "$suite ", "." x ( 72 - length($suite) - 2 - 4 ), " ";
-    my $result = `$prefix$suite`;
+    my $command = "$prefix$suite";
+    if( $verbose ) {
+        $command .= ' -v';
+    }
+    my $result = `$command`;
 
     $suite_cases_passed = () = $result =~ /.. PASS/g;
     $suite_cases_failed = () = $result =~ /.. FAILED/g;
@@ -61,15 +67,25 @@
 
     if( $result =~ /PASSED/ ) {
         print "PASS\n";
+        if( $verbose > 2 ) {
+            pad_print_center( 72, '-', "Begin $suite" );
+            print $result;
+            pad_print_center( 72, '-', "End $suite" );
+        }
     } else {
         $failed_suites++;
         print "FAIL\n";
+        if( $verbose ) {
+            pad_print_center( 72, '-', "Begin $suite" );
+            print $result;
+            pad_print_center( 72, '-', "End $suite" );
+        }
     }
 
     my ($passed, $tests, $skipped) = $result =~ /([0-9]*) \/ ([0-9]*) tests.*?([0-9]*) skipped/;
     $total_tests_run += $tests - $skipped;
 
-    if ( $verbose ) {
+    if( $verbose > 1 ) {
         print "(test cases passed:", $suite_cases_passed,
                 " failed:", $suite_cases_failed,
                 " skipped:", $suite_cases_skipped,
@@ -87,7 +103,7 @@
 print $failed_suites ? "FAILED" : "PASSED";
 printf " (%d suites, %d tests run)\n", scalar @suites, $total_tests_run;
 
-if ( $verbose ) {
+if( $verbose > 1 ) {
     print "  test cases passed :", $total_cases_passed, "\n";
     print "             failed :", $total_cases_failed, "\n";
     print "            skipped :", $total_cases_skipped, "\n";
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index ce9aee2..335f59d 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -7306,6 +7306,11 @@
             -s "Extra-header:" \
             -c "Extra-header:"
 
+# The next two test are disabled because they tend to trigger a bug in the
+# version of GnuTLS that's currently installed on our CI. The bug occurs when
+# different fragments of the same handshake message are received out-of-order
+# by GnuTLS and results in a timeout. It's been fixed in GnuTLS 3.5.2.
+skip_next_test
 requires_gnutls
 client_needs_more_time 8
 not_with_valgrind # risk of non-mbedtls peer timing out
@@ -7317,6 +7322,7 @@
             -s "Extra-header:" \
             -c "Extra-header:"
 
+skip_next_test
 requires_gnutls
 client_needs_more_time 8
 not_with_valgrind # risk of non-mbedtls peer timing out
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 32b1b79..2e227f0 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -23,6 +23,11 @@
 #include "mbedtls/memory_buffer_alloc.h"
 #endif
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+#include "mbedtls/platform_util.h"
+#include <setjmp.h>
+#endif
+
 #ifdef _MSC_VER
 #include <basetsd.h>
 typedef UINT8 uint8_t;
@@ -65,19 +70,143 @@
 #define DISPATCH_UNSUPPORTED_SUITE      -5  /* Test suite not supported by the
                                                build */
 
+typedef enum
+{
+    PARAMFAIL_TESTSTATE_IDLE = 0,           /* No parameter failure call test */
+    PARAMFAIL_TESTSTATE_PENDING,            /* Test call to the parameter failure
+                                             * is pending */
+    PARAMFAIL_TESTSTATE_CALLED              /* The test call to the parameter
+                                             * failure function has been made */
+} paramfail_test_state_t;
+
 
 /*----------------------------------------------------------------------------*/
 /* Macros */
 
-#define TEST_ASSERT( TEST )                         \
-    do {                                            \
-        if( ! (TEST) )                              \
-        {                                           \
-            test_fail( #TEST, __LINE__, __FILE__ ); \
-            goto exit;                              \
-        }                                           \
+/**
+ * \brief   This macro tests the expression passed to it as a test step or
+ *          individual test in a test case.
+ *
+ *          It allows a library function to return a value and return an error
+ *          code that can be tested.
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAILED(), will be assumed to be a test
+ *          failure.
+ *
+ *          This macro is not suitable for negative parameter validation tests,
+ *          as it assumes the test step will not create an error.
+ *
+ * \param   TEST    The test expression to be tested.
+ */
+#define TEST_ASSERT( TEST )                                 \
+    do {                                                    \
+       if( ! (TEST) )                                       \
+       {                                                    \
+          test_fail( #TEST, __LINE__, __FILE__ );           \
+          goto exit;                                        \
+       }                                                    \
     } while( 0 )
 
+#if defined(MBEDTLS_CHECK_PARAMS) && !defined(MBEDTLS_PARAM_FAILED_ALT)
+/**
+ * \brief   This macro tests the statement passed to it as a test step or
+ *          individual test in a test case. The macro assumes the test will fail
+ *          and will generate an error.
+ *
+ *          It allows a library function to return a value and tests the return
+ *          code on return to confirm the given error code was returned.
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the
+ *          expected failure, and the test will pass.
+ *
+ *          This macro is intended for negative parameter validation tests,
+ *          where the failing function may return an error value or call
+ *          MBEDTLS_PARAM_FAILED() to indicate the error.
+ *
+ * \param   PARAM_ERROR_VALUE   The expected error code.
+ *
+ * \param   TEST                The test expression to be tested.
+ */
+#define TEST_INVALID_PARAM_RET( PARAM_ERR_VALUE, TEST )                     \
+    do {                                                                    \
+        test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_PENDING;       \
+        if( (TEST) != (PARAM_ERR_VALUE) ||                                  \
+            test_info.paramfail_test_state != PARAMFAIL_TESTSTATE_CALLED )  \
+        {                                                                   \
+            test_fail( #TEST, __LINE__, __FILE__ );                         \
+            goto exit;                                                      \
+        }                                                                   \
+   } while( 0 )
+
+/**
+ * \brief   This macro tests the statement passed to it as a test step or
+ *          individual test in a test case. The macro assumes the test will fail
+ *          and will generate an error.
+ *
+ *          It assumes the library function under test cannot return a value and
+ *          assumes errors can only be indicated byt calls to
+ *          MBEDTLS_PARAM_FAILED().
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the
+ *          expected failure. If MBEDTLS_CHECK_PARAMS is not enabled, no test
+ *          can be made.
+ *
+ *          This macro is intended for negative parameter validation tests,
+ *          where the failing function can only return an error by calling
+ *          MBEDTLS_PARAM_FAILED() to indicate the error.
+ *
+ * \param   TEST                The test expression to be tested.
+ */
+#define TEST_INVALID_PARAM( TEST )                                          \
+    do {                                                                    \
+        memcpy(jmp_tmp, param_fail_jmp, sizeof(jmp_buf));                   \
+        if( setjmp( param_fail_jmp ) == 0 )                                 \
+        {                                                                   \
+            TEST;                                                           \
+            test_fail( #TEST, __LINE__, __FILE__ );                         \
+            goto exit;                                                      \
+        }                                                                   \
+        memcpy(param_fail_jmp, jmp_tmp, sizeof(jmp_buf));                   \
+    } while( 0 )
+#endif /* MBEDTLS_CHECK_PARAMS && !MBEDTLS_PARAM_FAILED_ALT */
+
+/**
+ * \brief   This macro tests the statement passed to it as a test step or
+ *          individual test in a test case. The macro assumes the test will not fail.
+ *
+ *          It assumes the library function under test cannot return a value and
+ *          assumes errors can only be indicated by calls to
+ *          MBEDTLS_PARAM_FAILED().
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the
+ *          expected failure. If MBEDTLS_CHECK_PARAMS is not enabled, no test
+ *          can be made.
+ *
+ *          This macro is intended to test that functions returning void
+ *          accept all of the parameter values they're supposed to accept - eg
+ *          that they don't call MBEDTLS_PARAM_FAILED() when a parameter
+ *          that's allowed to be NULL happens to be NULL.
+ *
+ *          Note: for functions that return something other that void,
+ *          checking that they accept all the parameters they're supposed to
+ *          accept is best done by using TEST_ASSERT() and checking the return
+ *          value as well.
+ *
+ *          Note: this macro is available even when #MBEDTLS_CHECK_PARAMS is
+ *          disabled, as it makes sense to check that the functions accept all
+ *          legal values even if this option is disabled - only in that case,
+ *          the test is more about whether the function segfaults than about
+ *          whether it invokes MBEDTLS_PARAM_FAILED().
+ *
+ * \param   TEST                The test expression to be tested.
+ */
+#define TEST_VALID_PARAM( TEST )                                    \
+    TEST_ASSERT( ( TEST, 1 ) );
+
 #define assert(a) if( !( a ) )                                      \
 {                                                                   \
     mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n",   \
@@ -112,9 +241,9 @@
 /*----------------------------------------------------------------------------*/
 /* Global variables */
 
-
 static struct
 {
+    paramfail_test_state_t paramfail_test_state;
     int failed;
     const char *test;
     const char *filename;
@@ -126,6 +255,11 @@
 mbedtls_platform_context platform_ctx;
 #endif
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+jmp_buf param_fail_jmp;
+jmp_buf jmp_tmp;
+#endif
+
 /*----------------------------------------------------------------------------*/
 /* Helper flags for complex dependencies */
 
@@ -143,6 +277,15 @@
 
 /*----------------------------------------------------------------------------*/
 /* Helper Functions */
+
+static void test_fail( const char *test, int line_no, const char* filename )
+{
+    test_info.failed = 1;
+    test_info.test = test;
+    test_info.line_no = line_no;
+    test_info.filename = filename;
+}
+
 static int platform_setup()
 {
     int ret = 0;
@@ -159,6 +302,30 @@
 #endif /* MBEDTLS_PLATFORM_C */
 }
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+void mbedtls_param_failed( const char *failure_condition,
+                           const char *file,
+                           int line )
+{
+    /* If we are testing the callback function...  */
+    if( test_info.paramfail_test_state == PARAMFAIL_TESTSTATE_PENDING )
+    {
+        test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_CALLED;
+    }
+    else
+    {
+        /* ...else we treat this as an error */
+
+        /* Record the location of the failure, but not as a failure yet, in case
+         * it was part of the test */
+        test_fail( failure_condition, line, file );
+        test_info.failed = 0;
+
+        longjmp( param_fail_jmp, 1 );
+    }
+}
+#endif
+
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 static int redirect_output( FILE** out_stream, const char* path )
 {
@@ -447,25 +614,17 @@
     return( 0 );
 }
 
-static void test_fail( const char *test, int line_no, const char* filename )
-{
-    test_info.failed = 1;
-    test_info.test = test;
-    test_info.line_no = line_no;
-    test_info.filename = filename;
-}
-
 int hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len )
 {
     int ret = 0;
     uint32_t i = 0;
 
-    if ( a_len != b_len )
+    if( a_len != b_len )
         return( -1 );
 
     for( i = 0; i < a_len; i++ )
     {
-        if ( a[i] != b[i] )
+        if( a[i] != b[i] )
         {
             ret = -1;
             break;
@@ -473,4 +632,3 @@
     }
     return ret;
 }
-
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index b354af4..3c43032 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -546,6 +546,7 @@
             if( unmet_dep_count == 0 )
             {
                 test_info.failed = 0;
+                test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_IDLE;
 
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
                 /* Suppress all output from the library unless we're verbose
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 2ba919c..ca4783d 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -134,9 +134,39 @@
 #line $line_no "suites/main_test.function"
 };
 
+/**
+ * \brief        Execute the test function.
+ *
+ *               This is a wrapper function around the test function execution
+ *               to allow the setjmp() call used to catch any calls to the
+ *               parameter failure callback, to be used. Calls to setjmp()
+ *               can invalidate the state of any local auto variables.
+ *
+ * \param fp     Function pointer to the test function
+ * \param params Parameters to pass
+ *
+ */
+void execute_function_ptr(TestWrapper_t fp, void **params)
+{
+#if defined(MBEDTLS_CHECK_PARAMS)
+    if ( setjmp( param_fail_jmp ) == 0 )
+    {
+        fp( params );
+    }
+    else
+    {
+        /* Unexpected parameter validation error */
+        test_info.failed = 1;
+    }
+
+    memset( param_fail_jmp, 0, sizeof(jmp_buf) );
+#else
+    fp( params );
+#endif
+}
 
 /**
- * \brief       Dispatches test functions based on function index.
+ * \brief        Dispatches test functions based on function index.
  *
  * \param exp_id    Test function index.
  *
@@ -153,7 +183,7 @@
     {
         fp = test_funcs[func_idx];
         if ( fp )
-            fp( params );
+            execute_function_ptr(fp, params);
         else
             ret = DISPATCH_UNSUPPORTED_SUITE;
     }
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index a797e69..da8c1e9 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -15,8 +15,8 @@
     mbedtls_aes_context ctx;
 
     memset(output, 0x00, 100);
-    mbedtls_aes_init( &ctx );
 
+    mbedtls_aes_init( &ctx );
 
     TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == setkey_result );
     if( setkey_result == 0 )
@@ -39,8 +39,8 @@
     mbedtls_aes_context ctx;
 
     memset(output, 0x00, 100);
-    mbedtls_aes_init( &ctx );
 
+    mbedtls_aes_init( &ctx );
 
     TEST_ASSERT( mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 ) == setkey_result );
     if( setkey_result == 0 )
@@ -64,8 +64,8 @@
     mbedtls_aes_context ctx;
 
     memset(output, 0x00, 100);
-    mbedtls_aes_init( &ctx );
 
+    mbedtls_aes_init( &ctx );
 
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
@@ -91,7 +91,6 @@
     memset(output, 0x00, 100);
     mbedtls_aes_init( &ctx );
 
-
     mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0)
@@ -195,8 +194,8 @@
 void aes_crypt_xts_size( int size, int retval )
 {
     mbedtls_aes_xts_context ctx;
-    const unsigned char *src = NULL;
-    unsigned char *output = NULL;
+    const unsigned char src[16] = { 0 };
+    unsigned char output[16];
     unsigned char data_unit[16];
     size_t length = size;
 
@@ -204,10 +203,8 @@
     memset( data_unit, 0x00, sizeof( data_unit ) );
 
 
-    /* Note that this function will most likely crash on failure, as NULL
-     * parameters will be used. In the passing case, the length check in
-     * mbedtls_aes_crypt_xts() will prevent any accesses to parameters by
-     * exiting the function early. */
+    /* Valid pointers are passed for builds with MBEDTLS_CHECK_PARAMS, as
+     * otherwise we wouldn't get to the size check we're interested in. */
     TEST_ASSERT( mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, length, data_unit, src, output ) == retval );
 }
 /* END_CASE */
@@ -216,7 +213,7 @@
 void aes_crypt_xts_keysize( int size, int retval )
 {
     mbedtls_aes_xts_context ctx;
-    const unsigned char *key = NULL;
+    const unsigned char key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
     size_t key_len = size;
 
     mbedtls_aes_xts_init( &ctx );
@@ -372,6 +369,259 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void aes_check_params( )
+{
+    mbedtls_aes_context aes_ctx;
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    mbedtls_aes_xts_context xts_ctx;
+#endif
+    const unsigned char key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+    const unsigned char in[16] = { 0 };
+    unsigned char out[16];
+    size_t size;
+    const int valid_mode = MBEDTLS_AES_ENCRYPT;
+    const int invalid_mode = 42;
+
+    TEST_INVALID_PARAM( mbedtls_aes_init( NULL ) );
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    TEST_INVALID_PARAM( mbedtls_aes_xts_init( NULL ) );
+#endif
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_enc( NULL, key, 128 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_enc( &aes_ctx, NULL, 128 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_dec( NULL, key, 128 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_dec( &aes_ctx, NULL, 128 ) );
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_xts_setkey_enc( NULL, key, 128 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_xts_setkey_enc( &xts_ctx, NULL, 128 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_xts_setkey_dec( NULL, key, 128 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_xts_setkey_dec( &xts_ctx, NULL, 128 ) );
+#endif
+
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ecb( NULL,
+                                                   valid_mode, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ecb( &aes_ctx,
+                                                   invalid_mode, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ecb( &aes_ctx,
+                                                   valid_mode, NULL, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ecb( &aes_ctx,
+                                                   valid_mode, in, NULL ) );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cbc( NULL,
+                                                   valid_mode, 16,
+                                                   out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cbc( &aes_ctx,
+                                                   invalid_mode, 16,
+                                                   out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cbc( &aes_ctx,
+                                                   valid_mode, 16,
+                                                   NULL, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cbc( &aes_ctx,
+                                                   valid_mode, 16,
+                                                   out, NULL, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cbc( &aes_ctx,
+                                                   valid_mode, 16,
+                                                   out, in, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_xts( NULL,
+                                                   valid_mode, 16,
+                                                   in, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_xts( &xts_ctx,
+                                                   invalid_mode, 16,
+                                                   in, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_xts( &xts_ctx,
+                                                   valid_mode, 16,
+                                                   NULL, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_xts( &xts_ctx,
+                                                   valid_mode, 16,
+                                                   in, NULL, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_xts( &xts_ctx,
+                                                   valid_mode, 16,
+                                                   in, in, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb128( NULL,
+                                                      valid_mode, 16,
+                                                      &size, out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb128( &aes_ctx,
+                                                      invalid_mode, 16,
+                                                      &size, out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb128( &aes_ctx,
+                                                      valid_mode, 16,
+                                                      NULL, out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb128( &aes_ctx,
+                                                      valid_mode, 16,
+                                                      &size, NULL, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb128( &aes_ctx,
+                                                      valid_mode, 16,
+                                                      &size, out, NULL, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb128( &aes_ctx,
+                                                      valid_mode, 16,
+                                                      &size, out, in, NULL ) );
+
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb8( NULL,
+                                                    valid_mode, 16,
+                                                    out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb8( &aes_ctx,
+                                                    invalid_mode, 16,
+                                                    out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb8( &aes_ctx,
+                                                    valid_mode, 16,
+                                                    NULL, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb8( &aes_ctx,
+                                                    valid_mode, 16,
+                                                    out, NULL, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_cfb8( &aes_ctx,
+                                                    valid_mode, 16,
+                                                    out, in, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ofb( NULL, 16,
+                                                   &size, out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ofb( &aes_ctx, 16,
+                                                   NULL, out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ofb( &aes_ctx, 16,
+                                                   &size, NULL, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ofb( &aes_ctx, 16,
+                                                   &size, out, NULL, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ofb( &aes_ctx, 16,
+                                                   &size, out, in, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ctr( NULL, 16, &size, out,
+                                                   out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ctr( &aes_ctx, 16, NULL, out,
+                                                   out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ctr( &aes_ctx, 16, &size, NULL,
+                                                   out, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ctr( &aes_ctx, 16, &size, out,
+                                                   NULL, in, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ctr( &aes_ctx, 16, &size, out,
+                                                   out, NULL, out ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_crypt_ctr( &aes_ctx, 16, &size, out,
+                                                   out, in, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aes_misc_params( )
+{
+#if defined(MBEDTLS_CIPHER_MODE_CBC) || \
+    defined(MBEDTLS_CIPHER_MODE_XTS) || \
+    defined(MBEDTLS_CIPHER_MODE_CFB) || \
+    defined(MBEDTLS_CIPHER_MODE_OFB)
+    mbedtls_aes_context aes_ctx;
+    const unsigned char in[16] = { 0 };
+    unsigned char out[16];
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    mbedtls_aes_xts_context xts_ctx;
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB) || \
+    defined(MBEDTLS_CIPHER_MODE_OFB)
+    size_t size;
+#endif
+
+    /* These calls accept NULL */
+    TEST_VALID_PARAM( mbedtls_aes_free( NULL ) );
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    TEST_VALID_PARAM( mbedtls_aes_xts_free( NULL ) );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    TEST_ASSERT( mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+                                        15,
+                                        out, in, out )
+                 == MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+    TEST_ASSERT( mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+                                        17,
+                                        out, in, out )
+                 == MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    TEST_ASSERT( mbedtls_aes_crypt_xts( &xts_ctx, MBEDTLS_AES_ENCRYPT,
+                                        15,
+                                        in, in, out )
+                 == MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+    TEST_ASSERT( mbedtls_aes_crypt_xts( &xts_ctx, MBEDTLS_AES_ENCRYPT,
+                                        (1 << 24) + 1,
+                                        in, in, out )
+                 == MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    size = 16;
+    TEST_ASSERT( mbedtls_aes_crypt_cfb128( &aes_ctx, MBEDTLS_AES_ENCRYPT, 16,
+                                           &size, out, in, out )
+                 == MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    size = 16;
+    TEST_ASSERT( mbedtls_aes_crypt_ofb( &aes_ctx, 16, &size, out, in, out )
+                 == MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+#endif
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void aes_selftest(  )
 {
diff --git a/tests/suites/test_suite_aes.rest.data b/tests/suites/test_suite_aes.rest.data
index bbb222f..6a76b43 100644
--- a/tests/suites/test_suite_aes.rest.data
+++ b/tests/suites/test_suite_aes.rest.data
@@ -10,6 +10,12 @@
 AES-256-CBC Decrypt (Invalid input length)
 aes_decrypt_cbc:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"623a52fcea5d443e48d9181ab32c74":"":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
 
+AES - Optional Parameter Validation (MBEDTLS_CHECK_PARAMS)
+aes_check_params:
+
+AES - Mandatory Parameter Validation and Valid Parameters
+aes_misc_params:
+
 AES Selftest
 depends_on:MBEDTLS_SELF_TEST
 aes_selftest:
diff --git a/tests/suites/test_suite_aria.data b/tests/suites/test_suite_aria.data
index 8cb2d2a..2da0b30 100644
--- a/tests/suites/test_suite_aria.data
+++ b/tests/suites/test_suite_aria.data
@@ -1,3 +1,9 @@
+ARIA - Valid parameters
+aria_valid_param:
+
+ARIA - Invalid parameters
+aria_invalid_param:
+
 ARIA-128-ECB Encrypt - RFC 5794
 aria_encrypt_ecb:"000102030405060708090a0b0c0d0e0f":"00112233445566778899aabbccddeeff":"d718fbd6ab644c739da95f3be6451778":0
 
diff --git a/tests/suites/test_suite_aria.function b/tests/suites/test_suite_aria.function
index 4e39078..7e35f15 100644
--- a/tests/suites/test_suite_aria.function
+++ b/tests/suites/test_suite_aria.function
@@ -17,6 +17,195 @@
  */
 
 /* BEGIN_CASE */
+void aria_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_aria_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void aria_invalid_param( )
+{
+    mbedtls_aria_context ctx;
+    unsigned char key[128 / 8] = { 0 };
+    unsigned char input[MBEDTLS_ARIA_BLOCKSIZE] = { 0 };
+    unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] = { 0 };
+    unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE] = { 0 };
+    size_t iv_off = 0;
+
+    ((void) iv_off);
+    ((void) iv);
+
+    TEST_INVALID_PARAM( mbedtls_aria_init( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_setkey_enc( NULL, key,
+                                                     sizeof( key ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_setkey_enc( &ctx, NULL,
+                                                     sizeof( key ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_setkey_dec( NULL, key,
+                                                     sizeof( key ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_setkey_dec( &ctx, NULL,
+                                                     sizeof( key ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ecb( NULL, input, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ecb( &ctx, NULL, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ecb( &ctx, input, NULL ) );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cbc( NULL,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cbc( &ctx,
+                                                    42 /* invalid mode */,
+                                                    sizeof( input ),
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cbc( &ctx,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    NULL,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cbc( &ctx,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    iv,
+                                                    NULL,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cbc( &ctx,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    iv,
+                                                    input,
+                                                    NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cfb128( NULL,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cfb128( &ctx,
+                                                    42, /* invalid mode */
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cfb128( &ctx,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    NULL,
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cfb128( &ctx,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    NULL,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cfb128( &ctx,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    NULL,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_cfb128( &ctx,
+                                                    MBEDTLS_ARIA_ENCRYPT,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    input,
+                                                    NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ctr( NULL,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ctr( &ctx,
+                                                    sizeof( input ),
+                                                    NULL,
+                                                    iv,
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ctr( &ctx,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    NULL,
+                                                    iv,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ctr( &ctx,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    NULL,
+                                                    input,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ctr( &ctx,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    iv,
+                                                    NULL,
+                                                    output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
+                            mbedtls_aria_crypt_ctr( &ctx,
+                                                    sizeof( input ),
+                                                    &iv_off,
+                                                    iv,
+                                                    iv,
+                                                    input,
+                                                    NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+exit:
+    return;
+
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void aria_encrypt_ecb( char *hex_key_string, char *hex_src_string,
                        char *hex_dst_string, int setkey_result )
 {
diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function
index aae44a8..57a9741 100644
--- a/tests/suites/test_suite_asn1write.function
+++ b/tests/suites/test_suite_asn1write.function
@@ -78,7 +78,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_ASN1PARSE_C */
 void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
                              int result )
 {
diff --git a/tests/suites/test_suite_blowfish.data b/tests/suites/test_suite_blowfish.data
index 1ba311f..fd172d3 100644
--- a/tests/suites/test_suite_blowfish.data
+++ b/tests/suites/test_suite_blowfish.data
@@ -1,3 +1,9 @@
+BLOWFISH - Valid parameters
+blowfish_valid_param:
+
+BLOWFISH - Invalid parameters
+blowfish_invalid_param:
+
 BLOWFISH-ECB Encrypt SSLeay reference #1
 blowfish_encrypt_ecb:"0000000000000000":"0000000000000000":"4ef997456198dd78":0
 
@@ -203,13 +209,13 @@
 blowfish_decrypt_ecb:"fedcba9876543210":"6b5c5a9c5d9e0a5a":"ffffffffffffffff":0
 
 BLOWFISH-SETKEY Setkey SSLeay reference #1
-blowfish_encrypt_ecb:"f0":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
+blowfish_encrypt_ecb:"f0":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA
 
 BLOWFISH-SETKEY Setkey SSLeay reference #2
-blowfish_encrypt_ecb:"f0e1":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
+blowfish_encrypt_ecb:"f0e1":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA
 
 BLOWFISH-SETKEY Setkey SSLeay reference #3
-blowfish_encrypt_ecb:"f0e1d2":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
+blowfish_encrypt_ecb:"f0e1d2":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA
 
 BLOWFISH-SETKEY Setkey SSLeay reference #4
 blowfish_encrypt_ecb:"f0e1d2c3":"fedcba9876543210":"be1e639408640f05":0
@@ -281,7 +287,7 @@
 blowfish_encrypt_ecb:"f0e1d2c3b4a5968778695a4b3c2d1e0f00112233445566778899aabbccddeeff0123456789abcdef0102030405060708090a0b0c0d0e0fff":"fedcba9876543210":"2fb3ab7f0ee91b69":0
 
 BLOWFISH-SETKEY Setkey 456 bits
-blowfish_encrypt_ecb:"f0e1d2c3b4a5968778695a4b3c2d1e0f00112233445566778899aabbccddeeff0123456789abcdef0102030405060708090a0b0c0d0e0fffff":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
+blowfish_encrypt_ecb:"f0e1d2c3b4a5968778695a4b3c2d1e0f00112233445566778899aabbccddeeff0123456789abcdef0102030405060708090a0b0c0d0e0fffff":"fedcba9876543210":"":MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA
 
 BLOWFISH-CBC Encrypt
 blowfish_encrypt_cbc:"0123456789ABCDEFF0E1D2C3B4A59687":"FEDCBA9876543210":"37363534333231204E6F77206973207468652074696D6520666F722000000000":"6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc":0
diff --git a/tests/suites/test_suite_blowfish.function b/tests/suites/test_suite_blowfish.function
index 189e23d..7a93cd1 100644
--- a/tests/suites/test_suite_blowfish.function
+++ b/tests/suites/test_suite_blowfish.function
@@ -8,6 +8,164 @@
  */
 
 /* BEGIN_CASE */
+void blowfish_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_blowfish_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void blowfish_invalid_param( )
+{
+    mbedtls_blowfish_context ctx;
+    unsigned char buf[16] = { 0 };
+    size_t const valid_keylength = sizeof( buf ) * 8;
+    size_t valid_mode = MBEDTLS_BLOWFISH_ENCRYPT;
+    size_t invalid_mode = 42;
+    size_t off;
+    ((void) off);
+
+    TEST_INVALID_PARAM( mbedtls_blowfish_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_blowfish_free( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_setkey( NULL,
+                                                     buf,
+                                                     valid_keylength ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_setkey( &ctx,
+                                                     NULL,
+                                                     valid_keylength ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ecb( NULL,
+                                                     valid_mode,
+                                                     buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ecb( &ctx,
+                                                        invalid_mode,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ecb( &ctx,
+                                                        valid_mode,
+                                                        NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ecb( &ctx,
+                                                        valid_mode,
+                                                        buf, NULL ) );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cbc( NULL,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        buf, buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cbc( &ctx,
+                                                        invalid_mode,
+                                                        sizeof( buf ),
+                                                        buf, buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cbc( &ctx,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        NULL, buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cbc( &ctx,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        buf, NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cbc( &ctx,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        buf, buf, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cfb64( NULL,
+                                                          valid_mode,
+                                                          sizeof( buf ),
+                                                          &off, buf,
+                                                          buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cfb64( &ctx,
+                                                          invalid_mode,
+                                                          sizeof( buf ),
+                                                          &off, buf,
+                                                          buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cfb64( &ctx,
+                                                          valid_mode,
+                                                          sizeof( buf ),
+                                                          NULL, buf,
+                                                          buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cfb64( &ctx,
+                                                          valid_mode,
+                                                          sizeof( buf ),
+                                                          &off, NULL,
+                                                          buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cfb64( &ctx,
+                                                          valid_mode,
+                                                          sizeof( buf ),
+                                                          &off, buf,
+                                                          NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_cfb64( &ctx,
+                                                          valid_mode,
+                                                          sizeof( buf ),
+                                                          &off, buf,
+                                                          buf, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ctr( NULL,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, buf,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        NULL,
+                                                        buf, buf,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        NULL, buf,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, NULL,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, buf,
+                                                        NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA,
+                            mbedtls_blowfish_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, buf,
+                                                        buf, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void blowfish_encrypt_ecb( data_t * key_str, data_t * src_str,
                            data_t * hex_dst_string, int setkey_result )
 {
diff --git a/tests/suites/test_suite_camellia.data b/tests/suites/test_suite_camellia.data
index 1429838..671d570 100644
--- a/tests/suites/test_suite_camellia.data
+++ b/tests/suites/test_suite_camellia.data
@@ -1,3 +1,9 @@
+Camellia - Valid parameters
+camellia_valid_param:
+
+Camellia - Invalid parameters
+camellia_invalid_param:
+
 Camellia-128-ECB Encrypt RFC3713 #1
 camellia_encrypt_ecb:"0123456789abcdeffedcba9876543210":"0123456789abcdeffedcba9876543210":"67673138549669730857065648eabe43":0
 
@@ -185,10 +191,10 @@
 camellia_decrypt_cfb128:"603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4":"555FC3F34BDD2D54C62D9E3BF338C1C4":"F69F2445DF4F9B17AD2B417BE66C3710":"5953ADCE14DB8C7F39F1BD39F359BFFA"
 
 Camellia-ECB Encrypt (Invalid key length)
-camellia_encrypt_ecb:"0123456789abcdeffedcba98765432":"0123456789abcdeffedcba9876543210":"67673138549669730857065648eabe43":MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
+camellia_encrypt_ecb:"0123456789abcdeffedcba98765432":"0123456789abcdeffedcba9876543210":"67673138549669730857065648eabe43":MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA
 
 Camellia-ECB Decrypt (Invalid key length)
-camellia_decrypt_ecb:"0123456789abcdeffedcba98765432":"0123456789abcdeffedcba9876543210":"67673138549669730857065648eabe43":MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
+camellia_decrypt_ecb:"0123456789abcdeffedcba98765432":"0123456789abcdeffedcba9876543210":"67673138549669730857065648eabe43":MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA
 
 Camellia-256-CBC Encrypt (Invalid input length)
 camellia_encrypt_cbc:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"ffffffffffffffe000000000000000":"":MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
diff --git a/tests/suites/test_suite_camellia.function b/tests/suites/test_suite_camellia.function
index d09a610..9408348 100644
--- a/tests/suites/test_suite_camellia.function
+++ b/tests/suites/test_suite_camellia.function
@@ -8,6 +8,172 @@
  */
 
 /* BEGIN_CASE */
+void camellia_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_camellia_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void camellia_invalid_param( )
+{
+    mbedtls_camellia_context ctx;
+    unsigned char buf[16] = { 0 };
+    const size_t valid_keybits   = 128;
+    const int invalid_mode = 42;
+    const int valid_mode = MBEDTLS_CAMELLIA_ENCRYPT;
+    size_t off;
+    ((void) off);
+
+    TEST_INVALID_PARAM( mbedtls_camellia_init( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_setkey_enc( NULL,
+                                                         buf,
+                                                         valid_keybits ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_setkey_enc( &ctx,
+                                                         NULL,
+                                                         valid_keybits ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_setkey_dec( NULL,
+                                                         buf,
+                                                         valid_keybits ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_setkey_dec( &ctx,
+                                                         NULL,
+                                                         valid_keybits ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ecb( NULL,
+                                                        valid_mode,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ecb( &ctx,
+                                                        invalid_mode,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ecb( &ctx,
+                                                        valid_mode,
+                                                        NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ecb( &ctx,
+                                                        valid_mode,
+                                                        buf, NULL ) );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cbc( NULL,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        buf, buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cbc( &ctx,
+                                                        invalid_mode,
+                                                        sizeof( buf ),
+                                                        buf, buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cbc( &ctx,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        NULL, buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cbc( &ctx,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        buf, NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cbc( &ctx,
+                                                        valid_mode,
+                                                        sizeof( buf ),
+                                                        buf, buf, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cfb128( NULL,
+                                                           valid_mode,
+                                                           sizeof( buf ),
+                                                           &off, buf,
+                                                           buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cfb128( &ctx,
+                                                           invalid_mode,
+                                                           sizeof( buf ),
+                                                           &off, buf,
+                                                           buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cfb128( &ctx,
+                                                           valid_mode,
+                                                           sizeof( buf ),
+                                                           NULL, buf,
+                                                           buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cfb128( &ctx,
+                                                           valid_mode,
+                                                           sizeof( buf ),
+                                                           &off, NULL,
+                                                           buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cfb128( &ctx,
+                                                           valid_mode,
+                                                           sizeof( buf ),
+                                                           &off, buf,
+                                                           NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_cfb128( &ctx,
+                                                           valid_mode,
+                                                           sizeof( buf ),
+                                                           &off, buf,
+                                                           buf, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ctr( NULL,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, buf,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        NULL,
+                                                        buf, buf,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        NULL, buf,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, NULL,
+                                                        buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, buf,
+                                                        NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA,
+                            mbedtls_camellia_crypt_ctr( &ctx,
+                                                        sizeof( buf ),
+                                                        &off,
+                                                        buf, buf,
+                                                        buf, NULL ) );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void camellia_encrypt_ecb( data_t * key_str, data_t * src_str,
                            data_t * hex_dst_string, int setkey_result )
 {
diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data
index a2d8778..819b3b7 100644
--- a/tests/suites/test_suite_ccm.data
+++ b/tests/suites/test_suite_ccm.data
@@ -1,6 +1,12 @@
 CCM self test
 mbedtls_ccm_self_test:
 
+CCM - Invalid parameters
+ccm_invalid_param:
+
+CCM - Valid parameters
+ccm_valid_param:
+
 CCM init #1 AES-128: OK
 depends_on:MBEDTLS_AES_C
 mbedtls_ccm_setkey:MBEDTLS_CIPHER_ID_AES:128:0
diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function
index 9951ca1..16f9f8e 100644
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -326,3 +326,216 @@
     mbedtls_ccm_free( &ctx );
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void ccm_invalid_param( )
+{
+    struct mbedtls_ccm_context ctx;
+    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+    mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
+    int valid_len = sizeof(valid_buffer);
+    int valid_bitlen = valid_len * 8;
+
+    mbedtls_ccm_init( &ctx );
+
+    /* mbedtls_ccm_init() */
+    TEST_INVALID_PARAM( mbedtls_ccm_init( NULL ) );
+
+    /* mbedtls_ccm_setkey() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_setkey( NULL, valid_cipher, valid_buffer, valid_bitlen ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_setkey( &ctx, valid_cipher, NULL, valid_bitlen ) );
+
+    /* mbedtls_ccm_encrypt_and_tag() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_encrypt_and_tag( NULL, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, valid_buffer,
+                                     valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_encrypt_and_tag( &ctx, valid_len,
+                                     NULL, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, valid_buffer,
+                                     valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_encrypt_and_tag( &ctx, valid_len,
+                                     valid_buffer, valid_len,
+                                     NULL, valid_len,
+                                     valid_buffer, valid_buffer,
+                                     valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_encrypt_and_tag( &ctx, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, valid_len,
+                                     NULL, valid_buffer,
+                                     valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_encrypt_and_tag( &ctx, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, NULL,
+                                     valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_encrypt_and_tag( &ctx, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, valid_len,
+                                     valid_buffer, valid_buffer,
+                                     NULL, valid_len ) );
+
+    /* mbedtls_ccm_star_encrypt_and_tag() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_encrypt_and_tag( NULL, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, valid_buffer,
+                                          valid_buffer, valid_len) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len,
+                                          NULL, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, valid_buffer,
+                                          valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len,
+                                          valid_buffer, valid_len,
+                                          NULL, valid_len,
+                                          valid_buffer, valid_buffer,
+                                          valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, valid_len,
+                                          NULL, valid_buffer,
+                                          valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, NULL,
+                                          valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, valid_len,
+                                          valid_buffer, valid_buffer,
+                                          NULL, valid_len ) );
+
+    /* mbedtls_ccm_auth_decrypt() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_auth_decrypt( NULL, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_buffer,
+                                  valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_auth_decrypt( &ctx, valid_len,
+                                  NULL, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_buffer,
+                                  valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  NULL, valid_len,
+                                  valid_buffer, valid_buffer,
+                                  valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  NULL, valid_buffer,
+                                  valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, NULL,
+                                  valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_buffer,
+                                  NULL, valid_len ) );
+
+    /* mbedtls_ccm_star_auth_decrypt() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_auth_decrypt( NULL, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, valid_buffer,
+                                       valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_auth_decrypt( &ctx, valid_len,
+                                       NULL, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, valid_buffer,
+                                       valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_auth_decrypt( &ctx, valid_len,
+                                       valid_buffer, valid_len,
+                                       NULL, valid_len,
+                                       valid_buffer, valid_buffer,
+                                       valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_auth_decrypt( &ctx, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, valid_len,
+                                       NULL, valid_buffer,
+                                       valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_auth_decrypt( &ctx, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, NULL,
+                                       valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CCM_BAD_INPUT,
+        mbedtls_ccm_star_auth_decrypt( &ctx, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, valid_len,
+                                       valid_buffer, valid_buffer,
+                                       NULL, valid_len ) );
+
+exit:
+    mbedtls_ccm_free( &ctx );
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void ccm_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_ccm_free( NULL ) );
+exit:
+    return;
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function
index 669d91e..49b389c 100644
--- a/tests/suites/test_suite_chacha20.function
+++ b/tests/suites/test_suite_chacha20.function
@@ -82,7 +82,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
 void chacha20_bad_params()
 {
     unsigned char key[32];
@@ -93,42 +93,38 @@
     size_t len = sizeof( src );
     mbedtls_chacha20_context ctx;
 
-    mbedtls_chacha20_init( NULL );
-    mbedtls_chacha20_free( NULL );
+    TEST_INVALID_PARAM( mbedtls_chacha20_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_chacha20_free( NULL ) );
 
-    mbedtls_chacha20_init( &ctx );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_setkey( NULL, key ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_setkey( &ctx, NULL ) );
 
-    TEST_ASSERT( mbedtls_chacha20_setkey( NULL, key )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_setkey( &ctx, NULL )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_starts( NULL, nonce, counter ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_starts( &ctx, NULL, counter ) );
 
-    TEST_ASSERT( mbedtls_chacha20_starts( NULL, nonce, counter )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_starts( &ctx, NULL, counter )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_update( NULL, 0, src, dst ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_update( &ctx, len, NULL, dst ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_update( &ctx, len, src, NULL ) );
 
-    TEST_ASSERT( mbedtls_chacha20_update( NULL, 0, src, dst )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_update( &ctx, len, NULL, dst )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_update( &ctx, len, src, NULL )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_update( &ctx, 0, NULL, NULL )
-                 == 0 );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_crypt( NULL, nonce, counter, 0, src, dst ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_crypt( key, NULL, counter, 0, src, dst ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_crypt( key, nonce, counter, len, NULL, dst ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
+                            mbedtls_chacha20_crypt( key, nonce, counter, len, src, NULL ) );
 
-    mbedtls_chacha20_free( &ctx );
+exit:
+    return;
 
-    TEST_ASSERT( mbedtls_chacha20_crypt( NULL, nonce, counter, 0, src, dst )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_crypt( key, NULL, counter, 0, src, dst )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_crypt( key, nonce, counter, len, NULL, dst )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_crypt( key, nonce, counter, len, src, NULL )
-                 == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chacha20_crypt( key, nonce, counter, 0, NULL, NULL )
-                 == 0 );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function
index 95dfd8a..8e56bf6 100644
--- a/tests/suites/test_suite_chachapoly.function
+++ b/tests/suites/test_suite_chachapoly.function
@@ -118,7 +118,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
 void chachapoly_bad_params()
 {
     unsigned char key[32];
@@ -138,124 +138,114 @@
     memset( output, 0x00, sizeof( output ) );
     memset( mac,    0x00, sizeof( mac ) );
 
-    mbedtls_chachapoly_init( NULL );
-    mbedtls_chachapoly_free( NULL );
+    TEST_INVALID_PARAM( mbedtls_chachapoly_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_chachapoly_free( NULL ) );
 
-    mbedtls_chachapoly_init( &ctx );
+    /* setkey */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_setkey( NULL, key ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_setkey( &ctx, NULL ) );
 
-    TEST_ASSERT( mbedtls_chachapoly_setkey( NULL, key )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( NULL,
+    /* encrypt_and_tag */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_encrypt_and_tag( NULL,
                                       0, nonce,
                                       aad, 0,
-                                      input, output, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                      input, output, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
                                       0, NULL,
                                       aad, 0,
-                                      input, output, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                      input, output, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
                                       0, nonce,
                                       NULL, aad_len,
-                                      input, output, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                      input, output, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
                                       input_len, nonce,
                                       aad, 0,
-                                      NULL, output, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                      NULL, output, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
                                       input_len, nonce,
                                       aad, 0,
-                                      input, NULL, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                      input, NULL, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_encrypt_and_tag( &ctx,
                                       0, nonce,
                                       aad, 0,
-                                      input, output, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+                                      input, output, NULL ) );
 
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( NULL,
+    /* auth_decrypt */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_auth_decrypt( NULL,
                                            0, nonce,
                                            aad, 0,
-                                           mac, input, output )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx,
+                                           mac, input, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_auth_decrypt( &ctx,
                                            0, NULL,
                                            aad, 0,
-                                           mac, input, output )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx,
+                                           mac, input, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_auth_decrypt( &ctx,
                                            0, nonce,
                                            NULL, aad_len,
-                                           mac, input, output )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx,
+                                           mac, input, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_auth_decrypt( &ctx,
                                            0, nonce,
                                            aad, 0,
-                                           NULL, input, output )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx,
+                                           NULL, input, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_auth_decrypt( &ctx,
                                            input_len, nonce,
                                            aad, 0,
-                                           mac, NULL, output )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx,
+                                           mac, NULL, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_auth_decrypt( &ctx,
                                            input_len, nonce,
                                            aad, 0,
-                                           mac, input, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+                                           mac, input, NULL ) );
 
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
-                                      0, nonce,
-                                      aad, aad_len,
-                                      NULL, NULL, mac )
-                 == 0 );
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx,
-                                           0, nonce,
-                                           aad, aad_len,
-                                           mac, NULL, NULL )
-                 == 0 );
+    /* starts */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_starts( NULL, nonce,
+                                               MBEDTLS_CHACHAPOLY_ENCRYPT ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_starts( &ctx, NULL,
+                                               MBEDTLS_CHACHAPOLY_ENCRYPT ) );
 
-    TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx,
-                                      input_len, nonce,
-                                      NULL, 0,
-                                      input, output, mac )
-                 == 0 );
-    TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx,
-                                           input_len, nonce,
-                                           NULL, 0,
-                                           mac, input, output )
-                 == 0 );
+    /* update_aad */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_update_aad( NULL, aad,
+                                                           aad_len ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_update_aad( &ctx, NULL,
+                                                           aad_len ) );
 
-    TEST_ASSERT( mbedtls_chachapoly_starts( NULL, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, NULL, MBEDTLS_CHACHAPOLY_ENCRYPT )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+    /* update */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_update( NULL, input_len,
+                                                       input, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_update( &ctx, input_len,
+                                                       NULL, output ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_update( &ctx, input_len,
+                                                       input, NULL ) );
 
-    TEST_ASSERT( mbedtls_chachapoly_update_aad( NULL, aad, aad_len )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, NULL, aad_len )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-
-    TEST_ASSERT( mbedtls_chachapoly_update( NULL, input_len, input, output )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, NULL, output )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-
-    TEST_ASSERT( mbedtls_chachapoly_finish( NULL, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+    /* finish */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_finish( NULL, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                            mbedtls_chachapoly_finish( &ctx, NULL ) );
 
 exit:
-    mbedtls_chachapoly_free( &ctx );
+    return;
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index c5bce7e..773c792 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -22,72 +22,464 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void cipher_null_args(  )
+void cipher_invalid_param_unconditional( )
 {
-    mbedtls_cipher_context_t ctx;
-    const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type( *( mbedtls_cipher_list() ) );
-    unsigned char buf[1] = { 0 };
-    size_t olen;
+    mbedtls_cipher_context_t valid_ctx;
+    mbedtls_cipher_context_t invalid_ctx;
+    mbedtls_operation_t valid_operation = MBEDTLS_ENCRYPT;
+    mbedtls_cipher_padding_t valid_mode = MBEDTLS_PADDING_ZEROS;
+    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
+    int valid_size = sizeof(valid_buffer);
+    int valid_bitlen = valid_size * 8;
+    const mbedtls_cipher_info_t *valid_info = mbedtls_cipher_info_from_type(
+        *( mbedtls_cipher_list() ) );
+    size_t size_t_var;
 
-    mbedtls_cipher_init( &ctx );
+    (void)valid_mode; /* In some configurations this is unused */
 
-    TEST_ASSERT( mbedtls_cipher_get_block_size( NULL ) == 0 );
-    TEST_ASSERT( mbedtls_cipher_get_block_size( &ctx ) == 0 );
+    mbedtls_cipher_init( &valid_ctx );
+    mbedtls_cipher_setup( &valid_ctx, valid_info );
+    mbedtls_cipher_init( &invalid_ctx );
 
-    TEST_ASSERT( mbedtls_cipher_get_cipher_mode( NULL ) == MBEDTLS_MODE_NONE );
-    TEST_ASSERT( mbedtls_cipher_get_cipher_mode( &ctx ) == MBEDTLS_MODE_NONE );
+    /* mbedtls_cipher_setup() */
+    TEST_ASSERT( mbedtls_cipher_setup( &valid_ctx, NULL ) ==
+                 MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-    TEST_ASSERT( mbedtls_cipher_get_iv_size( NULL ) == 0 );
-    TEST_ASSERT( mbedtls_cipher_get_iv_size( &ctx ) == 0 );
+    /* mbedtls_cipher_get_block_size() */
+    TEST_ASSERT( mbedtls_cipher_get_block_size( &invalid_ctx ) == 0 );
 
-    TEST_ASSERT( mbedtls_cipher_info_from_string( NULL ) == NULL );
+    /* mbedtls_cipher_get_cipher_mode() */
+    TEST_ASSERT( mbedtls_cipher_get_cipher_mode( &invalid_ctx ) ==
+                 MBEDTLS_MODE_NONE );
 
-    TEST_ASSERT( mbedtls_cipher_setup( &ctx, NULL )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_setup( NULL, info )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_get_iv_size() */
+    TEST_ASSERT( mbedtls_cipher_get_iv_size( &invalid_ctx ) == 0 );
 
-    TEST_ASSERT( mbedtls_cipher_setkey( NULL, buf, 0, MBEDTLS_ENCRYPT )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_setkey( &ctx, buf, 0, MBEDTLS_ENCRYPT )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_get_type() */
+    TEST_ASSERT(
+        mbedtls_cipher_get_type( &invalid_ctx ) ==
+        MBEDTLS_CIPHER_NONE);
 
-    TEST_ASSERT( mbedtls_cipher_set_iv( NULL, buf, 0 )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_set_iv( &ctx, buf, 0 )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_get_name() */
+    TEST_ASSERT( mbedtls_cipher_get_name( &invalid_ctx ) == 0 );
 
-    TEST_ASSERT( mbedtls_cipher_reset( NULL ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_reset( &ctx ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_get_key_bitlen() */
+    TEST_ASSERT( mbedtls_cipher_get_key_bitlen( &invalid_ctx ) ==
+                 MBEDTLS_KEY_LENGTH_NONE );
+
+    /* mbedtls_cipher_get_operation() */
+    TEST_ASSERT( mbedtls_cipher_get_operation( &invalid_ctx ) ==
+                 MBEDTLS_OPERATION_NONE );
+
+    /* mbedtls_cipher_setkey() */
+    TEST_ASSERT(
+        mbedtls_cipher_setkey( &invalid_ctx,
+                               valid_buffer,
+                               valid_bitlen,
+                               valid_operation ) ==
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    /* mbedtls_cipher_set_iv() */
+    TEST_ASSERT(
+        mbedtls_cipher_set_iv( &invalid_ctx,
+                               valid_buffer,
+                               valid_size ) ==
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    /* mbedtls_cipher_reset() */
+    TEST_ASSERT( mbedtls_cipher_reset( &invalid_ctx ) ==
+                 MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-    TEST_ASSERT( mbedtls_cipher_update_ad( NULL, buf, 0 )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_update_ad( &ctx, buf, 0 )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_update_ad() */
+    TEST_ASSERT(
+        mbedtls_cipher_update_ad( &invalid_ctx,
+                                  valid_buffer,
+                                  valid_size ) ==
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+    /* mbedtls_cipher_set_padding_mode() */
+    TEST_ASSERT( mbedtls_cipher_set_padding_mode( &invalid_ctx, valid_mode ) ==
+                 MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 #endif
 
-    TEST_ASSERT( mbedtls_cipher_update( NULL, buf, 0, buf, &olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_update( &ctx, buf, 0, buf, &olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_update() */
+    TEST_ASSERT(
+        mbedtls_cipher_update( &invalid_ctx,
+                               valid_buffer,
+                               valid_size,
+                               valid_buffer,
+                               &size_t_var ) ==
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-    TEST_ASSERT( mbedtls_cipher_finish( NULL, buf, &olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_finish( &ctx, buf, &olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_finish() */
+    TEST_ASSERT(
+        mbedtls_cipher_finish( &invalid_ctx,
+                               valid_buffer,
+                               &size_t_var ) ==
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-    TEST_ASSERT( mbedtls_cipher_write_tag( NULL, buf, olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_write_tag( &ctx, buf, olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_write_tag() */
+    TEST_ASSERT(
+        mbedtls_cipher_write_tag( &invalid_ctx,
+                                  valid_buffer,
+                                  valid_size ) ==
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-    TEST_ASSERT( mbedtls_cipher_check_tag( NULL, buf, olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_cipher_check_tag( &ctx, buf, olen )
-                 == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    /* mbedtls_cipher_check_tag() */
+    TEST_ASSERT(
+        mbedtls_cipher_check_tag( &invalid_ctx,
+                                  valid_buffer,
+                                  valid_size ) ==
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
+
+exit:
+    mbedtls_cipher_free( &invalid_ctx );
+    mbedtls_cipher_free( &valid_ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void cipher_invalid_param_conditional( )
+{
+    mbedtls_cipher_context_t valid_ctx;
+
+    mbedtls_operation_t valid_operation = MBEDTLS_ENCRYPT;
+    mbedtls_operation_t invalid_operation = 100;
+    mbedtls_cipher_padding_t valid_mode = MBEDTLS_PADDING_ZEROS;
+    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
+    int valid_size = sizeof(valid_buffer);
+    int valid_bitlen = valid_size * 8;
+    const mbedtls_cipher_info_t *valid_info = mbedtls_cipher_info_from_type(
+        *( mbedtls_cipher_list() ) );
+
+    size_t size_t_var;
+
+    (void)valid_mode; /* In some configurations this is unused */
+
+    /* mbedtls_cipher_init() */
+    TEST_VALID_PARAM( mbedtls_cipher_init( &valid_ctx ) );
+    TEST_INVALID_PARAM( mbedtls_cipher_init( NULL ) );
+
+    /* mbedtls_cipher_setup() */
+    TEST_VALID_PARAM( mbedtls_cipher_setup( &valid_ctx, valid_info ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_setup( NULL, valid_info ) );
+
+    /* mbedtls_cipher_get_block_size() */
+    TEST_INVALID_PARAM_RET( 0, mbedtls_cipher_get_block_size( NULL ) );
+
+    /* mbedtls_cipher_get_cipher_mode() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_MODE_NONE,
+        mbedtls_cipher_get_cipher_mode( NULL ) );
+
+    /* mbedtls_cipher_get_iv_size() */
+    TEST_INVALID_PARAM_RET( 0, mbedtls_cipher_get_iv_size( NULL ) );
+
+    /* mbedtls_cipher_get_type() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_CIPHER_NONE,
+        mbedtls_cipher_get_type( NULL ) );
+
+    /* mbedtls_cipher_get_name() */
+    TEST_INVALID_PARAM_RET( 0, mbedtls_cipher_get_name( NULL ) );
+
+    /* mbedtls_cipher_get_key_bitlen() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_KEY_LENGTH_NONE,
+        mbedtls_cipher_get_key_bitlen( NULL ) );
+
+    /* mbedtls_cipher_get_operation() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_OPERATION_NONE,
+        mbedtls_cipher_get_operation( NULL ) );
+
+    /* mbedtls_cipher_setkey() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_setkey( NULL,
+                               valid_buffer,
+                               valid_bitlen,
+                               valid_operation ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_setkey( &valid_ctx,
+                               NULL,
+                               valid_bitlen,
+                               valid_operation ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_setkey( &valid_ctx,
+                               valid_buffer,
+                               valid_bitlen,
+                               invalid_operation ) );
+
+    /* mbedtls_cipher_set_iv() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_set_iv( NULL,
+                               valid_buffer,
+                               valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_set_iv( &valid_ctx,
+                               NULL,
+                               valid_size ) );
+
+    /* mbedtls_cipher_reset() */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+                            mbedtls_cipher_reset( NULL ) );
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+    /* mbedtls_cipher_update_ad() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_update_ad( NULL,
+                                  valid_buffer,
+                                  valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_update_ad( &valid_ctx,
+                                  NULL,
+                                  valid_size ) );
+#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+    /* mbedtls_cipher_set_padding_mode() */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+                            mbedtls_cipher_set_padding_mode( NULL, valid_mode ) );
 #endif
+
+    /* mbedtls_cipher_update() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_update( NULL,
+                               valid_buffer,
+                               valid_size,
+                               valid_buffer,
+                               &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_update( &valid_ctx,
+                               NULL, valid_size,
+                               valid_buffer,
+                               &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_update( &valid_ctx,
+                               valid_buffer, valid_size,
+                               NULL,
+                               &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_update( &valid_ctx,
+                               valid_buffer, valid_size,
+                               valid_buffer,
+                               NULL ) );
+
+    /* mbedtls_cipher_finish() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_finish( NULL,
+                               valid_buffer,
+                               &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_finish( &valid_ctx,
+                               NULL,
+                               &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_finish( &valid_ctx,
+                               valid_buffer,
+                               NULL ) );
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+    /* mbedtls_cipher_write_tag() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_write_tag( NULL,
+                                  valid_buffer,
+                                  valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_write_tag( &valid_ctx,
+                                  NULL,
+                                  valid_size ) );
+
+    /* mbedtls_cipher_check_tag() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_check_tag( NULL,
+                                  valid_buffer,
+                                  valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_check_tag( &valid_ctx,
+                                  NULL,
+                                  valid_size ) );
+#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
+
+    /* mbedtls_cipher_crypt() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_crypt( NULL,
+                              valid_buffer, valid_size,
+                              valid_buffer, valid_size,
+                              valid_buffer, &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_crypt( &valid_ctx,
+                              NULL, valid_size,
+                              valid_buffer, valid_size,
+                              valid_buffer, &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_crypt( &valid_ctx,
+                              valid_buffer, valid_size,
+                              NULL, valid_size,
+                              valid_buffer, &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_crypt( &valid_ctx,
+                              valid_buffer, valid_size,
+                              valid_buffer, valid_size,
+                              NULL, &size_t_var ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_crypt( &valid_ctx,
+                              valid_buffer, valid_size,
+                              valid_buffer, valid_size,
+                              valid_buffer, NULL ) );
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+    /* mbedtls_cipher_auth_encrypt() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_encrypt( NULL,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_encrypt( &valid_ctx,
+                                     NULL, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_encrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     NULL, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_encrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     NULL, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_encrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     NULL, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_encrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, NULL,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_encrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     NULL, valid_size ) );
+
+    /* mbedtls_cipher_auth_decrypt() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_decrypt( NULL,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_decrypt( &valid_ctx,
+                                     NULL, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_decrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     NULL, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_decrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     NULL, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_decrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     NULL, &size_t_var,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_decrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, NULL,
+                                     valid_buffer, valid_size ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+        mbedtls_cipher_auth_decrypt( &valid_ctx,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, valid_size,
+                                     valid_buffer, &size_t_var,
+                                     NULL, valid_size ) );
+#endif /* defined(MBEDTLS_CIPHER_MODE_AEAD) */
+
+    /* mbedtls_cipher_free() */
+    TEST_VALID_PARAM( mbedtls_cipher_free( NULL ) );
+exit:
+    TEST_VALID_PARAM( mbedtls_cipher_free( &valid_ctx ) );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_cipher.misc.data b/tests/suites/test_suite_cipher.misc.data
new file mode 100644
index 0000000..25bfd40
--- /dev/null
+++ b/tests/suites/test_suite_cipher.misc.data
@@ -0,0 +1,5 @@
+CIPHER - Conditional invalid parameter checks
+cipher_invalid_param_conditional:
+
+CIPHER - Unconditional invalid parameter checks
+cipher_invalid_param_unconditional:
diff --git a/tests/suites/test_suite_cipher.padding.data b/tests/suites/test_suite_cipher.padding.data
index 1c0ba09..dc4c9d7 100644
--- a/tests/suites/test_suite_cipher.padding.data
+++ b/tests/suites/test_suite_cipher.padding.data
@@ -1,9 +1,6 @@
 Cipher list
 mbedtls_cipher_list:
 
-Cipher null/uninitialised arguments
-cipher_null_args:
-
 Set padding with AES-CBC
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
 set_padding:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:0
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index f10e98a..4a97826 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -244,9 +244,11 @@
     }
     TEST_ASSERT( last_idx == test_offset_idx );
 
-    /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT)
-     * (just make sure it doesn't cause memory corruption) */
-    mbedtls_ctr_drbg_update( &ctx, entropy, sizeof( entropy ) );
+    /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT).
+     * Make sure it's detected as an error and doesn't cause memory
+     * corruption. */
+    TEST_ASSERT( mbedtls_ctr_drbg_update_ret(
+                     &ctx, entropy, sizeof( entropy ) ) != 0 );
 
     /* Now enable PR, so the next few calls should all reseed */
     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data
index 734fd97..edebce0 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -1,3 +1,6 @@
+Diffie-Hellman parameter validation
+dhm_invalid_params:
+
 Diffie-Hellman full exchange #1
 dhm_do_dhm:10:"23":10:"5":0
 
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index 9a4c99c..8a05a38 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -7,6 +7,113 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void dhm_invalid_params( )
+{
+    mbedtls_dhm_context ctx;
+    unsigned char buf[42] = { 0 };
+    unsigned char *buf_null = NULL;
+    mbedtls_mpi X;
+    size_t const buflen = sizeof( buf );
+    size_t len;
+
+    TEST_INVALID_PARAM( mbedtls_dhm_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_dhm_free( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_read_params( NULL,
+                                                     (unsigned char**) &buf,
+                                                     buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_read_params( &ctx, &buf_null, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_read_params( &ctx, NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_read_params( &ctx,
+                                                     (unsigned char**) &buf,
+                                                     NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_make_params( NULL, buflen,
+                                                     buf, &len,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_make_params( &ctx, buflen,
+                                                     NULL, &len,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_make_params( &ctx, buflen,
+                                                     buf, NULL,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_make_params( &ctx, buflen,
+                                                     buf, &len,
+                                                     NULL,
+                                                     NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_set_group( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_set_group( &ctx, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_set_group( &ctx, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_read_public( NULL, buf, buflen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_read_public( &ctx, NULL, buflen ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_make_public( NULL, buflen,
+                                                     buf, buflen,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_make_public( &ctx, buflen,
+                                                     NULL, buflen,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_make_public( &ctx, buflen,
+                                                     buf, buflen,
+                                                     NULL,
+                                                     NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_calc_secret( NULL, buf, buflen,
+                                                     &len, rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_calc_secret( &ctx, NULL, buflen,
+                                                     &len, rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_calc_secret( &ctx, buf, buflen,
+                                                     NULL, rnd_std_rand,
+                                                     NULL ) );
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_parse_dhm( NULL, buf, buflen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_parse_dhm( &ctx, NULL, buflen ) );
+
+#if defined(MBEDTLS_FS_IO)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_parse_dhmfile( NULL, "" ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA,
+                            mbedtls_dhm_parse_dhmfile( &ctx, NULL ) );
+#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+exit:
+    return;
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void dhm_do_dhm( int radix_P, char *input_P,
                  int radix_G, char *input_G, int result )
diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data
index 0165a7e..fe24ed4 100644
--- a/tests/suites/test_suite_ecdh.data
+++ b/tests/suites/test_suite_ecdh.data
@@ -1,3 +1,9 @@
+ECDH - Valid parameters
+ecdh_valid_param:
+
+ECDH - Invalid parameters
+ecdh_invalid_param:
+
 ECDH primitive random #1
 depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
 ecdh_primitive_random:MBEDTLS_ECP_DP_SECP192R1
@@ -69,3 +75,7 @@
 ECDH restartable rfc 5903 p256 restart disabled max_ops=250
 depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 ecdh_restart:MBEDTLS_ECP_DP_SECP256R1:"C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D1433":"C6EF9C5D78AE012A011164ACB397CE2088685D8F06BF9BE0B283AB46476BEE53":"D6840F6B42F6EDAFD13116E0E12565202FEF8E9ECE7DCE03812464D04B9442DE":0:250:0:0
+
+ECDH exchange legacy context
+depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ecdh_exchange_legacy:MBEDTLS_ECP_DP_SECP192R1
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 9652308..08a1686 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -8,6 +8,148 @@
  */
 
 /* BEGIN_CASE */
+void ecdh_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_ecdh_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void ecdh_invalid_param( )
+{
+    mbedtls_ecp_group grp;
+    mbedtls_ecdh_context ctx;
+    mbedtls_mpi m;
+    mbedtls_ecp_point P;
+    mbedtls_ecp_keypair kp;
+    size_t olen;
+    unsigned char buf[42] = { 0 };
+    const unsigned char *buf_null = NULL;
+    size_t const buflen = sizeof( buf );
+    int invalid_side = 42;
+    mbedtls_ecp_group_id valid_grp = MBEDTLS_ECP_DP_SECP192R1;
+
+    TEST_INVALID_PARAM( mbedtls_ecdh_init( NULL ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    TEST_INVALID_PARAM( mbedtls_ecdh_enable_restart( NULL ) );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_gen_public( NULL, &m, &P,
+                                                     rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_gen_public( &grp, NULL, &P,
+                                                     rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_gen_public( &grp, &m, NULL,
+                                                     rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_gen_public( &grp, &m, &P,
+                                                     NULL, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_compute_shared( NULL, &m, &P, &m,
+                                                         rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_compute_shared( &grp, NULL, &P, &m,
+                                                         rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_compute_shared( &grp, &m, NULL, &m,
+                                                         rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_compute_shared( &grp, &m, &P, NULL,
+                                                         rnd_std_rand, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_setup( NULL, valid_grp ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_params( NULL, &olen,
+                                                      buf, buflen,
+                                                      rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_params( &ctx, NULL,
+                                                      buf, buflen,
+                                                      rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_params( &ctx, &olen,
+                                                      NULL, buflen,
+                                                      rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_params( &ctx, &olen,
+                                                      buf, buflen,
+                                                      NULL, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_read_params( NULL,
+                                                  (const unsigned char**) &buf,
+                                                  buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_read_params( &ctx, &buf_null,
+                                                      buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_read_params( &ctx, NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_read_params( &ctx,
+                                                  (const unsigned char**) &buf,
+                                                  NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_get_params( NULL, &kp,
+                                                     MBEDTLS_ECDH_OURS ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_get_params( &ctx, NULL,
+                                                     MBEDTLS_ECDH_OURS ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_get_params( &ctx, &kp,
+                                                     invalid_side ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_public( NULL, &olen,
+                                                      buf, buflen,
+                                                      rnd_std_rand,
+                                                      NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_public( &ctx, NULL,
+                                                      buf, buflen,
+                                                      rnd_std_rand,
+                                                      NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_public( &ctx, &olen,
+                                                      NULL, buflen,
+                                                      rnd_std_rand,
+                                                      NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_make_public( &ctx, &olen,
+                                                      buf, buflen,
+                                                      NULL,
+                                                      NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_read_public( NULL, buf, buflen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_read_public( &ctx, NULL, buflen ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_calc_secret( NULL, &olen, buf, buflen,
+                                                      rnd_std_rand,
+                                                      NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_calc_secret( &ctx, NULL, buf, buflen,
+                                                      rnd_std_rand,
+                                                      NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdh_calc_secret( &ctx, &olen, NULL, buflen,
+                                                      rnd_std_rand,
+                                                      NULL ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void ecdh_primitive_random( int id )
 {
     mbedtls_ecp_group grp;
@@ -129,27 +271,31 @@
     const unsigned char *vbuf;
     size_t len;
     rnd_pseudo_info rnd_info;
+    unsigned char res_buf[1000];
+    size_t res_len;
 
     mbedtls_ecdh_init( &srv );
     mbedtls_ecdh_init( &cli );
     memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
+    TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 );
 
     memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
     TEST_ASSERT( mbedtls_ecdh_make_params( &srv, &len, buf, 1000,
-                                   &rnd_pseudo_rand, &rnd_info ) == 0 );
+                                           &rnd_pseudo_rand, &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
 
     memset( buf, 0x00, sizeof( buf ) );
     TEST_ASSERT( mbedtls_ecdh_make_public( &cli, &len, buf, 1000,
-                                   &rnd_pseudo_rand, &rnd_info ) == 0 );
+                                           &rnd_pseudo_rand, &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
 
     TEST_ASSERT( mbedtls_ecdh_calc_secret( &srv, &len, buf, 1000,
-                                   &rnd_pseudo_rand, &rnd_info ) == 0 );
-    TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &len, buf, 1000, NULL, NULL ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &srv.z, &cli.z ) == 0 );
+                                           &rnd_pseudo_rand, &rnd_info ) == 0 );
+    TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &res_len, res_buf, 1000,
+                                           NULL, NULL ) == 0 );
+    TEST_ASSERT( len == res_len );
+    TEST_ASSERT( memcmp( buf, res_buf, len ) == 0 );
 
 exit:
     mbedtls_ecdh_free( &srv );
@@ -172,7 +318,9 @@
     unsigned char rnd_buf_B[MBEDTLS_ECP_MAX_BYTES];
     rnd_buf_info rnd_info_A, rnd_info_B;
     int cnt_restart;
+    mbedtls_ecp_group grp;
 
+    mbedtls_ecp_group_init( &grp );
     mbedtls_ecdh_init( &srv );
     mbedtls_ecdh_init( &cli );
 
@@ -184,16 +332,20 @@
     rnd_info_B.buf = rnd_buf_B;
     rnd_info_B.length = unhexify( rnd_buf_B, dB_str );
 
-    TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
+    /* The ECDH context is not guaranteed ot have an mbedtls_ecp_group structure
+     * in every configuration, therefore we load it separately. */
+    TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    /* otherwise we would have to fix the random buffer,
-     * as in ecdh_primitive_test_vec */
-    TEST_ASSERT( srv.grp.nbits % 8 == 0 );
+    /* Otherwise we would have to fix the random buffer,
+     * as in ecdh_primitive_testvec. */
+    TEST_ASSERT( grp.nbits % 8 == 0 );
+
+    TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 );
 
     /* set up restart parameters */
     mbedtls_ecp_set_max_ops( max_ops );
 
-    if( enable)
+    if( enable )
     {
         mbedtls_ecdh_enable_restart( &srv );
         mbedtls_ecdh_enable_restart( &cli );
@@ -269,6 +421,45 @@
     TEST_ASSERT( memcmp( buf, z, len ) == 0 );
 
 exit:
+    mbedtls_ecp_group_free( &grp );
+    mbedtls_ecdh_free( &srv );
+    mbedtls_ecdh_free( &cli );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ECDH_LEGACY_CONTEXT */
+void ecdh_exchange_legacy( int id )
+{
+    mbedtls_ecdh_context srv, cli;
+    unsigned char buf[1000];
+    const unsigned char *vbuf;
+    size_t len;
+
+    rnd_pseudo_info rnd_info;
+
+    mbedtls_ecdh_init( &srv );
+    mbedtls_ecdh_init( &cli );
+    memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
+
+    TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
+
+    memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
+    TEST_ASSERT( mbedtls_ecdh_make_params( &srv, &len, buf, 1000,
+                                   &rnd_pseudo_rand, &rnd_info ) == 0 );
+    TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
+
+    memset( buf, 0x00, sizeof( buf ) );
+    TEST_ASSERT( mbedtls_ecdh_make_public( &cli, &len, buf, 1000,
+                                           &rnd_pseudo_rand, &rnd_info ) == 0 );
+    TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecdh_calc_secret( &srv, &len, buf, 1000,
+                                           &rnd_pseudo_rand, &rnd_info ) == 0 );
+    TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &len, buf, 1000, NULL,
+                                           NULL ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &srv.z, &cli.z ) == 0 );
+
+exit:
     mbedtls_ecdh_free( &srv );
     mbedtls_ecdh_free( &cli );
 }
diff --git a/tests/suites/test_suite_ecdsa.data b/tests/suites/test_suite_ecdsa.data
index 7e6ec6c..59e209b 100644
--- a/tests/suites/test_suite_ecdsa.data
+++ b/tests/suites/test_suite_ecdsa.data
@@ -1,3 +1,6 @@
+ECDSA Parameter validation
+ecdsa_invalid_param:
+
 ECDSA primitive random #1
 depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
 ecdsa_prim_random:MBEDTLS_ECP_DP_SECP192R1
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index 7f89952..22d92b6 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -7,6 +7,201 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void ecdsa_invalid_param( )
+{
+    mbedtls_ecdsa_context ctx;
+    mbedtls_ecp_keypair key;
+    mbedtls_ecp_group grp;
+    mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1;
+    mbedtls_ecp_point P;
+    mbedtls_md_type_t valid_md = MBEDTLS_MD_SHA256;
+    mbedtls_mpi m;
+    size_t slen;
+    unsigned char buf[42] = { 0 };
+
+    TEST_INVALID_PARAM( mbedtls_ecdsa_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_ecdsa_free( NULL ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    TEST_INVALID_PARAM( mbedtls_ecdsa_restart_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_ecdsa_restart_free( NULL ) );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdsa_sign( NULL, &m, &m, &m,
+                                                buf, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecdsa_sign( &grp, NULL, &m, &m,
+                                                buf, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign( &grp, &m, NULL, &m,
+                                                buf, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign( &grp, &m, &m, NULL,
+                                                buf, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign( &grp, &m, &m, &m,
+                                                NULL, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign( &grp, &m, &m, &m,
+                                                buf, sizeof( buf ),
+                                                NULL, NULL ) );
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign_det( NULL, &m, &m, &m,
+                                                buf, sizeof( buf ),
+                                                valid_md ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign_det( &grp, NULL, &m, &m,
+                                                buf, sizeof( buf ),
+                                                valid_md ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign_det( &grp, &m, NULL, &m,
+                                                buf, sizeof( buf ),
+                                                valid_md ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign_det( &grp, &m, &m, NULL,
+                                                buf, sizeof( buf ),
+                                                valid_md ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_sign_det( &grp, &m, &m, &m,
+                                                NULL, sizeof( buf ),
+                                                valid_md ) );
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_verify( NULL,
+                                                  buf, sizeof( buf ),
+                                                  &P, &m, &m ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_verify( &grp,
+                                                  NULL, sizeof( buf ),
+                                                  &P, &m, &m ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_verify( &grp,
+                                                  buf, sizeof( buf ),
+                                                  NULL, &m, &m ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_verify( &grp,
+                                                  buf, sizeof( buf ),
+                                                  &P, NULL, &m ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_verify( &grp,
+                                                  buf, sizeof( buf ),
+                                                  &P, &m, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature( NULL,
+                                                           valid_md,
+                                                           buf, sizeof( buf ),
+                                                           buf, &slen,
+                                                           rnd_std_rand,
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature( &ctx,
+                                                           valid_md,
+                                                           NULL, sizeof( buf ),
+                                                           buf, &slen,
+                                                           rnd_std_rand,
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature( &ctx,
+                                                           valid_md,
+                                                           buf, sizeof( buf ),
+                                                           NULL, &slen,
+                                                           rnd_std_rand,
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature( &ctx,
+                                                           valid_md,
+                                                           buf, sizeof( buf ),
+                                                           buf, NULL,
+                                                           rnd_std_rand,
+                                                           NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature_restartable( NULL,
+                                                           valid_md,
+                                                           buf, sizeof( buf ),
+                                                           buf, &slen,
+                                                           rnd_std_rand,
+                                                           NULL, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature_restartable( &ctx,
+                                                           valid_md,
+                                                           NULL, sizeof( buf ),
+                                                           buf, &slen,
+                                                           rnd_std_rand,
+                                                           NULL, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature_restartable( &ctx,
+                                                           valid_md,
+                                                           buf, sizeof( buf ),
+                                                           NULL, &slen,
+                                                           rnd_std_rand,
+                                                           NULL, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_write_signature_restartable( &ctx,
+                                                           valid_md,
+                                                           buf, sizeof( buf ),
+                                                           buf, NULL,
+                                                           rnd_std_rand,
+                                                           NULL, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_read_signature( NULL,
+                                                        buf, sizeof( buf ),
+                                                        buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_read_signature( &ctx,
+                                                        NULL, sizeof( buf ),
+                                                        buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_read_signature( &ctx,
+                                                        buf, sizeof( buf ),
+                                                        NULL, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_read_signature_restartable( NULL,
+                                                        buf, sizeof( buf ),
+                                                        buf, sizeof( buf ),
+                                                        NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_read_signature_restartable( &ctx,
+                                                        NULL, sizeof( buf ),
+                                                        buf, sizeof( buf ),
+                                                        NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_read_signature_restartable( &ctx,
+                                                        buf, sizeof( buf ),
+                                                        NULL, sizeof( buf ),
+                                                        NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_genkey( NULL, valid_group,
+                                                  rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_genkey( &ctx, valid_group,
+                                                  NULL, NULL ) );
+
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_from_keypair( NULL, &key ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                       mbedtls_ecdsa_from_keypair( &ctx, NULL ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void ecdsa_prim_random( int id )
 {
@@ -14,7 +209,7 @@
     mbedtls_ecp_point Q;
     mbedtls_mpi d, r, s;
     rnd_pseudo_info rnd_info;
-    unsigned char buf[66];
+    unsigned char buf[MBEDTLS_MD_MAX_SIZE];
 
     mbedtls_ecp_group_init( &grp );
     mbedtls_ecp_point_init( &Q );
diff --git a/tests/suites/test_suite_ecjpake.data b/tests/suites/test_suite_ecjpake.data
index 1a772a9..84c99c9 100644
--- a/tests/suites/test_suite_ecjpake.data
+++ b/tests/suites/test_suite_ecjpake.data
@@ -1,3 +1,6 @@
+ECJPAKE parameter validation
+ecjpake_invalid_param:
+
 ECJPAKE selftest
 ecjpake_selftest:
 
diff --git a/tests/suites/test_suite_ecjpake.function b/tests/suites/test_suite_ecjpake.function
index 9e4f7a3..d267295 100644
--- a/tests/suites/test_suite_ecjpake.function
+++ b/tests/suites/test_suite_ecjpake.function
@@ -98,6 +98,137 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void ecjpake_invalid_param( )
+{
+    mbedtls_ecjpake_context ctx;
+    unsigned char buf[42] = { 0 };
+    size_t olen;
+    size_t const len = sizeof( buf );
+    mbedtls_ecjpake_role valid_role = MBEDTLS_ECJPAKE_SERVER;
+    mbedtls_ecjpake_role invalid_role = (mbedtls_ecjpake_role) 42;
+    mbedtls_md_type_t valid_md = MBEDTLS_MD_SHA256;
+    mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP256R1;
+
+    TEST_INVALID_PARAM( mbedtls_ecjpake_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_ecjpake_free( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_setup( NULL,
+                                                   valid_role,
+                                                   valid_md,
+                                                   valid_group,
+                                                   buf, len ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_setup( &ctx,
+                                                   invalid_role,
+                                                   valid_md,
+                                                   valid_group,
+                                                   buf, len ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_setup( &ctx,
+                                                   valid_role,
+                                                   valid_md,
+                                                   valid_group,
+                                                   NULL, len ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_check( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_one( NULL,
+                                                             buf, len,
+                                                             &olen,
+                                                             rnd_std_rand,
+                                                             NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_one( &ctx,
+                                                             NULL, len,
+                                                             &olen,
+                                                             rnd_std_rand,
+                                                             NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_one( &ctx,
+                                                             buf, len,
+                                                             NULL,
+                                                             rnd_std_rand,
+                                                             NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_one( &ctx,
+                                                             buf, len,
+                                                             &olen,
+                                                             NULL,
+                                                             NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_two( NULL,
+                                                             buf, len,
+                                                             &olen,
+                                                             rnd_std_rand,
+                                                             NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_two( &ctx,
+                                                             NULL, len,
+                                                             &olen,
+                                                             rnd_std_rand,
+                                                             NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_two( &ctx,
+                                                             buf, len,
+                                                             NULL,
+                                                             rnd_std_rand,
+                                                             NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_write_round_two( &ctx,
+                                                             buf, len,
+                                                             &olen,
+                                                             NULL,
+                                                             NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_read_round_one( NULL,
+                                                            buf, len ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_read_round_one( &ctx,
+                                                            NULL, len ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_read_round_two( NULL,
+                                                            buf, len ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_read_round_two( &ctx,
+                                                            NULL, len ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_derive_secret( NULL,
+                                                           buf, len,
+                                                           &olen,
+                                                           rnd_std_rand,
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_derive_secret( &ctx,
+                                                           NULL, len,
+                                                           &olen,
+                                                           rnd_std_rand,
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_derive_secret( &ctx,
+                                                           buf, len,
+                                                           NULL,
+                                                           rnd_std_rand,
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecjpake_derive_secret( &ctx,
+                                                           buf, len,
+                                                           &olen,
+                                                           NULL,
+                                                           NULL ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void ecjpake_selftest(  )
 {
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 321a1b4..30d5ec6 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -1,3 +1,9 @@
+ECP valid params
+ecp_valid_param:
+
+ECP invalid params
+ecp_invalid_param:
+
 ECP curve info #1
 depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED
 mbedtls_ecp_curve_info:MBEDTLS_ECP_DP_BP512R1:28:512:"brainpoolP512r1"
@@ -46,10 +52,6 @@
 depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED
 ecp_check_pub:MBEDTLS_ECP_DP_SECP224K1:"E2000000000000BB3A13D43B323337383935321F0603551D":"100101FF040830060101FF02010A30220603551D0E041B04636FC0C0":"101":MBEDTLS_ERR_ECP_INVALID_KEY
 
-ECP write binary #0 (zero, bad format)
-depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
-ecp_write_binary:MBEDTLS_ECP_DP_SECP192R1:"01":"01":"00":ECP_PF_UNKNOWN:"00":1:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
-
 ECP write binary #1 (zero, uncompressed, buffer just fits)
 depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
 ecp_write_binary:MBEDTLS_ECP_DP_SECP192R1:"01":"01":"00":MBEDTLS_ECP_PF_UNCOMPRESSED:"00":1:0
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 65c487e..606ddd2 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -14,6 +14,349 @@
  */
 
 /* BEGIN_CASE */
+void ecp_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_ecp_group_free( NULL ) );
+    TEST_VALID_PARAM( mbedtls_ecp_keypair_free( NULL ) );
+    TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    TEST_VALID_PARAM( mbedtls_ecp_restart_free( NULL ) );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void ecp_invalid_param( )
+{
+    mbedtls_ecp_group grp;
+    mbedtls_ecp_keypair kp;
+    mbedtls_ecp_point P;
+    mbedtls_mpi m;
+    const char *x = "deadbeef";
+    int valid_fmt   = MBEDTLS_ECP_PF_UNCOMPRESSED;
+    int invalid_fmt = 42;
+    size_t olen;
+    unsigned char buf[42] = { 0 };
+    const unsigned char *null_buf = NULL;
+    mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1;
+    mbedtls_ecp_restart_ctx restart_ctx;
+
+    TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) );
+    TEST_INVALID_PARAM( mbedtls_ecp_keypair_init( NULL ) );
+    TEST_INVALID_PARAM( mbedtls_ecp_group_init( NULL ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    TEST_INVALID_PARAM( mbedtls_ecp_restart_init( NULL ) );
+    TEST_INVALID_PARAM( mbedtls_ecp_check_budget( NULL, &restart_ctx, 42 ) );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_copy( NULL, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_copy( &P, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_group_copy( NULL, &grp ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_group_copy( &grp, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_privkey( NULL,
+                                                     &m,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_privkey( &grp,
+                                                     NULL,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_privkey( &grp,
+                                                     &m,
+                                                     NULL,
+                                                     NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_set_zero( NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_is_zero( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_cmp( NULL, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_cmp( &P, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_read_string( NULL, 2,
+                                                           x, x ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_read_string( &P, 2,
+                                                           NULL, x ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_read_string( &P, 2,
+                                                           x, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_write_binary( NULL, &P,
+                                                      valid_fmt,
+                                                      &olen,
+                                                      buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_write_binary( &grp, NULL,
+                                                      valid_fmt,
+                                                      &olen,
+                                                      buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_write_binary( &grp, &P,
+                                                      invalid_fmt,
+                                                      &olen,
+                                                      buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_write_binary( &grp, &P,
+                                                      valid_fmt,
+                                                      NULL,
+                                                      buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_write_binary( &grp, &P,
+                                                      valid_fmt,
+                                                      &olen,
+                                                      NULL, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_read_binary( NULL, &P, buf,
+                                                     sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_read_binary( &grp, NULL, buf,
+                                                     sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_point_read_binary( &grp, &P, NULL,
+                                                     sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_point( NULL, &P,
+                                                 (const unsigned char **) &buf,
+                                                 sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_point( &grp, NULL,
+                                                 (const unsigned char **) &buf,
+                                                 sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_point( &grp, &P, &null_buf,
+                                                        sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_point( &grp, &P, NULL,
+                                                    sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_point( NULL, &P,
+                                                     valid_fmt,
+                                                     &olen,
+                                                     buf,
+                                                     sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_point( &grp, NULL,
+                                                     valid_fmt,
+                                                     &olen,
+                                                     buf,
+                                                     sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_point( &grp, &P,
+                                                     invalid_fmt,
+                                                     &olen,
+                                                     buf,
+                                                     sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_point( &grp, &P,
+                                                     valid_fmt,
+                                                     NULL,
+                                                     buf,
+                                                     sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_point( &grp, &P,
+                                                     valid_fmt,
+                                                     &olen,
+                                                     NULL,
+                                                     sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_group_load( NULL, valid_group ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_group( NULL,
+                                                 (const unsigned char **) &buf,
+                                                 sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_group( &grp, NULL,
+                                                        sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_group( &grp, &null_buf,
+                                                        sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_group_id( NULL,
+                                                 (const unsigned char **) &buf,
+                                                 sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_group_id( &valid_group, NULL,
+                                                        sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_read_group_id( &valid_group,
+                                                           &null_buf,
+                                                           sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_group( NULL, &olen,
+                                                       buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_group( &grp, NULL,
+                                                       buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_tls_write_group( &grp, &olen,
+                                                       NULL, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul( NULL, &P, &m, &P,
+                                             rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul( &grp, NULL, &m, &P,
+                                             rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul( &grp, &P, NULL, &P,
+                                             rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul( &grp, &P, &m, NULL,
+                                             rnd_std_rand, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul_restartable( NULL, &P, &m, &P,
+                                                 rnd_std_rand, NULL , NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul_restartable( &grp, NULL, &m, &P,
+                                                 rnd_std_rand, NULL , NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul_restartable( &grp, &P, NULL, &P,
+                                                 rnd_std_rand, NULL , NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_mul_restartable( &grp, &P, &m, NULL,
+                                                 rnd_std_rand, NULL , NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd( NULL, &P, &m, &P,
+                                                &m, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd( &grp, NULL, &m, &P,
+                                                &m, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd( &grp, &P, NULL, &P,
+                                                &m, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd( &grp, &P, &m, NULL,
+                                                &m, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd( &grp, &P, &m, &P,
+                                                NULL, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd( &grp, &P, &m, &P,
+                                                &m, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd_restartable( NULL, &P, &m, &P,
+                                                            &m, &P, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd_restartable( &grp, NULL, &m, &P,
+                                                            &m, &P, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd_restartable( &grp, &P, NULL, &P,
+                                                            &m, &P, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd_restartable( &grp, &P, &m, NULL,
+                                                            &m, &P, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd_restartable( &grp, &P, &m, &P,
+                                                            NULL, &P, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_muladd_restartable( &grp, &P, &m, &P,
+                                                            &m, NULL, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_check_pubkey( NULL, &P ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_check_pubkey( &grp, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_check_pub_priv( NULL, &kp ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_check_pub_priv( &kp, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_check_privkey( NULL, &m ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_check_privkey( &grp, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair_base( NULL, &P,
+                                                          &m, &P,
+                                                          rnd_std_rand,
+                                                          NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair_base( &grp, NULL,
+                                                          &m, &P,
+                                                          rnd_std_rand,
+                                                          NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair_base( &grp, &P,
+                                                          NULL, &P,
+                                                          rnd_std_rand,
+                                                          NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair_base( &grp, &P,
+                                                          &m, NULL,
+                                                          rnd_std_rand,
+                                                          NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair_base( &grp, &P,
+                                                          &m, &P,
+                                                          NULL,
+                                                          NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair( NULL,
+                                                     &m, &P,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair( &grp,
+                                                     NULL, &P,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair( &grp,
+                                                     &m, NULL,
+                                                     rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_keypair( &grp,
+                                                     &m, &P,
+                                                     NULL,
+                                                     NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_key( valid_group, NULL,
+                                                 rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+                            mbedtls_ecp_gen_key( valid_group, &kp,
+                                                 NULL, NULL ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mbedtls_ecp_curve_info( int id, int tls_id, int size, char * name )
 {
     const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index 4d3bba1..1fcb681 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -103,6 +103,175 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void gcm_invalid_param( )
+{
+    mbedtls_gcm_context ctx;
+    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+    mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
+    int valid_mode = MBEDTLS_GCM_ENCRYPT;
+    int valid_len = sizeof(valid_buffer);
+    int valid_bitlen = 128, invalid_bitlen = 1;
+
+    mbedtls_gcm_init( &ctx );
+
+    /* mbedtls_gcm_init() */
+    TEST_INVALID_PARAM( mbedtls_gcm_init( NULL ) );
+
+    /* mbedtls_gcm_setkey */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_setkey( NULL, valid_cipher, valid_buffer, valid_bitlen ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_setkey( &ctx, valid_cipher, NULL, valid_bitlen ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_setkey( &ctx, valid_cipher, valid_buffer, invalid_bitlen ) );
+
+    /* mbedtls_gcm_crypt_and_tag() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_crypt_and_tag( NULL, valid_mode, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, valid_buffer,
+                                   valid_len, valid_buffer ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_crypt_and_tag( &ctx, valid_mode, valid_len,
+                                   NULL, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, valid_buffer,
+                                   valid_len, valid_buffer ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_crypt_and_tag( &ctx, valid_mode, valid_len,
+                                   valid_buffer, valid_len,
+                                   NULL, valid_len,
+                                   valid_buffer, valid_buffer,
+                                   valid_len, valid_buffer ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_crypt_and_tag( &ctx, valid_mode, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, valid_len,
+                                   NULL, valid_buffer,
+                                   valid_len, valid_buffer ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_crypt_and_tag( &ctx, valid_mode, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, NULL,
+                                   valid_len, valid_buffer ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_crypt_and_tag( &ctx, valid_mode, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, valid_len,
+                                   valid_buffer, valid_buffer,
+                                   valid_len, NULL ) );
+
+    /* mbedtls_gcm_auth_decrypt() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_auth_decrypt( NULL, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_buffer) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_auth_decrypt( &ctx, valid_len,
+                                  NULL, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_buffer) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  NULL, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_buffer) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  NULL, valid_len,
+                                  valid_buffer, valid_buffer) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  NULL, valid_buffer) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_auth_decrypt( &ctx, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, valid_len,
+                                  valid_buffer, NULL) );
+
+    /* mbedtls_gcm_starts() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_starts( NULL, valid_mode,
+                            valid_buffer, valid_len,
+                            valid_buffer, valid_len ) );
+
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_starts( &ctx, valid_mode,
+                            NULL, valid_len,
+                            valid_buffer, valid_len ) );
+
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_starts( &ctx, valid_mode,
+                            valid_buffer, valid_len,
+                            NULL, valid_len ) );
+
+    /* mbedtls_gcm_update() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_update( NULL, valid_len,
+                            valid_buffer, valid_buffer ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_update( &ctx, valid_len,
+                            NULL, valid_buffer ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_update( &ctx, valid_len,
+                            valid_buffer, NULL ) );
+
+    /* mbedtls_gcm_finish() */
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_finish( NULL, valid_buffer, valid_len ) );
+    TEST_INVALID_PARAM_RET(
+        MBEDTLS_ERR_GCM_BAD_INPUT,
+        mbedtls_gcm_finish( &ctx, NULL, valid_len ) );
+
+exit:
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_gcm_free( NULL ) );
+exit:
+    return;
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void gcm_selftest(  )
 {
diff --git a/tests/suites/test_suite_gcm.misc.data b/tests/suites/test_suite_gcm.misc.data
new file mode 100644
index 0000000..cf01526
--- /dev/null
+++ b/tests/suites/test_suite_gcm.misc.data
@@ -0,0 +1,5 @@
+GCM - Invalid parameters
+gcm_invalid_param:
+
+GCM - Valid parameters
+gcm_valid_param:
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 6ea3b29..8b5f97d 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -1,3 +1,9 @@
+MPI - Valid parameters
+mpi_valid_param:
+
+MPI - Invalid parameters
+mpi_invalid_param:
+
 Arguments with no value
 mpi_null:
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index 9c1d78f..d1fa5a4 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -51,6 +51,220 @@
  */
 
 /* BEGIN_CASE */
+void mpi_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_mpi_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void mpi_invalid_param( )
+{
+    mbedtls_mpi X;
+    const char *s_in = "00101000101010";
+    char s_out[16] = { 0 };
+    unsigned char u_out[16] = { 0 };
+    unsigned char u_in[16] = { 0 };
+    size_t olen;
+    mbedtls_mpi_uint mpi_uint;
+
+    TEST_INVALID_PARAM( mbedtls_mpi_init( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_grow( NULL, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_copy( NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_copy( &X, NULL ) );
+
+    TEST_INVALID_PARAM( mbedtls_mpi_swap( NULL, &X ) );
+    TEST_INVALID_PARAM( mbedtls_mpi_swap( &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_safe_cond_assign( NULL, &X, 0 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_safe_cond_assign( &X, NULL, 0 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_safe_cond_swap( NULL, &X, 0 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_safe_cond_swap( &X, NULL, 0 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_lset( NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_get_bit( NULL, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_set_bit( NULL, 42, 0 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_read_string( NULL, 2, s_in ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_read_string( &X, 2, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_write_string( NULL, 2,
+                                                      s_out, sizeof( s_out ),
+                                                      &olen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_write_string( &X, 2,
+                                                      NULL, sizeof( s_out ),
+                                                      &olen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_write_string( &X, 2,
+                                                      s_out, sizeof( s_out ),
+                                                      NULL ) );
+
+#if defined(MBEDTLS_FS_IO)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_read_file( NULL, 2, stdin ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_read_file( &X, 2, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_write_file( "", NULL, 2, NULL ) );
+#endif /* MBEDTLS_FS_IO */
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_read_binary( NULL, u_in,
+                                                     sizeof( u_in ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_read_binary( &X, NULL,
+                                                     sizeof( u_in ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_write_binary( NULL, u_out,
+                                                      sizeof( u_out ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_write_binary( &X, NULL,
+                                                      sizeof( u_out ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_shift_l( NULL, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_shift_r( NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_cmp_abs( NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_cmp_abs( &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_cmp_mpi( NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_cmp_mpi( &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_cmp_int( NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_abs( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_abs( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_abs( &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_abs( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_abs( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_abs( &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_mpi( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_mpi( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_mpi( &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_mpi( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_mpi( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_mpi( &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_int( NULL, &X, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_add_int( &X, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_int( NULL, &X, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_sub_int( &X, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mul_mpi( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mul_mpi( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mul_mpi( &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mul_int( NULL, &X, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mul_int( &X, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_div_mpi( &X, &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_div_mpi( &X, &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_div_int( &X, &X, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( 0, mbedtls_mpi_lsb( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mod_mpi( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mod_mpi( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mod_mpi( &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mod_int( NULL, &X, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_mod_int( &mpi_uint, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_exp_mod( NULL, &X, &X, &X, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_exp_mod( &X, NULL, &X, &X, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_exp_mod( &X, &X, NULL, &X, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_exp_mod( &X, &X, &X, NULL, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_fill_random( NULL, 42, rnd_std_rand,
+                                                     NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_fill_random( &X, 42, NULL, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_gcd( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_gcd( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_gcd( &X, &X, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_inv_mod( NULL, &X, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_inv_mod( &X, NULL, &X ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                            mbedtls_mpi_inv_mod( &X, &X, NULL ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mpi_null(  )
 {
     mbedtls_mpi X, Y, Z;
diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data
index 478cde7..e41dfa7 100644
--- a/tests/suites/test_suite_pk.data
+++ b/tests/suites/test_suite_pk.data
@@ -1,3 +1,13 @@
+PK invalid parameters
+invalid_parameters:
+
+PK valid parameters
+valid_parameters:
+
+PK write valid parameters
+depends_on:MBEDTLS_RSA_C
+valid_parameters_pkwrite:"308204a20201000282010100a9021f3d406ad555538bfd36ee82652e15615e89bfb8e84590dbee881652d3f143504796125964876bfd2be046f973beddcf92e1915bed66a06f8929794580d0836ad54143775f397c09044782b0573970eda3ec15191ea8330847c10542a9fd4cc3b4dfdd061f4d1051406773130f40f86d81255f0ab153c6307e1539acf95aee7f929ea6055be7139785b52392d9d42406d50925897507dda61a8f3f0919bead652c64eb959bdcfe415e17a6da6c5b69cc02ba142c16249c4adccdd0f7526773f12da023fd7ef431ca2d70ca890b04db2ea64f706e9ecebd5889e253599e6e5a9265e2883f0c9419a3dde5e89d9513ed29dbab7012dc5aca6b17ab528254b10203010001028201001689f5e89142ae18a6ffb0513715a4b0b4a13b9e5b3729a2bd62d738c6e15cea7bf3a4d85ab2193a0628c9452bb1f0c1af8b132789df1c95e72778bf5330f5b0d915d242d5e0818e85001ed5fa93d1ce13455deb0a15438562e8e3c8d60ec1e4c9ebff9f2b36b9cde9332cc79f0d17a7ae79cc1353cd75409ad9b4b6d7ee3d82af6f3207656cf2ac98947c15c398db0cebf8dc3eef5398269480cdd09411b960273ae3f364da09af849f24aa87346c58618ea91d9d6cd1d3932c80dbfc1f0a4166a9036911999ca27761079f0ce02db02c1c909ff9b4278578d7bb1b54b2b7082fc9e864b6b394e331c0d11a9a68255565b6dd477f4119c5809839520700711102818100d7db987ad86de6a9b0749fb5da80bacde3bebd72dcc83f60a27db74f927ac3661386577bfce5b4a00ad024682401d6aad29713c8e223b53415305ca07559821099b187fdd1bad3dc4dec9da96f5fa6128331e8f7d89f1e1a788698d1a27256dc7cd392f04e531a9e38e7265bf4fd7eec01e7835e9b1a0dd8923e440381be1c2702818100c87025fff7a493c623404966fbc8b32ed164ca620ad1a0ad11ef42fd12118456017856a8b42e5d4ad36104e9dc9f8a2f3003c3957ffddb20e2f4e3fc3cf2cdddae01f57a56de4fd24b91ab6d3e5cc0e8af0473659594a6bbfdaacf958f19c8d508eac12d8977616af6877106288093d37904a139220c1bc278ea56edc086976702818043e708685c7cf5fa9b4f948e1856366d5e1f3a694f9a8e954f884c89f3823ac5798ee12657bfcaba2dac9c47464c6dc2fecc17a531be19da706fee336bb6e47b645dbc71d3eff9856bddeb1ac9b644ffbdd58d7ba9e1240f1faaf797ba8a4d58becbaf85789e1bd979fcfccc209d3db7f0416bc9eef09b3a6d86b8ce8199d4310281804f4b86ccffe49d0d8ace98fb63ea9f708b284ba483d130b6a75cb76cb4e4372d6b41774f20912319420ca4cbfc1b25a8cb5f01d6381f6ebc50ed3ef08010327f5ba2acc1ac7220b3fa6f7399314db2879b0db0b5647abd87abb01295815a5b086491b2c0d81c616ed67ef8a8ce0727f446711d7323d4147b5828a52143c43b4b028180540756beba83c20a0bda11d6dec706a71744ff28090cec079dffb507d82828038fe657f61496a20317f779cb683ce8196c29a6fe28839a282eef4de57773be56808b0c3e2ac7747e2b200b2fbf20b55258cd24622a1ce0099de098ab0855106ae087f08b0c8c346d81619400c1b4838e33ed9ff90f05db8fccf8fb7ab881ca12"
+
 PK utils: RSA
 depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
 pk_utils:MBEDTLS_PK_RSA:512:64:"RSA"
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 4813f71..4e6ab17 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -2,6 +2,8 @@
 #include "mbedtls/pk.h"
 
 /* For error codes */
+#include "mbedtls/asn1.h"
+#include "mbedtls/base64.h"
 #include "mbedtls/ecp.h"
 #include "mbedtls/rsa.h"
 
@@ -70,6 +72,426 @@
  */
 
 /* BEGIN_CASE */
+void valid_parameters( )
+{
+    mbedtls_pk_context pk;
+    unsigned char buf[1];
+    size_t len;
+    void *options = NULL;
+
+    mbedtls_pk_init( &pk );
+
+    TEST_VALID_PARAM( mbedtls_pk_free( NULL ) );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    TEST_VALID_PARAM( mbedtls_pk_restart_free( NULL ) );
+#endif
+
+    TEST_ASSERT( mbedtls_pk_setup( &pk, NULL ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    /* In informational functions, we accept NULL where a context pointer
+     * is expected because that's what the library has done forever.
+     * We do not document that NULL is accepted, so we may wish to change
+     * the behavior in a future version. */
+    TEST_ASSERT( mbedtls_pk_get_bitlen( NULL ) == 0 );
+    TEST_ASSERT( mbedtls_pk_get_len( NULL ) == 0 );
+    TEST_ASSERT( mbedtls_pk_can_do( NULL, MBEDTLS_PK_NONE ) == 0 );
+
+    TEST_ASSERT( mbedtls_pk_sign_restartable( &pk,
+                                              MBEDTLS_MD_NONE,
+                                              NULL, 0,
+                                              buf, &len,
+                                              rnd_std_rand, NULL,
+                                              NULL ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    TEST_ASSERT( mbedtls_pk_sign_restartable( &pk,
+                                              MBEDTLS_MD_NONE,
+                                              NULL, 0,
+                                              buf, &len,
+                                              rnd_std_rand, NULL,
+                                              NULL ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    TEST_ASSERT( mbedtls_pk_sign( &pk,
+                                  MBEDTLS_MD_NONE,
+                                  NULL, 0,
+                                  buf, &len,
+                                  rnd_std_rand, NULL ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    TEST_ASSERT( mbedtls_pk_verify_restartable( &pk,
+                                                MBEDTLS_MD_NONE,
+                                                NULL, 0,
+                                                buf, sizeof( buf ),
+                                                NULL ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    TEST_ASSERT( mbedtls_pk_verify( &pk,
+                                    MBEDTLS_MD_NONE,
+                                    NULL, 0,
+                                    buf, sizeof( buf ) ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    TEST_ASSERT( mbedtls_pk_verify_ext( MBEDTLS_PK_NONE, options,
+                                        &pk,
+                                        MBEDTLS_MD_NONE,
+                                        NULL, 0,
+                                        buf, sizeof( buf ) ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    TEST_ASSERT( mbedtls_pk_encrypt( &pk,
+                                     NULL, 0,
+                                     NULL, &len, 0,
+                                     rnd_std_rand, NULL ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    TEST_ASSERT( mbedtls_pk_decrypt( &pk,
+                                     NULL, 0,
+                                     NULL, &len, 0,
+                                     rnd_std_rand, NULL ) ==
+                 MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_PK_PARSE_C)
+    TEST_ASSERT( mbedtls_pk_parse_key( &pk, NULL, 0, NULL, 1 ) ==
+                 MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+
+    TEST_ASSERT( mbedtls_pk_parse_public_key( &pk, NULL, 0 ) ==
+                 MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+#endif /* MBEDTLS_PK_PARSE_C */
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PK_WRITE_C */
+void valid_parameters_pkwrite( data_t *key_data )
+{
+    mbedtls_pk_context pk;
+
+    /* For the write tests to be effective, we need a valid key pair. */
+    mbedtls_pk_init( &pk );
+    TEST_ASSERT( mbedtls_pk_parse_key( &pk,
+                                       key_data->x, key_data->len,
+                                       NULL, 0 ) == 0 );
+
+    TEST_ASSERT( mbedtls_pk_write_key_der( &pk, NULL, 0 ) ==
+                 MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    TEST_ASSERT( mbedtls_pk_write_pubkey_der( &pk, NULL, 0 ) ==
+                 MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+    TEST_ASSERT( mbedtls_pk_write_key_pem( &pk, NULL, 0 ) ==
+                 MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
+
+    TEST_ASSERT( mbedtls_pk_write_pubkey_pem( &pk, NULL, 0 ) ==
+                 MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
+#endif /* MBEDTLS_PEM_WRITE_C */
+
+exit:
+    mbedtls_pk_free( &pk );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void invalid_parameters( )
+{
+    size_t len;
+    unsigned char *null_buf = NULL;
+    unsigned char buf[1];
+    unsigned char *p = buf;
+    char str[1] = {0};
+    mbedtls_pk_context pk;
+    mbedtls_md_type_t valid_md = MBEDTLS_MD_SHA256;
+    void *options = buf;
+
+    (void) null_buf;
+    (void) p;
+    (void) str;
+
+    mbedtls_pk_init( &pk );
+
+    TEST_INVALID_PARAM( mbedtls_pk_init( NULL ) );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    TEST_INVALID_PARAM( mbedtls_pk_restart_init( NULL ) );
+#endif
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_setup( NULL, NULL ) );
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_setup_rsa_alt( NULL, buf,
+                                                      NULL, NULL, NULL ) );
+#endif
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_restartable( NULL,
+                                                           MBEDTLS_MD_NONE,
+                                                           buf, sizeof( buf ),
+                                                           buf, sizeof( buf ),
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_restartable( &pk,
+                                                           MBEDTLS_MD_NONE,
+                                                           NULL, sizeof( buf ),
+                                                           buf, sizeof( buf ),
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_restartable( &pk,
+                                                           valid_md,
+                                                           NULL, 0,
+                                                           buf, sizeof( buf ),
+                                                           NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_restartable( &pk,
+                                                           MBEDTLS_MD_NONE,
+                                                           buf, sizeof( buf ),
+                                                           NULL, sizeof( buf ),
+                                                           NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify( NULL,
+                                               MBEDTLS_MD_NONE,
+                                               buf, sizeof( buf ),
+                                               buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify( &pk,
+                                               MBEDTLS_MD_NONE,
+                                               NULL, sizeof( buf ),
+                                               buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify( &pk,
+                                               valid_md,
+                                               NULL, 0,
+                                               buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify( &pk,
+                                               MBEDTLS_MD_NONE,
+                                               buf, sizeof( buf ),
+                                               NULL, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_ext( MBEDTLS_PK_NONE, options,
+                                                   NULL,
+                                                   MBEDTLS_MD_NONE,
+                                                   buf, sizeof( buf ),
+                                                   buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_ext( MBEDTLS_PK_NONE, options,
+                                                   &pk,
+                                                   MBEDTLS_MD_NONE,
+                                                   NULL, sizeof( buf ),
+                                                   buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_ext( MBEDTLS_PK_NONE, options,
+                                                   &pk,
+                                                   valid_md,
+                                                   NULL, 0,
+                                                   buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_verify_ext( MBEDTLS_PK_NONE, options,
+                                                   &pk,
+                                                   MBEDTLS_MD_NONE,
+                                                   buf, sizeof( buf ),
+                                                   NULL, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign_restartable( NULL,
+                                                         MBEDTLS_MD_NONE,
+                                                         buf, sizeof( buf ),
+                                                         buf, &len,
+                                                         rnd_std_rand, NULL,
+                                                         NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign_restartable( &pk,
+                                                         MBEDTLS_MD_NONE,
+                                                         NULL, sizeof( buf ),
+                                                         buf, &len,
+                                                         rnd_std_rand, NULL,
+                                                         NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign_restartable( &pk,
+                                                         valid_md,
+                                                         NULL, 0,
+                                                         buf, &len,
+                                                         rnd_std_rand, NULL,
+                                                         NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign_restartable( &pk,
+                                                         MBEDTLS_MD_NONE,
+                                                         buf, sizeof( buf ),
+                                                         NULL, &len,
+                                                         rnd_std_rand, NULL,
+                                                         NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign( NULL,
+                                             MBEDTLS_MD_NONE,
+                                             buf, sizeof( buf ),
+                                             buf, &len,
+                                             rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign( &pk,
+                                             MBEDTLS_MD_NONE,
+                                             NULL, sizeof( buf ),
+                                             buf, &len,
+                                             rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign( &pk,
+                                             valid_md,
+                                             NULL, 0,
+                                             buf, &len,
+                                             rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_sign( &pk,
+                                             MBEDTLS_MD_NONE,
+                                             buf, sizeof( buf ),
+                                             NULL, &len,
+                                             rnd_std_rand, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_decrypt( NULL,
+                                                buf, sizeof( buf ),
+                                                buf, &len, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_decrypt( &pk,
+                                                NULL, sizeof( buf ),
+                                                buf, &len, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_decrypt( &pk,
+                                                buf, sizeof( buf ),
+                                                NULL, &len, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_decrypt( &pk,
+                                                buf, sizeof( buf ),
+                                                buf, NULL, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_encrypt( NULL,
+                                                buf, sizeof( buf ),
+                                                buf, &len, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_encrypt( &pk,
+                                                NULL, sizeof( buf ),
+                                                buf, &len, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_encrypt( &pk,
+                                                buf, sizeof( buf ),
+                                                NULL, &len, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_encrypt( &pk,
+                                                buf, sizeof( buf ),
+                                                buf, NULL, sizeof( buf ),
+                                                rnd_std_rand, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_check_pair( NULL, &pk ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_check_pair( &pk, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_debug( NULL, NULL ) );
+
+#if defined(MBEDTLS_PK_PARSE_C)
+#if defined(MBEDTLS_FS_IO)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_load_file( NULL, &p, &len ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_load_file( str, NULL, &len ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_load_file( str, &p, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_keyfile( NULL, str, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_keyfile( &pk, NULL, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_public_keyfile( NULL, str ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_public_keyfile( &pk, NULL ) );
+#endif
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_subpubkey( NULL, buf, &pk ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_subpubkey( &null_buf, buf, &pk ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_subpubkey( &p, NULL, &pk ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_subpubkey( &p, buf, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_key( NULL,
+                                                  buf, sizeof( buf ),
+                                                  buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_key( &pk,
+                                                  NULL, sizeof( buf ),
+                                                  buf, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_public_key( NULL,
+                                                         buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_parse_public_key( &pk,
+                                                         NULL, sizeof( buf ) ) );
+#endif /* MBEDTLS_PK_PARSE_C */
+
+#if defined(MBEDTLS_PK_WRITE_C)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey( NULL, p, &pk ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey( &null_buf, p, &pk ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey( &p, NULL, &pk ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey( &p, p, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey_der( NULL,
+                                                         buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey_der( &pk,
+                                                         NULL, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_key_der( NULL,
+                                                      buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_key_der( &pk,
+                                                      NULL, sizeof( buf ) ) );
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey_pem( NULL,
+                                                         buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_pubkey_pem( &pk,
+                                                         NULL, sizeof( buf ) ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_key_pem( NULL,
+                                                      buf, sizeof( buf ) ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_PK_BAD_INPUT_DATA,
+                            mbedtls_pk_write_key_pem( &pk,
+                                                      NULL, sizeof( buf ) ) );
+#endif /* MBEDTLS_PEM_WRITE_C */
+
+#endif /* MBEDTLS_PK_WRITE_C */
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void pk_utils( int type, int size, int len, char * name )
 {
     mbedtls_pk_context pk;
diff --git a/tests/suites/test_suite_pkcs1_v15.data b/tests/suites/test_suite_pkcs1_v15.data
index 0309400..a4d6eb5 100644
--- a/tests/suites/test_suite_pkcs1_v15.data
+++ b/tests/suites/test_suite_pkcs1_v15.data
@@ -33,3 +33,93 @@
 
 RSASSA-V15 Verification Test Vector Int
 pkcs1_rsassa_v15_verify:1024:16:"a2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5":16:"010001":MBEDTLS_MD_SHA1:MBEDTLS_MD_SHA1:"859eef2fd78aca00308bdc471193bf55bf9d78db8f8a672b484634f3c9c26e6478ae10260fe0dd8c082e53a5293af2173cd50c6d5d354febf78b26021c25c02712e78cd4694c9f469777e451e7f8e9e04cd3739c6bbfedae487fb55644e9ca74ff77a53cb729802f6ed4a5ffa8ba159890fc":"e3b5d5d002c1bce50c2b65ef88a188d83bce7e61":"2154f928615e5101fcdeb57bc08fc2f35c3d5996403861ae3efb1d0712f8bb05cc21f7f5f11f62e5b6ea9f0f2b62180e5cbe7ba535032d6ac8068fff7f362f73d2c3bf5eca6062a1723d7cfd5abb6dcf7e405f2dc560ffe6fc37d38bee4dc9e24fe2bece3e3b4a3f032701d3f0947b42930083dd4ad241b3309b514595482d42":0
+
+RSAES-V15 decoding: good, payload=max, tight output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505152535455565700":117:117:0
+
+RSAES-V15 decoding: good, payload=max, larger output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505152535455565700":117:128:0
+
+RSAES-V15 decoding: good, payload=max-1, tight output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000250515253545556575800":116:116:0
+
+RSAES-V15 decoding: good, payload=max-1, larger output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000250515253545556575800":116:117:0
+
+RSAES-V15 decoding: good, payload=1
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"00025050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505000":1:1:0
+
+RSAES-V15 decoding: good, empty payload
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505000":0:0:0
+
+RSAES-V15 decoding: payload=max, output too large
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505152535455565700":117:116:MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
+
+RSAES-V15 decoding: payload=max-1, output too large
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000250515253545556575800":116:115:MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
+
+RSAES-V15 decoding: bad first byte
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0102505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSAES-V15 decoding: bad second byte (0 instead of 2)
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0000505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSAES-V15 decoding: bad second byte (1 instead of 2)
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSAES-V15 decoding: padding too short (0)
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000200":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSAES-V15 decoding: padding too short (7)
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505050505050500000ffffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+RSAES-V15 decoding: unfinished padding
+pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: good, payload=max, tight output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffff00":117:117:0
+
+EMSA-V15 decoding: good, payload=max, larger output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffff00":117:128:0
+
+EMSA-V15 decoding: good, payload=max-1, tight output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffff00":116:116:0
+
+EMSA-V15 decoding: good, payload=max-1, larger output buffer
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffff00":116:117:0
+
+EMSA-V15 decoding: good, payload=1
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00":1:1:0
+
+EMSA-V15 decoding: good, empty payload
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00":0:0:0
+
+EMSA-V15 decoding: bad first byte
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0101ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: bad second byte (0 instead of 1)
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0000ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: bad second byte (2 instead of 1)
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0002ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: padding too short (0)
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"000100":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: padding too short (7)
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffff0000ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: invalid padding at first byte
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001fffffffffffffffe00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: invalid padding at last byte
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001feffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: unfinished padding
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: unfinished padding with invalid first byte
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
+
+EMSA-V15 decoding: unfinished padding with invalid last byte
+pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
index 83f417c..0723623 100644
--- a/tests/suites/test_suite_pkcs1_v15.function
+++ b/tests/suites/test_suite_pkcs1_v15.function
@@ -94,6 +94,154 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void pkcs1_v15_decode( int mode,
+                       data_t *input,
+                       int expected_plaintext_length_arg,
+                       int output_size_arg,
+                       int expected_result )
+{
+    size_t expected_plaintext_length = expected_plaintext_length_arg;
+    size_t output_size = output_size_arg;
+    rnd_pseudo_info rnd_info;
+    mbedtls_mpi Nmpi, Empi, Pmpi, Qmpi;
+    mbedtls_rsa_context ctx;
+    static unsigned char N[128] = {
+        0xc4, 0x79, 0x4c, 0x6d, 0xb2, 0xe9, 0xdf, 0xc5,
+        0xe5, 0xd7, 0x55, 0x4b, 0xfb, 0x6c, 0x2e, 0xec,
+        0x84, 0xd0, 0x88, 0x12, 0xaf, 0xbf, 0xb4, 0xf5,
+        0x47, 0x3c, 0x7e, 0x92, 0x4c, 0x58, 0xc8, 0x73,
+        0xfe, 0x8f, 0x2b, 0x8f, 0x8e, 0xc8, 0x5c, 0xf5,
+        0x05, 0xeb, 0xfb, 0x0d, 0x7b, 0x2a, 0x93, 0xde,
+        0x15, 0x0d, 0xc8, 0x13, 0xcf, 0xd2, 0x6f, 0x0d,
+        0x9d, 0xad, 0x30, 0xe5, 0x70, 0x20, 0x92, 0x9e,
+        0xb3, 0x6b, 0xba, 0x5c, 0x50, 0x0f, 0xc3, 0xb2,
+        0x7e, 0x64, 0x07, 0x94, 0x7e, 0xc9, 0x4e, 0xc1,
+        0x65, 0x04, 0xaf, 0xb3, 0x9f, 0xde, 0xa8, 0x46,
+        0xfa, 0x6c, 0xf3, 0x03, 0xaf, 0x1c, 0x1b, 0xec,
+        0x75, 0x44, 0x66, 0x77, 0xc9, 0xde, 0x51, 0x33,
+        0x64, 0x27, 0xb0, 0xd4, 0x8d, 0x31, 0x6a, 0x11,
+        0x27, 0x3c, 0x99, 0xd4, 0x22, 0xc0, 0x9d, 0x12,
+        0x01, 0xc7, 0x4a, 0x73, 0xac, 0xbf, 0xc2, 0xbb
+    };
+    static unsigned char E[1] = { 0x03 };
+    static unsigned char P[64] = {
+        0xe5, 0x53, 0x1f, 0x88, 0x51, 0xee, 0x59, 0xf8,
+        0xc1, 0xe4, 0xcc, 0x5b, 0xb3, 0x75, 0x8d, 0xc8,
+        0xe8, 0x95, 0x2f, 0xd0, 0xef, 0x37, 0xb4, 0xcd,
+        0xd3, 0x9e, 0x48, 0x8b, 0x81, 0x58, 0x60, 0xb9,
+        0x27, 0x1d, 0xb6, 0x28, 0x92, 0x64, 0xa3, 0xa5,
+        0x64, 0xbd, 0xcc, 0x53, 0x68, 0xdd, 0x3e, 0x55,
+        0xea, 0x9d, 0x5e, 0xcd, 0x1f, 0x96, 0x87, 0xf1,
+        0x29, 0x75, 0x92, 0x70, 0x8f, 0x28, 0xfb, 0x2b
+    };
+    static unsigned char Q[64] = {
+        0xdb, 0x53, 0xef, 0x74, 0x61, 0xb4, 0x20, 0x3b,
+        0x3b, 0x87, 0x76, 0x75, 0x81, 0x56, 0x11, 0x03,
+        0x59, 0x31, 0xe3, 0x38, 0x4b, 0x8c, 0x7a, 0x9c,
+        0x05, 0xd6, 0x7f, 0x1e, 0x5e, 0x60, 0xf0, 0x4e,
+        0x0b, 0xdc, 0x34, 0x54, 0x1c, 0x2e, 0x90, 0x83,
+        0x14, 0xef, 0xc0, 0x96, 0x5c, 0x30, 0x10, 0xcc,
+        0xc1, 0xba, 0xa0, 0x54, 0x3f, 0x96, 0x24, 0xca,
+        0xa3, 0xfb, 0x55, 0xbc, 0x71, 0x29, 0x4e, 0xb1
+    };
+    unsigned char original[128];
+    unsigned char intermediate[128];
+    static unsigned char default_content[128] = {
+        /* A randomly generated pattern. */
+        0x4c, 0x27, 0x54, 0xa0, 0xce, 0x0d, 0x09, 0x4a,
+        0x1c, 0x38, 0x8e, 0x2d, 0xa3, 0xc4, 0xe0, 0x19,
+        0x4c, 0x99, 0xb2, 0xbf, 0xe6, 0x65, 0x7e, 0x58,
+        0xd7, 0xb6, 0x8a, 0x05, 0x2f, 0xa5, 0xec, 0xa4,
+        0x35, 0xad, 0x10, 0x36, 0xff, 0x0d, 0x08, 0x50,
+        0x74, 0x47, 0xc9, 0x9c, 0x4a, 0xe7, 0xfd, 0xfa,
+        0x83, 0x5f, 0x14, 0x5a, 0x1e, 0xe7, 0x35, 0x08,
+        0xad, 0xf7, 0x0d, 0x86, 0xdf, 0xb8, 0xd4, 0xcf,
+        0x32, 0xb9, 0x5c, 0xbe, 0xa3, 0xd2, 0x89, 0x70,
+        0x7b, 0xc6, 0x48, 0x7e, 0x58, 0x4d, 0xf3, 0xef,
+        0x34, 0xb7, 0x57, 0x54, 0x79, 0xc5, 0x8e, 0x0a,
+        0xa3, 0xbf, 0x6d, 0x42, 0x83, 0x25, 0x13, 0xa2,
+        0x95, 0xc0, 0x0d, 0x32, 0xec, 0x77, 0x91, 0x2b,
+        0x68, 0xb6, 0x8c, 0x79, 0x15, 0xfb, 0x94, 0xde,
+        0xb9, 0x2b, 0x94, 0xb3, 0x28, 0x23, 0x86, 0x3d,
+        0x37, 0x00, 0xe6, 0xf1, 0x1f, 0x4e, 0xd4, 0x42
+    };
+    unsigned char final[128];
+    size_t output_length = 0x7EA0;
+
+    memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
+    mbedtls_mpi_init( &Nmpi ); mbedtls_mpi_init( &Empi );
+    mbedtls_mpi_init( &Pmpi ); mbedtls_mpi_init( &Qmpi );
+    mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_binary( &Nmpi, N, sizeof( N ) ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &Empi, E, sizeof( E ) ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &Pmpi, P, sizeof( P ) ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &Qmpi, Q, sizeof( Q ) ) == 0 );
+
+    TEST_ASSERT( mbedtls_rsa_import( &ctx, &Nmpi, &Pmpi, &Qmpi,
+                                     NULL, &Empi ) == 0 );
+    TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
+
+    TEST_ASSERT( input->len <= sizeof( N ) );
+    memcpy( original, input->x, input->len );
+    memset( original + input->len, 'd', sizeof( original ) - input->len );
+    if( mode == MBEDTLS_RSA_PRIVATE )
+        TEST_ASSERT( mbedtls_rsa_public( &ctx, original, intermediate ) == 0 );
+    else
+        TEST_ASSERT( mbedtls_rsa_private( &ctx, &rnd_pseudo_rand, &rnd_info,
+                                          original, intermediate ) == 0 );
+
+    memcpy( final, default_content, sizeof( final ) );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx,
+                                            &rnd_pseudo_rand, &rnd_info,
+                                            mode,
+                                            &output_length,
+                                            intermediate,
+                                            final,
+                                            output_size ) == expected_result );
+    if( expected_result == 0 )
+    {
+        TEST_ASSERT( output_length == expected_plaintext_length );
+        TEST_ASSERT( memcmp( original + sizeof( N ) - output_length,
+                             final,
+                             output_length ) == 0 );
+    }
+    else if( expected_result == MBEDTLS_ERR_RSA_INVALID_PADDING ||
+             expected_result == MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE )
+    {
+        size_t max_payload_length =
+            output_size > sizeof( N ) - 11 ? sizeof( N ) - 11 : output_size;
+        size_t i;
+        size_t count = 0;
+
+#if !defined(MBEDTLS_RSA_ALT)
+        /* Check that the output in invalid cases is what the default
+         * implementation currently does. Alternative implementations
+         * may produce different output, so we only perform these precise
+         * checks when using the default implementation. */
+        TEST_ASSERT( output_length == max_payload_length );
+        for( i = 0; i < max_payload_length; i++ )
+            TEST_ASSERT( final[i] == 0 );
+#endif
+        /* Even in alternative implementations, the outputs must have
+         * changed, otherwise it indicates at least a timing vulnerability
+         * because no write to the outputs is performed in the bad case. */
+        TEST_ASSERT( output_length != 0x7EA0 );
+        for( i = 0; i < max_payload_length; i++ )
+            count += ( final[i] == default_content[i] );
+        /* If more than 16 bytes are unchanged in final, that's evidence
+         * that final wasn't overwritten. */
+        TEST_ASSERT( count < 16 );
+    }
+
+exit:
+    mbedtls_mpi_free( &Nmpi ); mbedtls_mpi_free( &Empi );
+    mbedtls_mpi_free( &Pmpi ); mbedtls_mpi_free( &Qmpi );
+    mbedtls_rsa_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void pkcs1_rsassa_v15_sign( int mod, int radix_P, char * input_P, int radix_Q,
                             char * input_Q, int radix_N, char * input_N,
                             int radix_E, char * input_E, int digest, int hash,
diff --git a/tests/suites/test_suite_pkwrite.function b/tests/suites/test_suite_pkwrite.function
index 3ad782d..43c275e 100644
--- a/tests/suites/test_suite_pkwrite.function
+++ b/tests/suites/test_suite_pkwrite.function
@@ -5,7 +5,7 @@
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_PK_WRITE_C:MBEDTLS_BIGNUM_C:MBEDTLS_FS_IO
+ * depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_BIGNUM_C:MBEDTLS_FS_IO
  * END_DEPENDENCIES
  */
 
diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function
index 62d2ad9..066bb39 100644
--- a/tests/suites/test_suite_poly1305.function
+++ b/tests/suites/test_suite_poly1305.function
@@ -88,7 +88,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
 void poly1305_bad_params()
 {
     unsigned char src[1];
@@ -97,38 +97,33 @@
     size_t src_len = sizeof( src );
     mbedtls_poly1305_context ctx;
 
-    mbedtls_poly1305_init( NULL );
-    mbedtls_poly1305_free( NULL );
+    TEST_INVALID_PARAM( mbedtls_poly1305_init( NULL ) );
+    TEST_VALID_PARAM( mbedtls_poly1305_free( NULL ) );
 
-    mbedtls_poly1305_init( &ctx );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_starts( NULL, key ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_starts( &ctx, NULL ) );
 
-    TEST_ASSERT( mbedtls_poly1305_starts( NULL, key )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_poly1305_starts( &ctx, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_update( NULL, src, 0 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_update( &ctx, NULL, src_len ) );
 
-    TEST_ASSERT( mbedtls_poly1305_update( NULL, src, 0 )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_poly1305_update( &ctx, NULL, src_len )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_poly1305_update( &ctx, NULL, 0 )
-                 == 0 );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_finish( NULL, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_finish( &ctx, NULL ) );
 
-    TEST_ASSERT( mbedtls_poly1305_finish( NULL, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_poly1305_finish( &ctx, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_mac( NULL, src, 0, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_mac( key, NULL, src_len, mac ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA,
+                 mbedtls_poly1305_mac( key, src, 0, NULL ) );
 
-    TEST_ASSERT( mbedtls_poly1305_mac( NULL, src, 0, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_poly1305_mac( key, NULL, src_len, mac )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_poly1305_mac( key, src, 0, NULL )
-                 == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
-    TEST_ASSERT( mbedtls_poly1305_mac( key, NULL, 0, mac )
-                 == 0 );
-
-    mbedtls_poly1305_free( &ctx );
+exit:
+    return;
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index e495151..a25d61c 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -1,3 +1,6 @@
+RSA parameter validation
+rsa_invalid_param:
+
 RSA PKCS1 Verify v1.5 CAVS #1
 depends_on:MBEDTLS_SHA1_C:MBEDTLS_PKCS1_V15
 # Good padding but wrong hash
@@ -255,12 +258,6 @@
 depends_on:MBEDTLS_PKCS1_V15
 mbedtls_rsa_pkcs1_verify:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870":MBEDTLS_RSA_PKCS_V15:255:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"3bcf673c3b27f6e2ece4bb97c7a37161e6c6ee7419ef366efc3cfee0f15f415ff6d9d4390937386c6fec1771acba73f24ec6b0469ea8b88083f0b4e1b6069d7bf286e67cf94182a548663137e82a6e09c35de2c27779da0503f1f5bedfebadf2a875f17763a0564df4a6d945a5a3e46bc90fb692af3a55106aafc6b577587456ff8d49cfd5c299d7a2b776dbe4c1ae777b0f64aa3bab27689af32d6cc76157c7dc6900a3469e18a7d9b6bfe4951d1105a08864575e4f4ec05b3e053f9b7a2d5653ae085e50a63380d6bdd6f58ab378d7e0a2be708c559849891317089ab04c82d8bc589ea088b90b11dea5cf85856ff7e609cc1adb1d403beead4c126ff29021":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
 
-RSA PKCS1 Sign #8 (Invalid padding type)
-mbedtls_rsa_pkcs1_sign:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870":2:MBEDTLS_MD_MD5:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"3bcf673c3b27f6e2ece4bb97c7a37161e6c6ee7419ef366efc3cfee0f15f415ff6d9d4390937386c6fec1771acba73f24ec6b0469ea8b88083f0b4e1b6069d7bf286e67cf94182a548663137e82a6e09c35de2c27779da0503f1f5bedfebadf2a875f17763a0564df4a6d945a5a3e46bc90fb692af3a55106aafc6b577587456ff8d49cfd5c299d7a2b776dbe4c1ae777b0f64aa3bab27689af32d6cc76157c7dc6900a3469e18a7d9b6bfe4951d1105a08864575e4f4ec05b3e053f9b7a2d5653ae085e50a63380d6bdd6f58ab378d7e0a2be708c559849891317089ab04c82d8bc589ea088b90b11dea5cf85856ff7e609cc1adb1d403beead4c126ff29021":MBEDTLS_ERR_RSA_INVALID_PADDING
-
-RSA PKCS1 Sign #8 Verify (Invalid padding type)
-mbedtls_rsa_pkcs1_verify:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870":1:MBEDTLS_MD_MD5:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"3bcf673c3b27f6e2ece4bb97c7a37161e6c6ee7419ef366efc3cfee0f15f415ff6d9d4390937386c6fec1771acba73f24ec6b0469ea8b88083f0b4e1b6069d7bf286e67cf94182a548663137e82a6e09c35de2c27779da0503f1f5bedfebadf2a875f17763a0564df4a6d945a5a3e46bc90fb692af3a55106aafc6b577587456ff8d49cfd5c299d7a2b776dbe4c1ae777b0f64aa3bab27689af32d6cc76157c7dc6900a3469e18a7d9b6bfe4951d1105a08864575e4f4ec05b3e053f9b7a2d5653ae085e50a63380d6bdd6f58ab378d7e0a2be708c559849891317089ab04c82d8bc589ea088b90b11dea5cf85856ff7e609cc1adb1d403beead4c126ff29021":MBEDTLS_ERR_RSA_INVALID_PADDING
-
 RSA PKCS1 Encrypt #1
 depends_on:MBEDTLS_PKCS1_V15
 mbedtls_rsa_pkcs1_encrypt:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_RSA_PKCS_V15:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"b0c0b193ba4a5b4502bfacd1a9c2697da5510f3e3ab7274cf404418afd2c62c89b98d83bbc21c8c1bf1afe6d8bf40425e053e9c03e03a3be0edbe1eda073fade1cc286cc0305a493d98fe795634c3cad7feb513edb742d66d910c87d07f6b0055c3488bb262b5fd1ce8747af64801fb39d2d3a3e57086ffe55ab8d0a2ca86975629a0f85767a4990c532a7c2dab1647997ebb234d0b28a0008bfebfc905e7ba5b30b60566a5e0190417465efdbf549934b8f0c5c9f36b7c5b6373a47ae553ced0608a161b1b70dfa509375cf7a3598223a6d7b7a1d1a06ac74d345a9bb7c0e44c8388858a4f1d8115f2bd769ffa69020385fa286302c80e950f9e2751308666c":0
@@ -277,12 +274,6 @@
 depends_on:MBEDTLS_PKCS1_V15
 mbedtls_rsa_pkcs1_decrypt:"deadbeafcafedeadbeeffedcba9876":MBEDTLS_RSA_PKCS_V15:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":1000:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_ERR_RSA_PRIVATE_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
-RSA PKCS1 Encrypt #3 (Invalid padding mode)
-mbedtls_rsa_pkcs1_encrypt:"4E636AF98E40F3ADCFCCB698F4E80B9F":2:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":MBEDTLS_ERR_RSA_INVALID_PADDING
-
-RSA PKCS1 Decrypt #3 (Invalid padding mode)
-mbedtls_rsa_pkcs1_decrypt:"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":2:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":1000:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_ERR_RSA_INVALID_PADDING
-
 RSA PKCS1 Decrypt #4 (Output buffer too small)
 depends_on:MBEDTLS_PKCS1_V15
 mbedtls_rsa_pkcs1_decrypt:"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":MBEDTLS_RSA_PKCS_V15:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":15:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index c43ef20..89c84e8 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -17,6 +17,454 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void rsa_invalid_param( )
+{
+    mbedtls_rsa_context ctx;
+    const int valid_padding = MBEDTLS_RSA_PKCS_V21;
+    const int invalid_padding = 42;
+    const int valid_mode = MBEDTLS_RSA_PRIVATE;
+    const int invalid_mode = 42;
+    unsigned char buf[42] = { 0 };
+    size_t olen;
+
+    TEST_INVALID_PARAM( mbedtls_rsa_init( NULL, valid_padding, 0 ) );
+    TEST_INVALID_PARAM( mbedtls_rsa_init( &ctx, invalid_padding, 0 ) );
+    TEST_VALID_PARAM( mbedtls_rsa_free( NULL ) );
+
+    /* No more variants because only the first argument must be non-NULL. */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_import( NULL, NULL, NULL,
+                                                NULL, NULL, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_import_raw( NULL,
+                                                    NULL, 0,
+                                                    NULL, 0,
+                                                    NULL, 0,
+                                                    NULL, 0,
+                                                    NULL, 0 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_complete( NULL ) );
+
+    /* No more variants because only the first argument must be non-NULL. */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_export( NULL, NULL, NULL,
+                                                NULL, NULL, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_export_raw( NULL,
+                                                    NULL, 0,
+                                                    NULL, 0,
+                                                    NULL, 0,
+                                                    NULL, 0,
+                                                    NULL, 0 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_export_crt( NULL, NULL, NULL, NULL ) );
+
+    TEST_INVALID_PARAM( mbedtls_rsa_set_padding( NULL,
+                                                 valid_padding, 0 ) );
+    TEST_INVALID_PARAM( mbedtls_rsa_set_padding( &ctx,
+                                                 invalid_padding, 0 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_gen_key( NULL, rnd_std_rand,
+                                                 NULL, 0, 0 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_gen_key( &ctx, NULL,
+                                                 NULL, 0, 0 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_check_pubkey( NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_check_privkey( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_check_pub_priv( NULL, &ctx ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_check_pub_priv( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_public( NULL, buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_public( &ctx, NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_public( &ctx, buf, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_private( NULL, NULL, NULL,
+                                                 buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_private( &ctx, NULL, NULL,
+                                                 NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_private( &ctx, NULL, NULL,
+                                                 buf, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_encrypt( NULL, NULL, NULL,
+                                                       valid_mode,
+                                                       sizeof( buf ), buf,
+                                                       buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_encrypt( &ctx, NULL, NULL,
+                                                       invalid_mode,
+                                                       sizeof( buf ), buf,
+                                                       buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_encrypt( &ctx, NULL, NULL,
+                                                       valid_mode,
+                                                       sizeof( buf ), NULL,
+                                                       buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_encrypt( &ctx, NULL, NULL,
+                                                       valid_mode,
+                                                       sizeof( buf ), buf,
+                                                       NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_encrypt( NULL, NULL,
+                                                           NULL,
+                                                           valid_mode,
+                                                           sizeof( buf ), buf,
+                                                           buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_encrypt( &ctx, NULL,
+                                                           NULL,
+                                                           invalid_mode,
+                                                           sizeof( buf ), buf,
+                                                           buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_encrypt( &ctx, NULL,
+                                                           NULL,
+                                                           valid_mode,
+                                                           sizeof( buf ), NULL,
+                                                           buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_encrypt( &ctx, NULL,
+                                                           NULL,
+                                                           valid_mode,
+                                                           sizeof( buf ), buf,
+                                                           NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_encrypt( NULL, NULL, NULL,
+                                                            valid_mode,
+                                                            buf, sizeof( buf ),
+                                                            sizeof( buf ), buf,
+                                                            buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_encrypt( &ctx, NULL, NULL,
+                                                            invalid_mode,
+                                                            buf, sizeof( buf ),
+                                                            sizeof( buf ), buf,
+                                                            buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_encrypt( &ctx, NULL, NULL,
+                                                            valid_mode,
+                                                            NULL, sizeof( buf ),
+                                                            sizeof( buf ), buf,
+                                                            buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_encrypt( &ctx, NULL, NULL,
+                                                            valid_mode,
+                                                            buf, sizeof( buf ),
+                                                            sizeof( buf ), NULL,
+                                                            buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_encrypt( &ctx, NULL, NULL,
+                                                            valid_mode,
+                                                            buf, sizeof( buf ),
+                                                            sizeof( buf ), buf,
+                                                            NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_decrypt( NULL, NULL, NULL,
+                                                       valid_mode, &olen,
+                                                       buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_decrypt( &ctx, NULL, NULL,
+                                                       invalid_mode, &olen,
+                                                       buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_decrypt( &ctx, NULL, NULL,
+                                                       valid_mode, NULL,
+                                                       buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_decrypt( &ctx, NULL, NULL,
+                                                       valid_mode, &olen,
+                                                       NULL, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_decrypt( &ctx, NULL, NULL,
+                                                       valid_mode, &olen,
+                                                       buf, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_decrypt( NULL, NULL,
+                                                           NULL,
+                                                           valid_mode, &olen,
+                                                           buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_decrypt( &ctx, NULL,
+                                                           NULL,
+                                                           invalid_mode, &olen,
+                                                           buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_decrypt( &ctx, NULL,
+                                                           NULL,
+                                                           valid_mode, NULL,
+                                                           buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_decrypt( &ctx, NULL,
+                                                           NULL,
+                                                           valid_mode, &olen,
+                                                           NULL, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_pkcs1_v15_decrypt( &ctx, NULL,
+                                                           NULL,
+                                                           valid_mode, &olen,
+                                                           buf, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_decrypt( NULL, NULL, NULL,
+                                                            valid_mode,
+                                                            buf, sizeof( buf ),
+                                                            &olen,
+                                                            buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_decrypt( &ctx, NULL, NULL,
+                                                            invalid_mode,
+                                                            buf, sizeof( buf ),
+                                                            &olen,
+                                                            buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_decrypt( &ctx, NULL, NULL,
+                                                            valid_mode,
+                                                            NULL, sizeof( buf ),
+                                                            NULL,
+                                                            buf, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_decrypt( &ctx, NULL, NULL,
+                                                            valid_mode,
+                                                            buf, sizeof( buf ),
+                                                            &olen,
+                                                            NULL, buf, 42 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsaes_oaep_decrypt( &ctx, NULL, NULL,
+                                                            valid_mode,
+                                                            buf, sizeof( buf ),
+                                                            &olen,
+                                                            buf, NULL, 42 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_sign( NULL, NULL, NULL,
+                                                    valid_mode,
+                                                    0, sizeof( buf ), buf,
+                                                    buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_sign( &ctx, NULL, NULL,
+                                                    invalid_mode,
+                                                    0, sizeof( buf ), buf,
+                                                    buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_sign( &ctx, NULL, NULL,
+                                                    valid_mode,
+                                                    0, sizeof( buf ), NULL,
+                                                    buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_sign( &ctx, NULL, NULL,
+                                                    valid_mode,
+                                                    0, sizeof( buf ), buf,
+                                                    NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_sign( &ctx, NULL, NULL,
+                                                    valid_mode,
+                                                    MBEDTLS_MD_SHA1,
+                                                    0, NULL,
+                                                    buf ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_sign( NULL, NULL, NULL,
+                                                        valid_mode,
+                                                        0, sizeof( buf ), buf,
+                                                        buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_sign( &ctx, NULL, NULL,
+                                                        invalid_mode,
+                                                        0, sizeof( buf ), buf,
+                                                        buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_sign( &ctx, NULL, NULL,
+                                                        valid_mode,
+                                                        0, sizeof( buf ), NULL,
+                                                        buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_sign( &ctx, NULL, NULL,
+                                                        valid_mode,
+                                                        0, sizeof( buf ), buf,
+                                                        NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_sign( &ctx, NULL, NULL,
+                                                        valid_mode,
+                                                        MBEDTLS_MD_SHA1,
+                                                        0, NULL,
+                                                        buf ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_sign( NULL, NULL, NULL,
+                                                         valid_mode,
+                                                         0, sizeof( buf ), buf,
+                                                         buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_sign( &ctx, NULL, NULL,
+                                                         invalid_mode,
+                                                         0, sizeof( buf ), buf,
+                                                         buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_sign( &ctx, NULL, NULL,
+                                                         valid_mode,
+                                                         0, sizeof( buf ), NULL,
+                                                         buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_sign( &ctx, NULL, NULL,
+                                                         valid_mode,
+                                                         0, sizeof( buf ), buf,
+                                                         NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_sign( &ctx, NULL, NULL,
+                                                         valid_mode,
+                                                         MBEDTLS_MD_SHA1,
+                                                         0, NULL,
+                                                         buf ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_verify( NULL, NULL, NULL,
+                                                      valid_mode,
+                                                      0, sizeof( buf ), buf,
+                                                      buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL,
+                                                      invalid_mode,
+                                                      0, sizeof( buf ), buf,
+                                                      buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL,
+                                                      valid_mode,
+                                                      0, sizeof( buf ), NULL,
+                                                      buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL,
+                                                      valid_mode,
+                                                      0, sizeof( buf ), buf,
+                                                      NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL,
+                                                      valid_mode,
+                                                      MBEDTLS_MD_SHA1, 0, NULL,
+                                                      buf ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_verify( NULL, NULL,
+                                                          NULL,
+                                                          valid_mode,
+                                                          0, sizeof( buf ), buf,
+                                                          buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_verify( &ctx, NULL,
+                                                          NULL,
+                                                          invalid_mode,
+                                                          0, sizeof( buf ), buf,
+                                                          buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_verify( &ctx, NULL,
+                                                          NULL,
+                                                          valid_mode,
+                                                          0, sizeof( buf ),
+                                                          NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_verify( &ctx, NULL,
+                                                          NULL,
+                                                          valid_mode,
+                                                          0, sizeof( buf ), buf,
+                                                          NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pkcs1_v15_verify( &ctx, NULL,
+                                                          NULL,
+                                                          valid_mode,
+                                                          MBEDTLS_MD_SHA1,
+                                                          0, NULL,
+                                                          buf ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify( NULL, NULL, NULL,
+                                                           valid_mode,
+                                                           0, sizeof( buf ),
+                                                           buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify( &ctx, NULL, NULL,
+                                                           invalid_mode,
+                                                           0, sizeof( buf ),
+                                                           buf, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify( &ctx, NULL, NULL,
+                                                           valid_mode,
+                                                           0, sizeof( buf ),
+                                                           NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify( &ctx, NULL, NULL,
+                                                           valid_mode,
+                                                           0, sizeof( buf ),
+                                                           buf, NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify( &ctx, NULL, NULL,
+                                                           valid_mode,
+                                                           MBEDTLS_MD_SHA1,
+                                                           0, NULL,
+                                                           buf ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify_ext( NULL, NULL, NULL,
+                                                               valid_mode,
+                                                               0, sizeof( buf ),
+                                                               buf,
+                                                               0, 0,
+                                                               buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify_ext( &ctx, NULL, NULL,
+                                                               invalid_mode,
+                                                               0, sizeof( buf ),
+                                                               buf,
+                                                               0, 0,
+                                                               buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify_ext( &ctx, NULL, NULL,
+                                                               valid_mode,
+                                                               0, sizeof( buf ),
+                                                               NULL, 0, 0,
+                                                               buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify_ext( &ctx, NULL, NULL,
+                                                               valid_mode,
+                                                               0, sizeof( buf ),
+                                                               buf, 0, 0,
+                                                               NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_rsassa_pss_verify_ext( &ctx, NULL, NULL,
+                                                               valid_mode,
+                                                               MBEDTLS_MD_SHA1,
+                                                               0, NULL,
+                                                               0, 0,
+                                                               buf ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_copy( NULL, &ctx ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_RSA_BAD_INPUT_DATA,
+                            mbedtls_rsa_copy( &ctx, NULL ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void mbedtls_rsa_pkcs1_sign( data_t * message_str, int padding_mode,
                              int digest, int mod, int radix_P, char * input_P,
diff --git a/tests/suites/test_suite_shax.data b/tests/suites/test_suite_shax.data
index ee8074d..2f65c23 100644
--- a/tests/suites/test_suite_shax.data
+++ b/tests/suites/test_suite_shax.data
@@ -1,3 +1,9 @@
+SHA-1 - Valid parameters
+sha1_valid_param:
+
+SHA-1 - Invalid parameters
+sha1_invalid_param:
+
 # Test the operation of SHA-1 and SHA-2
 SHA-1 Test Vector NIST CAVS #1
 depends_on:MBEDTLS_SHA1_C
@@ -39,6 +45,12 @@
 depends_on:MBEDTLS_SHA1_C
 mbedtls_sha1:"8236153781bd2f1b81ffe0def1beb46f5a70191142926651503f1b3bb1016acdb9e7f7acced8dd168226f118ff664a01a8800116fd023587bfba52a2558393476f5fc69ce9c65001f23e70476d2cc81c97ea19caeb194e224339bcb23f77a83feac5096f9b3090c51a6ee6d204b735aa71d7e996d380b80822e4dfd43683af9c7442498cacbea64842dfda238cb099927c6efae07fdf7b23a4e4456e0152b24853fe0d5de4179974b2b9d4a1cdbefcbc01d8d311b5dda059136176ea698ab82acf20dd490be47130b1235cb48f8a6710473cfc923e222d94b582f9ae36d4ca2a32d141b8e8cc36638845fbc499bce17698c3fecae2572dbbd470552430d7ef30c238c2124478f1f780483839b4fb73d63a9460206824a5b6b65315b21e3c2f24c97ee7c0e78faad3df549c7ca8ef241876d9aafe9a309f6da352bec2caaa92ee8dca392899ba67dfed90aef33d41fc2494b765cb3e2422c8e595dabbfaca217757453fb322a13203f425f6073a9903e2dc5818ee1da737afc345f0057744e3a56e1681c949eb12273a3bfc20699e423b96e44bd1ff62e50a848a890809bfe1611c6787d3d741103308f849a790f9c015098286dbacfc34c1718b2c2b77e32194a75dda37954a320fa68764027852855a7e5b5274eb1e2cbcd27161d98b59ad245822015f48af82a45c0ed59be94f9af03d9736048570d6e3ef63b1770bc98dfb77de84b1bb1708d872b625d9ab9b06c18e5dbbf34399391f0f8aa26ec0dac7ff4cb8ec97b52bcb942fa6db2385dcd1b3b9d567aaeb425d567b0ebe267235651a1ed9bf78fd93d3c1dd077fe340bb04b00529c58f45124b717c168d07e9826e33376988bc5cf62845c2009980a4dfa69fbc7e5a0b1bb20a5958ca967aec68eb31dd8fccca9afcd30a26bab26279f1bf6724ff":"11863b483809ef88413ca9b0084ac4a5390640af"
 
+SHA-256 Valid parameters
+sha256_valid_param:
+
+SHA-256 Invalid parameters
+sha256_invalid_param:
+
 SHA-224 Test Vector NIST CAVS #1
 depends_on:MBEDTLS_SHA256_C
 sha224:"":"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"
@@ -95,6 +107,12 @@
 depends_on:MBEDTLS_SHA256_C
 mbedtls_sha256:"8390cf0be07661cc7669aac54ce09a37733a629d45f5d983ef201f9b2d13800e555d9b1097fec3b783d7a50dcb5e2b644b96a1e9463f177cf34906bf388f366db5c2deee04a30e283f764a97c3b377a034fefc22c259214faa99babaff160ab0aaa7e2ccb0ce09c6b32fe08cbc474694375aba703fadbfa31cf685b30a11c57f3cf4edd321e57d3ae6ebb1133c8260e75b9224fa47a2bb205249add2e2e62f817491482ae152322be0900355cdcc8d42a98f82e961a0dc6f537b7b410eff105f59673bfb787bf042aa071f7af68d944d27371c64160fe9382772372516c230c1f45c0d6b6cca7f274b394da9402d3eafdf733994ec58ab22d71829a98399574d4b5908a447a5a681cb0dd50a31145311d92c22a16de1ead66a5499f2dceb4cae694772ce90762ef8336afec653aa9b1a1c4820b221136dfce80dce2ba920d88a530c9410d0a4e0358a3a11052e58dd73b0b179ef8f56fe3b5a2d117a73a0c38a1392b6938e9782e0d86456ee4884e3c39d4d75813f13633bc79baa07c0d2d555afbf207f52b7dca126d015aa2b9873b3eb065e90b9b065a5373fe1fb1b20d594327d19fba56cb81e7b6696605ffa56eba3c27a438697cc21b201fd7e09f18deea1b3ea2f0d1edc02df0e20396a145412cd6b13c32d2e605641c948b714aec30c0649dc44143511f35ab0fd5dd64c34d06fe86f3836dfe9edeb7f08cfc3bd40956826356242191f99f53473f32b0cc0cf9321d6c92a112e8db90b86ee9e87cc32d0343db01e32ce9eb782cb24efbbbeb440fe929e8f2bf8dfb1550a3a2e742e8b455a3e5730e9e6a7a9824d17acc0f72a7f67eae0f0970f8bde46dcdefaed3047cf807e7f00a42e5fd11d40f5e98533d7574425b7d2bc3b3845c443008b58980e768e464e17cc6f6b3939eee52f713963d07d8c4abf02448ef0b889c9671e2f8a436ddeeffcca7176e9bf9d1005ecd377f2fa67c23ed1f137e60bf46018a8bd613d038e883704fc26e798969df35ec7bbc6a4fe46d8910bd82fa3cded265d0a3b6d399e4251e4d8233daa21b5812fded6536198ff13aa5a1cd46a5b9a17a4ddc1d9f85544d1d1cc16f3df858038c8e071a11a7e157a85a6a8dc47e88d75e7009a8b26fdb73f33a2a70f1e0c259f8f9533b9b8f9af9288b7274f21baeec78d396f8bacdcc22471207d9b4efccd3fedc5c5a2214ff5e51c553f35e21ae696fe51e8df733a8e06f50f419e599e9f9e4b37ce643fc810faaa47989771509d69a110ac916261427026369a21263ac4460fb4f708f8ae28599856db7cb6a43ac8e03d64a9609807e76c5f312b9d1863bfa304e8953647648b4f4ab0ed995e":"4109cdbec3240ad74cc6c37f39300f70fede16e21efc77f7865998714aad0b5e"
 
+SHA-512 Invalid parameters
+sha512_invalid_param:
+
+SHA-512 Valid parameters
+sha512_valid_param:
+
 SHA-384 Test Vector NIST CAVS #1
 depends_on:MBEDTLS_SHA512_C
 sha384:"":"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"
diff --git a/tests/suites/test_suite_shax.function b/tests/suites/test_suite_shax.function
index 147ae0e..e621f49 100644
--- a/tests/suites/test_suite_shax.function
+++ b/tests/suites/test_suite_shax.function
@@ -5,6 +5,53 @@
 /* END_HEADER */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA1_C */
+void sha1_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_sha1_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SHA1_C:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void sha1_invalid_param( )
+{
+    mbedtls_sha1_context ctx;
+    unsigned char buf[64] = { 0 };
+    size_t const buflen = sizeof( buf );
+
+    TEST_INVALID_PARAM( mbedtls_sha1_init( NULL ) );
+
+    TEST_INVALID_PARAM( mbedtls_sha1_clone( NULL, &ctx ) );
+    TEST_INVALID_PARAM( mbedtls_sha1_clone( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_sha1_starts_ret( NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_sha1_update_ret( NULL, buf, buflen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_sha1_update_ret( &ctx, NULL, buflen ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_sha1_finish_ret( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_sha1_finish_ret( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_internal_sha1_process( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_internal_sha1_process( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_sha1_ret( NULL, buflen, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA1_BAD_INPUT_DATA,
+                            mbedtls_sha1_ret( buf, buflen, NULL ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SHA1_C */
 void mbedtls_sha1( data_t * src_str, data_t * hex_hash_string )
 {
     unsigned char output[41];
@@ -19,6 +66,62 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
+void sha256_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_sha256_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void sha256_invalid_param( )
+{
+    mbedtls_sha256_context ctx;
+    unsigned char buf[64] = { 0 };
+    size_t const buflen = sizeof( buf );
+    int valid_type = 0;
+    int invalid_type = 42;
+
+    TEST_INVALID_PARAM( mbedtls_sha256_init( NULL ) );
+
+    TEST_INVALID_PARAM( mbedtls_sha256_clone( NULL, &ctx ) );
+    TEST_INVALID_PARAM( mbedtls_sha256_clone( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_starts_ret( NULL, valid_type ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_starts_ret( &ctx, invalid_type ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_update_ret( NULL, buf, buflen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_update_ret( &ctx, NULL, buflen ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_finish_ret( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_finish_ret( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_internal_sha256_process( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_internal_sha256_process( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_ret( NULL, buflen,
+                                                buf, valid_type ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_ret( buf, buflen,
+                                                NULL, valid_type ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA,
+                            mbedtls_sha256_ret( buf, buflen,
+                                                buf, invalid_type ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
 void sha224( data_t * src_str, data_t * hex_hash_string )
 {
     unsigned char output[57];
@@ -47,6 +150,62 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA512_C */
+void sha512_valid_param( )
+{
+    TEST_VALID_PARAM( mbedtls_sha512_free( NULL ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SHA512_C:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
+void sha512_invalid_param( )
+{
+    mbedtls_sha512_context ctx;
+    unsigned char buf[64] = { 0 };
+    size_t const buflen = sizeof( buf );
+    int valid_type = 0;
+    int invalid_type = 42;
+
+    TEST_INVALID_PARAM( mbedtls_sha512_init( NULL ) );
+
+    TEST_INVALID_PARAM( mbedtls_sha512_clone( NULL, &ctx ) );
+    TEST_INVALID_PARAM( mbedtls_sha512_clone( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_starts_ret( NULL, valid_type ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_starts_ret( &ctx, invalid_type ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_update_ret( NULL, buf, buflen ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_update_ret( &ctx, NULL, buflen ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_finish_ret( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_finish_ret( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_internal_sha512_process( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_internal_sha512_process( &ctx, NULL ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_ret( NULL, buflen,
+                                                buf, valid_type ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_ret( buf, buflen,
+                                                NULL, valid_type ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA,
+                            mbedtls_sha512_ret( buf, buflen,
+                                                buf, invalid_type ) );
+
+exit:
+    return;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SHA512_C */
 void sha384( data_t * src_str, data_t * hex_hash_string )
 {
     unsigned char output[97];
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index 3fe549a..62bb782 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.14.0"
+check_compiletime_version:"2.16.0"
 
 Check runtime library version
-check_runtime_version:"2.14.0"
+check_runtime_version:"2.16.0"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0