You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/05/14 07:22:34 UTC

[GitHub] sjanc closed pull request #1079: Update mbedTLS to 2.9.0

sjanc closed pull request #1079: Update mbedTLS to 2.9.0
URL: https://github.com/apache/mynewt-core/pull/1079
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/crypto/mbedtls/include/mbedtls/aes.h b/crypto/mbedtls/include/mbedtls/aes.h
index 1829f7240..e0fc238d7 100644
--- a/crypto/mbedtls/include/mbedtls/aes.h
+++ b/crypto/mbedtls/include/mbedtls/aes.h
@@ -1,9 +1,21 @@
 /**
  * \file aes.h
  *
- * \brief AES block cipher
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * \brief   This file contains AES definitions and functions.
+ *
+ *          The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ *          cryptographic algorithm that can be used to protect electronic
+ *          data.
+ *
+ *          The AES algorithm is a symmetric block cipher that can
+ *          encrypt and decrypt information. For more information, see
+ *          <em>FIPS Publication 197: Advanced Encryption Standard</em> and
+ *          <em>ISO/IEC 18033-2:2006: Information technology -- Security
+ *          techniques -- Encryption algorithms -- Part 2: Asymmetric
+ *          ciphers</em>.
+ */
+
+/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,8 +30,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_AES_H
 #define MBEDTLS_AES_H
 
@@ -33,88 +46,120 @@
 #include <stdint.h>
 
 /* padlock.c and aesni.c rely on these values! */
-#define MBEDTLS_AES_ENCRYPT     1
-#define MBEDTLS_AES_DECRYPT     0
+#define MBEDTLS_AES_ENCRYPT     1 /**< AES encryption. */
+#define MBEDTLS_AES_DECRYPT     0 /**< AES decryption. */
 
+/* Error codes in range 0x0020-0x0022 */
 #define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH                -0x0020  /**< Invalid key length. */
 #define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH              -0x0022  /**< Invalid data input length. */
 
+/* Error codes in range 0x0023-0x0025 */
+#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023  /**< Feature not available. For example, an unsupported AES key size. */
+#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED                   -0x0025  /**< AES hardware accelerator failed. */
+
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
 #define inline __inline
 #endif
 
-#if !defined(MBEDTLS_AES_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_AES_ALT)
+// Regular implementation
+//
+
 /**
- * \brief          AES context structure
- *
- * \note           buf is able to hold 32 extra bytes, which can be used:
- *                 - for alignment purposes if VIA padlock is used, and/or
- *                 - to simplify key expansion in the 256-bit case by
- *                 generating an extra round key
+ * \brief The AES context-type definition.
  */
 typedef struct
 {
-    int nr;                     /*!<  number of rounds  */
-    uint32_t *rk;               /*!<  AES round keys    */
-    uint32_t buf[68];           /*!<  unaligned data    */
+    int nr;                     /*!< The number of rounds. */
+    uint32_t *rk;               /*!< AES round keys. */
+    uint32_t buf[68];           /*!< Unaligned data buffer. This buffer can
+                                     hold 32 extra Bytes, which can be used for
+                                     one of the following purposes:
+                                     <ul><li>Alignment if VIA padlock is
+                                             used.</li>
+                                     <li>Simplifying key expansion in the 256-bit
+                                         case by generating an extra round key.
+                                         </li></ul> */
 }
 mbedtls_aes_context;
 
+#else  /* MBEDTLS_AES_ALT */
+#include "aes_alt.h"
+#endif /* MBEDTLS_AES_ALT */
+
 /**
- * \brief          Initialize AES context
+ * \brief          This function initializes the specified AES context.
+ *
+ *                 It must be the first API called before using
+ *                 the context.
  *
- * \param ctx      AES context to be initialized
+ * \param ctx      The AES context to initialize.
  */
 void mbedtls_aes_init( mbedtls_aes_context *ctx );
 
 /**
- * \brief          Clear AES context
+ * \brief          This function releases and clears the specified AES context.
  *
- * \param ctx      AES context to be cleared
+ * \param ctx      The AES context to clear.
  */
 void mbedtls_aes_free( mbedtls_aes_context *ctx );
 
 /**
- * \brief          AES key schedule (encryption)
+ * \brief          This function sets the encryption key.
  *
- * \param ctx      AES context to be initialized
- * \param key      encryption key
- * \param keybits  must be 128, 192 or 256
+ * \param ctx      The AES 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:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
  *
- * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
 int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
 /**
- * \brief          AES key schedule (decryption)
+ * \brief          This function sets the decryption key.
  *
- * \param ctx      AES context to be initialized
- * \param key      decryption key
- * \param keybits  must be 128, 192 or 256
+ * \param ctx      The AES context to which the key should be bound.
+ * \param key      The decryption key.
+ * \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         0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
 int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
 /**
- * \brief          AES-ECB block encryption/decryption
- *
- * \param ctx      AES context
- * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
- * \param input    16-byte input block
- * \param output   16-byte output block
- *
- * \return         0 if successful
+ * \brief          This function performs an AES single-block encryption or
+ *                 decryption operation.
+ *
+ *                 It performs the operation defined in the \p mode parameter
+ *                 (encrypt or decrypt), on the input data buffer defined in
+ *                 the \p input parameter.
+ *
+ *                 mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
+ *                 mbedtls_aes_setkey_dec() must be called before the first
+ *                 call to this API with the same context.
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ * \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.
+
+ * \return         \c 0 on success.
  */
 int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
                     int mode,
@@ -123,26 +168,41 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
 /**
- * \brief          AES-CBC buffer encryption/decryption
- *                 Length should be a multiple of the block
- *                 size (16 bytes)
- *
- * \note           Upon exit, the content of the IV is updated so that you can
- *                 call the function same function again on the following
- *                 block(s) of data and get the same result as if it was
- *                 encrypted in one call. This allows a "streaming" usage.
- *                 If on the other hand you need to retain the contents of the
- *                 IV, you should either save it manually or use the cipher
- *                 module instead.
- *
- * \param ctx      AES context
- * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_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
- *
- * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+ * \brief  This function performs an AES-CBC encryption or decryption operation
+ *         on full blocks.
+ *
+ *         It performs the operation defined in the \p mode
+ *         parameter (encrypt/decrypt), on the input data buffer defined in
+ *         the \p input parameter.
+ *
+ *         It can be called as many times as needed, until all the input
+ *         data is processed. mbedtls_aes_init(), and either
+ *         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   Upon exit, the content of the IV is updated so that you can
+ *         call the same function again on the next
+ *         block(s) of data and get the same result as if it was
+ *         encrypted in one call. This allows a "streaming" usage.
+ *         If you need to retain the contents of the IV, you should
+ *         either save it manually or use the cipher module instead.
+ *
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ * \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).
+ * \param iv       Initialization vector (updated after use).
+ * \param input    The buffer holding the input data.
+ * \param output   The buffer holding the output data.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+ *                 on failure.
  */
 int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
                     int mode,
@@ -154,29 +214,38 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
 /**
- * \brief          AES-CFB128 buffer encryption/decryption.
- *
- * 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_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
- *
- * \note           Upon exit, the content of the IV is updated so that you can
- *                 call the function same function again on the following
- *                 block(s) of data and get the same result as if it was
- *                 encrypted in one call. This allows a "streaming" usage.
- *                 If on the other hand you need to retain the contents of the
- *                 IV, you should either save it manually or use the cipher
- *                 module instead.
- *
- * \param ctx      AES context
- * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_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
- *
- * \return         0 if successful
+ * \brief This function performs an AES-CFB128 encryption or decryption
+ *        operation.
+ *
+ *        It performs the operation defined in the \p mode
+ *        parameter (encrypt or decrypt), on the input data buffer
+ *        defined in the \p input parameter.
+ *
+ *        For CFB, you must set up the context with mbedtls_aes_setkey_enc(),
+ *        regardless of whether you are performing an encryption or decryption
+ *        operation, that is, regardless of the \p mode parameter. This is
+ *        because CFB mode uses the same key schedule for encryption and
+ *        decryption.
+ *
+ * \note  Upon exit, the content of the IV is updated so that you can
+ *        call the same function again on the next
+ *        block(s) of data and get the same result as if it was
+ *        encrypted in one call. This allows a "streaming" usage.
+ *        If you need to retain the contents of the
+ *        IV, you must either save it manually or use the cipher
+ *        module instead.
+ *
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
+ *                 #MBEDTLS_AES_DECRYPT.
+ * \param length   The length of the input data.
+ * \param iv_off   The offset in IV (updated after use).
+ * \param iv       The initialization vector (updated after use).
+ * \param input    The buffer holding the input data.
+ * \param output   The buffer holding the output data.
+ *
+ * \return         \c 0 on success.
  */
 int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
                        int mode,
@@ -187,28 +256,36 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
                        unsigned char *output );
 
 /**
- * \brief          AES-CFB8 buffer encryption/decryption.
- *
- * 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_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
- *
- * \note           Upon exit, the content of the IV is updated so that you can
- *                 call the function same function again on the following
- *                 block(s) of data and get the same result as if it was
- *                 encrypted in one call. This allows a "streaming" usage.
- *                 If on the other hand you need to retain the contents of the
- *                 IV, you should either save it manually or use the cipher
- *                 module instead.
- *
- * \param ctx      AES context
- * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_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
- *
- * \return         0 if successful
+ * \brief This function performs an AES-CFB8 encryption or decryption
+ *        operation.
+ *
+ *        It performs the operation defined in the \p mode
+ *        parameter (encrypt/decrypt), on the input data buffer defined
+ *        in the \p input parameter.
+ *
+ *        Due to the nature of CFB, you must use the same key schedule for
+ *        both encryption and decryption operations. Therefore, you must
+ *        use the context initialized with mbedtls_aes_setkey_enc() for
+ *        both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
+ *
+ * \note  Upon exit, the content of the IV is updated so that you can
+ *        call the same function again on the next
+ *        block(s) of data and get the same result as if it was
+ *        encrypted in one call. This allows a "streaming" usage.
+ *        If you need to retain the contents of the
+ *        IV, you should either save it manually or use the cipher
+ *        module instead.
+ *
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ * \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).
+ * \param input    The buffer holding the input data.
+ * \param output   The buffer holding the output data.
+ *
+ * \return         \c 0 on success.
  */
 int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
                     int mode,
@@ -220,26 +297,32 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /**
- * \brief               AES-CTR buffer encryption/decryption
- *
- * Warning: You have to keep the maximum use of your counter in mind!
- *
- * 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_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
- *
- * \param ctx           AES context
- * \param length        The length of the data
- * \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 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
- *
- * \return         0 if successful
+ * \brief      This function performs an AES-CTR encryption or decryption
+ *             operation.
+ *
+ *             This function performs the operation defined in the \p mode
+ *             parameter (encrypt/decrypt), on the input data buffer
+ *             defined in the \p input parameter.
+ *
+ *             Due to the nature of CTR, you must use the same key schedule
+ *             for both encryption and decryption operations. Therefore, you
+ *             must use the context initialized with mbedtls_aes_setkey_enc()
+ *             for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
+ *
+ * \warning    You must keep the maximum use of your counter in mind.
+ *
+ * \param ctx              The AES 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.
+ *
+ * \return                 \c 0 on success.
  */
 int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
                        size_t length,
@@ -251,30 +334,30 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
 /**
- * \brief           Internal AES block encryption function
- *                  (Only exposed to allow overriding it,
- *                  see MBEDTLS_AES_ENCRYPT_ALT)
+ * \brief           Internal AES block encryption function. This is only
+ *                  exposed to allow overriding it using
+ *                  \c MBEDTLS_AES_ENCRYPT_ALT.
  *
- * \param ctx       AES context
- * \param input     Plaintext block
- * \param output    Output (ciphertext) block
+ * \param ctx       The AES context to use for encryption.
+ * \param input     The plaintext block.
+ * \param output    The output (ciphertext) block.
  *
- * \return          0 if successful
+ * \return          \c 0 on success.
  */
 int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
                                   unsigned char output[16] );
 
 /**
- * \brief           Internal AES block decryption function
- *                  (Only exposed to allow overriding it,
- *                  see MBEDTLS_AES_DECRYPT_ALT)
+ * \brief           Internal AES block decryption function. This is only
+ *                  exposed to allow overriding it using see
+ *                  \c MBEDTLS_AES_DECRYPT_ALT.
  *
- * \param ctx       AES context
- * \param input     Ciphertext block
- * \param output    Output (plaintext) block
+ * \param ctx       The AES context to use for decryption.
+ * \param input     The ciphertext block.
+ * \param output    The output (plaintext) block.
  *
- * \return          0 if successful
+ * \return          \c 0 on success.
  */
 int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
@@ -290,11 +373,11 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
  * \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_aes_encrypt_ext() in 2.5.0.
  *
- * \param ctx       AES context
- * \param input     Plaintext block
- * \param output    Output (ciphertext) block
+ * \param ctx       The AES context to use for encryption.
+ * \param input     Plaintext block.
+ * \param output    Output (ciphertext) block.
  */
 MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
                                              const unsigned char input[16],
@@ -304,11 +387,11 @@ MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
  * \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_aes_decrypt_ext() in 2.5.0.
  *
- * \param ctx       AES context
- * \param input     Ciphertext block
- * \param output    Output (plaintext) block
+ * \param ctx       The AES context to use for decryption.
+ * \param input     Ciphertext block.
+ * \param output    Output (plaintext) block.
  */
 MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
                                              const unsigned char input[16],
@@ -317,22 +400,11 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_AES_ALT */
-#include "aes_alt.h"
-#endif /* MBEDTLS_AES_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
- * \brief          Checkup routine
+ * \brief          Checkup routine.
  *
- * \return         0 if successful, or 1 if the test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_aes_self_test( int verbose );
 
diff --git a/crypto/mbedtls/include/mbedtls/aesni.h b/crypto/mbedtls/include/mbedtls/aesni.h
index b1b7f1cde..746baa0e1 100644
--- a/crypto/mbedtls/include/mbedtls/aesni.h
+++ b/crypto/mbedtls/include/mbedtls/aesni.h
@@ -2,7 +2,8 @@
  * \file aesni.h
  *
  * \brief AES-NI for hardware AES acceleration on some Intel processors
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/arc4.h b/crypto/mbedtls/include/mbedtls/arc4.h
index 5fc5395a8..f11fc5be0 100644
--- a/crypto/mbedtls/include/mbedtls/arc4.h
+++ b/crypto/mbedtls/include/mbedtls/arc4.h
@@ -3,6 +3,10 @@
  *
  * \brief The ARCFOUR stream cipher
  *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -19,6 +23,7 @@
  *  limitations under the License.
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
  */
 #ifndef MBEDTLS_ARC4_H
 #define MBEDTLS_ARC4_H
@@ -31,16 +36,22 @@
 
 #include <stddef.h>
 
-#if !defined(MBEDTLS_ARC4_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED                  -0x0019  /**< ARC4 hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_ARC4_ALT)
+// Regular implementation
+//
+
 /**
- * \brief          ARC4 context structure
+ * \brief     ARC4 context structure
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ *
  */
 typedef struct
 {
@@ -50,10 +61,19 @@ typedef struct
 }
 mbedtls_arc4_context;
 
+#else  /* MBEDTLS_ARC4_ALT */
+#include "arc4_alt.h"
+#endif /* MBEDTLS_ARC4_ALT */
+
 /**
  * \brief          Initialize ARC4 context
  *
  * \param ctx      ARC4 context to be initialized
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
  */
 void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
 
@@ -61,6 +81,11 @@ void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
  * \brief          Clear ARC4 context
  *
  * \param ctx      ARC4 context to be cleared
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
  */
 void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
 
@@ -70,6 +95,11 @@ void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
  * \param ctx      ARC4 context to be setup
  * \param key      the secret key
  * \param keylen   length of the key, in bytes
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
  */
 void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
                  unsigned int keylen );
@@ -83,26 +113,24 @@ void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
  * \param output   buffer for the output data
  *
  * \return         0 if successful
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
  */
 int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
                 unsigned char *output );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_ARC4_ALT */
-#include "arc4_alt.h"
-#endif /* MBEDTLS_ARC4_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
  */
 int mbedtls_arc4_self_test( int verbose );
 
diff --git a/crypto/mbedtls/include/mbedtls/asn1.h b/crypto/mbedtls/include/mbedtls/asn1.h
index 082832c87..96c1c9a8a 100644
--- a/crypto/mbedtls/include/mbedtls/asn1.h
+++ b/crypto/mbedtls/include/mbedtls/asn1.h
@@ -2,7 +2,8 @@
  * \file asn1.h
  *
  * \brief Generic ASN.1 parsing
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -59,7 +60,7 @@
 
 /**
  * \name DER constants
- * These constants comply with DER encoded the ANS1 type tags.
+ * These constants comply with the DER encoded ASN.1 type tags.
  * DER encoding uses hexadecimal representation.
  * An example DER sequence is:\n
  * - 0x02 -- tag indicating INTEGER
@@ -87,6 +88,21 @@
 #define MBEDTLS_ASN1_PRIMITIVE               0x00
 #define MBEDTLS_ASN1_CONSTRUCTED             0x20
 #define MBEDTLS_ASN1_CONTEXT_SPECIFIC        0x80
+
+/*
+ * Bit masks for each of the components of an ASN.1 tag as specified in
+ * ITU X.690 (08/2015), section 8.1 "General rules for encoding",
+ * paragraph 8.1.2.2:
+ *
+ * Bit  8     7   6   5          1
+ *     +-------+-----+------------+
+ *     | Class | P/C | Tag number |
+ *     +-------+-----+------------+
+ */
+#define MBEDTLS_ASN1_TAG_CLASS_MASK          0xC0
+#define MBEDTLS_ASN1_TAG_PC_MASK             0x20
+#define MBEDTLS_ASN1_TAG_VALUE_MASK          0x1F
+
 /* \} name */
 /* \} addtogroup asn1_module */
 
diff --git a/crypto/mbedtls/include/mbedtls/asn1write.h b/crypto/mbedtls/include/mbedtls/asn1write.h
index 73ff32b66..f76fc807d 100644
--- a/crypto/mbedtls/include/mbedtls/asn1write.h
+++ b/crypto/mbedtls/include/mbedtls/asn1write.h
@@ -2,7 +2,8 @@
  * \file asn1write.h
  *
  * \brief ASN.1 buffer writing functionality
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/base64.h b/crypto/mbedtls/include/mbedtls/base64.h
index 352c652db..7a64f5216 100644
--- a/crypto/mbedtls/include/mbedtls/base64.h
+++ b/crypto/mbedtls/include/mbedtls/base64.h
@@ -2,7 +2,8 @@
  * \file base64.h
  *
  * \brief RFC 1521 base64 encoding/decoding
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/bignum.h b/crypto/mbedtls/include/mbedtls/bignum.h
index 456a80420..31383b1eb 100644
--- a/crypto/mbedtls/include/mbedtls/bignum.h
+++ b/crypto/mbedtls/include/mbedtls/bignum.h
@@ -1,8 +1,9 @@
 /**
  * \file bignum.h
  *
- * \brief  Multi-precision integer library
- *
+ * \brief Multi-precision integer library
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -70,7 +71,7 @@
  * Maximum size of MPIs allowed in bits and bytes for user-MPIs.
  * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
  *
- * Note: Calculations can results temporarily in larger MPIs. So the number
+ * Note: Calculations can temporarily result in larger MPIs. So the number
  * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher.
  */
 #define MBEDTLS_MPI_MAX_SIZE                              1024     /**< Maximum number of bytes for usable MPIs. */
@@ -203,6 +204,8 @@ void mbedtls_mpi_free( mbedtls_mpi *X );
 /**
  * \brief          Enlarge to the specified number of limbs
  *
+ *                 This function does nothing if the MPI is already large enough.
+ *
  * \param X        MPI to grow
  * \param nblimbs  The target number of limbs
  *
@@ -214,19 +217,23 @@ int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs );
 /**
  * \brief          Resize down, 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
  *
  * \return         0 if successful,
  *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ *                 (this can only happen when resizing up).
  */
 int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs );
 
 /**
  * \brief          Copy the contents of Y into X
  *
- * \param X        Destination MPI
- * \param Y        Source MPI
+ * \param X        Destination MPI. It is enlarged if necessary.
+ * \param Y        Source MPI.
  *
  * \return         0 if successful,
  *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
@@ -683,6 +690,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
  *
  * \return         0 if successful,
  *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ *
+ * \note           The bytes obtained from the PRNG are interpreted
+ *                 as a big-endian representation of an MPI; this can
+ *                 be relevant in applications like deterministic ECDSA.
  */
 int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
                      int (*f_rng)(void *, unsigned char *, size_t),
diff --git a/crypto/mbedtls/include/mbedtls/blowfish.h b/crypto/mbedtls/include/mbedtls/blowfish.h
index 34626eef4..22479be5a 100644
--- a/crypto/mbedtls/include/mbedtls/blowfish.h
+++ b/crypto/mbedtls/include/mbedtls/blowfish.h
@@ -2,7 +2,8 @@
  * \file blowfish.h
  *
  * \brief Blowfish block cipher
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -40,16 +41,17 @@
 #define MBEDTLS_BLOWFISH_BLOCKSIZE   8          /* Blowfish uses 64 bit blocks */
 
 #define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH                -0x0016  /**< Invalid key length. */
+#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED                   -0x0017  /**< Blowfish hardware accelerator failed. */
 #define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH              -0x0018  /**< Invalid data input length. */
 
-#if !defined(MBEDTLS_BLOWFISH_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_BLOWFISH_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          Blowfish context structure
  */
@@ -60,6 +62,10 @@ typedef struct
 }
 mbedtls_blowfish_context;
 
+#else  /* MBEDTLS_BLOWFISH_ALT */
+#include "blowfish_alt.h"
+#endif /* MBEDTLS_BLOWFISH_ALT */
+
 /**
  * \brief          Initialize Blowfish context
  *
@@ -196,8 +202,4 @@ int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
 }
 #endif
 
-#else  /* MBEDTLS_BLOWFISH_ALT */
-#include "blowfish_alt.h"
-#endif /* MBEDTLS_BLOWFISH_ALT */
-
 #endif /* blowfish.h */
diff --git a/crypto/mbedtls/include/mbedtls/bn_mul.h b/crypto/mbedtls/include/mbedtls/bn_mul.h
index cac3f1457..354c1cc1a 100644
--- a/crypto/mbedtls/include/mbedtls/bn_mul.h
+++ b/crypto/mbedtls/include/mbedtls/bn_mul.h
@@ -1,8 +1,9 @@
 /**
  * \file bn_mul.h
  *
- * \brief  Multi-precision integer library
- *
+ * \brief Multi-precision integer library
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/camellia.h b/crypto/mbedtls/include/mbedtls/camellia.h
index 0424d623f..f0466bfd7 100644
--- a/crypto/mbedtls/include/mbedtls/camellia.h
+++ b/crypto/mbedtls/include/mbedtls/camellia.h
@@ -2,7 +2,8 @@
  * \file camellia.h
  *
  * \brief Camellia block cipher
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -37,15 +38,16 @@
 
 #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_CAMELLIA_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED              -0x0027  /**< Camellia hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_CAMELLIA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          CAMELLIA context structure
  */
@@ -56,6 +58,10 @@ typedef struct
 }
 mbedtls_camellia_context;
 
+#else  /* MBEDTLS_CAMELLIA_ALT */
+#include "camellia_alt.h"
+#endif /* MBEDTLS_CAMELLIA_ALT */
+
 /**
  * \brief          Initialize CAMELLIA context
  *
@@ -209,18 +215,6 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
                        unsigned char *output );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_CAMELLIA_ALT */
-#include "camellia_alt.h"
-#endif /* MBEDTLS_CAMELLIA_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Checkup routine
  *
diff --git a/crypto/mbedtls/include/mbedtls/ccm.h b/crypto/mbedtls/include/mbedtls/ccm.h
index ef75839ba..8585ce5e7 100644
--- a/crypto/mbedtls/include/mbedtls/ccm.h
+++ b/crypto/mbedtls/include/mbedtls/ccm.h
@@ -1,9 +1,22 @@
 /**
  * \file ccm.h
  *
- * \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers
+ * \brief This file provides an API for the CCM authenticated encryption
+ *        mode for block ciphers.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * CCM combines Counter mode encryption with CBC-MAC authentication
+ * for 128-bit block ciphers.
+ *
+ * Input to CCM includes the following elements:
+ * <ul><li>Payload - data that is both authenticated and encrypted.</li>
+ * <li>Associated data (Adata) - data that is authenticated but not
+ * encrypted, For example, a header.</li>
+ * <li>Nonce - A unique value that is assigned to the payload and the
+ * associated data.</li></ul>
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,46 +31,60 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_CCM_H
 #define MBEDTLS_CCM_H
 
 #include "cipher.h"
 
-#define MBEDTLS_ERR_CCM_BAD_INPUT      -0x000D /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_CCM_AUTH_FAILED    -0x000F /**< Authenticated decryption failed. */
+#define MBEDTLS_ERR_CCM_BAD_INPUT       -0x000D /**< Bad input parameters to the function. */
+#define MBEDTLS_ERR_CCM_AUTH_FAILED     -0x000F /**< Authenticated decryption failed. */
+#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
+
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_CCM_ALT)
+// Regular implementation
+//
+
 /**
- * \brief          CCM context structure
+ * \brief    The CCM context-type definition. The CCM context is passed
+ *           to the APIs called.
  */
 typedef struct {
-    mbedtls_cipher_context_t cipher_ctx;    /*!< cipher context used */
+    mbedtls_cipher_context_t cipher_ctx;    /*!< The cipher context used. */
 }
 mbedtls_ccm_context;
 
+#else  /* MBEDTLS_CCM_ALT */
+#include "ccm_alt.h"
+#endif /* MBEDTLS_CCM_ALT */
+
 /**
- * \brief           Initialize CCM context (just makes references valid)
- *                  Makes the context ready for mbedtls_ccm_setkey() or
- *                  mbedtls_ccm_free().
+ * \brief           This function initializes the specified CCM context,
+ *                  to make references valid, and prepare the context
+ *                  for mbedtls_ccm_setkey() or mbedtls_ccm_free().
  *
- * \param ctx       CCM context to initialize
+ * \param ctx       The CCM context to initialize.
  */
 void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
 
 /**
- * \brief           CCM initialization (encryption and decryption)
+ * \brief           This function initializes the CCM context set in the
+ *                  \p ctx parameter and sets the encryption key.
  *
- * \param ctx       CCM context to be initialized
- * \param cipher    cipher to use (a 128-bit block cipher)
- * \param key       encryption key
- * \param keybits   key size in bits (must be acceptable by the cipher)
+ * \param ctx       The CCM context to initialize.
+ * \param cipher    The 128-bit block cipher to use.
+ * \param key       The encryption key.
+ * \param keybits   The key size in bits. This must be acceptable by the cipher.
  *
- * \return          0 if successful, or a cipher specific error code
+ * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
  */
 int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
                         mbedtls_cipher_id_t cipher,
@@ -65,36 +92,39 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
                         unsigned int keybits );
 
 /**
- * \brief           Free a CCM context and underlying cipher sub-context
+ * \brief   This function releases and clears the specified CCM context
+ *          and underlying cipher sub-context.
  *
- * \param ctx       CCM context to free
+ * \param ctx       The CCM context to clear.
  */
 void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
 
 /**
- * \brief           CCM buffer encryption
- *
- * \param ctx       CCM context
- * \param length    length of the input data in bytes
- * \param iv        nonce (initialization vector)
- * \param iv_len    length of IV in bytes
- *                  must be 2, 3, 4, 5, 6, 7 or 8
- * \param add       additional data
- * \param add_len   length of additional data in bytes
- *                  must be less than 2^16 - 2^8
- * \param input     buffer holding the input data
- * \param output    buffer for holding the output data
- *                  must be at least 'length' bytes wide
- * \param tag       buffer for holding the tag
- * \param tag_len   length of the tag to generate in bytes
- *                  must be 4, 6, 8, 10, 14 or 16
- *
- * \note            The tag is written to a separate buffer. To get the tag
- *                  concatenated with the output as in the CCM spec, use
- *                  tag = output + length and make sure the output buffer is
- *                  at least length + tag_len wide.
- *
- * \return          0 if successful
+ * \brief           This function encrypts a buffer using CCM.
+ *
+ *
+ * \note            The tag is written to a separate buffer. To concatenate
+ *                  the \p tag with the \p output, as done in <em>RFC-3610:
+ *                  Counter with CBC-MAC (CCM)</em>, use
+ *                  \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 length    The length of the input data in Bytes.
+ * \param iv        Initialization vector (nonce).
+ * \param iv_len    The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
+ * \param add       The additional data field.
+ * \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 tag.
+ * \param tag_len   The length of the tag to generate in Bytes:
+ *                  4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
  */
 int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
                          const unsigned char *iv, size_t iv_len,
@@ -103,21 +133,26 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
                          unsigned char *tag, size_t tag_len );
 
 /**
- * \brief           CCM buffer authenticated decryption
- *
- * \param ctx       CCM context
- * \param length    length of the input data
- * \param iv        initialization vector
- * \param iv_len    length of IV
- * \param add       additional data
- * \param add_len   length of additional data
- * \param input     buffer holding the input data
- * \param output    buffer for holding the output data
- * \param tag       buffer holding the tag
- * \param tag_len   length of the tag
- *
- * \return         0 if successful and authenticated,
- *                 MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match
+ * \brief           This function performs a CCM authenticated decryption of a
+ *                  buffer.
+ *
+ * \param ctx       The CCM context to use for decryption.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        Initialization vector.
+ * \param iv_len    The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
+ * \param add       The additional data field.
+ * \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 tag.
+ * \param tag_len   The length of the tag in Bytes.
+ *                  4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \return          \c 0 on success. This indicates that the message is authentic.
+ * \return          #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return          A cipher-specific error code on calculation failure.
  */
 int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                       const unsigned char *iv, size_t iv_len,
@@ -125,11 +160,13 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                       const unsigned char *input, unsigned char *output,
                       const unsigned char *tag, size_t tag_len );
 
+
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
 /**
- * \brief          Checkup routine
+ * \brief          The CCM checkup routine.
  *
- * \return         0 if successful, or 1 if the test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_ccm_self_test( int verbose );
 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
diff --git a/crypto/mbedtls/include/mbedtls/certs.h b/crypto/mbedtls/include/mbedtls/certs.h
index ca49086e4..8dab7b5ce 100644
--- a/crypto/mbedtls/include/mbedtls/certs.h
+++ b/crypto/mbedtls/include/mbedtls/certs.h
@@ -2,7 +2,8 @@
  * \file certs.h
  *
  * \brief Sample certificates and DHM parameters for testing
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/check_config.h b/crypto/mbedtls/include/mbedtls/check_config.h
index fa72454e5..be8033296 100644
--- a/crypto/mbedtls/include/mbedtls/check_config.h
+++ b/crypto/mbedtls/include/mbedtls/check_config.h
@@ -2,7 +2,8 @@
  * \file check_config.h
  *
  * \brief Consistency checks for configuration options
- *
+ */
+/*
  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -77,6 +78,10 @@
 #error "MBEDTLS_DHM_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_CMAC_C) && \
     !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
 #error "MBEDTLS_CMAC_C defined, but not all prerequisites"
diff --git a/crypto/mbedtls/include/mbedtls/cipher.h b/crypto/mbedtls/include/mbedtls/cipher.h
index b12e38843..3ee2ab7db 100644
--- a/crypto/mbedtls/include/mbedtls/cipher.h
+++ b/crypto/mbedtls/include/mbedtls/cipher.h
@@ -1,11 +1,14 @@
 /**
  * \file cipher.h
  *
- * \brief Generic cipher wrapper.
+ * \brief This file contains an abstraction interface for use with the cipher
+ * primitives provided by the library. It provides a common interface to all of
+ * the available cipher operations.
  *
  * \author Adriaan de Jong <de...@fox-it.com>
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -20,7 +23,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
 
 #ifndef MBEDTLS_CIPHER_H
@@ -51,104 +54,122 @@
 #define inline __inline
 #endif
 
-#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE            -0x6080  /**< The selected feature is not available. */
-#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA                 -0x6100  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED                   -0x6180  /**< Failed to allocate memory. */
-#define MBEDTLS_ERR_CIPHER_INVALID_PADDING                -0x6200  /**< Input data contains invalid padding and is rejected. */
-#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED            -0x6280  /**< Decryption of block requires a full block. */
-#define MBEDTLS_ERR_CIPHER_AUTH_FAILED                    -0x6300  /**< Authentication failed (for AEAD modes). */
-#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT              -0x6380  /**< The context is invalid, eg because it was free()ed. */
+#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE  -0x6080  /**< The selected feature is not available. */
+#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA       -0x6100  /**< Bad input parameters. */
+#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED         -0x6180  /**< Failed to allocate memory. */
+#define MBEDTLS_ERR_CIPHER_INVALID_PADDING      -0x6200  /**< Input data contains invalid padding and is rejected. */
+#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED  -0x6280  /**< Decryption of block requires a full block. */
+#define MBEDTLS_ERR_CIPHER_AUTH_FAILED          -0x6300  /**< Authentication failed (for AEAD modes). */
+#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT      -0x6380  /**< The context is invalid. For example, because it was freed. */
+#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED      -0x6400  /**< Cipher hardware accelerator failed. */
 
-#define MBEDTLS_CIPHER_VARIABLE_IV_LEN     0x01    /**< Cipher accepts IVs of variable length */
-#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN    0x02    /**< Cipher accepts keys of variable length */
+#define MBEDTLS_CIPHER_VARIABLE_IV_LEN     0x01    /**< Cipher accepts IVs of variable length. */
+#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN    0x02    /**< Cipher accepts keys of variable length. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * \brief     Supported cipher types.
+ *
+ * \warning   RC4 and DES are considered weak ciphers and their use
+ *            constitutes a security risk. Arm recommends considering stronger
+ *            ciphers instead.
+ */
 typedef enum {
-    MBEDTLS_CIPHER_ID_NONE = 0,
-    MBEDTLS_CIPHER_ID_NULL,
-    MBEDTLS_CIPHER_ID_AES,
-    MBEDTLS_CIPHER_ID_DES,
-    MBEDTLS_CIPHER_ID_3DES,
-    MBEDTLS_CIPHER_ID_CAMELLIA,
-    MBEDTLS_CIPHER_ID_BLOWFISH,
-    MBEDTLS_CIPHER_ID_ARC4,
+    MBEDTLS_CIPHER_ID_NONE = 0,  /**< Placeholder to mark the end of cipher ID lists. */
+    MBEDTLS_CIPHER_ID_NULL,      /**< The identity cipher, treated as a stream cipher. */
+    MBEDTLS_CIPHER_ID_AES,       /**< The AES cipher. */
+    MBEDTLS_CIPHER_ID_DES,       /**< The DES cipher. */
+    MBEDTLS_CIPHER_ID_3DES,      /**< The Triple DES cipher. */
+    MBEDTLS_CIPHER_ID_CAMELLIA,  /**< The Camellia cipher. */
+    MBEDTLS_CIPHER_ID_BLOWFISH,  /**< The Blowfish cipher. */
+    MBEDTLS_CIPHER_ID_ARC4,      /**< The RC4 cipher. */
 } mbedtls_cipher_id_t;
 
+/**
+ * \brief     Supported {cipher type, cipher mode} pairs.
+ *
+ * \warning   RC4 and DES are considered weak ciphers and their use
+ *            constitutes a security risk. Arm recommends considering stronger
+ *            ciphers instead.
+ */
 typedef enum {
-    MBEDTLS_CIPHER_NONE = 0,
-    MBEDTLS_CIPHER_NULL,
-    MBEDTLS_CIPHER_AES_128_ECB,
-    MBEDTLS_CIPHER_AES_192_ECB,
-    MBEDTLS_CIPHER_AES_256_ECB,
-    MBEDTLS_CIPHER_AES_128_CBC,
-    MBEDTLS_CIPHER_AES_192_CBC,
-    MBEDTLS_CIPHER_AES_256_CBC,
-    MBEDTLS_CIPHER_AES_128_CFB128,
-    MBEDTLS_CIPHER_AES_192_CFB128,
-    MBEDTLS_CIPHER_AES_256_CFB128,
-    MBEDTLS_CIPHER_AES_128_CTR,
-    MBEDTLS_CIPHER_AES_192_CTR,
-    MBEDTLS_CIPHER_AES_256_CTR,
-    MBEDTLS_CIPHER_AES_128_GCM,
-    MBEDTLS_CIPHER_AES_192_GCM,
-    MBEDTLS_CIPHER_AES_256_GCM,
-    MBEDTLS_CIPHER_CAMELLIA_128_ECB,
-    MBEDTLS_CIPHER_CAMELLIA_192_ECB,
-    MBEDTLS_CIPHER_CAMELLIA_256_ECB,
-    MBEDTLS_CIPHER_CAMELLIA_128_CBC,
-    MBEDTLS_CIPHER_CAMELLIA_192_CBC,
-    MBEDTLS_CIPHER_CAMELLIA_256_CBC,
-    MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
-    MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
-    MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
-    MBEDTLS_CIPHER_CAMELLIA_128_CTR,
-    MBEDTLS_CIPHER_CAMELLIA_192_CTR,
-    MBEDTLS_CIPHER_CAMELLIA_256_CTR,
-    MBEDTLS_CIPHER_CAMELLIA_128_GCM,
-    MBEDTLS_CIPHER_CAMELLIA_192_GCM,
-    MBEDTLS_CIPHER_CAMELLIA_256_GCM,
-    MBEDTLS_CIPHER_DES_ECB,
-    MBEDTLS_CIPHER_DES_CBC,
-    MBEDTLS_CIPHER_DES_EDE_ECB,
-    MBEDTLS_CIPHER_DES_EDE_CBC,
-    MBEDTLS_CIPHER_DES_EDE3_ECB,
-    MBEDTLS_CIPHER_DES_EDE3_CBC,
-    MBEDTLS_CIPHER_BLOWFISH_ECB,
-    MBEDTLS_CIPHER_BLOWFISH_CBC,
-    MBEDTLS_CIPHER_BLOWFISH_CFB64,
-    MBEDTLS_CIPHER_BLOWFISH_CTR,
-    MBEDTLS_CIPHER_ARC4_128,
-    MBEDTLS_CIPHER_AES_128_CCM,
-    MBEDTLS_CIPHER_AES_192_CCM,
-    MBEDTLS_CIPHER_AES_256_CCM,
-    MBEDTLS_CIPHER_CAMELLIA_128_CCM,
-    MBEDTLS_CIPHER_CAMELLIA_192_CCM,
-    MBEDTLS_CIPHER_CAMELLIA_256_CCM,
+    MBEDTLS_CIPHER_NONE = 0,             /**< Placeholder to mark the end of cipher-pair lists. */
+    MBEDTLS_CIPHER_NULL,                 /**< The identity stream cipher. */
+    MBEDTLS_CIPHER_AES_128_ECB,          /**< AES cipher with 128-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_192_ECB,          /**< AES cipher with 192-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_256_ECB,          /**< AES cipher with 256-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_128_CBC,          /**< AES cipher with 128-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_192_CBC,          /**< AES cipher with 192-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_256_CBC,          /**< AES cipher with 256-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_128_CFB128,       /**< AES cipher with 128-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_192_CFB128,       /**< AES cipher with 192-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_256_CFB128,       /**< AES cipher with 256-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_128_CTR,          /**< AES cipher with 128-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_192_CTR,          /**< AES cipher with 192-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_256_CTR,          /**< AES cipher with 256-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_128_GCM,          /**< AES cipher with 128-bit GCM mode. */
+    MBEDTLS_CIPHER_AES_192_GCM,          /**< AES cipher with 192-bit GCM mode. */
+    MBEDTLS_CIPHER_AES_256_GCM,          /**< AES cipher with 256-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_ECB,     /**< Camellia cipher with 128-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_ECB,     /**< Camellia cipher with 192-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_ECB,     /**< Camellia cipher with 256-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CBC,     /**< Camellia cipher with 128-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CBC,     /**< Camellia cipher with 192-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CBC,     /**< Camellia cipher with 256-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CFB128,  /**< Camellia cipher with 128-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CFB128,  /**< Camellia cipher with 192-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CFB128,  /**< Camellia cipher with 256-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CTR,     /**< Camellia cipher with 128-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CTR,     /**< Camellia cipher with 192-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CTR,     /**< Camellia cipher with 256-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_GCM,     /**< Camellia cipher with 128-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_GCM,     /**< Camellia cipher with 192-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_GCM,     /**< Camellia cipher with 256-bit GCM mode. */
+    MBEDTLS_CIPHER_DES_ECB,              /**< DES cipher with ECB mode. */
+    MBEDTLS_CIPHER_DES_CBC,              /**< DES cipher with CBC mode. */
+    MBEDTLS_CIPHER_DES_EDE_ECB,          /**< DES cipher with EDE ECB mode. */
+    MBEDTLS_CIPHER_DES_EDE_CBC,          /**< DES cipher with EDE CBC mode. */
+    MBEDTLS_CIPHER_DES_EDE3_ECB,         /**< DES cipher with EDE3 ECB mode. */
+    MBEDTLS_CIPHER_DES_EDE3_CBC,         /**< DES cipher with EDE3 CBC mode. */
+    MBEDTLS_CIPHER_BLOWFISH_ECB,         /**< Blowfish cipher with ECB mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CBC,         /**< Blowfish cipher with CBC mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CFB64,       /**< Blowfish cipher with CFB64 mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CTR,         /**< Blowfish cipher with CTR mode. */
+    MBEDTLS_CIPHER_ARC4_128,             /**< RC4 cipher with 128-bit mode. */
+    MBEDTLS_CIPHER_AES_128_CCM,          /**< AES cipher with 128-bit CCM mode. */
+    MBEDTLS_CIPHER_AES_192_CCM,          /**< AES cipher with 192-bit CCM mode. */
+    MBEDTLS_CIPHER_AES_256_CCM,          /**< AES cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CCM,     /**< Camellia cipher with 128-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CCM,     /**< Camellia cipher with 192-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CCM,     /**< Camellia cipher with 256-bit CCM mode. */
 } mbedtls_cipher_type_t;
 
+/** Supported cipher modes. */
 typedef enum {
-    MBEDTLS_MODE_NONE = 0,
-    MBEDTLS_MODE_ECB,
-    MBEDTLS_MODE_CBC,
-    MBEDTLS_MODE_CFB,
-    MBEDTLS_MODE_OFB, /* Unused! */
-    MBEDTLS_MODE_CTR,
-    MBEDTLS_MODE_GCM,
-    MBEDTLS_MODE_STREAM,
-    MBEDTLS_MODE_CCM,
+    MBEDTLS_MODE_NONE = 0,               /**< None. */
+    MBEDTLS_MODE_ECB,                    /**< The ECB cipher mode. */
+    MBEDTLS_MODE_CBC,                    /**< The CBC cipher mode. */
+    MBEDTLS_MODE_CFB,                    /**< The CFB cipher mode. */
+    MBEDTLS_MODE_OFB,                    /**< The OFB cipher mode - unsupported. */
+    MBEDTLS_MODE_CTR,                    /**< The CTR cipher mode. */
+    MBEDTLS_MODE_GCM,                    /**< The GCM cipher mode. */
+    MBEDTLS_MODE_STREAM,                 /**< The stream cipher mode. */
+    MBEDTLS_MODE_CCM,                    /**< The CCM cipher mode. */
 } mbedtls_cipher_mode_t;
 
+/** Supported cipher padding types. */
 typedef enum {
-    MBEDTLS_PADDING_PKCS7 = 0,     /**< PKCS7 padding (default)        */
-    MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding         */
-    MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding             */
-    MBEDTLS_PADDING_ZEROS,         /**< zero padding (not reversible!) */
-    MBEDTLS_PADDING_NONE,          /**< never pad (full blocks only)   */
+    MBEDTLS_PADDING_PKCS7 = 0,     /**< PKCS7 padding (default).        */
+    MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding.         */
+    MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding.             */
+    MBEDTLS_PADDING_ZEROS,         /**< Zero padding (not reversible). */
+    MBEDTLS_PADDING_NONE,          /**< Never pad (full blocks only).   */
 } mbedtls_cipher_padding_t;
 
+/** Type of operation. */
 typedef enum {
     MBEDTLS_OPERATION_NONE = -1,
     MBEDTLS_DECRYPT = 0,
@@ -156,19 +177,19 @@ typedef enum {
 } mbedtls_operation_t;
 
 enum {
-    /** Undefined key length */
+    /** Undefined key length. */
     MBEDTLS_KEY_LENGTH_NONE = 0,
-    /** Key length, in bits (including parity), for DES keys */
+    /** Key length, in bits (including parity), for DES keys. */
     MBEDTLS_KEY_LENGTH_DES  = 64,
-    /** Key length, in bits (including parity), for DES in two key EDE */
+    /** Key length in bits, including parity, for DES in two-key EDE. */
     MBEDTLS_KEY_LENGTH_DES_EDE = 128,
-    /** Key length, in bits (including parity), for DES in three-key EDE */
+    /** Key length in bits, including parity, for DES in three-key EDE. */
     MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
 };
 
-/** Maximum length of any IV, in bytes */
+/** Maximum length of any IV, in Bytes. */
 #define MBEDTLS_MAX_IV_LENGTH      16
-/** Maximum block size of any cipher, in bytes */
+/** Maximum block size of any cipher, in Bytes. */
 #define MBEDTLS_MAX_BLOCK_LENGTH   16
 
 /**
@@ -182,33 +203,43 @@ typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
 typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
 
 /**
- * Cipher information. Allows cipher functions to be called in a generic way.
+ * Cipher information. Allows calling cipher functions
+ * in a generic way.
  */
 typedef struct {
-    /** Full cipher identifier (e.g. MBEDTLS_CIPHER_AES_256_CBC) */
+    /** Full cipher identifier. For example,
+     * MBEDTLS_CIPHER_AES_256_CBC.
+     */
     mbedtls_cipher_type_t type;
 
-    /** Cipher mode (e.g. MBEDTLS_MODE_CBC) */
+    /** The cipher mode. For example, MBEDTLS_MODE_CBC. */
     mbedtls_cipher_mode_t mode;
 
-    /** Cipher key length, in bits (default length for variable sized ciphers)
-     *  (Includes parity bits for ciphers like DES) */
+    /** The cipher key length, in bits. This is the
+     * default length for variable sized ciphers.
+     * Includes parity bits for ciphers like DES.
+     */
     unsigned int key_bitlen;
 
-    /** Name of the cipher */
+    /** Name of the cipher. */
     const char * name;
 
-    /** IV/NONCE size, in bytes.
-     *  For cipher that accept many sizes: recommended size */
+    /** IV or nonce size, in Bytes.
+     * For ciphers that accept variable IV sizes,
+     * this is the recommended size.
+     */
     unsigned int iv_size;
 
-    /** Flags for variable IV size, variable key size, etc. */
+    /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
+     *  MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
+     *  cipher supports variable IV or variable key sizes, respectively.
+     */
     int flags;
 
-    /** block size, in bytes */
+    /** The block size, in Bytes. */
     unsigned int block_size;
 
-    /** Base cipher information and functions */
+    /** Struct for base cipher information and functions. */
     const mbedtls_cipher_base_t *base;
 
 } mbedtls_cipher_info_t;
@@ -217,125 +248,137 @@ typedef struct {
  * Generic cipher context.
  */
 typedef struct {
-    /** Information about the associated cipher */
+    /** Information about the associated cipher. */
     const mbedtls_cipher_info_t *cipher_info;
 
-    /** Key length to use */
+    /** Key length to use. */
     int key_bitlen;
 
-    /** Operation that the context's key has been initialised for */
+    /** Operation that the key of the context has been
+     * initialized for.
+     */
     mbedtls_operation_t operation;
 
 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
-    /** Padding functions to use, if relevant for cipher mode */
+    /** Padding functions to use, if relevant for
+     * the specific cipher mode.
+     */
     void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
     int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
 #endif
 
-    /** Buffer for data that hasn't been encrypted yet */
+    /** Buffer for input that has not been processed yet. */
     unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
 
-    /** Number of bytes that still need processing */
+    /** Number of Bytes that have not been processed yet. */
     size_t unprocessed_len;
 
-    /** Current IV or NONCE_COUNTER for CTR-mode */
+    /** Current IV or NONCE_COUNTER for CTR-mode. */
     unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
 
-    /** IV size in bytes (for ciphers with variable-length IVs) */
+    /** IV size in Bytes, for ciphers with variable-length IVs. */
     size_t iv_size;
 
-    /** Cipher-specific context */
+    /** The cipher-specific context. */
     void *cipher_ctx;
 
 #if defined(MBEDTLS_CMAC_C)
-    /** CMAC Specific context */
+    /** CMAC-specific context. */
     mbedtls_cmac_context_t *cmac_ctx;
 #endif
 } mbedtls_cipher_context_t;
 
 /**
- * \brief Returns the list of ciphers supported by the generic cipher module.
+ * \brief This function retrieves the list of ciphers supported by the generic
+ * cipher module.
  *
- * \return              a statically allocated array of ciphers, the last entry
- *                      is 0.
+ * \return      A statically-allocated array of ciphers. The last entry
+ *              is zero.
  */
 const int *mbedtls_cipher_list( void );
 
 /**
- * \brief               Returns the cipher information structure associated
- *                      with the given cipher name.
+ * \brief               This function retrieves the cipher-information
+ *                      structure associated with the given cipher name.
  *
  * \param cipher_name   Name of the cipher to search for.
  *
- * \return              the cipher information structure associated with the
- *                      given cipher_name, or NULL if not found.
+ * \return              The cipher information structure associated with the
+ *                      given \p cipher_name.
+ * \return              NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
 
 /**
- * \brief               Returns the cipher information structure associated
- *                      with the given cipher type.
+ * \brief               This function retrieves the cipher-information
+ *                      structure associated with the given cipher type.
  *
  * \param cipher_type   Type of the cipher to search for.
  *
- * \return              the cipher information structure associated with the
- *                      given cipher_type, or NULL if not found.
+ * \return              The cipher information structure associated with the
+ *                      given \p cipher_type.
+ * \return              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 );
 
 /**
- * \brief               Returns the cipher information structure associated
- *                      with the given cipher id, key size and mode.
- *
- * \param cipher_id     Id of the cipher to search for
- *                      (e.g. MBEDTLS_CIPHER_ID_AES)
- * \param key_bitlen    Length of the key in bits
- * \param mode          Cipher mode (e.g. MBEDTLS_MODE_CBC)
- *
- * \return              the cipher information structure associated with the
- *                      given cipher_type, or NULL if not found.
+ * \brief               This function retrieves the cipher-information
+ *                      structure associated with the given cipher ID,
+ *                      key size and mode.
+ *
+ * \param cipher_id     The ID of the cipher to search for. For example,
+ *                      #MBEDTLS_CIPHER_ID_AES.
+ * \param key_bitlen    The length of the key in bits.
+ * \param mode          The cipher mode. For example, #MBEDTLS_MODE_CBC.
+ *
+ * \return              The cipher information structure associated with the
+ *                      given \p cipher_id.
+ * \return              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,
                                               const mbedtls_cipher_mode_t mode );
 
 /**
- * \brief               Initialize a cipher_context (as NONE)
+ * \brief               This function initializes a \p cipher_context as NONE.
  */
 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
 
 /**
- * \brief               Free and clear the cipher-specific context of ctx.
- *                      Freeing ctx itself remains the responsibility of the
- *                      caller.
+ * \brief               This function frees and clears the cipher-specific
+ *                      context of \p ctx. Freeing \p ctx itself remains the
+ *                      responsibility of the caller.
  */
 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
 
+
 /**
- * \brief               Initialises and fills the cipher context structure with
- *                      the appropriate values.
- *
- * \note                Currently also clears structure. In future versions you
- *                      will be required to call mbedtls_cipher_init() on the structure
- *                      first.
- *
- * \param ctx           context to initialise. May not be NULL.
- * \param cipher_info   cipher to use.
- *
- * \return              0 on success,
- *                      MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
- *                      MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
- *                      cipher-specific context failed.
+ * \brief               This function initializes and fills the cipher-context
+ *                      structure with the appropriate values. It also clears
+ *                      the structure.
+ *
+ * \param ctx           The context to initialize. May not be NULL.
+ * \param cipher_info   The cipher to use.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
+ *                      cipher-specific context fails.
+ *
+ * \internal Currently, the function also clears the structure.
+ * 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 );
 
 /**
- * \brief               Returns the block size of the given cipher.
+ * \brief        This function returns the block size of the given cipher.
  *
- * \param ctx           cipher's context. Must have been initialised.
+ * \param ctx    The context of the cipher. Must be initialized.
  *
- * \return              size of the cipher's blocks, or 0 if ctx has not been
- *                      initialised.
+ * \return       The size of the blocks of the cipher.
+ * \return       0 if \p ctx has not been initialized.
  */
 static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
 {
@@ -346,13 +389,13 @@ static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_c
 }
 
 /**
- * \brief               Returns the mode of operation for the cipher.
- *                      (e.g. MBEDTLS_MODE_CBC)
+ * \brief        This function returns the mode of operation for
+ *               the cipher. For example, MBEDTLS_MODE_CBC.
  *
- * \param ctx           cipher's context. Must have been initialised.
+ * \param ctx    The context of the cipher. Must be initialized.
  *
- * \return              mode of operation, or MBEDTLS_MODE_NONE if ctx
- *                      has not been initialised.
+ * \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 )
 {
@@ -363,13 +406,14 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtl
 }
 
 /**
- * \brief               Returns the size of the cipher's IV/NONCE in bytes.
+ * \brief       This function returns the size of the IV or nonce
+ *              of the cipher, in Bytes.
  *
- * \param ctx           cipher's context. Must have been initialised.
+ * \param ctx   The context of the cipher. Must be initialized.
  *
- * \return              If IV has not been set yet: (recommended) IV size
- *                      (0 for ciphers not using IV/NONCE).
- *                      If IV has already been set: actual size.
+ * \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 )
 {
@@ -383,12 +427,12 @@ static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ct
 }
 
 /**
- * \brief               Returns the type of the given cipher.
+ * \brief               This function returns the type of the given cipher.
  *
- * \param ctx           cipher's context. Must have been initialised.
+ * \param ctx           The context of the cipher. Must be initialized.
  *
- * \return              type of the cipher, or MBEDTLS_CIPHER_NONE if ctx has
- *                      not been initialised.
+ * \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 )
 {
@@ -399,11 +443,13 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_ciphe
 }
 
 /**
- * \brief               Returns the name of the given cipher, as a string.
+ * \brief               This function returns the name of the given cipher
+ *                      as a string.
  *
- * \param ctx           cipher's context. Must have been initialised.
+ * \param ctx           The context of the cipher. Must be initialized.
  *
- * \return              name of the cipher, or NULL if ctx was not initialised.
+ * \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 )
 {
@@ -414,13 +460,13 @@ static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_
 }
 
 /**
- * \brief               Returns the key length of the cipher.
+ * \brief               This function returns the key length of the cipher.
  *
- * \param ctx           cipher's context. Must have been initialised.
+ * \param ctx           The context of the cipher. Must be initialized.
  *
- * \return              cipher's key length, in bits, or
- *                      MBEDTLS_KEY_LENGTH_NONE if ctx has not been
- *                      initialised.
+ * \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 )
 {
@@ -431,13 +477,12 @@ static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t
 }
 
 /**
- * \brief               Returns the operation of the given cipher.
+ * \brief          This function returns the operation of the given cipher.
  *
- * \param ctx           cipher's context. Must have been initialised.
+ * \param ctx      The context of the cipher. Must be initialized.
  *
- * \return              operation (MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT),
- *                      or MBEDTLS_OPERATION_NONE if ctx has not been
- *                      initialised.
+ * \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 )
 {
@@ -448,189 +493,206 @@ static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_ci
 }
 
 /**
- * \brief               Set the key to use with the given context.
+ * \brief               This function sets the key to use with the given context.
  *
- * \param ctx           generic cipher context. May not be NULL. Must have been
- *                      initialised using cipher_context_from_type or
- *                      cipher_context_from_string.
+ * \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    key length to use, in bits.
- * \param operation     Operation that the key will be used for, either
- *                      MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT.
- *
- * \returns             0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
- *                      parameter verification fails or a cipher specific
- *                      error code.
+ * \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.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      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 );
 
 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
 /**
- * \brief               Set padding mode, for cipher modes that use padding.
- *                      (Default: PKCS7 padding.)
+ * \brief               This function sets the padding mode, for cipher modes
+ *                      that use padding.
+ *
+ *                      The default passing mode is PKCS7 padding.
  *
- * \param ctx           generic cipher context
- * \param mode          padding mode
+ * \param ctx           The generic cipher context.
+ * \param mode          The padding mode.
  *
- * \returns             0 on success, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
- *                      if selected padding mode is not supported, or
- *                      MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
+ *                      if the selected padding mode is not supported.
+ * \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 );
 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
 
 /**
- * \brief               Set the initialization vector (IV) or nonce
+ * \brief           This function sets the initialization vector (IV)
+ *                  or nonce.
  *
- * \param ctx           generic cipher context
- * \param iv            IV to use (or NONCE_COUNTER for CTR-mode ciphers)
- * \param iv_len        IV length for ciphers with variable-size IV;
- *                      discarded by ciphers with fixed-size IV.
+ * \note            Some ciphers do not use IVs nor nonce. For these
+ *                  ciphers, this function has no effect.
  *
- * \returns             0 on success, or MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+ * \param ctx       The generic cipher context.
+ * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \param iv_len    The IV length for ciphers with variable-size IV.
+ *                  This parameter is discarded by ciphers with fixed-size IV.
  *
- * \note                Some ciphers don't use IVs nor NONCE. For these
- *                      ciphers, this function has no effect.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                  parameter-verification failure.
  */
 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
                    const unsigned char *iv, size_t iv_len );
 
 /**
- * \brief               Finish preparation of the given context
+ * \brief         This function resets the cipher state.
  *
- * \param ctx           generic cipher context
+ * \param ctx     The generic cipher context.
  *
- * \returns             0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
- *                      if parameter verification fails.
+ * \return        \c 0 on success.
+ * \return        #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                parameter-verification failure.
  */
 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
 
 #if defined(MBEDTLS_GCM_C)
 /**
- * \brief               Add additional data (for AEAD ciphers).
- *                      Currently only supported with GCM.
- *                      Must be called exactly once, after mbedtls_cipher_reset().
+ * \brief               This function adds additional data for AEAD ciphers.
+ *                      Only supported with GCM. Must be called
+ *                      exactly once, after mbedtls_cipher_reset().
  *
- * \param ctx           generic cipher context
- * \param ad            Additional data to use.
- * \param ad_len        Length of ad.
+ * \param ctx           The generic cipher context.
+ * \param ad            The additional data to use.
+ * \param ad_len        the Length of \p ad.
  *
- * \return              0 on success, or a specific error code.
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
  */
 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
                       const unsigned char *ad, size_t ad_len );
 #endif /* MBEDTLS_GCM_C */
 
 /**
- * \brief               Generic cipher update function. Encrypts/decrypts
- *                      using the given cipher context. Writes as many block
- *                      size'd blocks of data as possible to output. Any data
- *                      that cannot be written immediately will either be added
- *                      to the next block, or flushed when cipher_final is
- *                      called.
- *                      Exception: for MBEDTLS_MODE_ECB, expects single block
- *                                 in size (e.g. 16 bytes for AES)
- *
- * \param ctx           generic cipher context
- * \param input         buffer holding the input data
- * \param ilen          length of the input data
- * \param output        buffer for the output data. Should be able to hold at
- *                      least ilen + block_size. Cannot be the same buffer as
- *                      input!
- * \param olen          length of the output data, will be filled with the
- *                      actual number of bytes written.
- *
- * \returns             0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
- *                      parameter verification fails,
- *                      MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
- *                      unsupported mode for a cipher or a cipher specific
- *                      error code.
- *
- * \note                If the underlying cipher is GCM, all calls to this
- *                      function, except the last one before mbedtls_cipher_finish(),
- *                      must have ilen a multiple of the block size.
+ * \brief               The generic cipher update function. It encrypts or
+ *                      decrypts using the given cipher context. Writes as
+ *                      many block-sized blocks of data as possible to output.
+ *                      Any data that cannot be written immediately is either
+ *                      added to the next block, or flushed when
+ *                      mbedtls_cipher_finish() is called.
+ *                      Exception: For MBEDTLS_MODE_ECB, expects a single block
+ *                      in size. For example, 16 Bytes for AES.
+ *
+ * \note                If the underlying cipher is used in GCM mode, all calls
+ *                      to this function, except for the last one before
+ *                      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 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 olen          The length of the output data, to be updated with the
+ *                      actual number of Bytes written.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
+ *                      unsupported mode for a cipher.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
                    size_t ilen, unsigned char *output, size_t *olen );
 
 /**
- * \brief               Generic cipher finalisation function. If data still
- *                      needs to be flushed from an incomplete block, data
- *                      contained within it will be padded with the size of
- *                      the last block, and written to the output buffer.
- *
- * \param ctx           Generic cipher context
- * \param output        buffer to write data to. Needs block_size available.
- * \param olen          length of the data written to the output buffer.
- *
- * \returns             0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
- *                      parameter verification fails,
- *                      MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
- *                      expected a full block but was not provided one,
- *                      MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
- *                      while decrypting or a cipher specific error code.
+ * \brief               The generic cipher finalization function. If data still
+ *                      needs to be flushed from an incomplete block, the data
+ *                      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 olen          The length of the data written to the \p output buffer.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ *                      expecting a full block but not receiving one.
+ * \return              #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ *                      while decrypting.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
                    unsigned char *output, size_t *olen );
 
 #if defined(MBEDTLS_GCM_C)
 /**
- * \brief               Write tag for AEAD ciphers.
- *                      Currently only supported with GCM.
+ * \brief               This function writes a tag for AEAD ciphers.
+ *                      Only supported with GCM.
  *                      Must be called after mbedtls_cipher_finish().
  *
- * \param ctx           Generic cipher context
- * \param tag           buffer to write the tag
- * \param tag_len       Length of the tag to write
+ * \param ctx           The generic cipher context.
+ * \param tag           The buffer to write the tag to.
+ * \param tag_len       The length of the tag to write.
  *
- * \return              0 on success, or a specific error code.
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
  */
 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
                       unsigned char *tag, size_t tag_len );
 
 /**
- * \brief               Check tag for AEAD ciphers.
- *                      Currently only supported with GCM.
+ * \brief               This function checks the tag for AEAD ciphers.
+ *                      Only supported with GCM.
  *                      Must be called after mbedtls_cipher_finish().
  *
- * \param ctx           Generic cipher context
- * \param tag           Buffer holding the tag
- * \param tag_len       Length of the tag to check
+ * \param ctx           The generic cipher context.
+ * \param tag           The buffer holding the tag.
+ * \param tag_len       The length of the tag to check.
  *
- * \return              0 on success, or a specific error code.
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
  */
 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
                       const unsigned char *tag, size_t tag_len );
 #endif /* MBEDTLS_GCM_C */
 
 /**
- * \brief               Generic all-in-one encryption/decryption
- *                      (for all ciphers except AEAD constructs).
- *
- * \param ctx           generic cipher context
- * \param iv            IV to use (or NONCE_COUNTER for CTR-mode ciphers)
- * \param iv_len        IV length for ciphers with variable-size IV;
- *                      discarded by ciphers with fixed-size IV.
- * \param input         buffer holding the input data
- * \param ilen          length of the input data
- * \param output        buffer for the output data. Should be able to hold at
- *                      least ilen + block_size. Cannot be the same buffer as
- *                      input!
- * \param olen          length of the output data, will be filled with the
- *                      actual number of bytes written.
- *
- * \note                Some ciphers don't use IVs nor NONCE. For these
- *                      ciphers, use iv = NULL and iv_len = 0.
- *
- * \returns             0 on success, or
- *                      MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
- *                      MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
- *                      expected a full block but was not provided one, or
- *                      MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
- *                      while decrypting, or
- *                      a cipher specific error code.
+ * \brief               The generic all-in-one encryption/decryption function,
+ *                      for all ciphers except AEAD constructs.
+ *
+ * \param ctx           The generic cipher context.
+ * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \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 olen          The length of the output data, to be updated with the
+ *                      actual number of Bytes written.
+ *
+ * \note                Some ciphers do not use IVs nor nonce. For these
+ *                      ciphers, use \p iv = NULL and \p iv_len = 0.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ *                      expecting a full block but not receiving one.
+ * \return              #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ *                      while decrypting.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
                   const unsigned char *iv, size_t iv_len,
@@ -639,26 +701,27 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_AEAD)
 /**
- * \brief               Generic autenticated encryption (AEAD ciphers).
- *
- * \param ctx           generic cipher context
- * \param iv            IV to use (or NONCE_COUNTER for CTR-mode ciphers)
- * \param iv_len        IV length for ciphers with variable-size IV;
- *                      discarded by ciphers with fixed-size IV.
- * \param ad            Additional data to authenticate.
- * \param ad_len        Length of ad.
- * \param input         buffer holding the input data
- * \param ilen          length of the input data
- * \param output        buffer for the output data.
- *                      Should be able to hold at least ilen.
- * \param olen          length of the output data, will be filled with the
- *                      actual number of bytes written.
- * \param tag           buffer for the authentication tag
- * \param tag_len       desired tag length
- *
- * \returns             0 on success, or
- *                      MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
- *                      a cipher specific error code.
+ * \brief               The generic autenticated encryption (AEAD) function.
+ *
+ * \param ctx           The generic cipher context.
+ * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \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_len        The length of \p ad.
+ * \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.
+ * \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.
+ * \param tag_len       The desired length of the authentication tag.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
                          const unsigned char *iv, size_t iv_len,
@@ -668,31 +731,32 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
                          unsigned char *tag, size_t tag_len );
 
 /**
- * \brief               Generic autenticated decryption (AEAD ciphers).
- *
- * \param ctx           generic cipher context
- * \param iv            IV to use (or NONCE_COUNTER for CTR-mode ciphers)
- * \param iv_len        IV length for ciphers with variable-size IV;
- *                      discarded by ciphers with fixed-size IV.
- * \param ad            Additional data to be authenticated.
- * \param ad_len        Length of ad.
- * \param input         buffer holding the input data
- * \param ilen          length of the input data
- * \param output        buffer for the output data.
- *                      Should be able to hold at least ilen.
- * \param olen          length of the output data, will be filled with the
- *                      actual number of bytes written.
- * \param tag           buffer holding the authentication tag
- * \param tag_len       length of the authentication tag
- *
- * \returns             0 on success, or
- *                      MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
- *                      MBEDTLS_ERR_CIPHER_AUTH_FAILED if data isn't authentic,
- *                      or a cipher specific error code.
+ * \brief               The generic autenticated decryption (AEAD) function.
  *
  * \note                If the data is not authentic, then the output buffer
- *                      is zeroed out to prevent the unauthentic plaintext to
- *                      be used by mistake, making this interface safer.
+ *                      is zeroed out to prevent the unauthentic plaintext being
+ *                      used, making this interface safer.
+ *
+ * \param ctx           The generic cipher context.
+ * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \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_len        The length of \p ad.
+ * \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.
+ * \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.
+ * \param tag_len       The length of the authentication tag.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
                          const unsigned char *iv, size_t iv_len,
diff --git a/crypto/mbedtls/include/mbedtls/cipher_internal.h b/crypto/mbedtls/include/mbedtls/cipher_internal.h
index 6c58bcc52..969ff9ccb 100644
--- a/crypto/mbedtls/include/mbedtls/cipher_internal.h
+++ b/crypto/mbedtls/include/mbedtls/cipher_internal.h
@@ -4,7 +4,8 @@
  * \brief Cipher wrappers.
  *
  * \author Adriaan de Jong <de...@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/cmac.h b/crypto/mbedtls/include/mbedtls/cmac.h
index 9a2b96bc9..913c05f8a 100644
--- a/crypto/mbedtls/include/mbedtls/cmac.h
+++ b/crypto/mbedtls/include/mbedtls/cmac.h
@@ -1,10 +1,13 @@
 /**
  * \file cmac.h
  *
- * \brief Cipher-based Message Authentication Code (CMAC) Mode for
- *        Authentication
+ * \brief This file contains CMAC definitions and functions.
  *
- *  Copyright (C) 2015-2016, ARM Limited, All Rights Reserved
+ * The Cipher-based Message Authentication Code (CMAC) Mode for
+ * Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
+ */
+/*
+ *  Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -19,8 +22,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_CMAC_H
 #define MBEDTLS_CMAC_H
 
@@ -30,106 +34,132 @@
 extern "C" {
 #endif
 
+#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A  /**< CMAC hardware accelerator failed. */
+
 #define MBEDTLS_AES_BLOCK_SIZE          16
 #define MBEDTLS_DES3_BLOCK_SIZE         8
 
 #if defined(MBEDTLS_AES_C)
-#define MBEDTLS_CIPHER_BLKSIZE_MAX      16  /* longest used by CMAC is AES */
+#define MBEDTLS_CIPHER_BLKSIZE_MAX      16  /**< The longest block used by CMAC is that of AES. */
 #else
-#define MBEDTLS_CIPHER_BLKSIZE_MAX      8   /* longest used by CMAC is 3DES */
+#define MBEDTLS_CIPHER_BLKSIZE_MAX      8   /**< The longest block used by CMAC is that of 3DES. */
 #endif
 
+#if !defined(MBEDTLS_CMAC_ALT)
+
 /**
- * CMAC context structure - Contains internal state information only
+ * The CMAC context structure.
  */
 struct mbedtls_cmac_context_t
 {
-    /** Internal state of the CMAC algorithm  */
+    /** The internal state of the CMAC algorithm.  */
     unsigned char       state[MBEDTLS_CIPHER_BLKSIZE_MAX];
 
     /** Unprocessed data - either data that was not block aligned and is still
-     *  pending to be processed, or the final block */
+     *  pending processing, or the final block. */
     unsigned char       unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX];
 
-    /** Length of data pending to be processed */
+    /** The length of data pending processing. */
     size_t              unprocessed_len;
 };
 
+#else  /* !MBEDTLS_CMAC_ALT */
+#include "cmac_alt.h"
+#endif /* !MBEDTLS_CMAC_ALT */
+
 /**
- * \brief               Set the CMAC key and prepare to authenticate the input
- *                      data.
- *                      Should be called with an initialized cipher context.
- *
- * \param ctx           Cipher context. This should be a cipher context,
- *                      initialized to be one of the following types:
- *                      MBEDTLS_CIPHER_AES_128_ECB, MBEDTLS_CIPHER_AES_192_ECB,
- *                      MBEDTLS_CIPHER_AES_256_ECB or
- *                      MBEDTLS_CIPHER_DES_EDE3_ECB.
- * \param key           CMAC key
- * \param keybits       length of the CMAC key in bits
- *                      (must be acceptable by the cipher)
- *
- * \return              0 if successful, or a cipher specific error code
+ * \brief               This function sets the CMAC key, and prepares to authenticate
+ *                      the input data.
+ *                      Must be called with an initialized cipher context.
+ *
+ * \param ctx           The cipher context used for the CMAC operation, initialized
+ *                      as one of the following types: MBEDTLS_CIPHER_AES_128_ECB,
+ *                      MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
+ *                      or MBEDTLS_CIPHER_DES_EDE3_ECB.
+ * \param key           The CMAC key.
+ * \param keybits       The length of the CMAC key in bits.
+ *                      Must be supported by the cipher.
+ *
+ * \return              \c 0 on success.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
                                 const unsigned char *key, size_t keybits );
 
 /**
- * \brief               Generic CMAC process buffer.
- *                      Called between mbedtls_cipher_cmac_starts() or
- *                      mbedtls_cipher_cmac_reset() and
- *                      mbedtls_cipher_cmac_finish().
- *                      May be called repeatedly.
- *
- * \param ctx           CMAC context
- * \param input         buffer holding the  data
- * \param ilen          length of the input data
- *
- * \returns             0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                      verification fails.
+ * \brief               This function feeds an input buffer into an ongoing CMAC
+ *                      computation.
+ *
+ *                      It is called between mbedtls_cipher_cmac_starts() or
+ *                      mbedtls_cipher_cmac_reset(), and mbedtls_cipher_cmac_finish().
+ *                      Can be called repeatedly.
+ *
+ * \param ctx           The cipher context used for the CMAC operation.
+ * \param input         The buffer holding the input data.
+ * \param ilen          The length of the input data.
+ *
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                     if parameter verification fails.
  */
 int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
                                 const unsigned char *input, size_t ilen );
 
 /**
- * \brief               Output CMAC.
- *                      Called after mbedtls_cipher_cmac_update().
- *                      Usually followed by mbedtls_cipher_cmac_reset(), then
- *                      mbedtls_cipher_cmac_starts(), or mbedtls_cipher_free().
+ * \brief               This function finishes the CMAC operation, and writes
+ *                      the result to the output buffer.
  *
- * \param ctx           CMAC context
- * \param output        Generic CMAC checksum result
+ *                      It is called after mbedtls_cipher_cmac_update().
+ *                      It can be followed by mbedtls_cipher_cmac_reset() and
+ *                      mbedtls_cipher_cmac_update(), or mbedtls_cipher_free().
  *
- * \returns             0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                      verification fails.
+ * \param ctx           The cipher context used for the CMAC operation.
+ * \param output        The output buffer for the CMAC checksum result.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                      if parameter verification fails.
  */
 int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
                                 unsigned char *output );
 
 /**
- * \brief               Prepare to authenticate a new message with the same key.
- *                      Called after mbedtls_cipher_cmac_finish() and before
- *                      mbedtls_cipher_cmac_update().
+ * \brief               This function prepares the authentication of another
+ *                      message with the same key as the previous CMAC
+ *                      operation.
+ *
+ *                      It is called after mbedtls_cipher_cmac_finish()
+ *                      and before mbedtls_cipher_cmac_update().
  *
- * \param ctx           CMAC context to be reset
+ * \param ctx           The cipher context used for the CMAC operation.
  *
- * \returns             0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                      verification fails.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                      if parameter verification fails.
  */
 int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
 
 /**
- * \brief               Output = Generic_CMAC( cmac key, input buffer )
+ * \brief               This function calculates the full generic CMAC
+ *                      on the input buffer with the provided key.
+ *
+ *                      The function allocates the context, performs the
+ *                      calculation, and frees the context.
+ *
+ *                      The CMAC result is calculated as
+ *                      output = generic CMAC(cmac key, input buffer).
  *
- * \param cipher_info   message digest info
- * \param key           CMAC key
- * \param keylen        length of the CMAC key in bits
- * \param input         buffer holding the  data
- * \param ilen          length of the input data
- * \param output        Generic CMAC-result
  *
- * \returns             0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                      verification fails.
+ * \param cipher_info   The cipher information.
+ * \param key           The CMAC key.
+ * \param keylen        The length of the CMAC key in bits.
+ * \param input         The buffer holding the input data.
+ * \param ilen          The length of the input data.
+ * \param output        The buffer for the generic CMAC result.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                      if parameter verification fails.
  */
 int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
                          const unsigned char *key, size_t keylen,
@@ -138,16 +168,21 @@ int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
 
 #if defined(MBEDTLS_AES_C)
 /**
- * \brief           AES-CMAC-128-PRF
- *                  Implementation of (AES-CMAC-PRF-128), as defined in RFC 4615
- *
- * \param key       PRF key
- * \param key_len   PRF key length in bytes
- * \param input     buffer holding the input data
- * \param in_len    length of the input data in bytes
- * \param output    buffer holding the generated pseudorandom output (16 bytes)
- *
- * \return          0 if successful
+ * \brief           This function implements the AES-CMAC-PRF-128 pseudorandom
+ *                  function, as defined in
+ *                  <em>RFC-4615: The Advanced Encryption Standard-Cipher-based
+ *                  Message Authentication Code-Pseudo-Random Function-128
+ *                  (AES-CMAC-PRF-128) Algorithm for the Internet Key
+ *                  Exchange Protocol (IKE).</em>
+ *
+ * \param key       The key to use.
+ * \param key_len   The key length in Bytes.
+ * \param input     The buffer holding the input data.
+ * \param in_len    The length of the input data in Bytes.
+ * \param output    The buffer holding the generated 16 Bytes of
+ *                  pseudorandom output.
+ *
+ * \return          \c 0 on success.
  */
 int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
                               const unsigned char *input, size_t in_len,
@@ -156,9 +191,10 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
 
 #if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
 /**
- * \brief          Checkup routine
+ * \brief          The CMAC checkup routine.
  *
- * \return         0 if successful, or 1 if the test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_cmac_self_test( int verbose );
 #endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
diff --git a/crypto/mbedtls/include/mbedtls/compat-1.3.h b/crypto/mbedtls/include/mbedtls/compat-1.3.h
index bba1d2c24..600a0f154 100644
--- a/crypto/mbedtls/include/mbedtls/compat-1.3.h
+++ b/crypto/mbedtls/include/mbedtls/compat-1.3.h
@@ -5,7 +5,8 @@
  *  for the PolarSSL naming conventions.
  *
  * \deprecated Use the new names directly instead
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/config.h b/crypto/mbedtls/include/mbedtls/config.h
index 7a0e00f4d..7101ed7ac 100644
--- a/crypto/mbedtls/include/mbedtls/config.h
+++ b/crypto/mbedtls/include/mbedtls/config.h
@@ -6,7 +6,8 @@
  *  This set of compile-time options may be used to enable
  *  or disable features selectively, and reduce the global
  *  memory footprint.
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -261,20 +262,32 @@
  *
  * Uncomment a macro to enable alternate implementation of the corresponding
  * module.
+ *
+ * \warning   MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ *            use constitutes a security risk. If possible, we recommend
+ *            avoiding dependencies on them, and considering stronger message
+ *            digests and ciphers instead.
+ *
  */
 //#define MBEDTLS_AES_ALT
 //#define MBEDTLS_ARC4_ALT
 //#define MBEDTLS_BLOWFISH_ALT
 //#define MBEDTLS_CAMELLIA_ALT
+//#define MBEDTLS_CCM_ALT
+//#define MBEDTLS_CMAC_ALT
 //#define MBEDTLS_DES_ALT
-//#define MBEDTLS_XTEA_ALT
+//#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_ECJPAKE_ALT
+//#define MBEDTLS_GCM_ALT
 //#define MBEDTLS_MD2_ALT
 //#define MBEDTLS_MD4_ALT
 //#define MBEDTLS_MD5_ALT
 //#define MBEDTLS_RIPEMD160_ALT
+//#define MBEDTLS_RSA_ALT
 //#define MBEDTLS_SHA1_ALT
 //#define MBEDTLS_SHA256_ALT
 //#define MBEDTLS_SHA512_ALT
+//#define MBEDTLS_XTEA_ALT
 /*
  * When replacing the elliptic curve module, pleace consider, that it is
  * implemented with two .c files:
@@ -314,6 +327,12 @@
  *
  * Uncomment a macro to enable alternate implementation of the corresponding
  * function.
+ *
+ * \warning   MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ *            constitutes a security risk. If possible, we recommend avoiding
+ *            dependencies on them, and considering stronger message digests
+ *            and ciphers instead.
+ *
  */
 //#define MBEDTLS_MD2_PROCESS_ALT
 //#define MBEDTLS_MD4_PROCESS_ALT
@@ -329,6 +348,11 @@
 //#define MBEDTLS_AES_SETKEY_DEC_ALT
 //#define MBEDTLS_AES_ENCRYPT_ALT
 //#define MBEDTLS_AES_DECRYPT_ALT
+//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+//#define MBEDTLS_ECDSA_VERIFY_ALT
+//#define MBEDTLS_ECDSA_SIGN_ALT
+//#define MBEDTLS_ECDSA_GENKEY_ALT
 
 /**
  * \def MBEDTLS_ECP_INTERNAL_ALT
@@ -416,12 +440,45 @@
 /**
  * \def MBEDTLS_AES_ROM_TABLES
  *
- * Store the AES tables in ROM.
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
  *
- * Uncomment this macro to store the AES tables in ROM.
  */
 //#define MBEDTLS_AES_ROM_TABLES
 
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
 /**
  * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
  *
@@ -513,6 +570,9 @@
  *      MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
  *
  * Uncomment this macro to enable weak ciphersuites
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
  */
 //#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
 
@@ -549,6 +609,7 @@
 #define MBEDTLS_ECP_DP_BP384R1_ENABLED
 #define MBEDTLS_ECP_DP_BP512R1_ENABLED
 #define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#define MBEDTLS_ECP_DP_CURVE448_ENABLED
 
 /**
  * \def MBEDTLS_ECP_NIST_OPTIM
@@ -618,6 +679,13 @@
  *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
  *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
  *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
  */
 #define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
 
@@ -717,6 +785,13 @@
  *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
  *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
  *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
  */
 #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 
@@ -1008,7 +1083,8 @@
 /**
  * \def MBEDTLS_RSA_NO_CRT
  *
- * Do not use the Chinese Remainder Theorem for the RSA private operation.
+ * Do not use the Chinese Remainder Theorem
+ * for the RSA private operation.
  *
  * Uncomment this macro to disable the use of CRT in RSA.
  *
@@ -1155,6 +1231,13 @@
  * misuse/misunderstand.
  *
  * Comment this to disable support for renegotiation.
+ *
+ * \note   Even if this option is disabled, both client and server are aware
+ *         of the Renegotiation Indication Extension (RFC 5746) used to
+ *         prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ *         (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ *          configuration of this extension).
+ *
  */
 #define MBEDTLS_SSL_RENEGOTIATION
 
@@ -1363,6 +1446,30 @@
  */
 #define MBEDTLS_SSL_TRUNCATED_HMAC
 
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+ *
+ * Fallback to old (pre-2.7), non-conforming implementation of the truncated
+ * HMAC extension which also truncates the HMAC key. Note that this option is
+ * only meant for a transitory upgrade period and is likely to be removed in
+ * a future version of the library.
+ *
+ * \warning The old implementation is non-compliant and has a security weakness
+ *          (2^80 brute force attack on the HMAC key used for a single,
+ *          uninterrupted connection). This should only be enabled temporarily
+ *          when (1) the use of truncated HMAC is essential in order to save
+ *          bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
+ *          the fixed implementation yet (pre-2.7).
+ *
+ * \deprecated This option is deprecated and will likely be removed in a
+ *             future version of Mbed TLS.
+ *
+ * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
+ *
+ * Requires: MBEDTLS_SSL_TRUNCATED_HMAC
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+
 /**
  * \def MBEDTLS_THREADING_ALT
  *
@@ -1469,6 +1576,9 @@
  *
  * \note Currently compression can't be used with DTLS.
  *
+ * \deprecated This feature is deprecated and will be removed
+ *             in the next major revision of the library.
+ *
  * Used in: library/ssl_tls.c
  *          library/ssl_cli.c
  *          library/ssl_srv.c
@@ -1596,6 +1706,11 @@
  *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
  *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
  *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. If possible, we recommend avoidng dependencies on
+ *            it, and considering stronger ciphers instead.
+ *
  */
 #define MBEDTLS_ARC4_C
 
@@ -1649,6 +1764,7 @@
  *          library/ecp.c
  *          library/ecdsa.c
  *          library/rsa.c
+ *          library/rsa_internal.c
  *          library/ssl_tls.c
  *
  * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
@@ -1821,6 +1937,9 @@
  *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
  *
  * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
  */
 #define MBEDTLS_DES_C
 
@@ -1835,6 +1954,13 @@
  *
  * This module is used by the following key exchanges:
  *      DHE-RSA, DHE-PSK
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
  */
 #define MBEDTLS_DHM_C
 
@@ -2000,6 +2126,11 @@
  * Caller:
  *
  * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning   MD2 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
  */
 //#define MBEDTLS_MD2_C
 
@@ -2012,6 +2143,11 @@
  * Caller:
  *
  * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning   MD4 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
  */
 //#define MBEDTLS_MD4_C
 
@@ -2025,8 +2161,15 @@
  *          library/pem.c
  *          library/ssl_tls.c
  *
- * This module is required for SSL/TLS and X.509.
- * PEM_PARSE uses MD5 for decrypting encrypted keys.
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
  */
 #define MBEDTLS_MD5_C
 
@@ -2262,6 +2405,7 @@
  * Enable the RSA public-key cryptosystem.
  *
  * Module:  library/rsa.c
+ *          library/rsa_internal.c
  * Caller:  library/ssl_cli.c
  *          library/ssl_srv.c
  *          library/ssl_tls.c
@@ -2288,6 +2432,11 @@
  *
  * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
  * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
  */
 #define MBEDTLS_SHA1_C
 
@@ -2676,8 +2825,13 @@
  * Allow SHA-1 in the default TLS configuration for certificate signing.
  * Without this build-time option, SHA-1 support must be activated explicitly
  * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
- * recommended because of it is possible to generte SHA-1 collisions, however
+ * recommended because of it is possible to generate SHA-1 collisions, however
  * this may be safe for legacy infrastructure where additional controls apply.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
  */
 // #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
 
@@ -2688,7 +2842,13 @@
  * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
  * default. At the time of writing, there is no practical attack on the use
  * of SHA-1 in handshake signatures, hence this option is turned on by default
- * for compatibility with existing peers.
+ * to preserve compatibility with existing peers, but the general
+ * warning applies nonetheless:
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
  */
 #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
 
diff --git a/crypto/mbedtls/include/mbedtls/ctr_drbg.h b/crypto/mbedtls/include/mbedtls/ctr_drbg.h
index 059d3c5c9..dcbc04792 100644
--- a/crypto/mbedtls/include/mbedtls/ctr_drbg.h
+++ b/crypto/mbedtls/include/mbedtls/ctr_drbg.h
@@ -1,9 +1,18 @@
 /**
  * \file ctr_drbg.h
  *
- * \brief CTR_DRBG based on AES-256 (NIST SP 800-90)
+ * \brief    This file contains CTR_DRBG definitions and functions.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * CTR_DRBG is a standardized way of building a PRNG from a block-cipher
+ * in counter mode operation, as defined in <em>NIST SP 800-90A:
+ * Recommendation for Random Number Generation Using Deterministic Random
+ * Bit Generators</em>.
+ *
+ * The Mbed TLS implementation of CTR_DRBG uses AES-256 as the underlying
+ * block cipher.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,8 +27,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_CTR_DRBG_H
 #define MBEDTLS_CTR_DRBG_H
 
@@ -30,78 +40,95 @@
 #endif
 
 #define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED        -0x0034  /**< The entropy source failed. */
-#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG              -0x0036  /**< Too many random requested in single call. */
-#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG                -0x0038  /**< Input too large (Entropy + additional). */
-#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR                -0x003A  /**< Read/write error in file. */
+#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG              -0x0036  /**< The requested random buffer length is too big. */
+#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG                -0x0038  /**< The input (entropy + additional data) is too large. */
+#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR                -0x003A  /**< Read or write error in file. */
 
-#define MBEDTLS_CTR_DRBG_BLOCKSIZE          16      /**< Block size used by the cipher                  */
-#define MBEDTLS_CTR_DRBG_KEYSIZE            32      /**< Key size used by the cipher                    */
-#define MBEDTLS_CTR_DRBG_KEYBITS            ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 )
-#define MBEDTLS_CTR_DRBG_SEEDLEN            ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE )
-                                            /**< The seed length (counter + AES key)            */
+#define MBEDTLS_CTR_DRBG_BLOCKSIZE          16 /**< The block size used by the cipher. */
+#define MBEDTLS_CTR_DRBG_KEYSIZE            32 /**< The key size used by the cipher. */
+#define MBEDTLS_CTR_DRBG_KEYBITS            ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
+#define MBEDTLS_CTR_DRBG_SEEDLEN            ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
 
 /**
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in config.h or define them using the compiler command
+ * line.
  * \{
  */
 
 #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
 #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
-#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        48      /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        48
+/**< The amount of entropy used per seed by default:
+ * <ul><li>48 with SHA-512.</li>
+ * <li>32 with SHA-256.</li></ul>
+ */
 #else
-#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        32      /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        32
+/**< Amount of entropy used per seed by default:
+ * <ul><li>48 with SHA-512.</li>
+ * <li>32 with SHA-256.</li></ul>
+ */
 #endif
 #endif
 
 #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
-#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL    10000   /**< Interval before reseed is performed by default */
+#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL    10000
+/**< The interval before reseed is performed by default. */
 #endif
 
 #if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT)
-#define MBEDTLS_CTR_DRBG_MAX_INPUT          256     /**< Maximum number of additional input bytes */
+#define MBEDTLS_CTR_DRBG_MAX_INPUT          256
+/**< The maximum number of additional input Bytes. */
 #endif
 
 #if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST)
-#define MBEDTLS_CTR_DRBG_MAX_REQUEST        1024    /**< Maximum number of requested bytes per call */
+#define MBEDTLS_CTR_DRBG_MAX_REQUEST        1024
+/**< The maximum number of requested Bytes per call. */
 #endif
 
 #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
-#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT     384     /**< Maximum size of (re)seed buffer */
+#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT     384
+/**< The maximum size of seed or reseed buffer. */
 #endif
 
 /* \} name SECTION: Module settings */
 
-#define MBEDTLS_CTR_DRBG_PR_OFF             0       /**< No prediction resistance       */
-#define MBEDTLS_CTR_DRBG_PR_ON              1       /**< Prediction resistance enabled  */
+#define MBEDTLS_CTR_DRBG_PR_OFF             0
+/**< Prediction resistance is disabled. */
+#define MBEDTLS_CTR_DRBG_PR_ON              1
+/**< Prediction resistance is enabled. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * \brief          CTR_DRBG context structure
+ * \brief          The CTR_DRBG context structure.
  */
 typedef struct
 {
-    unsigned char counter[16];  /*!<  counter (V)       */
-    int reseed_counter;         /*!<  reseed counter    */
-    int prediction_resistance;  /*!<  enable prediction resistance (Automatic
-                                      reseed before every random generation)  */
-    size_t entropy_len;         /*!<  amount of entropy grabbed on each
-                                      (re)seed          */
-    int reseed_interval;        /*!<  reseed interval   */
-
-    mbedtls_aes_context aes_ctx;        /*!<  AES context       */
+    unsigned char counter[16];  /*!< The counter (V). */
+    int reseed_counter;         /*!< The reseed counter. */
+    int prediction_resistance;  /*!< This determines whether prediction
+                                     resistance is enabled, that is
+                                     whether to systematically reseed before
+                                     each random generation. */
+    size_t entropy_len;         /*!< The amount of entropy grabbed on each
+                                     seed or reseed operation. */
+    int reseed_interval;        /*!< The reseed interval. */
+
+    mbedtls_aes_context aes_ctx;        /*!< The AES context. */
 
     /*
      * Callbacks (Entropy)
      */
     int (*f_entropy)(void *, unsigned char *, size_t);
+                                /*!< The entropy callback function. */
 
-    void *p_entropy;            /*!<  context for the entropy function */
+    void *p_entropy;            /*!< The context for the entropy function. */
 
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_threading_mutex_t mutex;
@@ -110,31 +137,32 @@ typedef struct
 mbedtls_ctr_drbg_context;
 
 /**
- * \brief               CTR_DRBG context initialization
- *                      Makes the context ready for mbedtls_ctr_drbg_seed() or
- *                      mbedtls_ctr_drbg_free().
+ * \brief               This function initializes the CTR_DRBG context,
+ *                      and prepares it for mbedtls_ctr_drbg_seed()
+ *                      or mbedtls_ctr_drbg_free().
  *
- * \param ctx           CTR_DRBG context to be initialized
+ * \param ctx           The CTR_DRBG context to initialize.
  */
 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
 
 /**
- * \brief               CTR_DRBG initial seeding
- *                      Seed and setup entropy source for future reseeds.
- *
- * Note: Personalization data can be provided in addition to the more generic
- *       entropy source to make this instantiation as unique as possible.
- *
- * \param ctx           CTR_DRBG context to be seeded
- * \param f_entropy     Entropy callback (p_entropy, buffer to fill, buffer
- *                      length)
- * \param p_entropy     Entropy context
- * \param custom        Personalization data (Device specific identifiers)
- *                      (Can be NULL)
- * \param len           Length of personalization data
- *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+ * \brief               This function seeds and sets up the CTR_DRBG
+ *                      entropy source for future reseeds.
+ *
+ * \note Personalization data can be provided in addition to the more generic
+ *       entropy source, to make this instantiation as unique as possible.
+ *
+ * \param ctx           The CTR_DRBG context to seed.
+ * \param f_entropy     The entropy callback, taking as arguments the
+ *                      \p p_entropy context, the buffer to fill, and the
+                        length of the buffer.
+ * \param p_entropy     The entropy context.
+ * \param custom        Personalization data, that is device-specific
+                        identifiers. Can be NULL.
+ * \param len           The length of the personalization data.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
  */
 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
                    int (*f_entropy)(void *, unsigned char *, size_t),
@@ -143,138 +171,150 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
                    size_t len );
 
 /**
- * \brief               Clear CTR_CRBG context data
+ * \brief               This function clears CTR_CRBG context data.
  *
- * \param ctx           CTR_DRBG context to clear
+ * \param ctx           The CTR_DRBG context to clear.
  */
 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
 
 /**
- * \brief               Enable / disable prediction resistance (Default: Off)
+ * \brief               This function turns prediction resistance on or off.
+ *                      The default value is off.
  *
- * Note: If enabled, entropy is used for ctx->entropy_len before each call!
- *       Only use this if you have ample supply of good entropy!
+ * \note                If enabled, entropy is gathered at the beginning of
+ *                      every call to mbedtls_ctr_drbg_random_with_add().
+ *                      Only use this if your entropy source has sufficient
+ *                      throughput.
  *
- * \param ctx           CTR_DRBG context
- * \param resistance    MBEDTLS_CTR_DRBG_PR_ON or MBEDTLS_CTR_DRBG_PR_OFF
+ * \param ctx           The CTR_DRBG context.
+ * \param resistance    #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
  */
 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
                                          int resistance );
 
 /**
- * \brief               Set the amount of entropy grabbed on each (re)seed
- *                      (Default: MBEDTLS_CTR_DRBG_ENTROPY_LEN)
+ * \brief               This function sets the amount of entropy grabbed on each
+ *                      seed or reseed. The default value is
+ *                      #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
  *
- * \param ctx           CTR_DRBG context
- * \param len           Amount of entropy to grab
+ * \param ctx           The CTR_DRBG context.
+ * \param len           The amount of entropy to grab.
  */
 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
                                size_t len );
 
 /**
- * \brief               Set the reseed interval
- *                      (Default: MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
+ * \brief               This function sets the reseed interval.
+ *                      The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
  *
- * \param ctx           CTR_DRBG context
- * \param interval      Reseed interval
+ * \param ctx           The CTR_DRBG context.
+ * \param interval      The reseed interval.
  */
 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
                                    int interval );
 
 /**
- * \brief               CTR_DRBG reseeding (extracts data from entropy source)
+ * \brief               This function reseeds the CTR_DRBG context, that is
+ *                      extracts data from the entropy source.
  *
- * \param ctx           CTR_DRBG context
- * \param additional    Additional data to add to state (Can be NULL)
- * \param len           Length of additional data
+ * \param ctx           The CTR_DRBG context.
+ * \param additional    Additional data to add to the state. Can be NULL.
+ * \param len           The length of the additional data.
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
  */
 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
                      const unsigned char *additional, size_t len );
 
 /**
- * \brief               CTR_DRBG update state
+ * \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           CTR_DRBG context
- * \param additional    Additional data to update state with
- * \param add_len       Length of additional data
+ * \param ctx          The CTR_DRBG context.
+ * \param additional   The data to update the state with.
+ * \param add_len      Length of \p additional data.
  *
- * \note                If 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 ones are silently discarded.
  */
 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
                       const unsigned char *additional, size_t add_len );
 
 /**
- * \brief               CTR_DRBG generate random with additional update input
+ * \brief   This function updates a CTR_DRBG instance with additional
+ *          data and uses it to generate random data.
  *
- * Note: Automatically reseeds if reseed_counter is reached.
+ * \note    The function automatically reseeds if the reseed counter is exceeded.
  *
- * \param p_rng         CTR_DRBG context
- * \param output        Buffer to fill
- * \param output_len    Length of the buffer
- * \param additional    Additional data to update with (Can be NULL)
- * \param add_len       Length of additional data
+ * \param p_rng         The CTR_DRBG context. This must be a pointer to a
+ *                      #mbedtls_ctr_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param output_len    The length of the buffer.
+ * \param additional    Additional data to update. Can be NULL.
+ * \param add_len       The length of the additional data.
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
- *                      MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG
+ * \return    \c 0 on success.
+ * \return    #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ *            #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
  */
 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
                               unsigned char *output, size_t output_len,
                               const unsigned char *additional, size_t add_len );
 
 /**
- * \brief               CTR_DRBG generate random
+ * \brief   This function uses CTR_DRBG to generate random data.
  *
- * Note: Automatically reseeds if reseed_counter is reached.
+ * \note    The function automatically reseeds if the reseed counter is exceeded.
  *
- * \param p_rng         CTR_DRBG context
- * \param output        Buffer to fill
- * \param output_len    Length of the buffer
+ * \param p_rng         The CTR_DRBG context. This must be a pointer to a
+ *                      #mbedtls_ctr_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param output_len    The length of the buffer.
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
- *                      MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ *                      #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
  */
 int mbedtls_ctr_drbg_random( void *p_rng,
                      unsigned char *output, size_t output_len );
 
 #if defined(MBEDTLS_FS_IO)
 /**
- * \brief               Write a seed file
+ * \brief               This function writes a seed file.
  *
- * \param ctx           CTR_DRBG context
- * \param path          Name of the file
+ * \param ctx           The CTR_DRBG context.
+ * \param path          The name of the file.
  *
- * \return              0 if successful,
- *                      MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or
- *                      MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
+ *                      failure.
  */
 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
 
 /**
- * \brief               Read and update a seed file. Seed is added to this
- *                      instance
+ * \brief               This function reads and updates a seed file. The seed
+ *                      is added to this instance.
  *
- * \param ctx           CTR_DRBG context
- * \param path          Name of the file
+ * \param ctx           The CTR_DRBG context.
+ * \param path          The name of the file.
  *
- * \return              0 if successful,
- *                      MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error,
- *                      MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
- *                      MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ *                      #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
  */
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
 #endif /* MBEDTLS_FS_IO */
 
 /**
- * \brief               Checkup routine
+ * \brief               The CTR_DRBG checkup routine.
  *
- * \return              0 if successful, or 1 if the test failed
+ * \return              \c 0 on success.
+ * \return              \c 1 on failure.
  */
 int mbedtls_ctr_drbg_self_test( int verbose );
 
diff --git a/crypto/mbedtls/include/mbedtls/debug.h b/crypto/mbedtls/include/mbedtls/debug.h
index 295799640..ef8db67ff 100644
--- a/crypto/mbedtls/include/mbedtls/debug.h
+++ b/crypto/mbedtls/include/mbedtls/debug.h
@@ -2,7 +2,8 @@
  * \file debug.h
  *
  * \brief Functions for controlling and providing debug output from the library.
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/des.h b/crypto/mbedtls/include/mbedtls/des.h
index 5ca2ecf2e..6eb7d03ba 100644
--- a/crypto/mbedtls/include/mbedtls/des.h
+++ b/crypto/mbedtls/include/mbedtls/des.h
@@ -3,6 +3,11 @@
  *
  * \brief DES block cipher
  *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers
+ *            instead.
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -19,6 +24,7 @@
  *  limitations under the License.
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
  */
 #ifndef MBEDTLS_DES_H
 #define MBEDTLS_DES_H
@@ -36,19 +42,24 @@
 #define MBEDTLS_DES_DECRYPT     0
 
 #define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH              -0x0032  /**< The data input has an invalid length. */
+#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED                   -0x0033  /**< DES hardware accelerator failed. */
 
 #define MBEDTLS_DES_KEY_SIZE    8
 
-#if !defined(MBEDTLS_DES_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_DES_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          DES context structure
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 typedef struct
 {
@@ -65,10 +76,18 @@ typedef struct
 }
 mbedtls_des3_context;
 
+#else  /* MBEDTLS_DES_ALT */
+#include "des_alt.h"
+#endif /* MBEDTLS_DES_ALT */
+
 /**
  * \brief          Initialize DES context
  *
  * \param ctx      DES context to be initialized
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 void mbedtls_des_init( mbedtls_des_context *ctx );
 
@@ -76,6 +95,10 @@ void mbedtls_des_init( mbedtls_des_context *ctx );
  * \brief          Clear DES context
  *
  * \param ctx      DES context to be cleared
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 void mbedtls_des_free( mbedtls_des_context *ctx );
 
@@ -100,6 +123,10 @@ void mbedtls_des3_free( mbedtls_des3_context *ctx );
  *                 a parity bit to allow verification.
  *
  * \param key      8-byte secret key
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
@@ -112,6 +139,10 @@ void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
  * \param key      8-byte secret key
  *
  * \return         0 is parity was ok, 1 if parity was not correct.
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
@@ -121,6 +152,10 @@ int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SI
  * \param key      8-byte secret key
  *
  * \return         0 if no weak key was found, 1 if a weak key was identified.
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
@@ -131,6 +166,10 @@ int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
  * \param key      8-byte secret key
  *
  * \return         0
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
@@ -141,6 +180,10 @@ int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MB
  * \param key      8-byte secret key
  *
  * \return         0
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
@@ -196,6 +239,10 @@ int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
  * \param output   64-bit output block
  *
  * \return         0 if successful
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
                     const unsigned char input[8],
@@ -219,6 +266,10 @@ int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
  * \param iv       initialization vector (updated after use)
  * \param input    buffer holding the input data
  * \param output   buffer holding the output data
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
                     int mode,
@@ -277,20 +328,13 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
  *
  * \param SK       Round keys
  * \param key      Base key
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
  */
 void mbedtls_des_setkey( uint32_t SK[32],
                          const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_DES_ALT */
-#include "des_alt.h"
-#endif /* MBEDTLS_DES_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
 
 /**
  * \brief          Checkup routine
diff --git a/crypto/mbedtls/include/mbedtls/dhm.h b/crypto/mbedtls/include/mbedtls/dhm.h
index d7ab1522e..f848e221d 100644
--- a/crypto/mbedtls/include/mbedtls/dhm.h
+++ b/crypto/mbedtls/include/mbedtls/dhm.h
@@ -1,9 +1,50 @@
 /**
  * \file dhm.h
  *
- * \brief Diffie-Hellman-Merkle key exchange
+ * \brief   This file contains Diffie-Hellman-Merkle (DHM) key exchange 
+ *          definitions and functions.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Diffie-Hellman-Merkle (DHM) key exchange is defined in
+ * <em>RFC-2631: Diffie-Hellman Key Agreement Method</em> and 
+ * <em>Public-Key Cryptography Standards (PKCS) #3: Diffie 
+ * Hellman Key Agreement Standard</em>.
+ *
+ * <em>RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for
+ * Internet Key Exchange (IKE)</em> defines a number of standardized
+ * Diffie-Hellman groups for IKE.
+ *
+ * <em>RFC-5114: Additional Diffie-Hellman Groups for Use with IETF
+ * Standards</em> defines a number of standardized Diffie-Hellman
+ * groups that can be used.
+ *
+ * \warning  The security of the DHM key exchange relies on the proper choice
+ *           of prime modulus - optimally, it should be a safe prime. The usage
+ *           of non-safe primes both decreases the difficulty of the underlying
+ *           discrete logarithm problem and can lead to small subgroup attacks
+ *           leaking private exponent bits when invalid public keys are used
+ *           and not detected. This is especially relevant if the same DHM
+ *           parameters are reused for multiple key exchanges as in static DHM,
+ *           while the criticality of small-subgroup attacks is lower for
+ *           ephemeral DHM.
+ *
+ * \warning  For performance reasons, the code does neither perform primality
+ *           nor safe primality tests, nor the expensive checks for invalid
+ *           subgroups. Moreover, even if these were performed, non-standardized
+ *           primes cannot be trusted because of the possibility of backdoors
+ *           that can't be effectively checked for.
+ *
+ * \warning  Diffie-Hellman-Merkle is therefore a security risk when not using
+ *           standardized primes generated using a trustworthy ("nothing up
+ *           my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS
+ *           protocol, DH parameters need to be negotiated, so using the default
+ *           primes systematically is not always an option. If possible, use
+ *           Elliptic Curve Diffie-Hellman (ECDH), which has better performance,
+ *           and for which the TLS protocol mandates the use of standard
+ *           parameters.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,17 +59,23 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_DHM_H
 #define MBEDTLS_DHM_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
 #include "bignum.h"
 
 /*
  * DHM Error codes
  */
-#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA                    -0x3080  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA                    -0x3080  /**< Bad input parameters. */
 #define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED                -0x3100  /**< Reading of the DHM parameters failed. */
 #define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED                -0x3180  /**< Making of the DHM parameters failed. */
 #define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED                -0x3200  /**< Reading of the public values failed. */
@@ -36,167 +83,91 @@
 #define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED                -0x3300  /**< Calculation of the DHM secret failed. */
 #define MBEDTLS_ERR_DHM_INVALID_FORMAT                    -0x3380  /**< The ASN.1 data is not formatted correctly. */
 #define MBEDTLS_ERR_DHM_ALLOC_FAILED                      -0x3400  /**< Allocation of memory failed. */
-#define MBEDTLS_ERR_DHM_FILE_IO_ERROR                     -0x3480  /**< Read/write of file failed. */
-
-/**
- * RFC 3526 defines a number of standardized Diffie-Hellman groups
- * for IKE.
- * RFC 5114 defines a number of standardized Diffie-Hellman groups
- * that can be used.
- *
- * Some are included here for convenience.
- *
- * Included are:
- *  RFC 3526 3.    2048-bit MODP Group
- *  RFC 3526 4.    3072-bit MODP Group
- *  RFC 3526 5.    4096-bit MODP Group
- *  RFC 5114 2.2.  2048-bit MODP Group with 224-bit Prime Order Subgroup
- */
-#define MBEDTLS_DHM_RFC3526_MODP_2048_P               \
-    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
-    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
-    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
-    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
-    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
-    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
-    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
-    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
-    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
-    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
-    "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
-
-#define MBEDTLS_DHM_RFC3526_MODP_2048_G          "02"
-
-#define MBEDTLS_DHM_RFC3526_MODP_3072_P               \
-    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
-    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
-    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
-    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
-    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
-    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
-    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
-    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
-    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
-    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
-    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
-    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
-    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
-    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
-    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
-    "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
-
-#define MBEDTLS_DHM_RFC3526_MODP_3072_G          "02"
-
-#define MBEDTLS_DHM_RFC3526_MODP_4096_P                \
-    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
-    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
-    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
-    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
-    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
-    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
-    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
-    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
-    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
-    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
-    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
-    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
-    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
-    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
-    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
-    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \
-    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \
-    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \
-    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \
-    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \
-    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" \
-    "FFFFFFFFFFFFFFFF"
-
-#define MBEDTLS_DHM_RFC3526_MODP_4096_G          "02"
-
-#define MBEDTLS_DHM_RFC5114_MODP_2048_P               \
-    "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \
-    "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \
-    "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \
-    "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \
-    "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \
-    "B3BF8A317091883681286130BC8985DB1602E714415D9330" \
-    "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \
-    "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \
-    "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \
-    "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \
-    "CF9DE5384E71B81C0AC4DFFE0C10E64F"
-
-#define MBEDTLS_DHM_RFC5114_MODP_2048_G              \
-    "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"\
-    "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"\
-    "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"\
-    "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"\
-    "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"\
-    "F180EB34118E98D119529A45D6F834566E3025E316A330EF"\
-    "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"\
-    "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"\
-    "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"\
-    "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"\
-    "81BC087F2A7065B384B890D3191F2BFA"
+#define MBEDTLS_ERR_DHM_FILE_IO_ERROR                     -0x3480  /**< Read or write of file failed. */
+#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED                   -0x3500  /**< DHM hardware accelerator failed. */
+#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED                  -0x3580  /**< Setting the modulus and generator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_DHM_ALT)
+
 /**
- * \brief          DHM context structure
+ * \brief          The DHM context structure.
  */
 typedef struct
 {
-    size_t len; /*!<  size(P) in chars  */
-    mbedtls_mpi P;      /*!<  prime modulus     */
-    mbedtls_mpi G;      /*!<  generator         */
-    mbedtls_mpi X;      /*!<  secret value      */
-    mbedtls_mpi GX;     /*!<  self = G^X mod P  */
-    mbedtls_mpi GY;     /*!<  peer = G^Y mod P  */
-    mbedtls_mpi K;      /*!<  key = GY^X mod P  */
-    mbedtls_mpi RP;     /*!<  cached R^2 mod P  */
-    mbedtls_mpi Vi;     /*!<  blinding value    */
-    mbedtls_mpi Vf;     /*!<  un-blinding value */
-    mbedtls_mpi pX;     /*!<  previous X        */
+    size_t len;         /*!<  The size of \p P in Bytes. */
+    mbedtls_mpi P;      /*!<  The prime modulus. */
+    mbedtls_mpi G;      /*!<  The generator. */
+    mbedtls_mpi X;      /*!<  Our secret value. */
+    mbedtls_mpi GX;     /*!<  Our public key = \c G^X mod \c P. */
+    mbedtls_mpi GY;     /*!<  The public key of the peer = \c G^Y mod \c P. */
+    mbedtls_mpi K;      /*!<  The shared secret = \c G^(XY) mod \c P. */
+    mbedtls_mpi RP;     /*!<  The cached value = \c R^2 mod \c P. */
+    mbedtls_mpi Vi;     /*!<  The blinding value. */
+    mbedtls_mpi Vf;     /*!<  The unblinding value. */
+    mbedtls_mpi pX;     /*!<  The previous \c X. */
 }
 mbedtls_dhm_context;
 
+#else /* MBEDTLS_DHM_ALT */
+#include "dhm_alt.h"
+#endif /* MBEDTLS_DHM_ALT */
+
 /**
- * \brief          Initialize DHM context
+ * \brief          This function initializes the DHM context.
  *
- * \param ctx      DHM context to be initialized
+ * \param ctx      The DHM context to initialize.
  */
 void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
 
 /**
- * \brief          Parse the ServerKeyExchange parameters
+ * \brief          This function parses the ServerKeyExchange parameters.
  *
- * \param ctx      DHM context
- * \param p        &(start of input buffer)
- * \param end      end of buffer
+ * \param ctx      The DHM context.
+ * \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
+ *                 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         0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
+ * \return         \c 0 on success.
+ * \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 );
 
 /**
- * \brief          Setup and write the ServerKeyExchange parameters
+ * \brief          This function sets up and writes the ServerKeyExchange
+ *                 parameters.
+ *
+ * \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.
  *
- * \param ctx      DHM context
- * \param x_size   private value size in bytes
- * \param output   destination buffer
- * \param olen     number of chars written
- * \param f_rng    RNG function
- * \param p_rng    RNG parameter
+ * \note           This function assumes that \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().
  *
- * \note           This function assumes that ctx->P and ctx->G
- *                 have already been properly set (for example
- *                 using mbedtls_mpi_read_string or mbedtls_mpi_read_binary).
+ * \param ctx      The DHM context.
+ * \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.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
                      unsigned char *output, size_t *olen,
@@ -204,28 +175,54 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
                      void *p_rng );
 
 /**
- * \brief          Import the peer's public value G^Y
+ * \brief          This function sets the prime modulus and generator.
+ *
+ * \note           This function can be used to set \p P, \p 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.
+ *
+ * \return         \c 0 if successful.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
+ */
+int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
+                           const mbedtls_mpi *P,
+                           const mbedtls_mpi *G );
+
+/**
+ * \brief          This function imports the public value of the peer, G^Y.
  *
- * \param ctx      DHM context
- * \param input    input buffer
- * \param ilen     size of buffer
+ * \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.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
                      const unsigned char *input, size_t ilen );
 
 /**
- * \brief          Create own private value X and export G^X
+ * \brief          This function creates its own private key, \c X, and
+ *                 exports \c G^X.
  *
- * \param ctx      DHM context
- * \param x_size   private value size in bytes
- * \param output   destination buffer
- * \param olen     must be at least equal to the size of P, ctx->len
- * \param f_rng    RNG function
- * \param p_rng    RNG parameter
+ * \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
+ *                 with zero-bytes at the beginning.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
+ * \param ctx      The DHM context.
+ * \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.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
                      unsigned char *output, size_t olen,
@@ -233,22 +230,25 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
                      void *p_rng );
 
 /**
- * \brief          Derive and export the shared secret (G^Y)^X mod P
- *
- * \param ctx      DHM context
- * \param output   destination buffer
- * \param output_size   size of the destination buffer
- * \param olen     on exit, holds the actual number of bytes written
- * \param f_rng    RNG function, for blinding purposes
- * \param p_rng    RNG parameter
- *
- * \return         0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
- *
- * \note           If non-NULL, f_rng is used to blind the input as
- *                 countermeasure against timing attacks. Blinding is
- *                 automatically used if and only if our secret value X is
- *                 re-used and costs nothing otherwise, so it is recommended
- *                 to always pass a non-NULL f_rng argument.
+ * \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.
+ *
+ * \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 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.
+ *
+ * \return              \c 0 on success.
+ * \return              An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
                      unsigned char *output, size_t output_size, size_t *olen,
@@ -256,23 +256,25 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
                      void *p_rng );
 
 /**
- * \brief          Free and clear the components of a DHM key
+ * \brief          This function frees and clears the components of a DHM context.
  *
- * \param ctx      DHM context to free and clear
+ * \param ctx      The DHM context to free and clear.
  */
 void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
 
 #if defined(MBEDTLS_ASN1_PARSE_C)
 /** \ingroup x509_module */
 /**
- * \brief          Parse DHM parameters in PEM or DER format
+ * \brief             This function parses DHM parameters in PEM or DER format.
  *
- * \param dhm      DHM context to be initialized
- * \param dhmin    input buffer
- * \param dhminlen size of the buffer
- *                 (including the terminating null byte for PEM data)
+ * \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.
  *
- * \return         0 if successful, or a specific DHM or PEM error code
+ * \return            \c 0 on success.
+ * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error code
+ *                    error code on failure.
  */
 int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
                    size_t dhminlen );
@@ -280,21 +282,24 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
 #if defined(MBEDTLS_FS_IO)
 /** \ingroup x509_module */
 /**
- * \brief          Load and parse DHM parameters
+ * \brief          This function loads and parses DHM parameters from a file.
  *
- * \param dhm      DHM context to be initialized
- * \param path     filename to read the DHM Parameters from
+ * \param dhm      The DHM context to load the parameters to.
+ * \param path     The filename to read the DHM parameters from.
  *
- * \return         0 if successful, or a specific DHM or PEM error code
+ * \return         \c 0 on success.
+ * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error code
+ *                    error code on failure.
  */
 int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path );
 #endif /* MBEDTLS_FS_IO */
 #endif /* MBEDTLS_ASN1_PARSE_C */
 
 /**
- * \brief          Checkup routine
+ * \brief          The DMH checkup routine.
  *
- * \return         0 if successful, or 1 if the test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_dhm_self_test( int verbose );
 
@@ -302,4 +307,757 @@ int mbedtls_dhm_self_test( int verbose );
 }
 #endif
 
+/**
+ * RFC 3526, RFC 5114 and RFC 7919 standardize a number of
+ * Diffie-Hellman groups, some of which are included here
+ * for use within the SSL/TLS module and the user's convenience
+ * when configuring the Diffie-Hellman parameters by hand
+ * through \c mbedtls_ssl_conf_dh_param.
+ *
+ * The following lists the source of the above groups in the standards:
+ * - RFC 5114 section 2.2:  2048-bit MODP Group with 224-bit Prime Order Subgroup
+ * - RFC 3526 section 3:    2048-bit MODP Group
+ * - RFC 3526 section 4:    3072-bit MODP Group
+ * - RFC 3526 section 5:    4096-bit MODP Group
+ * - RFC 7919 section A.1:  ffdhe2048
+ * - RFC 7919 section A.2:  ffdhe3072
+ * - RFC 7919 section A.3:  ffdhe4096
+ * - RFC 7919 section A.4:  ffdhe6144
+ * - RFC 7919 section A.5:  ffdhe8192
+ *
+ * The constants with suffix "_p" denote the chosen prime moduli, while
+ * the constants with suffix "_g" denote the chosen generator
+ * of the associated prime field.
+ *
+ * The constants further suffixed with "_bin" are provided in binary format,
+ * while all other constants represent null-terminated strings holding the
+ * hexadecimal presentation of the respective numbers.
+ *
+ * The primes from RFC 3526 and RFC 7919 have been generating by the following
+ * trust-worthy procedure:
+ * - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number
+ *   the first and last 64 bits are all 1, and the remaining N - 128 bits of
+ *   which are 0x7ff...ff.
+ * - Add the smallest multiple of the first N - 129 bits of the binary expansion
+ *   of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string
+ *   such that the resulting integer is a safe-prime.
+ * - The result is the respective RFC 3526 / 7919 prime, and the corresponding
+ *   generator is always chosen to be 2 (which is a square for these prime,
+ *   hence the corresponding subgroup has order (p-1)/2 and avoids leaking a
+ *   bit in the private exponent).
+ *
+ */
+
+#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!
+ *
+ * \deprecated The hex-encoded primes from RFC 5114 are deprecated and are
+ *             likely to be removed in a future version of the library without
+ *             replacement.
+ */
+
+/**
+ * The hexadecimal presentation of the prime underlying the
+ * 2048-bit MODP Group with 224-bit Prime Order Subgroup, as defined
+ * in <em>RFC-5114: Additional Diffie-Hellman Groups for Use with
+ * IETF Standards</em>.
+ */
+#define MBEDTLS_DHM_RFC5114_MODP_2048_P                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1"      \
+        "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15"      \
+        "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212"      \
+        "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207"      \
+        "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708"      \
+        "B3BF8A317091883681286130BC8985DB1602E714415D9330"      \
+        "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D"      \
+        "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8"      \
+        "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763"      \
+        "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71"      \
+        "CF9DE5384E71B81C0AC4DFFE0C10E64F" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 2048-bit MODP
+ * Group with 224-bit Prime Order Subgroup, as defined in <em>RFC-5114:
+ * Additional Diffie-Hellman Groups for Use with IETF Standards</em>.
+ */
+#define MBEDTLS_DHM_RFC5114_MODP_2048_G                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"      \
+        "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"      \
+        "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"      \
+        "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"      \
+        "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"      \
+        "F180EB34118E98D119529A45D6F834566E3025E316A330EF"      \
+        "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"      \
+        "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"      \
+        "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"      \
+        "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"      \
+        "81BC087F2A7065B384B890D3191F2BFA" )
+
+/**
+ * The hexadecimal presentation of the prime underlying the 2048-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ *
+ * \deprecated The hex-encoded primes from RFC 3625 are deprecated and
+ *             superseded by the corresponding macros providing them as
+ *             binary constants. Their hex-encoded constants are likely
+ *             to be removed in a future version of the library.
+ *
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_2048_P                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"      \
+        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"      \
+        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"      \
+        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"      \
+        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"      \
+        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"      \
+        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"      \
+        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"      \
+        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"      \
+        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"      \
+        "15728E5A8AACAA68FFFFFFFFFFFFFFFF" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 2048-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_2048_G                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" )
+
+/**
+ * The hexadecimal presentation of the prime underlying the 3072-bit MODP
+ * Group, as defined in <em>RFC-3072: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_3072_P                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"      \
+        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"      \
+        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"      \
+        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"      \
+        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"      \
+        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"      \
+        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"      \
+        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"      \
+        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"      \
+        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"      \
+        "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"      \
+        "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"      \
+        "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"      \
+        "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"      \
+        "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"      \
+        "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 3072-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_3072_G                      \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" )
+
+/**
+ * The hexadecimal presentation of the prime underlying the 4096-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_4096_P                      \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                      \
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"   \
+        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"   \
+        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"   \
+        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"   \
+        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"   \
+        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"   \
+        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"   \
+        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"   \
+        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"   \
+        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"   \
+        "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"   \
+        "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"   \
+        "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"   \
+        "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"   \
+        "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"   \
+        "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"   \
+        "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"   \
+        "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"   \
+        "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"   \
+        "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"   \
+        "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"   \
+        "FFFFFFFFFFFFFFFF" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 4096-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_4096_G                      \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" )
+
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * Trustworthy DHM parameters in binary form
+ */
+
+#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN {        \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+     0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \
+     0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \
+     0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \
+     0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \
+     0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \
+     0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \
+     0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \
+     0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \
+     0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \
+     0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \
+     0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \
+     0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \
+     0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \
+     0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \
+     0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \
+     0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \
+     0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \
+     0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \
+     0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \
+     0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \
+     0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \
+     0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \
+     0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \
+     0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \
+     0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \
+     0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \
+     0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \
+     0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \
+     0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \
+     0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN {       \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN  {       \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  \
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,  \
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,  \
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,  \
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,  \
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,  \
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,  \
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,  \
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,  \
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,  \
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,  \
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,  \
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,  \
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,  \
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,  \
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,  \
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,  \
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,  \
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,  \
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,  \
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,  \
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,  \
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,  \
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,  \
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,  \
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,  \
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,  \
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,  \
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,  \
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,  \
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,  \
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,  \
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,  \
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,  \
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,  \
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,  \
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,  \
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,  \
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,  \
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,  \
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,  \
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,  \
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,  \
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,  \
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,  \
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,  \
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,  \
+    0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,  \
+    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,  \
+    0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,  \
+    0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,  \
+    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,  \
+    0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,  \
+    0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,  \
+    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,  \
+    0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,  \
+    0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,  \
+    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,  \
+    0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,  \
+    0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,  \
+    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,  \
+    0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,  \
+    0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,  \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN {        \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
+     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
+     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
+     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
+     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
+     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
+     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
+     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
+     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
+     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
+     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
+     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
+     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
+     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
+     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
+     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
+     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
+     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
+     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
+     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
+     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
+     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
+     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
+     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
+     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
+     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
+     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
+     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
+     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
+     0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
+     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
+     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
+     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
+     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
+     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
+     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
+     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
+     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
+     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
+     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
+     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
+     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
+     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
+     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
+     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
+     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
+     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
+     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
+     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
+     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
+     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
+     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
+     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
+     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
+     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
+     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
+     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
+     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
+     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
+     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
+     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
+     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
+     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
+     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
+     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
+     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
+     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
+     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
+     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
+     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
+     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
+     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
+     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
+     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
+     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN {        \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
+     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
+     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
+     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
+     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
+     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
+     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
+     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
+     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
+     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
+     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
+     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
+     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
+     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
+     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
+     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
+     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
+     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
+     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
+     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
+     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
+     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
+     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
+     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
+     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
+     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
+     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
+     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
+     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
+     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
+     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
+     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
+     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
+     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
+     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
+     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
+     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
+     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
+     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
+     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
+     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
+     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
+     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
+     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
+     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
+     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \
+     0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \
+     0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \
+     0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \
+     0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \
+     0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \
+     0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \
+     0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \
+     0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \
+     0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \
+     0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \
+     0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \
+     0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \
+     0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \
+     0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \
+     0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \
+     0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN {        \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
+     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
+     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
+     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
+     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
+     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
+     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
+     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
+     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
+     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
+     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
+     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
+     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
+     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
+     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
+     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
+     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
+     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
+     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
+     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
+     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
+     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
+     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
+     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
+     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
+     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
+     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
+     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
+     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
+     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
+     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
+     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
+     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
+     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
+     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
+     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
+     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
+     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
+     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
+     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
+     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
+     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
+     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
+     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
+     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
+     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \
+     0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \
+     0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \
+     0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \
+     0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \
+     0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \
+     0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \
+     0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \
+     0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \
+     0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \
+     0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \
+     0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \
+     0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \
+     0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \
+     0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \
+     0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \
+     0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \
+     0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \
+     0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \
+     0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \
+     0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \
+     0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \
+     0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \
+     0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \
+     0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \
+     0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \
+     0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \
+     0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \
+     0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \
+     0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \
+     0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \
+     0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \
+     0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \
+     0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \
+     0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \
+     0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \
+     0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \
+     0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \
+     0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \
+     0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \
+     0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \
+     0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \
+     0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \
+     0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \
+     0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \
+     0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \
+     0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \
+     0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \
+     0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN {        \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
+     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
+     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
+     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
+     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
+     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
+     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
+     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
+     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
+     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
+     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
+     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
+     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
+     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
+     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
+     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
+     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
+     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
+     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
+     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
+     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
+     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
+     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
+     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
+     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
+     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
+     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
+     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
+     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
+     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
+     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
+     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
+     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
+     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
+     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
+     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
+     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
+     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
+     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
+     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
+     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
+     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
+     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
+     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
+     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
+     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \
+     0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \
+     0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \
+     0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \
+     0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \
+     0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \
+     0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \
+     0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \
+     0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \
+     0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \
+     0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \
+     0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \
+     0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \
+     0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \
+     0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \
+     0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \
+     0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \
+     0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \
+     0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \
+     0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \
+     0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \
+     0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \
+     0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \
+     0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \
+     0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \
+     0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \
+     0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \
+     0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \
+     0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \
+     0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \
+     0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \
+     0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \
+     0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \
+     0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \
+     0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \
+     0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \
+     0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \
+     0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \
+     0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \
+     0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \
+     0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \
+     0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \
+     0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \
+     0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \
+     0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \
+     0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \
+     0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \
+     0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \
+     0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, \
+     0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, \
+     0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, \
+     0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, \
+     0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, \
+     0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, \
+     0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, \
+     0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, \
+     0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, \
+     0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, \
+     0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, \
+     0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, \
+     0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, \
+     0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, \
+     0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, \
+     0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, \
+     0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, \
+     0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, \
+     0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, \
+     0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, \
+     0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, \
+     0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, \
+     0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, \
+     0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, \
+     0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, \
+     0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, \
+     0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, \
+     0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, \
+     0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, \
+     0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, \
+     0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, \
+     0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, \
+     0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 }
+
 #endif /* dhm.h */
diff --git a/crypto/mbedtls/include/mbedtls/ecdh.h b/crypto/mbedtls/include/mbedtls/ecdh.h
index 625a28192..922f029d7 100644
--- a/crypto/mbedtls/include/mbedtls/ecdh.h
+++ b/crypto/mbedtls/include/mbedtls/ecdh.h
@@ -1,9 +1,19 @@
 /**
  * \file ecdh.h
  *
- * \brief Elliptic curve Diffie-Hellman
+ * \brief This file contains ECDH definitions and functions.
+ * 
+ * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous 
+ * key agreement protocol allowing two parties to establish a shared
+ * secret over an insecure channel. Each party must have an
+ * elliptic-curve public–private key pair.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
+ * Pair-Wise Key Establishment Schemes Using Discrete Logarithm
+ * Cryptography</em>.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,8 +28,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_ECDH_H
 #define MBEDTLS_ECDH_H
 
@@ -30,65 +41,79 @@ extern "C" {
 #endif
 
 /**
- * When importing from an EC key, select if it is our key or the peer's key
+ * Defines the source of the imported EC key.
  */
 typedef enum
 {
-    MBEDTLS_ECDH_OURS,
-    MBEDTLS_ECDH_THEIRS,
+    MBEDTLS_ECDH_OURS,   /**< Our key. */
+    MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
 } mbedtls_ecdh_side;
 
 /**
- * \brief           ECDH context structure
+ * \brief           The ECDH context structure.
  */
 typedef struct
 {
-    mbedtls_ecp_group grp;      /*!<  elliptic curve used                           */
-    mbedtls_mpi d;              /*!<  our secret value (private key)                */
-    mbedtls_ecp_point Q;        /*!<  our public value (public key)                 */
-    mbedtls_ecp_point Qp;       /*!<  peer's public value (public key)              */
-    mbedtls_mpi z;              /*!<  shared secret                                 */
-    int point_format;   /*!<  format for point export in TLS messages       */
-    mbedtls_ecp_point Vi;       /*!<  blinding value (for later)                    */
-    mbedtls_ecp_point Vf;       /*!<  un-blinding value (for later)                 */
-    mbedtls_mpi _d;             /*!<  previous d (for later)                        */
+    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. */
+    int point_format;        /*!< The format of point export in TLS messages. */
+    mbedtls_ecp_point Vi;    /*!< The blinding value. */
+    mbedtls_ecp_point Vf;    /*!< The unblinding value. */
+    mbedtls_mpi _d;          /*!< The previous \p d. */
 }
 mbedtls_ecdh_context;
 
 /**
- * \brief           Generate a public key.
- *                  Raw function that only does the core computation.
+ * \brief           This function generates an ECDH keypair on an elliptic
+ *                  curve.
+ *
+ *                  This function performs the first of two core computations
+ *                  implemented during the ECDH key exchange. The second core
+ *                  computation is performed by mbedtls_ecdh_compute_shared().
+ *
+ * \see             ecp.h
  *
- * \param grp       ECP group
- * \param d         Destination MPI (secret exponent, aka private key)
- * \param Q         Destination point (public key)
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param grp       The ECP group.
+ * \param d         The destination MPI (private key).
+ * \param Q         The destination point (public key).
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or
+ *                  \c MBEDTLS_MPI_XXX error code on failure.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
  */
 int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng );
 
 /**
- * \brief           Compute shared secret
- *                  Raw function that only does the core computation.
- *
- * \param grp       ECP group
- * \param z         Destination MPI (shared secret)
- * \param Q         Public key from other party
- * \param d         Our secret exponent (private key)
- * \param f_rng     RNG function (see notes)
- * \param p_rng     RNG parameter
- *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
- *
- * \note            If f_rng is not NULL, it is used to implement
- *                  countermeasures against potential elaborate timing
- *                  attacks, see \c mbedtls_ecp_mul() for details.
+ * \brief           This function computes the shared secret.
+ *
+ *                  This function performs the second of two core computations
+ *                  implemented during the ECDH key exchange. The first core
+ *                  computation is performed by mbedtls_ecdh_gen_public().
+ *
+ * \see             ecp.h
+ *
+ * \note            If \p f_rng is not NULL, it is used to implement
+ *                  countermeasures against side-channel attacks.
+ *                  For more information, see mbedtls_ecp_mul().
+ *
+ * \param grp       The ECP group.
+ * \param z         The destination MPI (shared secret).
+ * \param Q         The public key from another party.
+ * \param d         Our secret exponent (private key).
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or
+ *                  \c MBEDTLS_MPI_XXX error code on failure.
  */
 int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
                          const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
@@ -96,34 +121,41 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
                          void *p_rng );
 
 /**
- * \brief           Initialize context
+ * \brief           This function initializes an ECDH context.
  *
- * \param ctx       Context to initialize
+ * \param ctx       The ECDH context to initialize.
  */
 void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
 
 /**
- * \brief           Free context
+ * \brief           This function frees a context.
  *
- * \param ctx       Context to free
+ * \param ctx       The context to free.
  */
 void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
 
 /**
- * \brief           Generate a public key and a TLS ServerKeyExchange payload.
- *                  (First function used by a TLS server for ECDHE.)
+ * \brief           This function generates a public key and a TLS
+ *                  ServerKeyExchange payload.
  *
- * \param ctx       ECDH context
- * \param olen      number of chars written
- * \param buf       destination buffer
- * \param blen      length of buffer
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ *                  This is the first function used by a TLS server for ECDHE
+ *                  ciphersuites.
  *
- * \note            This function assumes that ctx->grp has already been
- *                  properly set (for example using mbedtls_ecp_group_load).
+ * \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().
  *
- * \return          0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
+ * \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.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
                       unsigned char *buf, size_t blen,
@@ -131,45 +163,64 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
                       void *p_rng );
 
 /**
- * \brief           Parse and procress a TLS ServerKeyExhange payload.
- *                  (First function used by a TLS client for ECDHE.)
+ * \brief           This function parses and processes a TLS ServerKeyExhange
+ *                  payload.
+ *
+ *                  This is the first function used by a TLS client for ECDHE
+ *                  ciphersuites.
  *
- * \param ctx       ECDH context
- * \param buf       pointer to start of input buffer
- * \param end       one past end of buffer
+ * \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.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  *
- * \return          0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
  */
 int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
                       const unsigned char **buf, const unsigned char *end );
 
 /**
- * \brief           Setup an ECDH context from an EC key.
- *                  (Used by clients and servers in place of the
- *                  ServerKeyEchange for static ECDH: import ECDH parameters
- *                  from a certificate's EC key information.)
+ * \brief           This function sets up an ECDH context from an EC key.
+ *
+ *                  It is used by clients and servers in place of the
+ *                  ServerKeyEchange for static ECDH, and imports ECDH
+ *                  parameters from the EC key information of a certificate.
  *
- * \param ctx       ECDH constext to set
- * \param key       EC key to use
- * \param side      Is it our key (1) or the peer's key (0) ?
+ * \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.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  *
- * \return          0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
  */
 int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
                      mbedtls_ecdh_side side );
 
 /**
- * \brief           Generate a public key and a TLS ClientKeyExchange payload.
- *                  (Second function used by a TLS client for ECDH(E).)
+ * \brief           This function generates a public key and a TLS
+ *                  ClientKeyExchange payload.
+ *
+ *                  This is the second function used by a TLS client for ECDH(E)
+ *                  ciphersuites.
  *
- * \param ctx       ECDH context
- * \param olen      number of bytes actually written
- * \param buf       destination buffer
- * \param blen      size of destination buffer
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \see             ecp.h
  *
- * \return          0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
+ * \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.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
                       unsigned char *buf, size_t blen,
@@ -177,30 +228,45 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
                       void *p_rng );
 
 /**
- * \brief           Parse and process a TLS ClientKeyExchange payload.
- *                  (Second function used by a TLS server for ECDH(E).)
+ * \brief       This function parses and processes a TLS ClientKeyExchange
+ *              payload.
+ *
+ *              This is the second function used by a TLS server for ECDH(E)
+ *              ciphersuites.
+ *
+ * \see         ecp.h
  *
- * \param ctx       ECDH context
- * \param buf       start of input buffer
- * \param blen      length of input buffer
+ * \param ctx   The ECDH context.
+ * \param buf   The start of the input buffer.
+ * \param blen  The length of the input buffer.
  *
- * \return          0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
+ * \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 );
 
 /**
- * \brief           Derive and export the shared secret.
- *                  (Last function used by both TLS client en servers.)
+ * \brief           This function derives and exports the shared secret.
+ *
+ *                  This is the last function used by both TLS client
+ *                  and servers.
+ *
+ * \note            If \p f_rng is not NULL, it is used to implement
+ *                  countermeasures against side-channel attacks.
+ *                  For more information, see mbedtls_ecp_mul().
+ *
+ * \see             ecp.h
  *
- * \param ctx       ECDH context
- * \param olen      number of bytes written
- * \param buf       destination buffer
- * \param blen      buffer length
- * \param f_rng     RNG function, see notes for \c mbedtls_ecdh_compute_shared()
- * \param p_rng     RNG parameter
+ * \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.
  *
- * \return          0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
                       unsigned char *buf, size_t blen,
diff --git a/crypto/mbedtls/include/mbedtls/ecdsa.h b/crypto/mbedtls/include/mbedtls/ecdsa.h
index a277715b3..ce1a03d79 100644
--- a/crypto/mbedtls/include/mbedtls/ecdsa.h
+++ b/crypto/mbedtls/include/mbedtls/ecdsa.h
@@ -1,9 +1,17 @@
 /**
  * \file ecdsa.h
  *
- * \brief Elliptic curve DSA
+ * \brief This file contains ECDSA definitions and functions.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG):
+ * SEC1 Elliptic Curve Cryptography</em>.
+ * The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
+ * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,8 +26,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_ECDSA_H
 #define MBEDTLS_ECDSA_H
 
@@ -27,7 +36,7 @@
 #include "md.h"
 
 /*
- * RFC 4492 page 20:
+ * RFC-4492 page 20:
  *
  *     Ecdsa-Sig-Value ::= SEQUENCE {
  *         r       INTEGER,
@@ -43,11 +52,11 @@
 #if MBEDTLS_ECP_MAX_BYTES > 124
 #error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
 #endif
-/** Maximum size of an ECDSA signature in bytes */
+/** The maximal size of an ECDSA signature in Bytes. */
 #define MBEDTLS_ECDSA_MAX_LEN  ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
 
 /**
- * \brief           ECDSA context structure
+ * \brief           The ECDSA context structure.
  */
 typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
 
@@ -56,25 +65,31 @@ extern "C" {
 #endif
 
 /**
- * \brief           Compute ECDSA signature of a previously hashed message
- *
- * \note            The deterministic version is usually prefered.
+ * \brief           This function computes the ECDSA signature of a
+ *                  previously-hashed message.
  *
- * \param grp       ECP group
- * \param r         First output integer
- * \param s         Second output integer
- * \param d         Private signing key
- * \param buf       Message hash
- * \param blen      Length of buf
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \note            The deterministic version 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 as
- *                  prescribed by SEC1 4.1.3 step 5.
- *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ *                  bitlength of the group order, then the hash is truncated
+ *                  as defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \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.
+ *
+ * \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( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
@@ -82,23 +97,32 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
 
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
 /**
- * \brief           Compute ECDSA signature of a previously hashed message,
- *                  deterministic version (RFC 6979).
+ * \brief           This function computes the ECDSA signature of a
+ *                  previously-hashed message, deterministic version.
  *
- * \param grp       ECP group
- * \param r         First output integer
- * \param s         Second output integer
- * \param d         Private signing key
- * \param buf       Message hash
- * \param blen      Length of buf
- * \param md_alg    MD algorithm used to hash the message
+ *                  For more information, see <em>RFC-6979: Deterministic
+ *                  Usage of the Digital Signature Algorithm (DSA) and Elliptic
+ *                  Curve Digital Signature Algorithm (ECDSA)</em>.
  *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
- *                  prescribed by SEC1 4.1.3 step 5.
- *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \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.
+ *
+ * \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,
@@ -106,55 +130,74 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
 /**
- * \brief           Verify ECDSA signature of a previously hashed message
- *
- * \param grp       ECP group
- * \param buf       Message hash
- * \param blen      Length of buf
- * \param Q         Public key to use for verification
- * \param r         First integer of the signature
- * \param s         Second integer of the signature
+ * \brief           This function verifies the ECDSA signature of a
+ *                  previously-hashed message.
  *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
- *                  prescribed by SEC1 4.1.4 step 3.
- *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.4, step 3.
+ *
+ * \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 r         The first integer of the signature.
+ * \param s         The second integer of the signature.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
+ *                  is invalid.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ *                  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);
 
 /**
- * \brief           Compute ECDSA signature and write it to buffer,
- *                  serialized as defined in RFC 4492 page 20.
- *                  (Not thread-safe to use same context in multiple threads)
- *
- * \note            The deterministic version (RFC 6979) is used if
- *                  MBEDTLS_ECDSA_DETERMINISTIC is defined.
- *
- * \param ctx       ECDSA context
- * \param md_alg    Algorithm that was used to hash the message
- * \param hash      Message hash
- * \param hlen      Length of hash
- * \param sig       Buffer that will hold the signature
- * \param slen      Length of the signature written
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
- *
- * \note            The "sig" buffer must be at least as large as twice the
- *                  size of the curve used, plus 9 (eg. 73 bytes if a 256-bit
- *                  curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \brief           This function computes the ECDSA signature and writes it
+ *                  to a buffer, serialized as defined in <em>RFC-4492:
+ *                  Elliptic Curve Cryptography (ECC) Cipher Suites for
+ *                  Transport Layer Security (TLS)</em>.
+ *
+ * \warning         It is not thread-safe to use the same context in
+ *                  multiple threads.
+ *
+ * \note            The deterministic version is used if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more
+ *                  information, see <em>RFC-6979: Deterministic Usage
+ *                  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
- *                  prescribed by SEC1 4.1.3 step 5.
- *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or
- *                  MBEDTLS_ERR_ASN1_XXX error code
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDSA context.
+ * \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.
+ *
+ * \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,
                            const unsigned char *hash, size_t hlen,
@@ -170,31 +213,44 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief           Compute ECDSA signature and write it to buffer,
- *                  serialized as defined in RFC 4492 page 20.
- *                  Deterministic version, RFC 6979.
- *                  (Not thread-safe to use same context in multiple threads)
+ * \brief           This function computes an ECDSA signature and writes
+ *                  it to a buffer, serialized as defined in <em>RFC-4492:
+ *                  Elliptic Curve Cryptography (ECC) Cipher Suites for
+ *                  Transport Layer Security (TLS)</em>.
  *
- * \deprecated      Superseded by mbedtls_ecdsa_write_signature() in 2.0.0
+ *                  The deterministic version is defined in <em>RFC-6979:
+ *                  Deterministic Usage of the Digital Signature Algorithm (DSA)
+ *                  and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
  *
- * \param ctx       ECDSA context
- * \param hash      Message hash
- * \param hlen      Length of hash
- * \param sig       Buffer that will hold the signature
- * \param slen      Length of the signature written
- * \param md_alg    MD algorithm used to hash the message
+ * \warning         It is not thread-safe to use the same context in
+ *                  multiple threads.
  *
- * \note            The "sig" buffer must be at least as large as twice the
- *                  size of the curve used, plus 9 (eg. 73 bytes if a 256-bit
- *                  curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \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
- *                  prescribed by SEC1 4.1.3 step 5.
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
+ * \deprecated      Superseded by mbedtls_ecdsa_write_signature() in
+ *                  Mbed TLS version 2.0 and later.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or
- *                  MBEDTLS_ERR_ASN1_XXX error code
+ * \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.
+ *
+ * \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_det( mbedtls_ecdsa_context *ctx,
                                const unsigned char *hash, size_t hlen,
@@ -205,63 +261,74 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
 /**
- * \brief           Read and verify an ECDSA signature
- *
- * \param ctx       ECDSA context
- * \param hash      Message hash
- * \param hlen      Size of hash
- * \param sig       Signature to read and verify
- * \param slen      Size of sig
+ * \brief           This function reads and verifies an ECDSA signature.
  *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
- *                  prescribed by SEC1 4.1.4 step 3.
- *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
- *                  MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if the signature is
- *                  valid but its actual length is less than siglen,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX error code
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.4, step 3.
+ *
+ * \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.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+ * \return          #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in \p sig, but its length is less than \p siglen.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on failure for any other reason.
  */
 int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
                           const unsigned char *hash, size_t hlen,
                           const unsigned char *sig, size_t slen );
 
 /**
- * \brief           Generate an ECDSA keypair on the given curve
+ * \brief          This function generates an ECDSA keypair on the given curve.
  *
- * \param ctx       ECDSA context in which the keypair should be stored
- * \param gid       Group (elliptic curve) to use. One of the various
- *                  MBEDTLS_ECP_DP_XXX macros depending on configuration.
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \see            ecp.h
  *
- * \return          0 on success, or a MBEDTLS_ERR_ECP_XXX code.
+ * \param ctx      The ECDSA context to store the keypair in.
+ * \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.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_ECP_XXX code on failure.
  */
 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 /**
- * \brief           Set an ECDSA context from an EC key pair
+ * \brief           This function sets an ECDSA context from an EC key pair.
+ *
+ * \see             ecp.h
  *
- * \param ctx       ECDSA context to set
- * \param key       EC key to use
+ * \param ctx       The ECDSA context to set.
+ * \param key       The EC key to use.
  *
- * \return          0 on success, or a MBEDTLS_ERR_ECP_XXX code.
+ * \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 );
 
 /**
- * \brief           Initialize context
+ * \brief           This function initializes an ECDSA context.
  *
- * \param ctx       Context to initialize
+ * \param ctx       The ECDSA context to initialize.
  */
 void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
 
 /**
- * \brief           Free context
+ * \brief           This function frees an ECDSA context.
  *
- * \param ctx       Context to free
+ * \param ctx       The ECDSA context to free.
  */
 void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
 
diff --git a/crypto/mbedtls/include/mbedtls/ecjpake.h b/crypto/mbedtls/include/mbedtls/ecjpake.h
index 161a5b213..cc2b316f5 100644
--- a/crypto/mbedtls/include/mbedtls/ecjpake.h
+++ b/crypto/mbedtls/include/mbedtls/ecjpake.h
@@ -2,7 +2,8 @@
  * \file ecjpake.h
  *
  * \brief Elliptic curve J-PAKE
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -55,6 +56,7 @@ typedef enum {
     MBEDTLS_ECJPAKE_SERVER,             /**< Server                         */
 } mbedtls_ecjpake_role;
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
 /**
  * EC J-PAKE context structure.
  *
@@ -85,6 +87,10 @@ typedef struct
     mbedtls_mpi s;                      /**< Pre-shared secret (passphrase) */
 } mbedtls_ecjpake_context;
 
+#else  /* MBEDTLS_ECJPAKE_ALT */
+#include "ecjpake_alt.h"
+#endif /* MBEDTLS_ECJPAKE_ALT */
+
 /**
  * \brief           Initialize a context
  *                  (just makes it ready for setup() or free()).
@@ -222,17 +228,22 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
  */
 void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
 
+
+
 #if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if a test failed
  */
 int mbedtls_ecjpake_self_test( int verbose );
-#endif
+
+#endif /* MBEDTLS_SELF_TEST */
 
 #ifdef __cplusplus
 }
 #endif
 
+
 #endif /* ecjpake.h */
diff --git a/crypto/mbedtls/include/mbedtls/ecp.h b/crypto/mbedtls/include/mbedtls/ecp.h
index dad9aef00..3a407986d 100644
--- a/crypto/mbedtls/include/mbedtls/ecp.h
+++ b/crypto/mbedtls/include/mbedtls/ecp.h
@@ -1,9 +1,21 @@
 /**
  * \file ecp.h
  *
- * \brief Elliptic curves over GF(p)
+ * \brief This file provides an API for Elliptic Curves over GF(P) (ECP).
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * The use of ECP in cryptography and TLS is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG): SEC1
+ * Elliptic Curve Cryptography</em> and
+ * <em>RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites
+ * for Transport Layer Security (TLS)</em>.
+ *
+ * <em>RFC-2409: The Internet Key Exchange (IKE)</em> defines ECP
+ * group types.
+ *
+ */
+
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,8 +30,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_ECP_H
 #define MBEDTLS_ECP_H
 
@@ -30,159 +43,157 @@
  */
 #define MBEDTLS_ERR_ECP_BAD_INPUT_DATA                    -0x4F80  /**< Bad input parameters to function. */
 #define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00  /**< The buffer is too small to write to. */
-#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< Requested curve not available. */
+#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< The requested feature is not available, for example, the requested curve is not supported. */
 #define MBEDTLS_ERR_ECP_VERIFY_FAILED                     -0x4E00  /**< The signature is not valid. */
 #define MBEDTLS_ERR_ECP_ALLOC_FAILED                      -0x4D80  /**< Memory allocation failed. */
-#define MBEDTLS_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as (ephemeral) key, failed. */
+#define MBEDTLS_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as ephemeral key, failed. */
 #define MBEDTLS_ERR_ECP_INVALID_KEY                       -0x4C80  /**< Invalid private or public key. */
-#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH                  -0x4C00  /**< Signature is valid but shorter than the user-supplied length. */
-
-#if !defined(MBEDTLS_ECP_ALT)
-/*
- * default mbed TLS elliptic curve arithmetic implementation
- *
- * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an
- * alternative implementation for the whole module and it will replace this
- * one.)
- */
+#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH                  -0x4C00  /**< The buffer contains a valid signature followed by more data. */
+#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED                   -0x4B80  /**< The ECP hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * Domain parameters (curve, subgroup and generator) identifiers.
+ * Domain-parameter identifiers: curve, subgroup, and generator.
  *
- * Only curves over prime fields are supported.
+ * \note Only curves over prime fields are supported.
  *
  * \warning This library does not support validation of arbitrary domain
- * parameters. Therefore, only well-known domain parameters from trusted
+ * parameters. Therefore, only standardized domain parameters from trusted
  * sources should be used. See mbedtls_ecp_group_load().
  */
 typedef enum
 {
-    MBEDTLS_ECP_DP_NONE = 0,
-    MBEDTLS_ECP_DP_SECP192R1,      /*!< 192-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP224R1,      /*!< 224-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP256R1,      /*!< 256-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP384R1,      /*!< 384-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP521R1,      /*!< 521-bits NIST curve  */
-    MBEDTLS_ECP_DP_BP256R1,        /*!< 256-bits Brainpool curve */
-    MBEDTLS_ECP_DP_BP384R1,        /*!< 384-bits Brainpool curve */
-    MBEDTLS_ECP_DP_BP512R1,        /*!< 512-bits Brainpool curve */
-    MBEDTLS_ECP_DP_CURVE25519,           /*!< Curve25519               */
-    MBEDTLS_ECP_DP_SECP192K1,      /*!< 192-bits "Koblitz" curve */
-    MBEDTLS_ECP_DP_SECP224K1,      /*!< 224-bits "Koblitz" curve */
-    MBEDTLS_ECP_DP_SECP256K1,      /*!< 256-bits "Koblitz" curve */
+    MBEDTLS_ECP_DP_NONE = 0,       /*!< Curve not defined. */
+    MBEDTLS_ECP_DP_SECP192R1,      /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP224R1,      /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP256R1,      /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP384R1,      /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP521R1,      /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_BP256R1,        /*!< Domain parameters for 256-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_BP384R1,        /*!< Domain parameters for 384-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_BP512R1,        /*!< Domain parameters for 512-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_CURVE25519,     /*!< Domain parameters for Curve25519. */
+    MBEDTLS_ECP_DP_SECP192K1,      /*!< Domain parameters for 192-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_SECP224K1,      /*!< Domain parameters for 224-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_SECP256K1,      /*!< Domain parameters for 256-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_CURVE448,       /*!< Domain parameters for Curve448. */
 } mbedtls_ecp_group_id;
 
 /**
- * Number of supported curves (plus one for NONE).
+ * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE.
  *
- * (Montgomery curves excluded for now.)
+ * \note Montgomery curves are currently excluded.
  */
 #define MBEDTLS_ECP_DP_MAX     12
 
 /**
- * Curve information for use by other modules
+ * Curve information, for use by other modules.
  */
 typedef struct
 {
-    mbedtls_ecp_group_id grp_id;    /*!< Internal identifier        */
-    uint16_t tls_id;                /*!< TLS NamedCurve identifier  */
-    uint16_t bit_size;              /*!< Curve size in bits         */
-    const char *name;               /*!< Human-friendly name        */
+    mbedtls_ecp_group_id grp_id;    /*!< An internal identifier. */
+    uint16_t tls_id;                /*!< The TLS NamedCurve identifier. */
+    uint16_t bit_size;              /*!< The curve size in bits. */
+    const char *name;               /*!< A human-friendly name. */
 } mbedtls_ecp_curve_info;
 
 /**
- * \brief           ECP point structure (jacobian coordinates)
+ * \brief           The ECP point structure, in Jacobian coordinates.
  *
  * \note            All functions expect and return points satisfying
- *                  the following condition: Z == 0 or Z == 1. (Other
- *                  values of Z are used by internal functions only.)
- *                  The point is zero, or "at infinity", if Z == 0.
- *                  Otherwise, X and Y are its standard (affine) coordinates.
+ *                  the following condition: <code>Z == 0</code> or
+ *                  <code>Z == 1</code>. Other values of \p Z are
+ *                  used only by internal functions.
+ *                  The point is zero, or "at infinity", if <code>Z == 0</code>.
+ *                  Otherwise, \p X and \p Y are its standard (affine)
+ *                  coordinates.
  */
 typedef struct
 {
-    mbedtls_mpi X;          /*!<  the point's X coordinate  */
-    mbedtls_mpi Y;          /*!<  the point's Y coordinate  */
-    mbedtls_mpi Z;          /*!<  the point's Z coordinate  */
+    mbedtls_mpi X;          /*!< The X coordinate of the ECP point. */
+    mbedtls_mpi Y;          /*!< The Y coordinate of the ECP point. */
+    mbedtls_mpi Z;          /*!< The Z coordinate of the ECP point. */
 }
 mbedtls_ecp_point;
 
-/**
- * \brief           ECP group structure
- *
- * We consider two types of curves equations:
- * 1. Short Weierstrass y^2 = x^3 + A x + B     mod P   (SEC1 + RFC 4492)
- * 2. Montgomery,       y^2 = x^3 + A x^2 + x   mod P   (Curve25519 + draft)
- * In both cases, a generator G for a prime-order subgroup is fixed. In the
- * short weierstrass, this subgroup is actually the whole curve, and its
- * cardinal is denoted by N.
- *
- * In the case of Short Weierstrass curves, our code requires that N is an odd
- * prime. (Use odd in mbedtls_ecp_mul() and prime in mbedtls_ecdsa_sign() for blinding.)
- *
- * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
- * the quantity actually used in the formulas. Also, nbits is not the size of N
- * but the required size for private keys.
+#if !defined(MBEDTLS_ECP_ALT)
+/*
+ * default mbed TLS elliptic curve arithmetic implementation
  *
- * If modp is NULL, reduction modulo P is done using a generic algorithm.
- * Otherwise, it must point to a function that takes an mbedtls_mpi in the range
- * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more
- * than pbits, so that the integer may be efficiently brought in the 0..P-1
- * range by a few additions or substractions. It must return 0 on success and
- * non-zero on failure.
+ * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an
+ * alternative implementation for the whole module and it will replace this
+ * one.)
  */
-typedef struct
-{
-    mbedtls_ecp_group_id id;    /*!<  internal group identifier                     */
-    mbedtls_mpi P;              /*!<  prime modulus of the base field               */
-    mbedtls_mpi A;              /*!<  1. A in the equation, or 2. (A + 2) / 4       */
-    mbedtls_mpi B;              /*!<  1. B in the equation, or 2. unused            */
-    mbedtls_ecp_point G;        /*!<  generator of the (sub)group used              */
-    mbedtls_mpi N;              /*!<  1. the order of G, or 2. unused               */
-    size_t pbits;       /*!<  number of bits in P                           */
-    size_t nbits;       /*!<  number of bits in 1. P, or 2. private keys    */
-    unsigned int h;     /*!<  internal: 1 if the constants are static       */
-    int (*modp)(mbedtls_mpi *); /*!<  function for fast reduction mod P             */
-    int (*t_pre)(mbedtls_ecp_point *, void *);  /*!< unused                         */
-    int (*t_post)(mbedtls_ecp_point *, void *); /*!< unused                         */
-    void *t_data;                       /*!< unused                         */
-    mbedtls_ecp_point *T;       /*!<  pre-computed points for ecp_mul_comb()        */
-    size_t T_size;      /*!<  number for pre-computed points                */
-}
-mbedtls_ecp_group;
 
 /**
- * \brief           ECP key pair structure
+ * \brief           The ECP group structure.
  *
- * A generic key pair that could be used for ECDSA, fixed ECDH, etc.
+ * We consider two types of curve equations:
+ * <ul><li>Short Weierstrass: <code>y^2 = x^3 + A x + B mod P</code>
+ * (SEC1 + RFC-4492)</li>
+ * <li>Montgomery: <code>y^2 = x^3 + A x^2 + x mod P</code> (Curve25519,
+ * Curve448)</li></ul>
+ * In both cases, the generator (\p G) for a prime-order subgroup is fixed.
+ *
+ * For Short Weierstrass, this subgroup is the whole curve, and its
+ * cardinality is denoted by \p N. Our code requires that \p N is an
+ * odd prime as mbedtls_ecp_mul() requires an odd number, and
+ * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes.
+ *
+ * For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>,
+ * which is the quantity used in the formulas. Additionally, \p nbits is
+ * not the size of \p N but the required size for private keys.
+ *
+ * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm.
+ * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the
+ * range of <code>0..2^(2*pbits)-1</code>, and transforms it in-place to an integer
+ * which is congruent mod \p P to the given MPI, and is close enough to \p pbits
+ * in size, so that it may be efficiently brought in the 0..P-1 range by a few
+ * additions or subtractions. Therefore, it is only an approximative modular
+ * reduction. It must return 0 on success and non-zero on failure.
  *
- * \note Members purposefully in the same order as struc mbedtls_ecdsa_context.
  */
 typedef struct
 {
-    mbedtls_ecp_group grp;      /*!<  Elliptic curve and base point     */
-    mbedtls_mpi d;              /*!<  our secret value                  */
-    mbedtls_ecp_point Q;        /*!<  our public value                  */
+    mbedtls_ecp_group_id id;    /*!< An internal group identifier. */
+    mbedtls_mpi P;              /*!< The prime modulus of the base field. */
+    mbedtls_mpi A;              /*!< For Short Weierstrass: \p A in the equation. For
+                                     Montgomery curves: <code>(A + 2) / 4</code>. */
+    mbedtls_mpi B;              /*!< For Short Weierstrass: \p B in the equation.
+                                     For Montgomery curves: unused. */
+    mbedtls_ecp_point G;        /*!< The generator of the subgroup used. */
+    mbedtls_mpi N;              /*!< The order of \p G. */
+    size_t pbits;               /*!< The number of bits in \p P.*/
+    size_t nbits;               /*!< For Short Weierstrass: The number of bits in \p P.
+                                     For Montgomery curves: the number of bits in the
+                                     private keys. */
+    unsigned int h;             /*!< \internal 1 if the constants are static. */
+    int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction
+                                     mod \p P (see above).*/
+    int (*t_pre)(mbedtls_ecp_point *, void *);  /*!< Unused. */
+    int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */
+    void *t_data;               /*!< Unused. */
+    mbedtls_ecp_point *T;       /*!< Pre-computed points for ecp_mul_comb(). */
+    size_t T_size;              /*!< The number of pre-computed points. */
 }
-mbedtls_ecp_keypair;
+mbedtls_ecp_group;
 
 /**
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in config.h, or define them using the compiler command line.
  * \{
  */
 
 #if !defined(MBEDTLS_ECP_MAX_BITS)
 /**
- * Maximum size of the groups (that is, of N and P)
+ * The maximum size of the groups, that is, of \c N and \c P.
  */
-#define MBEDTLS_ECP_MAX_BITS     521   /**< Maximum bit size of groups */
+#define MBEDTLS_ECP_MAX_BITS     521   /**< The maximum size of groups, in bits. */
 #endif
 
 #define MBEDTLS_ECP_MAX_BYTES    ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
@@ -205,11 +216,10 @@ mbedtls_ecp_keypair;
  *      521       145     141     135     120      97
  *      384       214     209     198     177     146
  *      256       320     320     303     262     226
-
  *      224       475     475     453     398     342
  *      192       640     640     633     587     476
  */
-#define MBEDTLS_ECP_WINDOW_SIZE    6   /**< Maximum window size used */
+#define MBEDTLS_ECP_WINDOW_SIZE    6   /**< The maximum window size used. */
 #endif /* MBEDTLS_ECP_WINDOW_SIZE */
 
 #if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
@@ -224,33 +234,55 @@ mbedtls_ecp_keypair;
  *
  * Change this value to 0 to reduce peak memory usage.
  */
-#define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up */
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up. */
 #endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
 
 /* \} name SECTION: Module settings */
 
+#else  /* MBEDTLS_ECP_ALT */
+#include "ecp_alt.h"
+#endif /* MBEDTLS_ECP_ALT */
+
+/**
+ * \brief    The ECP key-pair structure.
+ *
+ * A generic key-pair that may be used for ECDSA and fixed ECDH, for example.
+ *
+ * \note    Members are deliberately in the same order as in the
+ *          ::mbedtls_ecdsa_context structure.
+ */
+typedef struct
+{
+    mbedtls_ecp_group grp;      /*!<  Elliptic curve and base point     */
+    mbedtls_mpi d;              /*!<  our secret value                  */
+    mbedtls_ecp_point Q;        /*!<  our public value                  */
+}
+mbedtls_ecp_keypair;
+
 /*
  * Point formats, from RFC 4492's enum ECPointFormat
  */
-#define MBEDTLS_ECP_PF_UNCOMPRESSED    0   /**< Uncompressed point format */
-#define MBEDTLS_ECP_PF_COMPRESSED      1   /**< Compressed point format */
+#define MBEDTLS_ECP_PF_UNCOMPRESSED    0   /**< Uncompressed point format. */
+#define MBEDTLS_ECP_PF_COMPRESSED      1   /**< Compressed point format. */
 
 /*
  * Some other constants from RFC 4492
  */
-#define MBEDTLS_ECP_TLS_NAMED_CURVE    3   /**< ECCurveType's named_curve */
+#define MBEDTLS_ECP_TLS_NAMED_CURVE    3   /**< The named_curve of ECCurveType. */
 
 /**
- * \brief           Get the list of supported curves in order of preferrence
- *                  (full information)
+ * \brief           This function retrieves the information defined in
+ *                  mbedtls_ecp_curve_info() for all supported curves in order
+ *                  of preference.
  *
- * \return          A statically allocated array, the last entry is 0.
+ * \return          A statically allocated array. The last entry is 0.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
 
 /**
- * \brief           Get the list of supported curves in order of preferrence
- *                  (grp_id only)
+ * \brief           This function retrieves the list of internal group
+ *                  identifiers of all supported curves in the order of
+ *                  preference.
  *
  * \return          A statically allocated array,
  *                  terminated with MBEDTLS_ECP_DP_NONE.
@@ -258,357 +290,400 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
 const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void );
 
 /**
- * \brief           Get curve information from an internal group identifier
+ * \brief           This function retrieves curve information from an internal
+ *                  group identifier.
  *
- * \param grp_id    A MBEDTLS_ECP_DP_XXX value
+ * \param grp_id    An \c MBEDTLS_ECP_DP_XXX value.
  *
- * \return          The associated curve information or NULL
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id );
 
 /**
- * \brief           Get curve information from a TLS NamedCurve value
+ * \brief           This function retrieves curve information from a TLS
+ *                  NamedCurve value.
  *
- * \param tls_id    A MBEDTLS_ECP_DP_XXX value
+ * \param tls_id    An \c MBEDTLS_ECP_DP_XXX value.
  *
- * \return          The associated curve information or NULL
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id );
 
 /**
- * \brief           Get curve information from a human-readable name
+ * \brief           This function retrieves curve information from a
+ *                  human-readable name.
  *
- * \param name      The name
+ * \param name      The human-readable name.
  *
- * \return          The associated curve information or NULL
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name );
 
 /**
- * \brief           Initialize a point (as zero)
+ * \brief           This function initializes a point as zero.
+ *
+ * \param pt        The point to initialize.
  */
 void mbedtls_ecp_point_init( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Initialize a group (to something meaningless)
+ * \brief           This function initializes an ECP group context
+ *                  without loading any domain parameters.
+ *
+ * \note            After this function is called, domain parameters
+ *                  for various ECP groups can be loaded through the
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group()
+ *                  functions.
  */
 void mbedtls_ecp_group_init( mbedtls_ecp_group *grp );
 
 /**
- * \brief           Initialize a key pair (as an invalid one)
+ * \brief           This function initializes a key pair as an invalid one.
+ *
+ * \param key       The key pair to initialize.
  */
 void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key );
 
 /**
- * \brief           Free the components of a point
+ * \brief           This function frees the components of a point.
+ *
+ * \param pt        The point to free.
  */
 void mbedtls_ecp_point_free( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Free the components of an ECP group
+ * \brief           This function frees the components of an ECP group.
+ * \param grp       The group to free.
  */
 void mbedtls_ecp_group_free( mbedtls_ecp_group *grp );
 
 /**
- * \brief           Free the components of a key pair
+ * \brief           This function frees the components of a key pair.
+ * \param key       The key pair to free.
  */
 void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key );
 
 /**
- * \brief           Copy the contents of point Q into P
+ * \brief           This function copies the contents of point \p Q into
+ *                  point \p P.
  *
- * \param P         Destination point
- * \param Q         Source point
+ * \param P         The destination point.
+ * \param Q         The source point.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q );
 
 /**
- * \brief           Copy the contents of a group object
+ * \brief           This function copies the contents of group \p src into
+ *                  group \p dst.
  *
- * \param dst       Destination group
- * \param src       Source group
+ * \param dst       The destination group.
+ * \param src       The source group.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src );
 
 /**
- * \brief           Set a point to zero
+ * \brief           This function sets a point to zero.
  *
- * \param pt        Destination point
+ * \param pt        The point to set.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Tell if a point is zero
+ * \brief           This function checks if a point is zero.
  *
- * \param pt        Point to test
+ * \param pt        The point to test.
  *
- * \return          1 if point is zero, 0 otherwise
+ * \return          \c 1 if the point is zero.
+ * \return          \c 0 if the point is non-zero.
  */
 int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Compare two points
+ * \brief           This function compares two points.
  *
- * \note            This assumes the points are normalized. Otherwise,
+ * \note            This assumes that the points are normalized. Otherwise,
  *                  they may compare as "not equal" even if they are.
  *
- * \param P         First point to compare
- * \param Q         Second point to compare
+ * \param P         The first point to compare.
+ * \param Q         The second point to compare.
  *
- * \return          0 if the points are equal,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
+ * \return          \c 0 if the points are equal.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal.
  */
 int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
                            const mbedtls_ecp_point *Q );
 
 /**
- * \brief           Import a non-zero point from two ASCII strings
+ * \brief           This function imports a non-zero point from two ASCII
+ *                  strings.
  *
- * \param P         Destination point
- * \param radix     Input numeric base
- * \param x         First affine coordinate as a null-terminated string
- * \param y         Second affine coordinate as a null-terminated string
+ * \param P         The destination point.
+ * \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.
  *
- * \return          0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on failure.
  */
 int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
                            const char *x, const char *y );
 
 /**
- * \brief           Export a point into unsigned binary data
+ * \brief           This function exports a point into unsigned binary data.
  *
- * \param grp       Group to which the point should belong
- * \param P         Point to export
- * \param format    Point format, should be a MBEDTLS_ECP_PF_XXX macro
- * \param olen      Length of the actual output
- * \param buf       Output buffer
- * \param buflen    Length of the output buffer
+ * \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.
  *
- * \return          0 if successful,
- *                  or MBEDTLS_ERR_ECP_BAD_INPUT_DATA
- *                  or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+ *                  or #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
  */
 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 );
 
 /**
- * \brief           Import a point from unsigned binary data
+ * \brief           This function imports a point from unsigned binary data.
  *
- * \param grp       Group to which the point should belong
- * \param P         Point to import
- * \param buf       Input buffer
- * \param ilen      Actual length of input
+ * \note            This function does not check that the point actually
+ *                  belongs to the given group, see mbedtls_ecp_check_pubkey()
+ *                  for that.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
+ * \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.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if 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.
  *
- * \note            This function does NOT check that the point actually
- *                  belongs to the given group, see mbedtls_ecp_check_pubkey() for
- *                  that.
  */
 int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
                            const unsigned char *buf, size_t ilen );
 
 /**
- * \brief           Import a point from a TLS ECPoint record
+ * \brief           This function imports a point from a TLS ECPoint record.
  *
- * \param grp       ECP group used
- * \param pt        Destination point
- * \param buf       $(Start of input buffer)
- * \param len       Buffer length
+ * \note            On function return, \p buf is updated to point to immediately
+ *                  after the ECPoint record.
  *
- * \note            buf is updated to point right after the ECPoint on exit
+ * \param grp       The ECP group used.
+ * \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          0 if successful,
- *                  MBEDTLS_ERR_MPI_XXX if initialization failed
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid
+ * \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.
  */
 int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
                         const unsigned char **buf, size_t len );
 
 /**
- * \brief           Export a point as a TLS ECPoint record
+ * \brief           This function exports a point as a TLS ECPoint record.
  *
- * \param grp       ECP group used
- * \param pt        Point to export
- * \param format    Export format
- * \param olen      length of data written
- * \param buf       Buffer to write to
- * \param blen      Buffer length
+ * \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.
  *
- * \return          0 if successful,
- *                  or MBEDTLS_ERR_ECP_BAD_INPUT_DATA
- *                  or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA or
+ *                  #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on 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 );
 
 /**
- * \brief           Set a group using well-known domain parameters
+ * \brief           This function sets a group using standardized domain parameters.
  *
- * \param grp       Destination group
- * \param id        Index in the list of well-known 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.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_XXX if initialization failed
- *                  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
+ * \param grp       The destination group.
+ * \param id        The identifier of the domain parameter set to load.
  *
- * \note            Index should be a value of RFC 4492's enum NamedCurve,
- *                  usually in the form of a MBEDTLS_ECP_DP_XXX macro.
+ * \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.
+
  */
 int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id );
 
 /**
- * \brief           Set a group from a TLS ECParameters record
+ * \brief           This function sets a group from a TLS ECParameters record.
  *
- * \param grp       Destination group
- * \param buf       &(Start of input buffer)
- * \param len       Buffer length
+ * \note            \p buf is updated to point right after the ECParameters record
+ *                  on exit.
  *
- * \note            buf is updated to point right after ECParameters on exit
+ * \param grp       The destination group.
+ * \param buf       The address of the pointer to the start of the input buffer.
+ * \param len       The length of the buffer.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_XXX if initialization failed
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid
+ * \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.
  */
 int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len );
 
 /**
- * \brief           Write the TLS ECParameters record for a group
+ * \brief           This function writes the TLS ECParameters record for a group.
  *
- * \param grp       ECP group used
- * \param olen      Number of bytes actually written
- * \param buf       Buffer to write to
- * \param blen      Buffer length
+ * \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.
  *
- * \return          0 if successful,
- *                  or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
  */
 int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
                          unsigned char *buf, size_t blen );
 
 /**
- * \brief           Multiplication by an integer: R = m * P
- *                  (Not thread-safe to use same group in multiple threads)
+ * \brief           This function performs multiplication of a point by
+ *                  an integer: \p R = \p m * \p P.
  *
- * \note            In order to prevent timing attacks, this function
- *                  executes the exact same sequence of (base field)
- *                  operations for any valid m. It avoids any if-branch or
- *                  array index depending on the value of m.
+ *                  It is not thread-safe to use same group in multiple threads.
  *
- * \note            If f_rng is not NULL, it is used to randomize intermediate
- *                  results in order to prevent potential timing attacks
- *                  targeting these results. It is recommended to always
- *                  provide a non-NULL f_rng (the overhead is negligible).
+ * \note            To prevent timing attacks, this function
+ *                  executes the exact same sequence of base-field
+ *                  operations for any valid \p m. It avoids any if-branch or
+ *                  array index depending on the value of \p m.
  *
- * \param grp       ECP group
- * \param R         Destination point
- * \param m         Integer by which to multiply
- * \param P         Point to multiply
- * \param f_rng     RNG function (see notes)
- * \param p_rng     RNG parameter
+ * \note            If \p f_rng is not NULL, it is used to randomize
+ *                  intermediate results to prevent potential timing attacks
+ *                  targeting these results. We recommend always providing
+ *                  a non-NULL \p f_rng. The overhead is negligible.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY if m is not a valid privkey
- *                  or P is not a valid pubkey,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \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.
+ *
+ * \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.
  */
 int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 /**
- * \brief           Multiplication and addition of two points by integers:
- *                  R = m * P + n * Q
- *                  (Not thread-safe to use same group in multiple threads)
+ * \brief           This function performs multiplication and addition of two
+ *                  points by integers: \p R = \p m * \p P + \p n * \p Q
+ *
+ *                  It is not thread-safe to use same group in multiple threads.
  *
- * \note            In contrast to mbedtls_ecp_mul(), this function does not guarantee
- *                  a constant execution flow and timing.
+ * \note            In contrast to mbedtls_ecp_mul(), this function does not
+ *                  guarantee a constant execution flow and timing.
  *
- * \param grp       ECP group
- * \param R         Destination point
- * \param m         Integer by which to multiply P
- * \param P         Point to multiply by m
- * \param n         Integer by which to multiply Q
- * \param Q         Point to be multiplied by n
+ * \param grp       The ECP group.
+ * \param R         The destination point.
+ * \param m         The integer by which to multiply \p P.
+ * \param P         The point to multiply by \p m.
+ * \param n         The integer by which to multiply \p Q.
+ * \param Q         The point to be multiplied by \p n.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY if m or n is not a valid privkey
- *                  or P or Q is not a valid pubkey,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \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.
  */
 int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
              const mbedtls_mpi *n, const mbedtls_ecp_point *Q );
 
 /**
- * \brief           Check that a point is a valid public key on this curve
+ * \brief           This function checks that a point is a valid public key
+ *                  on this curve.
  *
- * \param grp       Curve/group the point should belong to
- * \param pt        Point to check
+ *                  It only checks that the point is non-zero, has
+ *                  valid coordinates and lies on the curve. It does not verify
+ *                  that it is indeed a multiple of \p G. This additional
+ *                  check is computationally more expensive, is not required
+ *                  by standards, and should not be necessary if the group
+ *                  used has a small cofactor. In particular, it is useless for
+ *                  the NIST groups which all have a cofactor of 1.
  *
- * \return          0 if point is a valid public key,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY otherwise.
+ * \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.
  *
- * \note            This function only checks the point is non-zero, has valid
- *                  coordinates and lies on the curve, but not that it is
- *                  indeed a multiple of G. This is additional check is more
- *                  expensive, isn't required by standards, and shouldn't be
- *                  necessary if the group used has a small cofactor. In
- *                  particular, it is useless for the NIST groups which all
- *                  have a cofactor of 1.
+ * \param grp       The curve the point should lie on.
+ * \param pt        The point to check.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \return          \c 0 if the point is a valid public key.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
  */
 int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt );
 
 /**
- * \brief           Check that an 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.
  *
- * \param grp       Group used
- * \param d         Integer to check
+ * \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.
  *
- * \return          0 if point is a valid private key,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY otherwise.
+ * \param grp       The group used.
+ * \param d         The integer to check.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \return          \c 0 if the point is a valid private key.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
  */
 int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
 
 /**
- * \brief           Generate a keypair with configurable base point
+ * \brief           This function generates a keypair with a configurable base
+ *                  point.
  *
- * \param grp       ECP group
- * \param G         Chosen base point
- * \param d         Destination MPI (secret part)
- * \param Q         Destination point (public part)
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \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.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ * \param grp       The ECP group.
+ * \param G         The chosen base point.
+ * \param d         The destination MPI (secret part).
+ * \param Q         The destination point (public part).
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \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,
@@ -617,57 +692,66 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
                      void *p_rng );
 
 /**
- * \brief           Generate a keypair
+ * \brief           This function generates an ECP keypair.
  *
- * \param grp       ECP group
- * \param d         Destination MPI (secret part)
- * \param Q         Destination point (public part)
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \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.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ * \param grp       The ECP group.
+ * \param d         The destination MPI (secret part).
+ * \param Q         The destination point (public part).
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \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 );
 
 /**
- * \brief           Generate a keypair
+ * \brief           This function generates an ECP key.
  *
- * \param grp_id    ECP group identifier
- * \param key       Destination keypair
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param grp_id    The ECP group identifier.
+ * \param key       The destination key.
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ * \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 );
 
 /**
- * \brief           Check a public-private key pair
+ * \brief           This function checks that the keypair objects
+ *                  \p pub and \p prv have the same group and the
+ *                  same public point, and that the private key in
+ *                  \p prv is consistent with the public key.
  *
- * \param pub       Keypair structure holding a public key
- * \param prv       Keypair structure holding a private (plus public) key
+ * \param pub       The keypair structure holding the public key.
+ *                  If it contains a private key, that part is ignored.
+ * \param prv       The keypair structure holding the full keypair.
  *
- * \return          0 if successful (keys are valid and match), or
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA, or
- *                  a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX code.
+ * \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 );
 
 #if defined(MBEDTLS_SELF_TEST)
 
 /**
- * \brief          Checkup routine
+ * \brief          The ECP checkup routine.
  *
- * \return         0 if successful, or 1 if a test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_ecp_self_test( int verbose );
 
@@ -677,8 +761,4 @@ int mbedtls_ecp_self_test( int verbose );
 }
 #endif
 
-#else  /* MBEDTLS_ECP_ALT */
-#include "ecp_alt.h"
-#endif /* MBEDTLS_ECP_ALT */
-
 #endif /* ecp.h */
diff --git a/crypto/mbedtls/include/mbedtls/ecp_internal.h b/crypto/mbedtls/include/mbedtls/ecp_internal.h
index 2991e26dd..8a6d517ed 100644
--- a/crypto/mbedtls/include/mbedtls/ecp_internal.h
+++ b/crypto/mbedtls/include/mbedtls/ecp_internal.h
@@ -3,7 +3,8 @@
  *
  * \brief Function declarations for alternative implementation of elliptic curve
  * point arithmetic.
- *
+ */
+/*
  *  Copyright (C) 2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/entropy.h b/crypto/mbedtls/include/mbedtls/entropy.h
index 747aca4df..fcb4d0255 100644
--- a/crypto/mbedtls/include/mbedtls/entropy.h
+++ b/crypto/mbedtls/include/mbedtls/entropy.h
@@ -2,7 +2,8 @@
  * \file entropy.h
  *
  * \brief Entropy accumulator implementation
- *
+ */
+/*
  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -121,6 +122,7 @@ mbedtls_entropy_source_state;
  */
 typedef struct
 {
+    int accumulator_started;
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
     mbedtls_sha512_context  accumulator;
 #else
diff --git a/crypto/mbedtls/include/mbedtls/entropy_poll.h b/crypto/mbedtls/include/mbedtls/entropy_poll.h
index 81258d5f3..94dd657eb 100644
--- a/crypto/mbedtls/include/mbedtls/entropy_poll.h
+++ b/crypto/mbedtls/include/mbedtls/entropy_poll.h
@@ -2,7 +2,8 @@
  * \file entropy_poll.h
  *
  * \brief Platform-specific and custom entropy polling functions
- *
+ */
+/*
  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/error.h b/crypto/mbedtls/include/mbedtls/error.h
index 31591e2d6..8b4d3a875 100644
--- a/crypto/mbedtls/include/mbedtls/error.h
+++ b/crypto/mbedtls/include/mbedtls/error.h
@@ -2,7 +2,8 @@
  * \file error.h
  *
  * \brief Error to string translation
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -49,23 +50,32 @@
  *
  * Module   Nr  Codes assigned
  * MPI       7  0x0002-0x0010
- * GCM       2  0x0012-0x0014
- * BLOWFISH  2  0x0016-0x0018
+ * GCM       3  0x0012-0x0014   0x0013-0x0013
+ * BLOWFISH  3  0x0016-0x0018   0x0017-0x0017
  * THREADING 3  0x001A-0x001E
- * AES       2  0x0020-0x0022
- * CAMELLIA  2  0x0024-0x0026
- * XTEA      1  0x0028-0x0028
+ * AES       4  0x0020-0x0022   0x0023-0x0025
+ * CAMELLIA  3  0x0024-0x0026   0x0027-0x0027
+ * XTEA      2  0x0028-0x0028   0x0029-0x0029
  * BASE64    2  0x002A-0x002C
  * OID       1  0x002E-0x002E   0x000B-0x000B
  * PADLOCK   1  0x0030-0x0030
- * DES       1  0x0032-0x0032
+ * DES       2  0x0032-0x0032   0x0033-0x0033
  * CTR_DBRG  4  0x0034-0x003A
  * ENTROPY   3  0x003C-0x0040   0x003D-0x003F
  * NET      11  0x0042-0x0052   0x0043-0x0045
  * ASN1      7  0x0060-0x006C
+ * CMAC      1  0x007A-0x007A
  * PBKDF2    1  0x007C-0x007C
- * HMAC_DRBG 4  0x0003-0x0009
- * CCM       2                  0x000D-0x000F
+ * HMAC_DRBG 4                  0x0003-0x0009
+ * CCM       3                  0x000D-0x0011
+ * ARC4      1                  0x0019-0x0019
+ * MD2       1                  0x002B-0x002B
+ * MD4       1                  0x002D-0x002D
+ * MD5       1                  0x002F-0x002F
+ * RIPEMD160 1                  0x0031-0x0031
+ * SHA1      1                  0x0035-0x0035
+ * SHA256    1                  0x0037-0x0037
+ * SHA512    1                  0x0039-0x0039
  *
  * High-level module nr (3 bits - 0x0...-0x7...)
  * Name      ID  Nr of Errors
@@ -73,12 +83,12 @@
  * PKCS#12   1   4 (Started from top)
  * X509      2   20
  * PKCS5     2   4 (Started from top)
- * DHM       3   9
- * PK        3   14 (Started from top)
- * RSA       4   9
- * ECP       4   8 (Started from top)
- * MD        5   4
- * CIPHER    6   6
+ * DHM       3   11
+ * PK        3   15 (Started from top)
+ * RSA       4   11
+ * ECP       4   9 (Started from top)
+ * MD        5   5
+ * CIPHER    6   8
  * SSL       6   17 (Started from top)
  * SSL       7   31
  *
diff --git a/crypto/mbedtls/include/mbedtls/gcm.h b/crypto/mbedtls/include/mbedtls/gcm.h
index 1b77aaedd..3c220331e 100644
--- a/crypto/mbedtls/include/mbedtls/gcm.h
+++ b/crypto/mbedtls/include/mbedtls/gcm.h
@@ -1,9 +1,18 @@
 /**
  * \file gcm.h
  *
- * \brief Galois/Counter mode for 128-bit block ciphers
+ * \brief This file contains GCM definitions and functions.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
+ * in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
+ * (GCM), Natl. Inst. Stand. Technol.</em>
+ *
+ * For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
+ * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,8 +27,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_GCM_H
 #define MBEDTLS_GCM_H
 
@@ -31,46 +41,64 @@
 #define MBEDTLS_GCM_DECRYPT     0
 
 #define MBEDTLS_ERR_GCM_AUTH_FAILED                       -0x0012  /**< Authenticated decryption failed. */
+#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED                   -0x0013  /**< GCM hardware accelerator failed. */
 #define MBEDTLS_ERR_GCM_BAD_INPUT                         -0x0014  /**< Bad input parameters to function. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_GCM_ALT)
+
 /**
- * \brief          GCM context structure
+ * \brief          The GCM context structure.
  */
 typedef struct {
-    mbedtls_cipher_context_t cipher_ctx;/*!< cipher context used */
-    uint64_t HL[16];            /*!< Precalculated HTable */
-    uint64_t HH[16];            /*!< Precalculated HTable */
-    uint64_t len;               /*!< Total data length */
-    uint64_t add_len;           /*!< Total add length */
-    unsigned char base_ectr[16];/*!< First ECTR for tag */
-    unsigned char y[16];        /*!< Y working value */
-    unsigned char buf[16];      /*!< buf working value */
-    int mode;                   /*!< Encrypt or Decrypt */
+    mbedtls_cipher_context_t cipher_ctx;  /*!< The cipher context used. */
+    uint64_t HL[16];                      /*!< Precalculated HTable low. */
+    uint64_t HH[16];                      /*!< Precalculated HTable high. */
+    uint64_t len;                         /*!< The total length of the encrypted data. */
+    uint64_t add_len;                     /*!< The total length of the additional data. */
+    unsigned char base_ectr[16];          /*!< The first ECTR for tag. */
+    unsigned char y[16];                  /*!< The Y working value. */
+    unsigned char buf[16];                /*!< The buf working value. */
+    int mode;                             /*!< The operation to perform:
+                                               #MBEDTLS_GCM_ENCRYPT or
+                                               #MBEDTLS_GCM_DECRYPT. */
 }
 mbedtls_gcm_context;
 
+#else  /* !MBEDTLS_GCM_ALT */
+#include "gcm_alt.h"
+#endif /* !MBEDTLS_GCM_ALT */
+
 /**
- * \brief           Initialize GCM context (just makes references valid)
- *                  Makes the context ready for mbedtls_gcm_setkey() or
- *                  mbedtls_gcm_free().
+ * \brief           This function initializes the specified GCM context,
+ *                  to make references valid, and prepares the context
+ *                  for mbedtls_gcm_setkey() or mbedtls_gcm_free().
  *
- * \param ctx       GCM context to initialize
+ *                  The function does not bind the GCM context to a particular
+ *                  cipher, nor set the key. For this purpose, use
+ *                  mbedtls_gcm_setkey().
+ *
+ * \param ctx       The GCM context to initialize.
  */
 void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
 
 /**
- * \brief           GCM initialization (encryption)
+ * \brief           This function associates a GCM context with a
+ *                  cipher algorithm and a key.
  *
- * \param ctx       GCM context to be initialized
- * \param cipher    cipher to use (a 128-bit block cipher)
- * \param key       encryption key
- * \param keybits   must be 128, 192 or 256
+ * \param ctx       The GCM context to initialize.
+ * \param cipher    The 128-bit block cipher to use.
+ * \param key       The encryption key.
+ * \param keybits   The key size in bits. Valid options are:
+ *                  <ul><li>128 bits</li>
+ *                  <li>192 bits</li>
+ *                  <li>256 bits</li></ul>
  *
- * \return          0 if successful, or a cipher specific error code
+ * \return          \c 0 on success.
+ * \return          A cipher-specific error code on failure.
  */
 int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
                         mbedtls_cipher_id_t cipher,
@@ -78,26 +106,28 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
                         unsigned int keybits );
 
 /**
- * \brief           GCM buffer encryption/decryption using a block cipher
- *
- * \note On encryption, the output buffer can be the same as the input buffer.
- *       On decryption, the output buffer cannot be the same as input buffer.
- *       If buffers overlap, the output buffer must trail at least 8 bytes
- *       behind the input buffer.
- *
- * \param ctx       GCM context
- * \param mode      MBEDTLS_GCM_ENCRYPT or MBEDTLS_GCM_DECRYPT
- * \param length    length of the input data
- * \param iv        initialization vector
- * \param iv_len    length of IV
- * \param add       additional data
- * \param add_len   length of additional data
- * \param input     buffer holding the input data
- * \param output    buffer for holding the output data
- * \param tag_len   length of the tag to generate
- * \param tag       buffer for holding the tag
- *
- * \return         0 if successful
+ * \brief           This function performs GCM encryption or decryption of a buffer.
+ *
+ * \note            For encryption, the output buffer can be the same as the
+ *                  input buffer. For decryption, the output buffer cannot be
+ *                  the same as input buffer. If the buffers overlap, the output
+ *                  buffer must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx       The GCM context to use for encryption or decryption.
+ * \param mode      The operation to perform: #MBEDTLS_GCM_ENCRYPT or
+ *                  #MBEDTLS_GCM_DECRYPT.
+ * \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 iv        The initialization vector.
+ * \param iv_len    The length of the IV.
+ * \param add       The buffer holding the additional data.
+ * \param add_len   The length of the additional data.
+ * \param input     The buffer holding the input data.
+ * \param output    The buffer for holding the output data.
+ * \param tag_len   The length of the tag to generate.
+ * \param tag       The buffer for holding the tag.
+ *
+ * \return         \c 0 on success.
  */
 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
                        int mode,
@@ -112,25 +142,27 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
                        unsigned char *tag );
 
 /**
- * \brief           GCM buffer authenticated decryption using a block cipher
- *
- * \note On decryption, the output buffer cannot be the same as input buffer.
- *       If buffers overlap, the output buffer must trail at least 8 bytes
- *       behind the input buffer.
- *
- * \param ctx       GCM context
- * \param length    length of the input data
- * \param iv        initialization vector
- * \param iv_len    length of IV
- * \param add       additional data
- * \param add_len   length of additional data
- * \param tag       buffer holding the tag
- * \param tag_len   length of the tag
- * \param input     buffer holding the input data
- * \param output    buffer for holding the output data
- *
- * \return         0 if successful and authenticated,
- *                 MBEDTLS_ERR_GCM_AUTH_FAILED if tag does not match
+ * \brief           This function performs a GCM authenticated decryption of a
+ *                  buffer.
+ *
+ * \note            For decryption, the output buffer cannot be the same as
+ *                  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 length    The length of the input data. This must be a multiple
+ *                  of 16 except in the last call before mbedtls_gcm_finish().
+ * \param iv        The initialization vector.
+ * \param iv_len    The length of the IV.
+ * \param add       The buffer holding the additional data.
+ * \param add_len   The length of the additional data.
+ * \param tag       The buffer holding the tag.
+ * \param tag_len   The length of the tag.
+ * \param input     The buffer holding the input data.
+ * \param output    The buffer for holding the output data.
+ *
+ * \return         0 if successful and authenticated.
+ * \return         #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
  */
 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
                       size_t length,
@@ -144,16 +176,20 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
                       unsigned char *output );
 
 /**
- * \brief           Generic GCM stream start function
+ * \brief           This function starts a GCM encryption or decryption
+ *                  operation.
  *
- * \param ctx       GCM context
- * \param mode      MBEDTLS_GCM_ENCRYPT or MBEDTLS_GCM_DECRYPT
- * \param iv        initialization vector
- * \param iv_len    length of IV
- * \param add       additional data (or NULL if length is 0)
- * \param add_len   length of additional data
+ * \param ctx       The GCM context.
+ * \param mode      The operation to perform: #MBEDTLS_GCM_ENCRYPT or
+ *                  #MBEDTLS_GCM_DECRYPT.
+ * \param iv        The initialization vector.
+ * \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.
  *
- * \return         0 if successful
+ * \return          \c 0 on success.
  */
 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
                 int mode,
@@ -163,21 +199,25 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
                 size_t add_len );
 
 /**
- * \brief           Generic GCM update function. Encrypts/decrypts using the
- *                  given GCM context. Expects input to be a multiple of 16
- *                  bytes! Only the last call before mbedtls_gcm_finish() can be less
- *                  than 16 bytes!
+ * \brief           This function feeds an input buffer into an ongoing GCM
+ *                  encryption or decryption operation.
+ *
+ *    `             The function expects input to be a multiple of 16
+ *                  Bytes. Only the last call before calling
+ *                  mbedtls_gcm_finish() can be less than 16 Bytes.
  *
- * \note On decryption, the output buffer cannot be the same as input buffer.
- *       If buffers overlap, the output buffer must trail at least 8 bytes
- *       behind the input buffer.
+ * \note            For decryption, the output buffer cannot be the same as
+ *                  input buffer. If the buffers overlap, the output buffer
+ *                  must trail at least 8 Bytes behind the input buffer.
  *
- * \param ctx       GCM context
- * \param length    length of the input data
- * \param input     buffer holding the input data
- * \param output    buffer for holding the output data
+ * \param ctx       The GCM context.
+ * \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.
  *
- * \return         0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
  */
 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
                 size_t length,
@@ -185,31 +225,36 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
                 unsigned char *output );
 
 /**
- * \brief           Generic GCM finalisation function. Wraps up the GCM stream
- *                  and generates the tag. The tag can have a maximum length of
- *                  16 bytes.
+ * \brief           This function finishes the GCM operation and generates
+ *                  the authentication tag.
  *
- * \param ctx       GCM context
- * \param tag       buffer for holding the tag
- * \param tag_len   length of the tag to generate (must be at least 4)
+ *                  It wraps up the GCM stream, and generates the
+ *                  tag. The tag can have a maximum length of 16 Bytes.
  *
- * \return          0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT
+ * \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.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
  */
 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
                 unsigned char *tag,
                 size_t tag_len );
 
 /**
- * \brief           Free a GCM context and underlying cipher sub-context
+ * \brief           This function clears a GCM context and the underlying
+ *                  cipher sub-context.
  *
- * \param ctx       GCM context to free
+ * \param ctx       The GCM context to clear.
  */
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
 
 /**
- * \brief          Checkup routine
+ * \brief          The GCM checkup routine.
  *
- * \return         0 if successful, or 1 if the test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_gcm_self_test( int verbose );
 
@@ -217,4 +262,5 @@ int mbedtls_gcm_self_test( int verbose );
 }
 #endif
 
+
 #endif /* gcm.h */
diff --git a/crypto/mbedtls/include/mbedtls/havege.h b/crypto/mbedtls/include/mbedtls/havege.h
index dac5d3113..d4cb3ed38 100644
--- a/crypto/mbedtls/include/mbedtls/havege.h
+++ b/crypto/mbedtls/include/mbedtls/havege.h
@@ -2,7 +2,8 @@
  * \file havege.h
  *
  * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/hmac_drbg.h b/crypto/mbedtls/include/mbedtls/hmac_drbg.h
index e01055802..e0821cf78 100644
--- a/crypto/mbedtls/include/mbedtls/hmac_drbg.h
+++ b/crypto/mbedtls/include/mbedtls/hmac_drbg.h
@@ -2,7 +2,8 @@
  * \file hmac_drbg.h
  *
  * \brief HMAC_DRBG (NIST SP 800-90A)
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/md.h b/crypto/mbedtls/include/mbedtls/md.h
index 9b996a951..6b6f5c53d 100644
--- a/crypto/mbedtls/include/mbedtls/md.h
+++ b/crypto/mbedtls/include/mbedtls/md.h
@@ -1,11 +1,12 @@
-/**
+ /**
  * \file md.h
  *
- * \brief Generic message digest wrapper
+ * \brief This file contains the generic message-digest wrapper.
  *
  * \author Adriaan de Jong <de...@fox-it.com>
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -20,33 +21,49 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_MD_H
 #define MBEDTLS_MD_H
 
 #include <stddef.h>
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE                -0x5080  /**< The selected feature is not available. */
 #define MBEDTLS_ERR_MD_BAD_INPUT_DATA                     -0x5100  /**< Bad input parameters to function. */
 #define MBEDTLS_ERR_MD_ALLOC_FAILED                       -0x5180  /**< Failed to allocate memory. */
 #define MBEDTLS_ERR_MD_FILE_IO_ERROR                      -0x5200  /**< Opening or reading of file failed. */
+#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED                    -0x5280  /**< MD hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * \brief     Supported message digests.
+ *
+ * \warning   MD2, MD4, MD5 and SHA-1 are considered weak message digests and
+ *            their use constitutes a security risk. We recommend considering
+ *            stronger message digests instead.
+ *
+ */
 typedef enum {
-    MBEDTLS_MD_NONE=0,
-    MBEDTLS_MD_MD2,
-    MBEDTLS_MD_MD4,
-    MBEDTLS_MD_MD5,
-    MBEDTLS_MD_SHA1,
-    MBEDTLS_MD_SHA224,
-    MBEDTLS_MD_SHA256,
-    MBEDTLS_MD_SHA384,
-    MBEDTLS_MD_SHA512,
-    MBEDTLS_MD_RIPEMD160,
+    MBEDTLS_MD_NONE=0,    /**< None. */
+    MBEDTLS_MD_MD2,       /**< The MD2 message digest. */
+    MBEDTLS_MD_MD4,       /**< The MD4 message digest. */
+    MBEDTLS_MD_MD5,       /**< The MD5 message digest. */
+    MBEDTLS_MD_SHA1,      /**< The SHA-1 message digest. */
+    MBEDTLS_MD_SHA224,    /**< The SHA-224 message digest. */
+    MBEDTLS_MD_SHA256,    /**< The SHA-256 message digest. */
+    MBEDTLS_MD_SHA384,    /**< The SHA-384 message digest. */
+    MBEDTLS_MD_SHA512,    /**< The SHA-512 message digest. */
+    MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
 } mbedtls_md_type_t;
 
 #if defined(MBEDTLS_SHA512_C)
@@ -56,65 +73,79 @@ typedef enum {
 #endif
 
 /**
- * Opaque struct defined in md_internal.h
+ * Opaque struct defined in md_internal.h.
  */
 typedef struct mbedtls_md_info_t mbedtls_md_info_t;
 
 /**
- * Generic message digest context.
+ * The generic message-digest context.
  */
 typedef struct {
-    /** Information about the associated message digest */
+    /** Information about the associated message digest. */
     const mbedtls_md_info_t *md_info;
 
-    /** Digest-specific context */
+    /** The digest-specific context. */
     void *md_ctx;
 
-    /** HMAC part of the context */
+    /** The HMAC part of the context. */
     void *hmac_ctx;
 } mbedtls_md_context_t;
 
 /**
- * \brief Returns the list of digests supported by the generic digest module.
+ * \brief           This function returns the list of digests supported by the
+ *                  generic digest module.
  *
- * \return          a statically allocated array of digests, the last entry
- *                  is 0.
+ * \return          A statically allocated array of digests. Each element
+ *                  in the returned list is an integer belonging to the
+ *                  message-digest enumeration #mbedtls_md_type_t.
+ *                  The last entry is 0.
  */
 const int *mbedtls_md_list( void );
 
 /**
- * \brief           Returns the message digest information associated with the
- *                  given digest name.
+ * \brief           This function returns the message-digest information
+ *                  associated with the given digest name.
  *
- * \param md_name   Name of the digest to search for.
+ * \param md_name   The name of the digest to search for.
  *
- * \return          The message digest information associated with md_name or
- *                  NULL if not found.
+ * \return          The message-digest information associated with \p md_name.
+ * \return          NULL if the associated message-digest information is not found.
  */
 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
 
 /**
- * \brief           Returns the message digest information associated with the
- *                  given digest type.
+ * \brief           This function returns the message-digest information
+ *                  associated with the given digest type.
  *
- * \param md_type   type of digest to search for.
+ * \param md_type   The type of digest to search for.
  *
- * \return          The message digest information associated with md_type or
- *                  NULL if not found.
+ * \return          The message-digest information associated with \p md_type.
+ * \return          NULL if the associated message-digest information is not found.
  */
 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
 
 /**
- * \brief           Initialize a md_context (as NONE)
- *                  This should always be called first.
- *                  Prepares the context for mbedtls_md_setup() or mbedtls_md_free().
+ * \brief           This function initializes a message-digest context without
+ *                  binding it to a particular message-digest algorithm.
+ *
+ *                  This function should always be called first. It prepares the
+ *                  context for mbedtls_md_setup() for binding it to a
+ *                  message-digest algorithm.
  */
 void mbedtls_md_init( mbedtls_md_context_t *ctx );
 
 /**
- * \brief           Free and clear the internal structures of ctx.
- *                  Can be called at any time after mbedtls_md_init().
- *                  Mandatory once mbedtls_md_setup() has been called.
+ * \brief           This function clears the internal structure of \p ctx and
+ *                  frees any embedded internal structure, but does not free
+ *                  \p ctx itself.
+ *
+ *                  If you have called mbedtls_md_setup() on \p ctx, you must
+ *                  call mbedtls_md_free() when you are no longer using the
+ *                  context.
+ *                  Calling this function if you have previously
+ *                  called mbedtls_md_init() and nothing else is optional.
+ *                  You must not call this function if you have not called
+ *                  mbedtls_md_init().
  */
 void mbedtls_md_free( mbedtls_md_context_t *ctx );
 
@@ -125,220 +156,300 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx );
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief           Select MD to use and allocate internal structures.
- *                  Should be called after mbedtls_md_init() or mbedtls_md_free().
+ * \brief           This function selects the message digest algorithm to use,
+ *                  and allocates internal structures.
+ *
+ *                  It should be called after mbedtls_md_init() or mbedtls_md_free().
  *                  Makes it necessary to call mbedtls_md_free() later.
  *
  * \deprecated      Superseded by mbedtls_md_setup() in 2.0.0
  *
- * \param ctx       Context to set up.
- * \param md_info   Message digest to use.
+ * \param ctx       The context to set up.
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
  *
- * \returns         \c 0 on success,
- *                  \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
- *                  \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ * \return          #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
 #undef MBEDTLS_DEPRECATED
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
 
 /**
- * \brief           Select MD to use and allocate internal structures.
- *                  Should be called after mbedtls_md_init() or mbedtls_md_free().
- *                  Makes it necessary to call mbedtls_md_free() later.
- *
- * \param ctx       Context to set up.
- * \param md_info   Message digest to use.
- * \param hmac      0 to save some memory if HMAC will not be used,
- *                  non-zero is HMAC is going to be used with this context.
- *
- * \returns         \c 0 on success,
- *                  \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
- *                  \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
+ * \brief           This function selects the message digest algorithm to use,
+ *                  and allocates internal structures.
+ *
+ *                  It should be called after mbedtls_md_init() or
+ *                  mbedtls_md_free(). Makes it necessary to call
+ *                  mbedtls_md_free() later.
+ *
+ * \param ctx       The context to set up.
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
+ * \param hmac      Defines if HMAC is used. 0: HMAC is not used (saves some memory),
+ *                  or non-zero: HMAC is used with this context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ * \return          #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
 
 /**
- * \brief           Clone the state of an MD context
+ * \brief           This function clones the state of an message-digest
+ *                  context.
+ *
+ * \note            You must call mbedtls_md_setup() on \c dst before calling
+ *                  this function.
  *
- * \note            The two contexts must have been setup to the same type
- *                  (cloning from SHA-256 to SHA-512 make no sense).
+ * \note            The two contexts must have the same type,
+ *                  for example, both are SHA-256.
  *
- * \warning         Only clones the MD state, not the HMAC state! (for now)
+ * \warning         This function clones the message-digest state, not the
+ *                  HMAC state.
  *
- * \param dst       The destination context
- * \param src       The context to be cloned
+ * \param dst       The destination context.
+ * \param src       The context to be cloned.
  *
- * \return          \c 0 on success,
- *                  \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
  */
 int mbedtls_md_clone( mbedtls_md_context_t *dst,
                       const mbedtls_md_context_t *src );
 
 /**
- * \brief           Returns the size of the message digest output.
+ * \brief           This function extracts the message-digest size from the
+ *                  message-digest information structure.
  *
- * \param md_info   message digest info
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
  *
- * \return          size of the message digest output in bytes.
+ * \return          The size of the message-digest output in Bytes.
  */
 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
 
 /**
- * \brief           Returns the type of the message digest output.
+ * \brief           This function extracts the message-digest type from the
+ *                  message-digest information structure.
  *
- * \param md_info   message digest info
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
  *
- * \return          type of the message digest output.
+ * \return          The type of the message digest.
  */
 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
 
 /**
- * \brief           Returns the name of the message digest output.
+ * \brief           This function extracts the message-digest name from the
+ *                  message-digest information structure.
  *
- * \param md_info   message digest info
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
  *
- * \return          name of the message digest output.
+ * \return          The name of the message digest.
  */
 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
 
 /**
- * \brief           Prepare the context to digest a new message.
- *                  Generally called after mbedtls_md_setup() or mbedtls_md_finish().
- *                  Followed by mbedtls_md_update().
+ * \brief           This function starts a message-digest computation.
  *
- * \param ctx       generic message digest context.
+ *                  You must call this function after setting up the context
+ *                  with mbedtls_md_setup(), and before passing data with
+ *                  mbedtls_md_update().
  *
- * \returns         0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                  verification fails.
+ * \param ctx       The generic message-digest context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_starts( mbedtls_md_context_t *ctx );
 
 /**
- * \brief           Generic message digest process buffer
- *                  Called between mbedtls_md_starts() and mbedtls_md_finish().
- *                  May be called repeatedly.
+ * \brief           This function feeds an input buffer into an ongoing
+ *                  message-digest computation.
+ *
+ *                  You must call mbedtls_md_starts() before calling this
+ *                  function. You may call this function multiple times.
+ *                  Afterwards, call mbedtls_md_finish().
  *
- * \param ctx       Generic message digest context
- * \param input     buffer holding the  datal
- * \param ilen      length of the input data
+ * \param ctx       The generic message-digest context.
+ * \param input     The buffer holding the input data.
+ * \param ilen      The length of the input data.
  *
- * \returns         0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                  verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
 
 /**
- * \brief           Generic message digest final digest
- *                  Called after mbedtls_md_update().
- *                  Usually followed by mbedtls_md_free() or mbedtls_md_starts().
- *
- * \param ctx       Generic message digest context
- * \param output    Generic message digest checksum result
- *
- * \returns         0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                  verification fails.
+ * \brief           This function finishes the digest operation,
+ *                  and writes the result to the output buffer.
+ *
+ *                  Call this function after a call to mbedtls_md_starts(),
+ *                  followed by any number of calls to mbedtls_md_update().
+ *                  Afterwards, you may either clear the context with
+ *                  mbedtls_md_free(), or call mbedtls_md_starts() to reuse
+ *                  the context for another digest operation with the same
+ *                  algorithm.
+ *
+ * \param ctx       The generic message-digest context.
+ * \param output    The buffer for the generic message-digest checksum result.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
 
 /**
- * \brief          Output = message_digest( input buffer )
- *
- * \param md_info  message digest info
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   Generic message digest checksum result
- *
- * \returns        0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \brief          This function calculates the message-digest of a buffer,
+ *                 with respect to a configurable message-digest algorithm
+ *                 in a single call.
+ *
+ *                 The result is calculated as
+ *                 Output = message_digest(input buffer).
+ *
+ * \param md_info  The information structure of the message-digest algorithm
+ *                 to use.
+ * \param input    The buffer holding the data.
+ * \param ilen     The length of the input data.
+ * \param output   The generic message-digest checksum result.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                 failure.
  */
 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
         unsigned char *output );
 
 #if defined(MBEDTLS_FS_IO)
 /**
- * \brief          Output = message_digest( file contents )
+ * \brief          This function calculates the message-digest checksum
+ *                 result of the contents of the provided file.
  *
- * \param md_info  message digest info
- * \param path     input file name
- * \param output   generic message digest checksum result
+ *                 The result is calculated as
+ *                 Output = message_digest(file contents).
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_MD_FILE_IO_ERROR if file input failed,
- *                 MBEDTLS_ERR_MD_BAD_INPUT_DATA if md_info was NULL.
+ * \param md_info  The information structure of the message-digest algorithm
+ *                 to use.
+ * \param path     The input file name.
+ * \param output   The generic message-digest checksum result.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
+ *                 the file pointed by \p path.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
  */
 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
                      unsigned char *output );
 #endif /* MBEDTLS_FS_IO */
 
 /**
- * \brief           Set HMAC key and prepare to authenticate a new message.
- *                  Usually called after mbedtls_md_setup() or mbedtls_md_hmac_finish().
- *
- * \param ctx       HMAC context
- * \param key       HMAC secret key
- * \param keylen    length of the HMAC key in bytes
- *
- * \returns         0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                  verification fails.
+ * \brief           This function sets the HMAC key and prepares to
+ *                  authenticate a new message.
+ *
+ *                  Call this function after mbedtls_md_setup(), to use
+ *                  the MD context for an HMAC calculation, then call
+ *                  mbedtls_md_hmac_update() to provide the input data, and
+ *                  mbedtls_md_hmac_finish() to get the HMAC value.
+ *
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
+ * \param key       The HMAC secret key.
+ * \param keylen    The length of the HMAC key in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
                     size_t keylen );
 
 /**
- * \brief           Generic HMAC process buffer.
- *                  Called between mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
- *                  and mbedtls_md_hmac_finish().
- *                  May be called repeatedly.
- *
- * \param ctx       HMAC context
- * \param input     buffer holding the  data
- * \param ilen      length of the input data
- *
- * \returns         0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                  verification fails.
+ * \brief           This function feeds an input buffer into an ongoing HMAC
+ *                  computation.
+ *
+ *                  Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
+ *                  before calling this function.
+ *                  You may call this function multiple times to pass the
+ *                  input piecewise.
+ *                  Afterwards, call mbedtls_md_hmac_finish().
+ *
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
+ * \param input     The buffer holding the input data.
+ * \param ilen      The length of the input data.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
                     size_t ilen );
 
 /**
- * \brief           Output HMAC.
- *                  Called after mbedtls_md_hmac_update().
- *                  Usually followed by mbedtls_md_hmac_reset(),
- *                  mbedtls_md_hmac_starts(), or mbedtls_md_free().
- *
- * \param ctx       HMAC context
- * \param output    Generic HMAC checksum result
- *
- * \returns         0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                  verification fails.
+ * \brief           This function finishes the HMAC operation, and writes
+ *                  the result to the output buffer.
+ *
+ *                  Call this function after mbedtls_md_hmac_starts() and
+ *                  mbedtls_md_hmac_update() to get the HMAC value. Afterwards
+ *                  you may either call mbedtls_md_free() to clear the context,
+ *                  or call mbedtls_md_hmac_reset() to reuse the context with
+ *                  the same HMAC key.
+ *
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
+ * \param output    The generic HMAC checksum result.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
 
 /**
- * \brief           Prepare to authenticate a new message with the same key.
- *                  Called after mbedtls_md_hmac_finish() and before
- *                  mbedtls_md_hmac_update().
+ * \brief           This function prepares to authenticate a new message with
+ *                  the same key as the previous HMAC operation.
+ *
+ *                  You may call this function after mbedtls_md_hmac_finish().
+ *                  Afterwards call mbedtls_md_hmac_update() to pass the new
+ *                  input.
  *
- * \param ctx       HMAC context to be reset
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
  *
- * \returns         0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                  verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
 
 /**
- * \brief          Output = Generic_HMAC( hmac key, input buffer )
- *
- * \param md_info  message digest info
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key in bytes
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   Generic HMAC-result
- *
- * \returns        0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \brief          This function calculates the full generic HMAC
+ *                 on the input buffer with the provided key.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The HMAC result is calculated as
+ *                 output = generic HMAC(hmac key, input buffer).
+ *
+ * \param md_info  The information structure of the message-digest algorithm
+ *                 to use.
+ * \param key      The HMAC secret key.
+ * \param keylen   The length of the HMAC secret key in Bytes.
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ * \param output   The generic HMAC result.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                 failure.
  */
 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
                 const unsigned char *input, size_t ilen,
diff --git a/crypto/mbedtls/include/mbedtls/md2.h b/crypto/mbedtls/include/mbedtls/md2.h
index 0f93fbf42..08e75b247 100644
--- a/crypto/mbedtls/include/mbedtls/md2.h
+++ b/crypto/mbedtls/include/mbedtls/md2.h
@@ -3,6 +3,11 @@
  *
  * \brief MD2 message digest algorithm (hash function)
  *
+ * \warning MD2 is considered a weak message digest and its use constitutes a
+ *          security risk. We recommend considering stronger message digests
+ *          instead.
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -19,6 +24,7 @@
  *  limitations under the License.
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
  */
 #ifndef MBEDTLS_MD2_H
 #define MBEDTLS_MD2_H
@@ -31,16 +37,23 @@
 
 #include <stddef.h>
 
-#if !defined(MBEDTLS_MD2_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED                   -0x002B  /**< MD2 hardware accelerator failed */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_MD2_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          MD2 context structure
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 typedef struct
 {
@@ -51,10 +64,19 @@ typedef struct
 }
 mbedtls_md2_context;
 
+#else  /* MBEDTLS_MD2_ALT */
+#include "md2_alt.h"
+#endif /* MBEDTLS_MD2_ALT */
+
 /**
  * \brief          Initialize MD2 context
  *
  * \param ctx      MD2 context to be initialized
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md2_init( mbedtls_md2_context *ctx );
 
@@ -62,6 +84,11 @@ void mbedtls_md2_init( mbedtls_md2_context *ctx );
  * \brief          Clear MD2 context
  *
  * \param ctx      MD2 context to be cleared
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md2_free( mbedtls_md2_context *ctx );
 
@@ -70,6 +97,11 @@ void mbedtls_md2_free( mbedtls_md2_context *ctx );
  *
  * \param dst      The destination context
  * \param src      The context to be cloned
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md2_clone( mbedtls_md2_context *dst,
                         const mbedtls_md2_context *src );
@@ -78,57 +110,190 @@ void mbedtls_md2_clone( mbedtls_md2_context *dst,
  * \brief          MD2 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md2_starts( mbedtls_md2_context *ctx );
+int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx );
 
 /**
  * \brief          MD2 process buffer
  *
  * \param ctx      MD2 context
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen );
+int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen );
 
 /**
  * \brief          MD2 final digest
  *
  * \param ctx      MD2 context
  * \param output   MD2 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] );
+int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
+                            unsigned char output[16] );
 
-#ifdef __cplusplus
-}
+/**
+ * \brief          MD2 process data block (internal use only)
+ *
+ * \param ctx      MD2 context
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_internal_md2_process( mbedtls_md2_context *ctx );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
+/**
+ * \brief          MD2 context setup
+ *
+ * \deprecated     Superseded by mbedtls_md2_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx );
 
-#else  /* MBEDTLS_MD2_ALT */
-#include "md2_alt.h"
-#endif /* MBEDTLS_MD2_ALT */
+/**
+ * \brief          MD2 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_md2_update_ret() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx,
+                                            const unsigned char *input,
+                                            size_t ilen );
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief          MD2 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md2_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ * \param output   MD2 checksum result
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx,
+                                            unsigned char output[16] );
+
+/**
+ * \brief          MD2 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_md2_process() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Output = MD2( input buffer )
  *
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
  * \param output   MD2 checksum result
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] );
+int mbedtls_md2_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Output = MD2( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_md2_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD2 checksum result
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
+                                     size_t ilen,
+                                     unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 int mbedtls_md2_self_test( int verbose );
 
-/* Internal use */
-void mbedtls_md2_process( mbedtls_md2_context *ctx );
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/mbedtls/include/mbedtls/md4.h b/crypto/mbedtls/include/mbedtls/md4.h
index 45214d41d..8ee4e5cab 100644
--- a/crypto/mbedtls/include/mbedtls/md4.h
+++ b/crypto/mbedtls/include/mbedtls/md4.h
@@ -3,6 +3,11 @@
  *
  * \brief MD4 message digest algorithm (hash function)
  *
+ * \warning MD4 is considered a weak message digest and its use constitutes a
+ *          security risk. We recommend considering stronger message digests
+ *          instead.
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -19,6 +24,7 @@
  *  limitations under the License.
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
  */
 #ifndef MBEDTLS_MD4_H
 #define MBEDTLS_MD4_H
@@ -32,16 +38,23 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#if !defined(MBEDTLS_MD4_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED                   -0x002D  /**< MD4 hardware accelerator failed */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_MD4_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          MD4 context structure
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 typedef struct
 {
@@ -51,10 +64,19 @@ typedef struct
 }
 mbedtls_md4_context;
 
+#else  /* MBEDTLS_MD4_ALT */
+#include "md4_alt.h"
+#endif /* MBEDTLS_MD4_ALT */
+
 /**
  * \brief          Initialize MD4 context
  *
  * \param ctx      MD4 context to be initialized
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md4_init( mbedtls_md4_context *ctx );
 
@@ -62,6 +84,11 @@ void mbedtls_md4_init( mbedtls_md4_context *ctx );
  * \brief          Clear MD4 context
  *
  * \param ctx      MD4 context to be cleared
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md4_free( mbedtls_md4_context *ctx );
 
@@ -70,6 +97,11 @@ void mbedtls_md4_free( mbedtls_md4_context *ctx );
  *
  * \param dst      The destination context
  * \param src      The context to be cloned
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md4_clone( mbedtls_md4_context *dst,
                         const mbedtls_md4_context *src );
@@ -78,57 +110,195 @@ void mbedtls_md4_clone( mbedtls_md4_context *dst,
  * \brief          MD4 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
  */
-void mbedtls_md4_starts( mbedtls_md4_context *ctx );
+int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx );
 
 /**
  * \brief          MD4 process buffer
  *
  * \param ctx      MD4 context
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen );
+int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen );
 
 /**
  * \brief          MD4 final digest
  *
  * \param ctx      MD4 context
  * \param output   MD4 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] );
+int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
+                            unsigned char output[16] );
 
-#ifdef __cplusplus
-}
+/**
+ * \brief          MD4 process data block (internal use only)
+ *
+ * \param ctx      MD4 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
+                                  const unsigned char data[64] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
+/**
+ * \brief          MD4 context setup
+ *
+ * \deprecated     Superseded by mbedtls_md4_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx );
 
-#else  /* MBEDTLS_MD4_ALT */
-#include "md4_alt.h"
-#endif /* MBEDTLS_MD4_ALT */
+/**
+ * \brief          MD4 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_md4_update_ret() in 2.7.0
+ *
+ * \param ctx      MD4 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx,
+                                            const unsigned char *input,
+                                            size_t ilen );
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief          MD4 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md4_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD4 context
+ * \param output   MD4 checksum result
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx,
+                                            unsigned char output[16] );
+
+/**
+ * \brief          MD4 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_md4_process() in 2.7.0
+ *
+ * \param ctx      MD4 context
+ * \param data     buffer holding one block of data
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx,
+                                             const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Output = MD4( input buffer )
  *
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
  * \param output   MD4 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] );
+int mbedtls_md4_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Output = MD4( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_md4_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD4 checksum result
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
+                                     size_t ilen,
+                                     unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 int mbedtls_md4_self_test( int verbose );
 
-/* Internal use */
-void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] );
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/mbedtls/include/mbedtls/md5.h b/crypto/mbedtls/include/mbedtls/md5.h
index 5a64061aa..43ead4b74 100644
--- a/crypto/mbedtls/include/mbedtls/md5.h
+++ b/crypto/mbedtls/include/mbedtls/md5.h
@@ -3,6 +3,11 @@
  *
  * \brief MD5 message digest algorithm (hash function)
  *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. We recommend considering stronger message
+ *            digests instead.
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -32,16 +37,23 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#if !defined(MBEDTLS_MD5_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED                   -0x002F  /**< MD5 hardware accelerator failed */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_MD5_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          MD5 context structure
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 typedef struct
 {
@@ -51,10 +63,19 @@ typedef struct
 }
 mbedtls_md5_context;
 
+#else  /* MBEDTLS_MD5_ALT */
+#include "md5_alt.h"
+#endif /* MBEDTLS_MD5_ALT */
+
 /**
  * \brief          Initialize MD5 context
  *
  * \param ctx      MD5 context to be initialized
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md5_init( mbedtls_md5_context *ctx );
 
@@ -62,6 +83,11 @@ void mbedtls_md5_init( mbedtls_md5_context *ctx );
  * \brief          Clear MD5 context
  *
  * \param ctx      MD5 context to be cleared
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md5_free( mbedtls_md5_context *ctx );
 
@@ -70,6 +96,11 @@ void mbedtls_md5_free( mbedtls_md5_context *ctx );
  *
  * \param dst      The destination context
  * \param src      The context to be cloned
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 void mbedtls_md5_clone( mbedtls_md5_context *dst,
                         const mbedtls_md5_context *src );
@@ -78,54 +109,193 @@ void mbedtls_md5_clone( mbedtls_md5_context *dst,
  * \brief          MD5 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md5_starts( mbedtls_md5_context *ctx );
+int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx );
 
 /**
  * \brief          MD5 process buffer
  *
  * \param ctx      MD5 context
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen );
+int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen );
 
 /**
  * \brief          MD5 final digest
  *
  * \param ctx      MD5 context
  * \param output   MD5 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] );
+int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
+                            unsigned char output[16] );
 
-/* Internal use */
-void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] );
+/**
+ * \brief          MD5 process data block (internal use only)
+ *
+ * \param ctx      MD5 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
+                                  const unsigned char data[64] );
 
-#ifdef __cplusplus
-}
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
+/**
+ * \brief          MD5 context setup
+ *
+ * \deprecated     Superseded by mbedtls_md5_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx );
 
-#else  /* MBEDTLS_MD5_ALT */
-#include "md5_alt.h"
-#endif /* MBEDTLS_MD5_ALT */
+/**
+ * \brief          MD5 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_md5_update_ret() in 2.7.0
+ *
+ * \param ctx      MD5 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx,
+                                            const unsigned char *input,
+                                            size_t ilen );
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief          MD5 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md5_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD5 context
+ * \param output   MD5 checksum result
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx,
+                                            unsigned char output[16] );
 
+/**
+ * \brief          MD5 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_md5_process() in 2.7.0
+ *
+ * \param ctx      MD5 context
+ * \param data     buffer holding one block of data
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
+                                             const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Output = MD5( input buffer )
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD5 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md5_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
 /**
  * \brief          Output = MD5( input buffer )
  *
- * \param input    buffer holding the  data
+ * \deprecated     Superseded by mbedtls_md5_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
  * \param output   MD5 checksum result
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
-void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] );
+MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
+                                     size_t ilen,
+                                     unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 int mbedtls_md5_self_test( int verbose );
 
diff --git a/crypto/mbedtls/include/mbedtls/md_internal.h b/crypto/mbedtls/include/mbedtls/md_internal.h
index e2441bbc4..04de48291 100644
--- a/crypto/mbedtls/include/mbedtls/md_internal.h
+++ b/crypto/mbedtls/include/mbedtls/md_internal.h
@@ -6,7 +6,8 @@
  * \warning This in an internal header. Do not include directly.
  *
  * \author Adriaan de Jong <de...@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -58,17 +59,17 @@ struct mbedtls_md_info_t
     int block_size;
 
     /** Digest initialisation function */
-    void (*starts_func)( void *ctx );
+    int (*starts_func)( void *ctx );
 
     /** Digest update function */
-    void (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
+    int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
 
     /** Digest finalisation function */
-    void (*finish_func)( void *ctx, unsigned char *output );
+    int (*finish_func)( void *ctx, unsigned char *output );
 
     /** Generic digest function */
-    void (*digest_func)( const unsigned char *input, size_t ilen,
-                         unsigned char *output );
+    int (*digest_func)( const unsigned char *input, size_t ilen,
+                        unsigned char *output );
 
     /** Allocate a new context */
     void * (*ctx_alloc_func)( void );
@@ -80,7 +81,7 @@ struct mbedtls_md_info_t
     void (*clone_func)( void *dst, const void *src );
 
     /** Internal use only */
-    void (*process_func)( void *ctx, const unsigned char *input );
+    int (*process_func)( void *ctx, const unsigned char *input );
 };
 
 #if defined(MBEDTLS_MD2_C)
diff --git a/crypto/mbedtls/include/mbedtls/memory_buffer_alloc.h b/crypto/mbedtls/include/mbedtls/memory_buffer_alloc.h
index d5df316fd..705f9a636 100644
--- a/crypto/mbedtls/include/mbedtls/memory_buffer_alloc.h
+++ b/crypto/mbedtls/include/mbedtls/memory_buffer_alloc.h
@@ -2,7 +2,8 @@
  * \file memory_buffer_alloc.h
  *
  * \brief Buffer-based memory allocator
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/net.h b/crypto/mbedtls/include/mbedtls/net.h
index 774559b3c..28ae8217c 100644
--- a/crypto/mbedtls/include/mbedtls/net.h
+++ b/crypto/mbedtls/include/mbedtls/net.h
@@ -3,6 +3,9 @@
  *
  * \brief Deprecated header file that includes mbedtls/net_sockets.h
  *
+ * \deprecated Superseded by mbedtls/net_sockets.h
+ */
+/*
  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -19,8 +22,6 @@
  *  limitations under the License.
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
- *
- * \deprecated Superseded by mbedtls/net_sockets.h
  */
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
diff --git a/crypto/mbedtls/include/mbedtls/net_sockets.h b/crypto/mbedtls/include/mbedtls/net_sockets.h
index de335526f..0f9b31ebc 100644
--- a/crypto/mbedtls/include/mbedtls/net_sockets.h
+++ b/crypto/mbedtls/include/mbedtls/net_sockets.h
@@ -2,7 +2,8 @@
  * \file net_sockets.h
  *
  * \brief Network communication functions
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -45,12 +46,17 @@
 #define MBEDTLS_ERR_NET_UNKNOWN_HOST                      -0x0052  /**< Failed to get an IP address for the given hostname. */
 #define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL                  -0x0043  /**< Buffer is too small to hold the data. */
 #define MBEDTLS_ERR_NET_INVALID_CONTEXT                   -0x0045  /**< The context is invalid, eg because it was free()ed. */
+#define MBEDTLS_ERR_NET_POLL_FAILED                       -0x0047  /**< Polling the net context failed. */
+#define MBEDTLS_ERR_NET_BAD_INPUT_DATA                    -0x0049  /**< Input invalid. */
 
 #define MBEDTLS_NET_LISTEN_BACKLOG         10 /**< The backlog that listen() should use. */
 
 #define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */
 #define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */
 
+#define MBEDTLS_NET_POLL_READ  1 /**< Used in \c mbedtls_net_poll to check for pending data  */
+#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -117,9 +123,10 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
  *
  * \param bind_ctx  Relevant socket
  * \param client_ctx Will contain the connected client socket
- * \param client_ip Will contain the client IP address
+ * \param client_ip Will contain the client IP address, can be NULL
  * \param buf_size  Size of the client_ip buffer
- * \param ip_len    Will receive the size of the client IP written
+ * \param ip_len    Will receive the size of the client IP written,
+ *                  can be NULL if client_ip is null
  *
  * \return          0 if successful, or
  *                  MBEDTLS_ERR_NET_ACCEPT_FAILED, or
@@ -131,6 +138,29 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
                         mbedtls_net_context *client_ctx,
                         void *client_ip, size_t buf_size, size_t *ip_len );
 
+/**
+ * \brief          Check and wait for the context to be ready for read/write
+ *
+ * \param ctx      Socket to check
+ * \param rw       Bitflag composed of MBEDTLS_NET_POLL_READ and
+ *                 MBEDTLS_NET_POLL_WRITE specifying the events
+ *                 to wait for:
+ *                 - If MBEDTLS_NET_POLL_READ is set, the function
+ *                   will return as soon as the net context is available
+ *                   for reading.
+ *                 - If MBEDTLS_NET_POLL_WRITE is set, the function
+ *                   will return as soon as the net context is available
+ *                   for writing.
+ * \param timeout  Maximal amount of time to wait before returning,
+ *                 in milliseconds. If \c timeout is zero, the
+ *                 function returns immediately. If \c timeout is
+ *                 -1u, the function blocks potentially indefinitely.
+ *
+ * \return         Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE
+ *                 on success or timeout, or a negative return code otherwise.
+ */
+int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout );
+
 /**
  * \brief          Set the socket blocking
  *
diff --git a/crypto/mbedtls/include/mbedtls/oid.h b/crypto/mbedtls/include/mbedtls/oid.h
index fcecdafdc..408645ece 100644
--- a/crypto/mbedtls/include/mbedtls/oid.h
+++ b/crypto/mbedtls/include/mbedtls/oid.h
@@ -2,7 +2,8 @@
  * \file oid.h
  *
  * \brief Object Identifier (OID) database
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -227,6 +228,14 @@
 
 #define MBEDTLS_OID_HMAC_SHA1                   MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
 
+#define MBEDTLS_OID_HMAC_SHA224                 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
+
+#define MBEDTLS_OID_HMAC_SHA256                 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
+
+#define MBEDTLS_OID_HMAC_SHA384                 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
+
+#define MBEDTLS_OID_HMAC_SHA512                 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
+
 /*
  * Encryption algorithms
  */
@@ -513,6 +522,16 @@ int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t
  * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
  */
 int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
+
+/**
+ * \brief          Translate hmac algorithm OID into md_type
+ *
+ * \param oid      OID to use
+ * \param md_hmac  place to store message hmac algorithm
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
 #endif /* MBEDTLS_MD_C */
 
 /**
diff --git a/crypto/mbedtls/include/mbedtls/padlock.h b/crypto/mbedtls/include/mbedtls/padlock.h
index 2045a5ab6..677936ebf 100644
--- a/crypto/mbedtls/include/mbedtls/padlock.h
+++ b/crypto/mbedtls/include/mbedtls/padlock.h
@@ -3,7 +3,8 @@
  *
  * \brief VIA PadLock ACE for HW encryption/decryption supported by some
  *        processors
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/pem.h b/crypto/mbedtls/include/mbedtls/pem.h
index 54dc02d7c..2cf4c0a70 100644
--- a/crypto/mbedtls/include/mbedtls/pem.h
+++ b/crypto/mbedtls/include/mbedtls/pem.h
@@ -2,7 +2,8 @@
  * \file pem.h
  *
  * \brief Privacy Enhanced Mail (PEM) decoding
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/pk.h b/crypto/mbedtls/include/mbedtls/pk.h
index f9f9b9bb0..ee06b2fd2 100644
--- a/crypto/mbedtls/include/mbedtls/pk.h
+++ b/crypto/mbedtls/include/mbedtls/pk.h
@@ -2,7 +2,8 @@
  * \file pk.h
  *
  * \brief Public Key abstraction layer
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -62,7 +63,8 @@
 #define MBEDTLS_ERR_PK_INVALID_ALG         -0x3A80  /**< The algorithm tag or value is invalid. */
 #define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00  /**< Elliptic curve is unsupported (only NIST curves are supported). */
 #define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980  /**< Unavailable feature, e.g. RSA disabled for RSA key. */
-#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH    -0x3900  /**< The signature is valid but its length is less than expected. */
+#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH    -0x3900  /**< The buffer contains a valid signature followed by more data. */
+#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED     -0x3880  /**< PK hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
@@ -267,8 +269,8 @@ int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
  * \param sig_len   Signature length
  *
  * \return          0 on success (signature is valid),
- *                  MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if the signature is
- *                  valid but its actual length is less than sig_len,
+ *                  #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in sig but its length is less than \p siglen,
  *                  or a specific error code.
  *
  * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
@@ -298,10 +300,10 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
  * \param sig_len   Signature length
  *
  * \return          0 on success (signature is valid),
- *                  MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
+ *                  #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
  *                  used for this type of signatures,
- *                  MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if the signature is
- *                  valid but its actual length is less than sig_len,
+ *                  #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in sig but its length is less than \p siglen,
  *                  or a specific error code.
  *
  * \note            If hash_len is 0, then the length associated with md_alg
diff --git a/crypto/mbedtls/include/mbedtls/pk_internal.h b/crypto/mbedtls/include/mbedtls/pk_internal.h
index 01d0f214b..3dae0fc5b 100644
--- a/crypto/mbedtls/include/mbedtls/pk_internal.h
+++ b/crypto/mbedtls/include/mbedtls/pk_internal.h
@@ -1,8 +1,9 @@
 /**
- * \file pk.h
+ * \file pk_internal.h
  *
  * \brief Public Key abstraction layer: wrapper functions
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/pkcs11.h b/crypto/mbedtls/include/mbedtls/pkcs11.h
index 2e8892813..bf65c55a7 100644
--- a/crypto/mbedtls/include/mbedtls/pkcs11.h
+++ b/crypto/mbedtls/include/mbedtls/pkcs11.h
@@ -4,7 +4,8 @@
  * \brief Wrapper for PKCS#11 library libpkcs11-helper
  *
  * \author Adriaan de Jong <de...@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/pkcs12.h b/crypto/mbedtls/include/mbedtls/pkcs12.h
index 9b2d90459..a621ef5b1 100644
--- a/crypto/mbedtls/include/mbedtls/pkcs12.h
+++ b/crypto/mbedtls/include/mbedtls/pkcs12.h
@@ -2,7 +2,8 @@
  * \file pkcs12.h
  *
  * \brief PKCS#12 Personal Information Exchange Syntax
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/pkcs5.h b/crypto/mbedtls/include/mbedtls/pkcs5.h
index ec5cb9e74..9a3c9fddc 100644
--- a/crypto/mbedtls/include/mbedtls/pkcs5.h
+++ b/crypto/mbedtls/include/mbedtls/pkcs5.h
@@ -4,7 +4,8 @@
  * \brief PKCS#5 functions
  *
  * \author Mathias Olsson <ma...@kompetensum.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/platform.h b/crypto/mbedtls/include/mbedtls/platform.h
index 35010f885..d50b266b7 100644
--- a/crypto/mbedtls/include/mbedtls/platform.h
+++ b/crypto/mbedtls/include/mbedtls/platform.h
@@ -1,9 +1,19 @@
 /**
  * \file platform.h
  *
- * \brief mbed TLS Platform abstraction layer
+ * \brief This file contains the definitions and functions of the
+ *        Mbed TLS platform abstraction layer.
  *
- *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *        The platform abstraction layer removes the need for the library
+ *        to directly link to standard C library functions or operating
+ *        system services, making the library easier to port and embed.
+ *        Application developers and users of the library can provide their own
+ *        implementations of these functions, or implementations specific to
+ *        their platform, which can be statically linked to the library or 
+ *        dynamically configured at runtime.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,7 +28,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
 #ifndef MBEDTLS_PLATFORM_H
 #define MBEDTLS_PLATFORM_H
@@ -51,34 +61,34 @@ extern "C" {
 #include <time.h>
 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
 #if defined(_WIN32)
-#define MBEDTLS_PLATFORM_STD_SNPRINTF   mbedtls_platform_win32_snprintf /**< Default snprintf to use  */
+#define MBEDTLS_PLATFORM_STD_SNPRINTF   mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use.  */
 #else
-#define MBEDTLS_PLATFORM_STD_SNPRINTF   snprintf /**< Default snprintf to use  */
+#define MBEDTLS_PLATFORM_STD_SNPRINTF   snprintf /**< The default \c snprintf function to use.  */
 #endif
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
-#define MBEDTLS_PLATFORM_STD_PRINTF   printf /**< Default printf to use  */
+#define MBEDTLS_PLATFORM_STD_PRINTF   printf /**< The default \c printf function to use. */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
-#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */
+#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
-#define MBEDTLS_PLATFORM_STD_CALLOC   calloc /**< Default allocator to use */
+#define MBEDTLS_PLATFORM_STD_CALLOC   calloc /**< The default \c calloc function to use. */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_FREE)
-#define MBEDTLS_PLATFORM_STD_FREE       free /**< Default free to use */
+#define MBEDTLS_PLATFORM_STD_FREE       free /**< The default \c free function to use. */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_EXIT)
-#define MBEDTLS_PLATFORM_STD_EXIT      exit /**< Default exit to use */
+#define MBEDTLS_PLATFORM_STD_EXIT      exit /**< The default \c exit function to use. */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_TIME)
-#define MBEDTLS_PLATFORM_STD_TIME       time    /**< Default time to use */
+#define MBEDTLS_PLATFORM_STD_TIME       time    /**< The default \c time function to use. */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
-#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS  EXIT_SUCCESS /**< Default exit value to use */
+#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS  EXIT_SUCCESS /**< The default exit value to use. */
 #endif
 #if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
-#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE  EXIT_FAILURE /**< Default exit value to use */
+#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE  EXIT_FAILURE /**< The default exit value to use. */
 #endif
 #if defined(MBEDTLS_FS_IO)
 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
@@ -101,7 +111,7 @@ extern "C" {
 /* \} name SECTION: Module settings */
 
 /*
- * The function pointers for calloc and free
+ * The function pointers for calloc and free.
  */
 #if defined(MBEDTLS_PLATFORM_MEMORY)
 #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
@@ -115,12 +125,13 @@ extern void * (*mbedtls_calloc)( size_t n, size_t size );
 extern void (*mbedtls_free)( void *ptr );
 
 /**
- * \brief   Set your own memory implementation function pointers
+ * \brief               This function dynamically sets the memory-management
+ *                      functions used by the library, during runtime.
  *
- * \param calloc_func   the calloc function implementation
- * \param free_func     the free function implementation
+ * \param calloc_func   The \c calloc function implementation.
+ * \param free_func     The \c free function implementation.
  *
- * \return              0 if successful
+ * \return              \c 0.
  */
 int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
                               void (*free_func)( void * ) );
@@ -139,11 +150,13 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
 extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
 
 /**
- * \brief   Set your own fprintf function pointer
+ * \brief                This function dynamically configures the fprintf
+ *                       function that is called when the
+ *                       mbedtls_fprintf() function is invoked by the library.
  *
- * \param fprintf_func   the fprintf function implementation
+ * \param fprintf_func   The \c fprintf function implementation.
  *
- * \return              0
+ * \return               \c 0.
  */
 int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
                                                ... ) );
@@ -162,11 +175,13 @@ int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char
 extern int (*mbedtls_printf)( const char *format, ... );
 
 /**
- * \brief   Set your own printf function pointer
+ * \brief               This function dynamically configures the snprintf
+ *                      function that is called when the mbedtls_snprintf()
+ *                      function is invoked by the library.
  *
- * \param printf_func   the printf function implementation
+ * \param printf_func   The \c printf function implementation.
  *
- * \return              0
+ * \return              \c 0 on success.
  */
 int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
 #else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
@@ -195,11 +210,12 @@ int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
 extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
 
 /**
- * \brief   Set your own snprintf function pointer
+ * \brief                 This function allows configuring a custom
+ *                        \c snprintf function pointer.
  *
- * \param snprintf_func   the snprintf function implementation
+ * \param snprintf_func   The \c snprintf function implementation.
  *
- * \return              0
+ * \return                \c 0 on success.
  */
 int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
                                                  const char * format, ... ) );
@@ -218,11 +234,13 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
 extern void (*mbedtls_exit)( int status );
 
 /**
- * \brief   Set your own exit function pointer
+ * \brief             This function dynamically configures the exit
+ *                    function that is called when the mbedtls_exit()
+ *                    function is invoked by the library.
  *
- * \param exit_func   the exit function implementation
+ * \param exit_func   The \c exit function implementation.
  *
- * \return              0
+ * \return            \c 0 on success.
  */
 int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
 #else
@@ -265,12 +283,13 @@ extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
 extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
 
 /**
- * \brief   Set your own seed file writing/reading functions
+ * \brief   This function allows configuring custom seed file writing and
+ *          reading functions.
  *
- * \param   nv_seed_read_func   the seed reading function implementation
- * \param   nv_seed_write_func  the seed writing function implementation
+ * \param   nv_seed_read_func   The seed reading function implementation.
+ * \param   nv_seed_write_func  The seed writing function implementation.
  *
- * \return              0
+ * \return  \c 0 on success.
  */
 int mbedtls_platform_set_nv_seed(
             int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
@@ -291,13 +310,13 @@ int mbedtls_platform_set_nv_seed(
 #if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
 
 /**
- * \brief   Platform context structure
+ * \brief   The platform context structure.
  *
  * \note    This structure may be used to assist platform-specific
- *          setup/teardown operations.
+ *          setup or teardown operations.
  */
 typedef struct {
-    char dummy; /**< Placeholder member as empty structs are not portable */
+    char dummy; /**< A placeholder member, as empty structs are not portable. */
 }
 mbedtls_platform_context;
 
@@ -306,33 +325,34 @@ mbedtls_platform_context;
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
 /**
- * \brief   Perform any platform initialisation operations
+ * \brief   This function performs any platform-specific initialization
+ *          operations.
+ *
+ * \note    This function should be called before any other library functions.
  *
- * \param   ctx     mbed TLS context
+ *          Its implementation is platform-specific, and unless
+ *          platform-specific code is provided, it does nothing. 
  *
- * \return  0 if successful
+ * \note    The usage and necessity of this function is dependent on the platform.
  *
- * \note    This function is intended to allow platform specific initialisation,
- *          and should be called before any other library functions. Its
- *          implementation is platform specific, and by default, unless platform
- *          specific code is provided, it does nothing.
+ * \param   ctx     The platform context.
  *
- *          Its use and whether its necessary to be called is dependent on the
- *          platform.
+ * \return  \c 0 on success.
  */
 int mbedtls_platform_setup( mbedtls_platform_context *ctx );
 /**
- * \brief   Perform any platform teardown operations
+ * \brief   This function performs any platform teardown operations.
+ *
+ * \note    This function should be called after every other Mbed TLS module
+ *          has been correctly freed using the appropriate free function.
+ *
+ *          Its implementation is platform-specific, and unless
+ *          platform-specific code is provided, it does nothing.
  *
- * \param   ctx     mbed TLS context
+ * \note    The usage and necessity of this function is dependent on the platform.
  *
- * \note    This function should be called after every other mbed TLS module has
- *          been correctly freed using the appropriate free function.
- *          Its implementation is platform specific, and by default, unless
- *          platform specific code is provided, it does nothing.
+ * \param   ctx     The platform context.
  *
- *          Its use and whether its necessary to be called is dependent on the
- *          platform.
  */
 void mbedtls_platform_teardown( mbedtls_platform_context *ctx );
 
diff --git a/crypto/mbedtls/include/mbedtls/platform_time.h b/crypto/mbedtls/include/mbedtls/platform_time.h
index abb343142..2ed36f56c 100644
--- a/crypto/mbedtls/include/mbedtls/platform_time.h
+++ b/crypto/mbedtls/include/mbedtls/platform_time.h
@@ -2,7 +2,8 @@
  * \file platform_time.h
  *
  * \brief mbed TLS Platform time abstraction
- *
+ */
+/*
  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/ripemd160.h b/crypto/mbedtls/include/mbedtls/ripemd160.h
index 7083fc859..a0dac0c36 100644
--- a/crypto/mbedtls/include/mbedtls/ripemd160.h
+++ b/crypto/mbedtls/include/mbedtls/ripemd160.h
@@ -2,7 +2,8 @@
  * \file ripemd160.h
  *
  * \brief RIPE MD-160 message digest
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -32,14 +33,16 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#if !defined(MBEDTLS_RIPEMD160_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED             -0x0031  /**< RIPEMD160 hardware accelerator failed */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_RIPEMD160_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          RIPEMD-160 context structure
  */
@@ -51,6 +54,10 @@ typedef struct
 }
 mbedtls_ripemd160_context;
 
+#else  /* MBEDTLS_RIPEMD160_ALT */
+#include "ripemd160.h"
+#endif /* MBEDTLS_RIPEMD160_ALT */
+
 /**
  * \brief          Initialize RIPEMD-160 context
  *
@@ -78,51 +85,137 @@ void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
  * \brief          RIPEMD-160 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
  */
-void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx );
+int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx );
 
 /**
  * \brief          RIPEMD-160 process buffer
  *
  * \param ctx      RIPEMD-160 context
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
+ *
+ * \return         0 if successful
  */
-void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
-                       const unsigned char *input, size_t ilen );
+int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
+                                  const unsigned char *input,
+                                  size_t ilen );
 
 /**
  * \brief          RIPEMD-160 final digest
  *
  * \param ctx      RIPEMD-160 context
  * \param output   RIPEMD-160 checksum result
+ *
+ * \return         0 if successful
  */
-void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] );
+int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
+                                  unsigned char output[20] );
 
-/* Internal use */
-void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] );
+/**
+ * \brief          RIPEMD-160 process data block (internal use only)
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ */
+int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
+                                        const unsigned char data[64] );
 
-#ifdef __cplusplus
-}
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
+/**
+ * \brief          RIPEMD-160 context setup
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_starts(
+                                            mbedtls_ripemd160_context *ctx );
 
-#else  /* MBEDTLS_RIPEMD160_ALT */
-#include "ripemd160.h"
-#endif /* MBEDTLS_RIPEMD160_ALT */
+/**
+ * \brief          RIPEMD-160 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_update_ret() in 2.7.0
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_update(
+                                                mbedtls_ripemd160_context *ctx,
+                                                const unsigned char *input,
+                                                size_t ilen );
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief          RIPEMD-160 final digest
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_finish_ret() in 2.7.0
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param output   RIPEMD-160 checksum result
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_finish(
+                                                mbedtls_ripemd160_context *ctx,
+                                                unsigned char output[20] );
+
+/**
+ * \brief          RIPEMD-160 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_ripemd160_process() in 2.7.0
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param data     buffer holding one block of data
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_process(
+                                            mbedtls_ripemd160_context *ctx,
+                                            const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Output = RIPEMD-160( input buffer )
  *
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
  * \param ilen     length of the input data
  * \param output   RIPEMD-160 checksum result
+ *
+ * \return         0 if successful
  */
-void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
-                unsigned char output[20] );
+int mbedtls_ripemd160_ret( const unsigned char *input,
+                           size_t ilen,
+                           unsigned char output[20] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Output = RIPEMD-160( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   RIPEMD-160 checksum result
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input,
+                                           size_t ilen,
+                                           unsigned char output[20] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
diff --git a/crypto/mbedtls/include/mbedtls/rsa.h b/crypto/mbedtls/include/mbedtls/rsa.h
index 7d7469d50..df6e3e557 100644
--- a/crypto/mbedtls/include/mbedtls/rsa.h
+++ b/crypto/mbedtls/include/mbedtls/rsa.h
@@ -1,9 +1,16 @@
 /**
  * \file rsa.h
  *
- * \brief The RSA public-key cryptosystem
+ * \brief This file provides an API for the RSA public-key cryptosystem.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * The RSA public-key cryptosystem is defined in <em>Public-Key
+ * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption</em>
+ * and <em>Public-Key Cryptography Standards (PKCS) #1 v2.1: 
+ * RSA Cryptography Specifications</em>.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,7 +25,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
 #ifndef MBEDTLS_RSA_H
 #define MBEDTLS_RSA_H
@@ -42,24 +49,26 @@
 #define MBEDTLS_ERR_RSA_BAD_INPUT_DATA                    -0x4080  /**< Bad input parameters to function. */
 #define MBEDTLS_ERR_RSA_INVALID_PADDING                   -0x4100  /**< Input data contains invalid padding and is rejected. */
 #define MBEDTLS_ERR_RSA_KEY_GEN_FAILED                    -0x4180  /**< Something failed during generation of a key. */
-#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED                  -0x4200  /**< Key failed to pass the library's validity check. */
+#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED                  -0x4200  /**< Key failed to pass the validity check of the library. */
 #define MBEDTLS_ERR_RSA_PUBLIC_FAILED                     -0x4280  /**< The public key operation failed. */
 #define MBEDTLS_ERR_RSA_PRIVATE_FAILED                    -0x4300  /**< The private key operation failed. */
 #define MBEDTLS_ERR_RSA_VERIFY_FAILED                     -0x4380  /**< The PKCS#1 verification failed. */
 #define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE                  -0x4400  /**< The output buffer for decryption is not large enough. */
 #define MBEDTLS_ERR_RSA_RNG_FAILED                        -0x4480  /**< The random generator failed to generate non-zeros. */
+#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION             -0x4500  /**< The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */
+#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED                   -0x4580  /**< RSA hardware accelerator failed. */
 
 /*
  * RSA constants
  */
-#define MBEDTLS_RSA_PUBLIC      0
-#define MBEDTLS_RSA_PRIVATE     1
+#define MBEDTLS_RSA_PUBLIC      0 /**< Request private key operation. */
+#define MBEDTLS_RSA_PRIVATE     1 /**< Request public key operation. */
 
-#define MBEDTLS_RSA_PKCS_V15    0
-#define MBEDTLS_RSA_PKCS_V21    1
+#define MBEDTLS_RSA_PKCS_V15    0 /**< Use PKCS#1 v1.5 encoding. */
+#define MBEDTLS_RSA_PKCS_V21    1 /**< Use PKCS#1 v2.1 encoding. */
 
-#define MBEDTLS_RSA_SIGN        1
-#define MBEDTLS_RSA_CRYPT       2
+#define MBEDTLS_RSA_SIGN        1 /**< Identifier for RSA signature operations. */
+#define MBEDTLS_RSA_CRYPT       2 /**< Identifier for RSA encryption and decryption operations. */
 
 #define MBEDTLS_RSA_SALT_LEN_ANY    -1
 
@@ -67,168 +76,469 @@
  * The above constants may be used even if the RSA module is compile out,
  * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
  */
-#if defined(MBEDTLS_RSA_C)
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_RSA_ALT)
+// Regular implementation
+//
+
 /**
- * \brief          RSA context structure
+ * \brief   The RSA context structure.
+ *
+ * \note    Direct manipulation of the members of this structure
+ *          is deprecated. All manipulation should instead be done through
+ *          the public interface functions.
  */
 typedef struct
 {
-    int ver;                    /*!<  always 0          */
-    size_t len;                 /*!<  size(N) in chars  */
-
-    mbedtls_mpi N;                      /*!<  public modulus    */
-    mbedtls_mpi E;                      /*!<  public exponent   */
-
-    mbedtls_mpi D;                      /*!<  private exponent  */
-    mbedtls_mpi P;                      /*!<  1st prime factor  */
-    mbedtls_mpi Q;                      /*!<  2nd prime factor  */
-    mbedtls_mpi DP;                     /*!<  D % (P - 1)       */
-    mbedtls_mpi DQ;                     /*!<  D % (Q - 1)       */
-    mbedtls_mpi QP;                     /*!<  1 / (Q % P)       */
-
-    mbedtls_mpi RN;                     /*!<  cached R^2 mod N  */
-    mbedtls_mpi RP;                     /*!<  cached R^2 mod P  */
-    mbedtls_mpi RQ;                     /*!<  cached R^2 mod Q  */
-
-    mbedtls_mpi Vi;                     /*!<  cached blinding value     */
-    mbedtls_mpi Vf;                     /*!<  cached un-blinding value  */
-
-    int padding;                /*!<  MBEDTLS_RSA_PKCS_V15 for 1.5 padding and
-                                      MBEDTLS_RSA_PKCS_v21 for OAEP/PSS         */
-    int hash_id;                /*!<  Hash identifier of mbedtls_md_type_t as
-                                      specified in the mbedtls_md.h header file
-                                      for the EME-OAEP and EMSA-PSS
-                                      encoding                          */
+    int ver;                    /*!<  Always 0.*/
+    size_t len;                 /*!<  The size of \p N in Bytes. */
+
+    mbedtls_mpi N;              /*!<  The public modulus. */
+    mbedtls_mpi E;              /*!<  The public exponent. */
+
+    mbedtls_mpi D;              /*!<  The private exponent. */
+    mbedtls_mpi P;              /*!<  The first prime factor. */
+    mbedtls_mpi Q;              /*!<  The second prime factor. */
+
+    mbedtls_mpi DP;             /*!<  <code>D % (P - 1)</code>. */
+    mbedtls_mpi DQ;             /*!<  <code>D % (Q - 1)</code>. */
+    mbedtls_mpi QP;             /*!<  <code>1 / (Q % P)</code>. */
+
+    mbedtls_mpi RN;             /*!<  cached <code>R^2 mod N</code>. */
+
+    mbedtls_mpi RP;             /*!<  cached <code>R^2 mod P</code>. */
+    mbedtls_mpi RQ;             /*!<  cached <code>R^2 mod Q</code>. */
+
+    mbedtls_mpi Vi;             /*!<  The cached blinding value. */
+    mbedtls_mpi Vf;             /*!<  The cached un-blinding value. */
+
+    int padding;                /*!< Selects padding mode:
+                                     #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and
+                                     #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */
+    int hash_id;                /*!< Hash identifier of mbedtls_md_type_t type,
+                                     as specified in md.h for use in the MGF
+                                     mask generating function used in the
+                                     EME-OAEP and EMSA-PSS encodings. */
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_threading_mutex_t mutex;    /*!<  Thread-safety mutex       */
+    mbedtls_threading_mutex_t mutex;    /*!<  Thread-safety mutex. */
 #endif
 }
 mbedtls_rsa_context;
 
+#else  /* MBEDTLS_RSA_ALT */
+#include "rsa_alt.h"
+#endif /* MBEDTLS_RSA_ALT */
+
 /**
- * \brief          Initialize an RSA context
+ * \brief          This function initializes an RSA context.
  *
- *                 Note: Set padding to MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP
+ * \note           Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP
  *                 encryption scheme and the RSASSA-PSS signature scheme.
  *
- * \param ctx      RSA context to be initialized
- * \param padding  MBEDTLS_RSA_PKCS_V15 or MBEDTLS_RSA_PKCS_V21
- * \param hash_id  MBEDTLS_RSA_PKCS_V21 hash identifier
- *
- * \note           The hash_id parameter is actually ignored
- *                 when using MBEDTLS_RSA_PKCS_V15 padding.
+ * \note           The \p hash_id parameter is ignored when using
+ *                 #MBEDTLS_RSA_PKCS_V15 padding.
  *
- * \note           Choice of padding mode is strictly enforced for private key
+ * \note           The choice of padding mode is strictly enforced for private key
  *                 operations, since there might be security concerns in
- *                 mixing padding modes. For public key operations it's merely
+ *                 mixing padding modes. For public key operations it is
  *                 a default value, which can be overriden by calling specific
- *                 rsa_rsaes_xxx or rsa_rsassa_xxx functions.
- *
- * \note           The chosen hash is always used for OEAP encryption.
- *                 For PSS signatures, it's always used for making signatures,
- *                 but can be overriden (and always is, if set to
- *                 MBEDTLS_MD_NONE) for verifying them.
+ *                 \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions.
+ *
+ * \note           The hash selected in \p hash_id is always used for OEAP
+ *                 encryption. For PSS signatures, it is always used for
+ *                 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.
  */
 void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
-               int padding,
-               int hash_id);
+                       int padding,
+                       int hash_id);
 
 /**
- * \brief          Set padding for an already initialized RSA context
- *                 See \c mbedtls_rsa_init() for details.
+ * \brief          This function imports a set of core parameters into an
+ *                 RSA context.
+ *
+ * \note           This function can be called multiple times for successive
+ *                 imports, if the parameters are not simultaneously present.
  *
- * \param ctx      RSA context to be set
- * \param padding  MBEDTLS_RSA_PKCS_V15 or MBEDTLS_RSA_PKCS_V21
- * \param hash_id  MBEDTLS_RSA_PKCS_V21 hash identifier
+ *                 Any sequence of calls to this function should be followed
+ *                 by a call to mbedtls_rsa_complete(), which checks and
+ *                 completes the provided information to a ready-for-use
+ *                 public or private RSA key.
+ *
+ * \note           See mbedtls_rsa_complete() for more information on which
+ *                 parameters are necessary to set up a private or public
+ *                 RSA key.
+ *
+ * \note           The imported parameters are copied and need not be preserved
+ *                 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.
+ *
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
  */
-void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id);
+int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
+                        const mbedtls_mpi *N,
+                        const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                        const mbedtls_mpi *D, const mbedtls_mpi *E );
 
 /**
- * \brief          Generate an RSA keypair
+ * \brief          This function imports core RSA parameters, in raw big-endian
+ *                 binary format, into an RSA context.
+ *
+ * \note           This function can be called multiple times for successive
+ *                 imports, if the parameters are not simultaneously present.
+ *
+ *                 Any sequence of calls to this function should be followed
+ *                 by a call to mbedtls_rsa_complete(), which checks and
+ *                 completes the provided information to a ready-for-use
+ *                 public or private RSA key.
+ *
+ * \note           See mbedtls_rsa_complete() for more information on which
+ *                 parameters are necessary to set up a private or public
+ *                 RSA key.
+ *
+ * \note           The imported parameters are copied and need not be preserved
+ *                 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.
+ *
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
+ */
+int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
+                            unsigned char const *N, size_t N_len,
+                            unsigned char const *P, size_t P_len,
+                            unsigned char const *Q, size_t Q_len,
+                            unsigned char const *D, size_t D_len,
+                            unsigned char const *E, size_t E_len );
+
+/**
+ * \brief          This function completes an RSA context from
+ *                 a set of imported core parameters.
+ *
+ *                 To setup an RSA public key, precisely \p N and \p E
+ *                 must have been imported.
  *
- * \param ctx      RSA context that will hold the key
- * \param f_rng    RNG function
- * \param p_rng    RNG parameter
- * \param nbits    size of the public key in bits
- * \param exponent public exponent (e.g., 65537)
+ *                 To setup an RSA private key, sufficient information must
+ *                 be present for the other parameters to be derivable.
  *
- * \note           mbedtls_rsa_init() must be called beforehand to setup
- *                 the RSA context.
+ *                 The default implementation supports the following:
+ *                 <ul><li>Derive \p P, \p Q from \p N, \p D, \p E.</li>
+ *                 <li>Derive \p N, \p D from \p P, \p Q, \p E.</li></ul>
+ *                 Alternative implementations need not support these.
+ *
+ *                 If this function runs successfully, it guarantees that
+ *                 the RSA context can be used for RSA operations without
+ *                 the risk of failure or crash.
+ *
+ * \warning        This function need not perform consistency checks
+ *                 for the imported parameters. In particular, parameters that
+ *                 are not needed by the implementation might be silently
+ *                 discarded and left unchecked. To check the consistency
+ *                 of the key material, see mbedtls_rsa_check_privkey().
+ *
+ * \param ctx      The initialized RSA context holding imported parameters.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations
+ *                 failed.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  */
-int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
-                 int (*f_rng)(void *, unsigned char *, size_t),
-                 void *p_rng,
-                 unsigned int nbits, int exponent );
+int mbedtls_rsa_complete( mbedtls_rsa_context *ctx );
 
 /**
- * \brief          Check a public RSA key
+ * \brief          This function exports the core parameters of an RSA key.
+ *
+ *                 If this function runs successfully, the non-NULL buffers
+ *                 pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ *                 written, with additional unused space filled leading by
+ *                 zero Bytes.
+ *
+ *                 Possible reasons for returning
+ *                 #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:<ul>
+ *                 <li>An alternative RSA implementation is in use, which
+ *                 stores the key externally, and either cannot or should
+ *                 not export it into RAM.</li>
+ *                 <li>A SW or HW implementation might not support a certain
+ *                 deduction. For example, \p P, \p Q from \p N, \p D,
+ *                 and \p E if the former are not part of the
+ *                 implementation.</li></ul>
+ *
+ *                 If the function fails due to an unsupported operation,
+ *                 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.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
+ *                 requested parameters cannot be done due to missing
+ *                 functionality or because of security policies.
+ * \return         A non-zero return code on any other failure.
  *
- * \param ctx      RSA context to be checked
+ */
+int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
+                        mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
+                        mbedtls_mpi *D, mbedtls_mpi *E );
+
+/**
+ * \brief          This function exports core parameters of an RSA key
+ *                 in raw big-endian binary format.
+ *
+ *                 If this function runs successfully, the non-NULL buffers
+ *                 pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ *                 written, with additional unused space filled leading by
+ *                 zero Bytes.
+ *
+ *                 Possible reasons for returning
+ *                 #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:<ul>
+ *                 <li>An alternative RSA implementation is in use, which
+ *                 stores the key externally, and either cannot or should
+ *                 not export it into RAM.</li>
+ *                 <li>A SW or HW implementation might not support a certain
+ *                 deduction. For example, \p P, \p Q from \p N, \p D,
+ *                 and \p E if the former are not part of the
+ *                 implementation.</li></ul>
+ *                 If the function fails due to an unsupported operation,
+ *                 the RSA context stays intact and remains usable.
+ *
+ * \note           The length parameters are ignored if the corresponding
+ *                 buffer pointers are NULL.
+ *
+ * \param ctx      The initialized RSA context.
+ * \param N        The Byte array to store the RSA modulus, or NULL.
+ * \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_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_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_len    The size of the buffer for the private exponent.
+ * \param E        The Byte array to hold the public exponent, or NULL.
+ * \param E_len    The size of the buffer for the public exponent.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
+ *                 requested parameters cannot be done due to missing
+ *                 functionality or because of security policies.
+ * \return         A non-zero return code on any other failure.
+ */
+int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
+                            unsigned char *N, size_t N_len,
+                            unsigned char *P, size_t P_len,
+                            unsigned char *Q, size_t Q_len,
+                            unsigned char *D, size_t D_len,
+                            unsigned char *E, size_t E_len );
+
+/**
+ * \brief          This function exports CRT parameters of a private RSA key.
+ *
+ * \note           Alternative RSA implementations not using CRT-parameters
+ *                 internally can implement this function based on
+ *                 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.
+ *
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  */
-int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx );
+int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
+                            mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP );
+
+/**
+ * \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 hash_id  The #MBEDTLS_RSA_PKCS_V21 hash identifier.
+ */
+void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+                              int hash_id);
 
 /**
- * \brief          Check a private RSA key
+ * \brief          This function retrieves the length of RSA modulus in Bytes.
+ *
+ * \param ctx      The initialized RSA context.
  *
- * \param ctx      RSA context to be checked
+ * \return         The length of the RSA modulus in Bytes.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  */
-int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx );
+size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx );
 
 /**
- * \brief          Check a public-private RSA key pair.
- *                 Check each of the contexts, and make sure they match.
+ * \brief          This function generates an RSA keypair.
+ *
+ * \note           mbedtls_rsa_init() must be called before this function,
+ *                 to set up the RSA context.
  *
- * \param pub      RSA context holding the public key
- * \param prv      RSA context holding the private key
+ * \param ctx      The RSA context used to hold the key.
+ * \param f_rng    The RNG function.
+ * \param p_rng    The RNG context.
+ * \param nbits    The size of the public key in bits.
+ * \param exponent The public exponent. For example, 65537.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
-int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv );
+int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         unsigned int nbits, int exponent );
+
+/**
+ * \brief          This function checks if a context contains at least an RSA
+ *                 public key.
+ *
+ *                 If the function runs successfully, it is guaranteed that
+ *                 enough information is present to perform an RSA public key
+ *                 operation using mbedtls_rsa_public().
+ *
+ * \param ctx      The RSA context to check.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx );
+
+/**
+ * \brief      This function checks if a context contains an RSA private key
+ *             and perform basic consistency checks.
+ *
+ * \note       The consistency checks performed by this function not only
+ *             ensure that mbedtls_rsa_private() can be called successfully
+ *             on the given context, but that the various parameters are
+ *             mutually consistent with high probability, in the sense that
+ *             mbedtls_rsa_public() and mbedtls_rsa_private() are inverses.
+ *
+ * \warning    This function should catch accidental misconfigurations
+ *             like swapping of parameters, but it cannot establish full
+ *             trust in neither the quality nor the consistency of the key
+ *             material that was used to setup the given RSA context:
+ *             <ul><li>Consistency: Imported parameters that are irrelevant
+ *             for the implementation might be silently dropped. If dropped,
+ *             the current function does not have access to them,
+ *             and therefore cannot check them. See mbedtls_rsa_complete().
+ *             If you want to check the consistency of the entire
+ *             content of an PKCS1-encoded RSA private key, for example, you
+ *             should use mbedtls_rsa_validate_params() before setting
+ *             up the RSA context.
+ *             Additionally, if the implementation performs empirical checks,
+ *             these checks substantiate but do not guarantee consistency.</li>
+ *             <li>Quality: This function is not expected to perform
+ *             extended quality assessments like checking that the prime
+ *             factors are safe. Additionally, it is the responsibility of the
+ *             user to ensure the trustworthiness of the source of his RSA
+ *             parameters, which goes beyond what is effectively checkable
+ *             by the library.</li></ul>
+ *
+ * \param ctx  The RSA context to check.
+ *
+ * \return     \c 0 on success.
+ * \return     An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx );
 
 /**
- * \brief          Do an RSA public key operation
+ * \brief          This function checks a public-private RSA key pair.
  *
- * \param ctx      RSA context
- * \param input    input buffer
- * \param output   output buffer
+ *                 It checks each of the contexts, and makes sure they match.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ * \param pub      The RSA context holding the public key.
+ * \param prv      The RSA context holding the private key.
  *
- * \note           This function does NOT take care of message
- *                 padding. Also, be sure to set input[0] = 0 or ensure that
- *                 input is smaller than N.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
+                                const mbedtls_rsa_context *prv );
+
+/**
+ * \brief          This function performs an RSA public key operation.
+ *
+ * \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 (eg. 128 bytes if RSA-1024 is used).
+ *                 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.
  */
 int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
                 const unsigned char *input,
                 unsigned char *output );
 
 /**
- * \brief          Do an RSA private key operation
+ * \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.
  *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Needed for blinding)
- * \param p_rng    RNG parameter
- * \param input    input buffer
- * \param output   output buffer
+ * \note           Blinding is used if and only if a PRNG is provided.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ * \note           If blinding is used, both the base of exponentation
+ *                 and the exponent are blinded, providing protection
+ *                 against some side-channel attacks.
+ *
+ * \warning        It is deprecated and a security risk to not provide
+ *                 a PRNG here and thereby prevent the use of blinding.
+ *                 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.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  *
- * \note           The input and output buffers must be large
- *                 enough (eg. 128 bytes if RSA-1024 is used).
  */
 int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -237,23 +547,35 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
                  unsigned char *output );
 
 /**
- * \brief          Generic wrapper to perform a PKCS#1 encryption using the
- *                 mode from the context. Add the message padding, then do an
- *                 RSA operation.
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Needed for padding and PKCS#1 v2.1 encoding
- *                               and MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param ilen     contains the plaintext length
- * \param input    buffer holding the data to be encrypted
- * \param output   buffer that will hold the ciphertext
- *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The output buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ * \brief          This function adds the message padding, then performs an RSA
+ *                 operation.
+ *
+ *                 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
+ *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
                        int (*f_rng)(void *, unsigned char *, size_t),
@@ -263,20 +585,32 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
                        unsigned char *output );
 
 /**
- * \brief          Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT)
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Needed for padding and MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param ilen     contains the plaintext length
- * \param input    buffer holding the data to be encrypted
- * \param output   buffer that will hold the ciphertext
- *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ * \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 ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *                 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
+ *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
                                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -286,23 +620,34 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
                                  unsigned char *output );
 
 /**
- * \brief          Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT)
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Needed for padding and PKCS#1 v2.1 encoding
- *                               and MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param label    buffer holding the custom label to use
- * \param label_len contains the label length
- * \param ilen     contains the plaintext length
- * \param input    buffer holding the data to be encrypted
- * \param output   buffer that will hold the ciphertext
- *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The output buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ * \brief            This function performs a PKCS#1 v2.1 OAEP encryption
+ *                   operation (RSAES-OAEP-ENCRYPT).
+ *
+ * \note             The output buffer must be as large as the size
+ *                   of 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
+ *                   implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note             Alternative implementations of RSA need not support
+ *                   mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                   return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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.
+ *
+ * \return           \c 0 on success.
+ * \return           An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
                             int (*f_rng)(void *, unsigned char *, size_t),
@@ -314,30 +659,42 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
                             unsigned char *output );
 
 /**
- * \brief          Generic wrapper to perform a PKCS#1 decryption using the
- *                 mode from the context. Do an RSA operation, then remove
- *                 the message padding
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param olen     will contain the plaintext length
- * \param input    buffer holding the encrypted data
- * \param output   buffer that will hold the plaintext
- * \param output_max_len    maximum length of the output buffer
+ * \brief          This function performs an RSA operation, then removes the
+ *                 message padding.
  *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ *                 It is the generic wrapper for performing a PKCS#1 decryption
+ *                 operation using the \p mode from the context.
  *
  * \note           The output buffer length \c output_max_len should be
- *                 as large as the size ctx->len of ctx->N (eg. 128 bytes
- *                 if RSA-1024 is used) to be able to hold an arbitrary
- *                 decrypted message. If it is not large enough to hold
- *                 the decryption of the particular ciphertext provided, 
- *                 the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *                 as large as the size \p ctx->len of \p ctx->N (for example,
+ *                 128 Bytes if RSA-1024 is used) to be able to hold an
+ *                 arbitrary decrypted message. If it is not large enough to
+ *                 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 ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *                 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
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
                        int (*f_rng)(void *, unsigned char *, size_t),
@@ -348,28 +705,40 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
                        size_t output_max_len );
 
 /**
- * \brief          Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT)
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param olen     will contain the plaintext length
- * \param input    buffer holding the encrypted data
- * \param output   buffer that will hold the plaintext
- * \param output_max_len    maximum length of the output buffer
- *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ * \brief          This function performs a PKCS#1 v1.5 decryption
+ *                 operation (RSAES-PKCS1-v1_5-DECRYPT).
  *
  * \note           The output buffer length \c output_max_len should be
- *                 as large as the size ctx->len of ctx->N (eg. 128 bytes
- *                 if RSA-1024 is used) to be able to hold an arbitrary
- *                 decrypted message. If it is not large enough to hold
- *                 the decryption of the particular ciphertext provided, 
- *                 the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *                 as large as the size \p ctx->len of \p ctx->N, for example,
+ *                 128 Bytes if RSA-1024 is used, to be able to hold an
+ *                 arbitrary decrypted message. If it is not large enough to
+ *                 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 ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *                 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
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
                                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -380,30 +749,42 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
                                  size_t output_max_len );
 
 /**
- * \brief          Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT)
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param label    buffer holding the custom label to use
- * \param label_len contains the label length
- * \param olen     will contain the plaintext length
- * \param input    buffer holding the encrypted data
- * \param output   buffer that will hold the plaintext
- * \param output_max_len    maximum length of the output buffer
- *
- * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The output buffer length \c output_max_len should be
- *                 as large as the size ctx->len of ctx->N (eg. 128 bytes
- *                 if RSA-1024 is used) to be able to hold an arbitrary
- *                 decrypted message. If it is not large enough to hold
- *                 the decryption of the particular ciphertext provided, 
- *                 the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
- *
- * \note           The input buffer must be as large as the size 
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ * \brief            This function performs a PKCS#1 v2.1 OAEP decryption
+ *                   operation (RSAES-OAEP-DECRYPT).
+ *
+ * \note             The output buffer length \c output_max_len should be
+ *                   as large as the size \p ctx->len of \p ctx->N, for
+ *                   example, 128 Bytes if RSA-1024 is used, to be able to
+ *                   hold an arbitrary decrypted message. If it is not
+ *                   large enough to 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
+ *                   implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note             Alternative implementations of RSA need not support
+ *                   mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                   return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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. 
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
                             int (*f_rng)(void *, unsigned char *, size_t),
@@ -416,28 +797,41 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
                             size_t output_max_len );
 
 /**
- * \brief          Generic wrapper to perform a PKCS#1 signature using the
- *                 mode from the context. Do a private RSA operation to sign
- *                 a message digest
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Needed for PKCS#1 v2.1 encoding and for
- *                               MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
- * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
- * \param hash     buffer holding the message digest
- * \param sig      buffer that will hold the ciphertext
- *
- * \return         0 if the signing operation was successful,
- *                 or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The "sig" buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
- *
- * \note           In case of PKCS#1 v2.1 encoding, see comments on
- * \note           \c mbedtls_rsa_rsassa_pss_sign() for details on md_alg and hash_id.
+ * \brief          This function performs a private RSA operation to sign
+ *                 a message digest using PKCS#1.
+ *
+ *                 It is the generic wrapper for performing a PKCS#1
+ *                 signature using the \p 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_sign() for details on
+ *                 \p md_alg and \p hash_id.
+ *
+ * \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
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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.
+ *
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
                     int (*f_rng)(void *, unsigned char *, size_t),
@@ -449,22 +843,33 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
                     unsigned char *sig );
 
 /**
- * \brief          Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN)
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
- * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
- * \param hash     buffer holding the message digest
- * \param sig      buffer that will hold the ciphertext
- *
- * \return         0 if the signing operation was successful,
- *                 or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The "sig" buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ * \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
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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.
+ *
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
                                int (*f_rng)(void *, unsigned char *, size_t),
@@ -476,28 +881,41 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
                                unsigned char *sig );
 
 /**
- * \brief          Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN)
- *
- * \param ctx      RSA context
- * \param f_rng    RNG function (Needed for PKCS#1 v2.1 encoding and for
- *                               MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
- * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
- * \param hash     buffer holding the message digest
- * \param sig      buffer that will hold the ciphertext
- *
- * \return         0 if the signing operation was successful,
- *                 or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The "sig" buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
- *
- * \note           The hash_id in the RSA context is the one used for the
- *                 encoding. md_alg in the function call is the type of hash
- *                 that is encoded. According to RFC 3447 it is advised to
- *                 keep both hashes the same.
+ * \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
+ *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ *                 Specifications</em> it is advised to keep both hashes the
+ *                 same.
+ *
+ * \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
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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.
+ *
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
                          int (*f_rng)(void *, unsigned char *, size_t),
@@ -509,27 +927,40 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
                          unsigned char *sig );
 
 /**
- * \brief          Generic wrapper to perform a PKCS#1 verification using the
- *                 mode from the context. Do a public RSA operation and check
- *                 the message digest
- *
- * \param ctx      points to an RSA public key
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
- * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
- * \param hash     buffer holding the message digest
- * \param sig      buffer holding the ciphertext
- *
- * \return         0 if the verify operation was successful,
- *                 or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The "sig" buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
- *
- * \note           In case of PKCS#1 v2.1 encoding, see comments on
- *                 \c mbedtls_rsa_rsassa_pss_verify() about md_alg and hash_id.
+ * \brief          This function performs a public RSA operation and checks
+ *                 the message digest.
+ *
+ *                 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.
+ *
+ * \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
+ *                 set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
                       int (*f_rng)(void *, unsigned char *, size_t),
@@ -541,22 +972,33 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
                       const unsigned char *sig );
 
 /**
- * \brief          Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY)
- *
- * \param ctx      points to an RSA public key
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
- * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
- * \param hash     buffer holding the message digest
- * \param sig      buffer holding the ciphertext
- *
- * \return         0 if the verify operation was successful,
- *                 or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The "sig" buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ * \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
+ *                 set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
                                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -568,29 +1010,44 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
                                  const unsigned char *sig );
 
 /**
- * \brief          Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY)
- *                 (This is the "simple" version.)
- *
- * \param ctx      points to an RSA public key
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
- * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
- * \param hash     buffer holding the message digest
- * \param sig      buffer holding the ciphertext
- *
- * \return         0 if the verify operation was successful,
- *                 or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The "sig" buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
- *
- * \note           The hash_id in the RSA context is the one used for the
- *                 verification. md_alg in the function call is the type of
- *                 hash that is verified. According to RFC 3447 it is advised to
- *                 keep both hashes the same. If hash_id in the RSA context is
- *                 unset, the md_alg from the function call is used.
+ * \brief          This function performs a PKCS#1 v2.1 PSS verification
+ *                 operation (RSASSA-PSS-VERIFY).
+ *
+ *                 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
+ *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ *                 Specifications</em> it is advised to keep both hashes the
+ *                 same. If \p hash_id in the RSA context is unset,
+ *                 the \p md_alg from the function call 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
+ *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \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 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.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
                            int (*f_rng)(void *, unsigned char *, size_t),
@@ -602,28 +1059,33 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
                            const unsigned char *sig );
 
 /**
- * \brief          Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY)
- *                 (This is the version with "full" options.)
- *
- * \param ctx      points to an RSA public key
- * \param f_rng    RNG function (Only needed for MBEDTLS_RSA_PRIVATE)
- * \param p_rng    RNG parameter
- * \param mode     MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE
- * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
- * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
- * \param hash     buffer holding the message digest
- * \param mgf1_hash_id message digest used for mask generation
- * \param expected_salt_len Length of the salt used in padding, use
- *                 MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length
- * \param sig      buffer holding the ciphertext
- *
- * \return         0 if the verify operation was successful,
- *                 or an MBEDTLS_ERR_RSA_XXX error code
- *
- * \note           The "sig" buffer must be as large as the size
- *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
- *
- * \note           The hash_id in the RSA context is ignored.
+ * \brief          This function performs a PKCS#1 v2.1 PSS verification
+ *                 operation (RSASSA-PSS-VERIFY).
+ *
+ *                 The hash function for the MGF mask generating function
+ *                 is that specified in \p mgf1_hash_id.
+ *
+ * \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 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 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.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
                                int (*f_rng)(void *, unsigned char *, size_t),
@@ -637,27 +1099,28 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
                                const unsigned char *sig );
 
 /**
- * \brief          Copy the components of an RSA context
+ * \brief          This function copies the components of an RSA context.
  *
- * \param dst      Destination context
- * \param src      Source context
+ * \param dst      The destination context.
+ * \param src      The source context.
  *
- * \return         0 on success,
- *                 MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure.
  */
 int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src );
 
 /**
- * \brief          Free the components of an RSA key
+ * \brief          This function frees the components of an RSA key.
  *
- * \param ctx      RSA Context to free
+ * \param ctx      The RSA Context to free.
  */
 void mbedtls_rsa_free( mbedtls_rsa_context *ctx );
 
 /**
- * \brief          Checkup routine
+ * \brief          The RSA checkup routine.
  *
- * \return         0 if successful, or 1 if the test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_rsa_self_test( int verbose );
 
@@ -665,6 +1128,4 @@ int mbedtls_rsa_self_test( int verbose );
 }
 #endif
 
-#endif /* MBEDTLS_RSA_C */
-
 #endif /* rsa.h */
diff --git a/crypto/mbedtls/include/mbedtls/rsa_internal.h b/crypto/mbedtls/include/mbedtls/rsa_internal.h
new file mode 100644
index 000000000..53abd3c5b
--- /dev/null
+++ b/crypto/mbedtls/include/mbedtls/rsa_internal.h
@@ -0,0 +1,226 @@
+/**
+ * \file rsa_internal.h
+ *
+ * \brief Context-independent RSA helper functions
+ *
+ *  This module declares some RSA-related helper functions useful when
+ *  implementing the RSA interface. These functions are provided in a separate
+ *  compilation unit in order to make it easy for designers of alternative RSA
+ *  implementations to use them in their own code, as it is conceived that the
+ *  functionality they provide will be necessary for most complete
+ *  implementations.
+ *
+ *  End-users of Mbed TLS who are not providing their own alternative RSA
+ *  implementations should not use these functions directly, and should instead
+ *  use only the functions declared in rsa.h.
+ *
+ *  The interface provided by this module will be maintained through LTS (Long
+ *  Term Support) branches of Mbed TLS, but may otherwise be subject to change,
+ *  and must be considered an internal interface of the library.
+ *
+ *  There are two classes of helper functions:
+ *
+ *  (1) Parameter-generating helpers. These are:
+ *      - mbedtls_rsa_deduce_primes
+ *      - mbedtls_rsa_deduce_private_exponent
+ *      - mbedtls_rsa_deduce_crt
+ *       Each of these functions takes a set of core RSA parameters and
+ *       generates some other, or CRT related parameters.
+ *
+ *  (2) Parameter-checking helpers. These are:
+ *      - mbedtls_rsa_validate_params
+ *      - mbedtls_rsa_validate_crt
+ *      They take a set of core or CRT related RSA parameters and check their
+ *      validity.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ */
+
+#ifndef MBEDTLS_RSA_INTERNAL_H
+#define MBEDTLS_RSA_INTERNAL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \brief          Compute RSA prime moduli P, Q from public modulus N=PQ
+ *                 and a pair of private and public key.
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param N        RSA modulus N = PQ, with P, Q to be found
+ * \param E        RSA public exponent
+ * \param D        RSA private exponent
+ * \param P        Pointer to MPI holding first prime factor of N on success
+ * \param Q        Pointer to MPI holding second prime factor of N on success
+ *
+ * \return
+ *                 - 0 if successful. In this case, P and Q constitute a
+ *                   factorization of N.
+ *                 - A non-zero error code otherwise.
+ *
+ * \note           It is neither checked that P, Q are prime nor that
+ *                 D, E are modular inverses wrt. P-1 and Q-1. For that,
+ *                 use the helper function \c mbedtls_rsa_validate_params.
+ *
+ */
+int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, mbedtls_mpi const *E,
+                               mbedtls_mpi const *D,
+                               mbedtls_mpi *P, mbedtls_mpi *Q );
+
+/**
+ * \brief          Compute RSA private exponent from
+ *                 prime moduli and public key.
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param P        First prime factor of RSA modulus
+ * \param Q        Second prime factor of RSA modulus
+ * \param E        RSA public exponent
+ * \param D        Pointer to MPI holding the private exponent on success.
+ *
+ * \return
+ *                 - 0 if successful. In this case, D is set to a simultaneous
+ *                   modular inverse of E modulo both P-1 and Q-1.
+ *                 - A non-zero error code otherwise.
+ *
+ * \note           This function does not check whether P and Q are primes.
+ *
+ */
+int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P,
+                                         mbedtls_mpi const *Q,
+                                         mbedtls_mpi const *E,
+                                         mbedtls_mpi *D );
+
+
+/**
+ * \brief          Generate RSA-CRT parameters
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param P        First prime factor of N
+ * \param Q        Second prime factor of N
+ * \param D        RSA private exponent
+ * \param DP       Output variable for D modulo P-1
+ * \param DQ       Output variable for D modulo Q-1
+ * \param QP       Output variable for the modular inverse of Q modulo P.
+ *
+ * \return         0 on success, non-zero error code otherwise.
+ *
+ * \note           This function does not check whether P, Q are
+ *                 prime and whether D is a valid private exponent.
+ *
+ */
+int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                            const mbedtls_mpi *D, mbedtls_mpi *DP,
+                            mbedtls_mpi *DQ, mbedtls_mpi *QP );
+
+
+/**
+ * \brief          Check validity of core RSA parameters
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param N        RSA modulus N = PQ
+ * \param P        First prime factor of N
+ * \param Q        Second prime factor of N
+ * \param D        RSA private exponent
+ * \param E        RSA public exponent
+ * \param f_rng    PRNG to be used for primality check, or NULL
+ * \param p_rng    PRNG context for f_rng, or NULL
+ *
+ * \return
+ *                 - 0 if the following conditions are satisfied
+ *                   if all relevant parameters are provided:
+ *                    - P prime if f_rng != NULL (%)
+ *                    - Q prime if f_rng != NULL (%)
+ *                    - 1 < N = P * Q
+ *                    - 1 < D, E < N
+ *                    - D and E are modular inverses modulo P-1 and Q-1
+ *                   (%) This is only done if MBEDTLS_GENPRIME is defined.
+ *                 - A non-zero error code otherwise.
+ *
+ * \note           The function can be used with a restricted set of arguments
+ *                 to perform specific checks only. E.g., calling it with
+ *                 (-,P,-,-,-) and a PRNG amounts to a primality check for P.
+ */
+int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
+                                 const mbedtls_mpi *Q, const mbedtls_mpi *D,
+                                 const mbedtls_mpi *E,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng );
+
+/**
+ * \brief          Check validity of RSA CRT parameters
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param P        First prime factor of RSA modulus
+ * \param Q        Second prime factor of RSA modulus
+ * \param D        RSA private exponent
+ * \param DP       MPI to check for D modulo P-1
+ * \param DQ       MPI to check for D modulo P-1
+ * \param QP       MPI to check for the modular inverse of Q modulo P.
+ *
+ * \return
+ *                 - 0 if the following conditions are satisfied:
+ *                    - D = DP mod P-1 if P, D, DP != NULL
+ *                    - Q = DQ mod P-1 if P, D, DQ != NULL
+ *                    - QP = Q^-1 mod P if P, Q, QP != NULL
+ *                 - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed,
+ *                   potentially including \c MBEDTLS_ERR_MPI_XXX if some
+ *                   MPI calculations failed.
+ *                 - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient
+ *                   data was provided to check DP, DQ or QP.
+ *
+ * \note           The function can be used with a restricted set of arguments
+ *                 to perform specific checks only. E.g., calling it with the
+ *                 parameters (P, -, D, DP, -, -) will check DP = D mod P-1.
+ */
+int mbedtls_rsa_validate_crt( const mbedtls_mpi *P,  const mbedtls_mpi *Q,
+                              const mbedtls_mpi *D,  const mbedtls_mpi *DP,
+                              const mbedtls_mpi *DQ, const mbedtls_mpi *QP );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa_internal.h */
diff --git a/crypto/mbedtls/include/mbedtls/sha1.h b/crypto/mbedtls/include/mbedtls/sha1.h
index 7a67c6c1f..8f805fb42 100644
--- a/crypto/mbedtls/include/mbedtls/sha1.h
+++ b/crypto/mbedtls/include/mbedtls/sha1.h
@@ -1,9 +1,17 @@
 /**
  * \file sha1.h
  *
- * \brief SHA-1 cryptographic hash function
+ * \brief This file contains SHA-1 definitions and functions.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in 
+ * <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. We recommend considering stronger message
+ *            digests instead.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,7 +26,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
 #ifndef MBEDTLS_SHA1_H
 #define MBEDTLS_SHA1_H
@@ -32,100 +40,280 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#if !defined(MBEDTLS_SHA1_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA1_ALT)
+// Regular implementation
+//
+
 /**
- * \brief          SHA-1 context structure
+ * \brief          The SHA-1 context structure.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  */
 typedef struct
 {
-    uint32_t total[2];          /*!< number of bytes processed  */
-    uint32_t state[5];          /*!< intermediate digest state  */
-    unsigned char buffer[64];   /*!< data block being processed */
+    uint32_t total[2];          /*!< The number of Bytes processed.  */
+    uint32_t state[5];          /*!< The intermediate digest state.  */
+    unsigned char buffer[64];   /*!< The data block being processed. */
 }
 mbedtls_sha1_context;
 
+#else  /* MBEDTLS_SHA1_ALT */
+#include "sha1_alt.h"
+#endif /* MBEDTLS_SHA1_ALT */
+
 /**
- * \brief          Initialize SHA-1 context
+ * \brief          This function initializes a SHA-1 context.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to initialize.
  *
- * \param ctx      SHA-1 context to be initialized
  */
 void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
 
 /**
- * \brief          Clear SHA-1 context
+ * \brief          This function clears a SHA-1 context.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to clear.
  *
- * \param ctx      SHA-1 context to be cleared
  */
 void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
 
 /**
- * \brief          Clone (the state of) a SHA-1 context
+ * \brief          This function clones the state of a SHA-1 context.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 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 destination context
- * \param src      The context to be cloned
  */
 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
                          const mbedtls_sha1_context *src );
 
 /**
- * \brief          SHA-1 context setup
+ * \brief          This function starts a SHA-1 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to initialize.
+ *
+ * \return         \c 0 on success.
  *
- * \param ctx      context to be initialized
  */
-void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
+int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
 
 /**
- * \brief          SHA-1 process buffer
+ * \brief          This function feeds an input buffer into an ongoing SHA-1
+ *                 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
  *
- * \param ctx      SHA-1 context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
+ * \param ctx      The SHA-1 context.
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ *
+ * \return         \c 0 on success.
  */
-void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );
+int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
+                             const unsigned char *input,
+                             size_t ilen );
 
 /**
- * \brief          SHA-1 final digest
+ * \brief          This function finishes the SHA-1 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 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      SHA-1 context
- * \param output   SHA-1 checksum result
+ * \return         \c 0 on success.
  */
-void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] );
+int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
+                             unsigned char output[20] );
 
-/* Internal use */
-void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
+/**
+ * \brief          SHA-1 process data block (internal use only).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context.
+ * \param data     The data block being processed.
+ *
+ * \return         \c 0 on success.
+ *
+ */
+int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
+                                   const unsigned char data[64] );
 
-#ifdef __cplusplus
-}
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
+/**
+ * \brief          This function starts a SHA-1 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_sha1_starts_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context to initialize.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
 
-#else  /* MBEDTLS_SHA1_ALT */
-#include "sha1_alt.h"
-#endif /* MBEDTLS_SHA1_ALT */
+/**
+ * \brief          This function feeds an input buffer into an ongoing SHA-1
+ *                 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_sha1_update_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context.
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
+                                             const unsigned char *input,
+                                             size_t ilen );
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief          This function finishes the SHA-1 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_sha1_finish_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context.
+ * \param output   The SHA-1 checksum result.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
+                                             unsigned char output[20] );
+
+/**
+ * \brief          SHA-1 process data block (internal use only).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_internal_sha1_process() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context.
+ * \param data     The data block being processed.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
+                                              const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          This function calculates the SHA-1 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-1 result is calculated as
+ *                 output = SHA-1(input buffer).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ * \param output   The SHA-1 checksum result.
+ *
+ * \return         \c 0 on success.
+ *
+ */
+int mbedtls_sha1_ret( const unsigned char *input,
+                      size_t ilen,
+                      unsigned char output[20] );
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
 /**
- * \brief          Output = SHA-1( input buffer )
+ * \brief          This function calculates the SHA-1 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-1 result is calculated as
+ *                 output = SHA-1(input buffer).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \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.
  *
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   SHA-1 checksum result
  */
-void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] );
+MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input,
+                                      size_t ilen,
+                                      unsigned char output[20] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
- * \brief          Checkup routine
+ * \brief          The SHA-1 checkup routine.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  *
- * \return         0 if successful, or 1 if the test failed
  */
 int mbedtls_sha1_self_test( int verbose );
 
diff --git a/crypto/mbedtls/include/mbedtls/sha256.h b/crypto/mbedtls/include/mbedtls/sha256.h
index f8041adf0..adf31a82e 100644
--- a/crypto/mbedtls/include/mbedtls/sha256.h
+++ b/crypto/mbedtls/include/mbedtls/sha256.h
@@ -1,9 +1,13 @@
 /**
  * \file sha256.h
  *
- * \brief SHA-224 and SHA-256 cryptographic hash function
+ * \brief This file contains SHA-224 and SHA-256 definitions and functions.
  *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,7 +22,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
 #ifndef MBEDTLS_SHA256_H
 #define MBEDTLS_SHA256_H
@@ -32,105 +36,232 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#if !defined(MBEDTLS_SHA256_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA256_ALT)
+// Regular implementation
+//
+
 /**
- * \brief          SHA-256 context structure
+ * \brief          The SHA-256 context structure.
+ *
+ *                 The structure is used both for SHA-256 and for SHA-224
+ *                 checksum calculations. The choice between these two is
+ *                 made in the call to mbedtls_sha256_starts_ret().
  */
 typedef struct
 {
-    uint32_t total[2];          /*!< number of bytes processed  */
-    uint32_t state[8];          /*!< intermediate digest state  */
-    unsigned char buffer[64];   /*!< data block being processed */
-    int is224;                  /*!< 0 => SHA-256, else SHA-224 */
+    uint32_t total[2];          /*!< The number of Bytes processed.  */
+    uint32_t state[8];          /*!< The intermediate digest state.  */
+    unsigned char buffer[64];   /*!< The data block being processed. */
+    int is224;                  /*!< Determines which function to use:
+                                     0: Use SHA-256, or 1: Use SHA-224. */
 }
 mbedtls_sha256_context;
 
+#else  /* MBEDTLS_SHA256_ALT */
+#include "sha256_alt.h"
+#endif /* MBEDTLS_SHA256_ALT */
+
 /**
- * \brief          Initialize SHA-256 context
+ * \brief          This function initializes a SHA-256 context.
  *
- * \param ctx      SHA-256 context to be initialized
+ * \param ctx      The SHA-256 context to initialize.
  */
 void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
 
 /**
- * \brief          Clear SHA-256 context
+ * \brief          This function clears a SHA-256 context.
  *
- * \param ctx      SHA-256 context to be cleared
+ * \param ctx      The SHA-256 context to clear.
  */
 void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
 
 /**
- * \brief          Clone (the state of) a SHA-256 context
+ * \brief          This function clones the state of a SHA-256 context.
  *
- * \param dst      The destination context
- * \param src      The context to be cloned
+ * \param dst      The destination context.
+ * \param src      The context to clone.
  */
 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
                            const mbedtls_sha256_context *src );
 
 /**
- * \brief          SHA-256 context setup
+ * \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      context to be initialized
- * \param is224    0 = use SHA256, 1 = use SHA224
+ * \return         \c 0 on success.
  */
-void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );
+int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 );
 
 /**
- * \brief          SHA-256 process buffer
+ * \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      SHA-256 context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
+ * \return         \c 0 on success.
  */
-void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
-                    size_t ilen );
+int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen );
 
 /**
- * \brief          SHA-256 final digest
+ * \brief          This function finishes the SHA-256 operation, and writes
+ *                 the result to the output buffer.
  *
- * \param ctx      SHA-256 context
- * \param output   SHA-224/256 checksum result
+ * \param ctx      The SHA-256 context.
+ * \param output   The SHA-224 or SHA-256 checksum result.
+ *
+ * \return         \c 0 on success.
  */
-void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] );
+int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
+                               unsigned char output[32] );
 
-/* Internal use */
-void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
+/**
+ * \brief          This function processes a single data block within
+ *                 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.
+ *
+ * \return         \c 0 on success.
+ */
+int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
+                                     const unsigned char data[64] );
 
-#ifdef __cplusplus
-}
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
+/**
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
+                                               int is224 );
 
-#else  /* MBEDTLS_SHA256_ALT */
-#include "sha256_alt.h"
-#endif /* MBEDTLS_SHA256_ALT */
+/**
+ * \brief          This function feeds an input buffer into an ongoing
+ *                 SHA-256 checksum calculation.
+ *
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
+                                               const unsigned char *input,
+                                               size_t ilen );
 
-#ifdef __cplusplus
-extern "C" {
+/**
+ * \brief          This function finishes the SHA-256 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
+                                               unsigned char output[32] );
+
+/**
+ * \brief          This function processes a single data block within
+ *                 the ongoing SHA-256 computation. This function is for
+ *                 internal use only.
+ *
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
+                                                const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          This function calculates the SHA-224 or SHA-256
+ *                 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 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.
+ */
+int mbedtls_sha256_ret( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[32],
+                        int is224 );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
 
 /**
- * \brief          Output = SHA-256( input buffer )
+ * \brief          This function calculates the SHA-224 or SHA-256 checksum
+ *                 of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
  *
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   SHA-224/256 checksum result
- * \param is224    0 = use SHA256, 1 = use SHA224
+ *                 The SHA-256 result is calculated as
+ *                 output = SHA-256(input buffer).
+ *
+ * \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.
  */
-void mbedtls_sha256( const unsigned char *input, size_t ilen,
-           unsigned char output[32], int is224 );
+MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input,
+                                        size_t ilen,
+                                        unsigned char output[32],
+                                        int is224 );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
- * \brief          Checkup routine
+ * \brief          The SHA-224 and SHA-256 checkup routine.
  *
- * \return         0 if successful, or 1 if the test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_sha256_self_test( int verbose );
 
diff --git a/crypto/mbedtls/include/mbedtls/sha512.h b/crypto/mbedtls/include/mbedtls/sha512.h
index 627694f42..5bb83f43b 100644
--- a/crypto/mbedtls/include/mbedtls/sha512.h
+++ b/crypto/mbedtls/include/mbedtls/sha512.h
@@ -1,9 +1,12 @@
 /**
  * \file sha512.h
+ * \brief This file contains SHA-384 and SHA-512 definitions and functions.
  *
- * \brief SHA-384 and SHA-512 cryptographic hash function
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,7 +21,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
 #ifndef MBEDTLS_SHA512_H
 #define MBEDTLS_SHA512_H
@@ -32,107 +35,233 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#if !defined(MBEDTLS_SHA512_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA512_ALT)
+// Regular implementation
+//
+
 /**
- * \brief          SHA-512 context structure
+ * \brief          The SHA-512 context structure.
+ *
+ *                 The structure is used both for SHA-384 and for SHA-512
+ *                 checksum calculations. The choice between these two is
+ *                 made in the call to mbedtls_sha512_starts_ret().
  */
 typedef struct
 {
-    uint64_t total[2];          /*!< number of bytes processed  */
-    uint64_t state[8];          /*!< intermediate digest state  */
-    unsigned char buffer[128];  /*!< data block being processed */
-    int is384;                  /*!< 0 => SHA-512, else SHA-384 */
+    uint64_t total[2];          /*!< The number of Bytes processed. */
+    uint64_t state[8];          /*!< The intermediate digest state. */
+    unsigned char buffer[128];  /*!< The data block being processed. */
+    int is384;                  /*!< Determines which function to use:
+                                     0: Use SHA-512, or 1: Use SHA-384. */
 }
 mbedtls_sha512_context;
 
+#else  /* MBEDTLS_SHA512_ALT */
+#include "sha512_alt.h"
+#endif /* MBEDTLS_SHA512_ALT */
+
 /**
- * \brief          Initialize SHA-512 context
+ * \brief          This function initializes a SHA-512 context.
  *
- * \param ctx      SHA-512 context to be initialized
+ * \param ctx      The SHA-512 context to initialize.
  */
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
 
 /**
- * \brief          Clear SHA-512 context
+ * \brief          This function clears a SHA-512 context.
  *
- * \param ctx      SHA-512 context to be cleared
+ * \param ctx      The SHA-512 context to clear.
  */
 void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
 
 /**
- * \brief          Clone (the state of) a SHA-512 context
+ * \brief          This function clones the state of a SHA-512 context.
  *
- * \param dst      The destination context
- * \param src      The context to be cloned
+ * \param dst      The destination context.
+ * \param src      The context to clone.
  */
 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
                            const mbedtls_sha512_context *src );
 
 /**
- * \brief          SHA-512 context setup
+ * \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      context to be initialized
- * \param is384    0 = use SHA512, 1 = use SHA384
+ * \return         \c 0 on success.
  */
-void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 );
+int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 );
 
 /**
- * \brief          SHA-512 process buffer
+ * \brief          This function feeds an input buffer into an ongoing
+ *                 SHA-512 checksum calculation.
  *
- * \param ctx      SHA-512 context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
+ * \param ctx      The SHA-512 context.
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ *
+ * \return         \c 0 on success.
  */
-void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
+int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
+                    const unsigned char *input,
                     size_t ilen );
 
 /**
- * \brief          SHA-512 final digest
+ * \brief          This function finishes the SHA-512 operation, and writes
+ *                 the result to the output buffer. This function is for
+ *                 internal use only.
+ *
+ * \param ctx      The SHA-512 context.
+ * \param output   The SHA-384 or SHA-512 checksum result.
  *
- * \param ctx      SHA-512 context
- * \param output   SHA-384/512 checksum result
+ * \return         \c 0 on success.
  */
-void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] );
+int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
+                               unsigned char output[64] );
 
-#ifdef __cplusplus
-}
+/**
+ * \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.
+ *
+ * \return         \c 0 on success.
+ */
+int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
+                                     const unsigned char data[128] );
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
 #endif
+/**
+ * \brief          This function starts a SHA-384 or SHA-512 checksum
+ *                 calculation.
+ *
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
+                                               int is384 );
 
-#else  /* MBEDTLS_SHA512_ALT */
-#include "sha512_alt.h"
-#endif /* MBEDTLS_SHA512_ALT */
+/**
+ * \brief          This function feeds an input buffer into an ongoing
+ *                 SHA-512 checksum calculation.
+ *
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
+                                               const unsigned char *input,
+                                               size_t ilen );
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief          This function finishes the SHA-512 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
+                                               unsigned char output[64] );
+
+/**
+ * \brief          This function processes a single data block within
+ *                 the ongoing SHA-512 computation. This function is for
+ *                 internal use only.
+ *
+ * \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.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_process(
+                                            mbedtls_sha512_context *ctx,
+                                            const unsigned char data[128] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
- * \brief          Output = SHA-512( input buffer )
+ * \brief          This function calculates the SHA-512 or SHA-384
+ *                 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
  *
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   SHA-384/512 checksum result
- * \param is384    0 = use SHA512, 1 = use SHA384
+ *                 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 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.
+ *
+ * \return         \c 0 on success.
  */
-void mbedtls_sha512( const unsigned char *input, size_t ilen,
-             unsigned char output[64], int is384 );
+int mbedtls_sha512_ret( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[64],
+                        int is384 );
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
 /**
- * \brief          Checkup routine
+ * \brief          This function calculates the SHA-512 or SHA-384
+ *                 checksum of a buffer.
  *
- * \return         0 if successful, or 1 if the test failed
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-512 result is calculated as
+ *                 output = SHA-512(input buffer).
+ *
+ * \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.
  */
-int mbedtls_sha512_self_test( int verbose );
+MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input,
+                                        size_t ilen,
+                                        unsigned char output[64],
+                                        int is384 );
 
-/* Internal use */
-void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+ /**
+ * \brief          The SHA-384 or SHA-512 checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_sha512_self_test( int verbose );
 
 #ifdef __cplusplus
 }
diff --git a/crypto/mbedtls/include/mbedtls/ssl.h b/crypto/mbedtls/include/mbedtls/ssl.h
index cc0007006..bb9c02dbf 100644
--- a/crypto/mbedtls/include/mbedtls/ssl.h
+++ b/crypto/mbedtls/include/mbedtls/ssl.h
@@ -2,7 +2,8 @@
  * \file ssl.h
  *
  * \brief SSL/TLS functions.
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -48,6 +49,15 @@
 #endif
 
 #if defined(MBEDTLS_ZLIB_SUPPORT)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library"
+#endif
+
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set"
+#endif
+
 #include "zlib.h"
 #endif
 
@@ -102,13 +112,14 @@
 #define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED             -0x6A80  /**< DTLS client must retry for hello verification */
 #define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL                  -0x6A00  /**< A buffer is too small to receive or write a message */
 #define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE             -0x6980  /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */
-#define MBEDTLS_ERR_SSL_WANT_READ                         -0x6900  /**< Connection requires a read call. */
+#define MBEDTLS_ERR_SSL_WANT_READ                         -0x6900  /**< No data of requested type currently available on underlying transport. */
 #define MBEDTLS_ERR_SSL_WANT_WRITE                        -0x6880  /**< Connection requires a write call. */
 #define MBEDTLS_ERR_SSL_TIMEOUT                           -0x6800  /**< The operation timed out. */
 #define MBEDTLS_ERR_SSL_CLIENT_RECONNECT                  -0x6780  /**< The client initiated a reconnect from the same port. */
 #define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD                 -0x6700  /**< Record header looks valid but is not expected. */
 #define MBEDTLS_ERR_SSL_NON_FATAL                         -0x6680  /**< The alert message received indicates a non-fatal error. */
 #define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH               -0x6600  /**< Couldn't set the hash for verifying CertificateVerify */
+#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING               -0x6580  /**< Internal-only message signaling that further message-processing should be done */
 
 /*
  * Various constants
@@ -672,10 +683,18 @@ struct mbedtls_ssl_config
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    unsigned char *psk;             /*!< pre-shared key                     */
-    size_t         psk_len;         /*!< length of the pre-shared key       */
-    unsigned char *psk_identity;    /*!< identity for PSK negotiation       */
-    size_t         psk_identity_len;/*!< length of identity                 */
+    unsigned char *psk;             /*!< pre-shared key. This field should
+                                         only be set via
+                                         mbedtls_ssl_conf_psk() */
+    size_t         psk_len;         /*!< length of the pre-shared key. This
+                                         field should only be set via
+                                         mbedtls_ssl_conf_psk() */
+    unsigned char *psk_identity;    /*!< identity for PSK negotiation. This
+                                         field should only be set via
+                                         mbedtls_ssl_conf_psk() */
+    size_t         psk_identity_len;/*!< length of identity. This field should
+                                         only be set via
+                                         mbedtls_ssl_conf_psk() */
 #endif
 
 #if defined(MBEDTLS_SSL_ALPN)
@@ -970,8 +989,13 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl );
  * \note           No copy of the configuration context is made, it can be
  *                 shared by many mbedtls_ssl_context structures.
  *
- * \warning        Modifying the conf structure after it has been used in this
- *                 function is unsupported!
+ * \warning        The conf structure will be accessed during the session.
+ *                 It must not be modified or freed as long as the session
+ *                 is active.
+ *
+ * \warning        This function must be called exactly once per context.
+ *                 Calling mbedtls_ssl_setup again is not supported, even
+ *                 if no session is active.
  *
  * \param ssl      SSL context
  * \param conf     SSL configuration to use
@@ -1586,6 +1610,10 @@ void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
 /**
  * \brief          Set the data required to verify peer certificate
  *
+ * \note           See \c mbedtls_x509_crt_verify() for notes regarding the
+ *                 parameters ca_chain (maps to trust_ca for that function)
+ *                 and ca_crl.
+ *
  * \param conf     SSL configuration
  * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs)
  * \param ca_crl   trusted CA CRLs
@@ -1699,18 +1727,50 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
 /**
  * \brief          Set the Diffie-Hellman public P and G values,
  *                 read as hexadecimal strings (server-side only)
- *                 (Default: MBEDTLS_DHM_RFC5114_MODP_2048_[PG])
+ *                 (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG])
  *
  * \param conf     SSL configuration
  * \param dhm_P    Diffie-Hellman-Merkle modulus
  * \param dhm_G    Diffie-Hellman-Merkle generator
  *
+ * \deprecated     Superseded by \c mbedtls_ssl_conf_dh_param_bin.
+ *
+ * \return         0 if successful
+ */
+MBEDTLS_DEPRECATED int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf,
+                                                  const char *dhm_P,
+                                                  const char *dhm_G );
+
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Set the Diffie-Hellman public P and G values
+ *                 from big-endian binary presentations.
+ *                 (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN)
+ *
+ * \param conf     SSL configuration
+ * \param dhm_P    Diffie-Hellman-Merkle modulus in big-endian binary form
+ * \param P_len    Length of DHM modulus
+ * \param dhm_G    Diffie-Hellman-Merkle generator in big-endian binary form
+ * \param G_len    Length of DHM generator
+ *
  * \return         0 if successful
  */
-int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G );
+int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
+                                   const unsigned char *dhm_P, size_t P_len,
+                                   const unsigned char *dhm_G,  size_t G_len );
 
 /**
  * \brief          Set the Diffie-Hellman public P and G values,
@@ -1794,15 +1854,22 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 /**
- * \brief          Set the hostname to check against the received server
- *                 certificate. It sets the ServerName TLS extension too,
- *                 if the extension is enabled.
- *                 (client-side only)
+ * \brief          Set or reset the hostname to check against the received 
+ *                 server certificate. It sets the ServerName TLS extension, 
+ *                 too, if that extension is enabled. (client-side only)
  *
  * \param ssl      SSL context
- * \param hostname the server hostname
+ * \param hostname the server hostname, may be NULL to clear hostname
+ 
+ * \note           Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN.
  *
- * \return         0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ * \return         0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on 
+ *                 allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on 
+ *                 too long input hostname.
+ *
+ *                 Hostname set to the one provided on success (cleared
+ *                 when NULL). On allocation failure hostname is cleared. 
+ *                 On too long input failure, old hostname is unchanged.
  */
 int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname );
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
@@ -2235,11 +2302,59 @@ void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
 
 /**
- * \brief          Return the number of data bytes available to read
+ * \brief          Check if there is data already read from the
+ *                 underlying transport but not yet processed.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         0 if nothing's pending, 1 otherwise.
+ *
+ * \note           This is different in purpose and behaviour from
+ *                 \c mbedtls_ssl_get_bytes_avail in that it considers
+ *                 any kind of unprocessed data, not only unread
+ *                 application data. If \c mbedtls_ssl_get_bytes
+ *                 returns a non-zero value, this function will
+ *                 also signal pending data, but the converse does
+ *                 not hold. For example, in DTLS there might be
+ *                 further records waiting to be processed from
+ *                 the current underlying transport's datagram.
+ *
+ * \note           If this function returns 1 (data pending), this
+ *                 does not imply that a subsequent call to
+ *                 \c mbedtls_ssl_read will provide any data;
+ *                 e.g., the unprocessed data might turn out
+ *                 to be an alert or a handshake message.
+ *
+ * \note           This function is useful in the following situation:
+ *                 If the SSL/TLS module successfully returns from an
+ *                 operation - e.g. a handshake or an application record
+ *                 read - and you're awaiting incoming data next, you
+ *                 must not immediately idle on the underlying transport
+ *                 to have data ready, but you need to check the value
+ *                 of this function first. The reason is that the desired
+ *                 data might already be read but not yet processed.
+ *                 If, in contrast, a previous call to the SSL/TLS module
+ *                 returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary
+ *                 to call this function, as the latter error code entails
+ *                 that all internal data has been processed.
+ *
+ */
+int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Return the number of application data bytes
+ *                 remaining to be read from the current record.
  *
  * \param ssl      SSL context
  *
- * \return         how many bytes are available in the read buffer
+ * \return         How many bytes are available in the application
+ *                 data record read buffer.
+ *
+ * \note           When working over a datagram transport, this is
+ *                 useful to detect the current datagram's boundary
+ *                 in case \c mbedtls_ssl_read has written the maximal
+ *                 amount of data fitting into the input buffer.
+ *
  */
 size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl );
 
@@ -2354,11 +2469,25 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session
  *                 MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED (see below), or
  *                 a specific SSL error code.
  *
+ *                 If this function returns MBEDTLS_ERR_SSL_WANT_READ, the
+ *                 handshake is unfinished and no further data is available
+ *                 from the underlying transport. In this case, you must call
+ *                 the function again at some later stage.
+ *
+ * \note           Remarks regarding event-driven DTLS:
+ *                 If the function returns MBEDTLS_ERR_SSL_WANT_READ, no datagram
+ *                 from the underlying transport layer is currently being processed,
+ *                 and it is safe to idle until the timer or the underlying transport
+ *                 signal a new event. This is not true for a successful handshake,
+ *                 in which case the datagram of the underlying transport that is
+ *                 currently being processed might or might not contain further
+ *                 DTLS records.
+ *
  * \note           If this function returns something other than 0 or
- *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
- *                 becomes unusable, and you should either free it or call
- *                 \c mbedtls_ssl_session_reset() on it before re-using it for
- *                 a new connection; the current connection must be closed.
+ *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
  *
  * \note           If DTLS is in use, then you may choose to handle
  *                 MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging
@@ -2375,10 +2504,10 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
  *                 call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER.
  *
  * \note           If this function returns something other than 0 or
- *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
- *                 becomes unusable, and you should either free it or call
- *                 \c mbedtls_ssl_session_reset() on it before re-using it for
- *                 a new connection; the current connection must be closed.
+ *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
  *
  * \param ssl      SSL context
  *
@@ -2402,10 +2531,10 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl );
  *                 value.
  *
  * \note           If this function returns something other than 0 or
- *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
- *                 becomes unusable, and you should either free it or call
- *                 \c mbedtls_ssl_session_reset() on it before re-using it for
- *                 a new connection; the current connection must be closed.
+ *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
  */
 int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
@@ -2417,20 +2546,20 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
  * \param buf      buffer that will hold the data
  * \param len      maximum number of bytes to read
  *
- * \return         the number of bytes read, or
- *                 0 for EOF, or
- *                 MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or
- *                 MBEDTLS_ERR_SSL_CLIENT_RECONNECT (see below), or
- *                 another negative error code.
+ * \return         One of the following:
+ *                 - 0 if the read end of the underlying transport was closed,
+ *                 - the (positive) number of bytes read, or
+ *                 - a negative error code on failure.
+ *
+ *                 If MBEDTLS_ERR_SSL_WANT_READ is returned, no application data
+ *                 is available from the underlying transport. In this case,
+ *                 the function needs to be called again at some later stage.
  *
- * \note           If this function returns something other than a positive
- *                 value or MBEDTLS_ERR_SSL_WANT_READ/WRITE or
- *                 MBEDTLS_ERR_SSL_CLIENT_RECONNECT, then the ssl context
- *                 becomes unusable, and you should either free it or call
- *                 \c mbedtls_ssl_session_reset() on it before re-using it for
- *                 a new connection; the current connection must be closed.
+ *                 If MBEDTLS_ERR_SSL_WANT_WRITE is returned, a write is pending
+ *                 but the underlying transport isn't available for writing. In this
+ *                 case, the function needs to be called again at some later stage.
  *
- * \note           When this function return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
+ *                 When this function return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
  *                 (which can only happen server-side), it means that a client
  *                 is initiating a new connection using the same source port.
  *                 You can either treat that as a connection close and wait
@@ -2443,6 +2572,28 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
  *                 again. WARNING: not validating the identity of the client
  *                 again, or not transmitting the new identity to the
  *                 application layer, would allow authentication bypass!
+ *
+ * \note           If this function returns something other than a positive value
+ *                 or MBEDTLS_ERR_SSL_WANT_READ/WRITE or MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
+ *                 you must stop using the SSL context for reading or writing,
+ *                 and either free it or call \c mbedtls_ssl_session_reset() on it
+ *                 before re-using it for a new connection; the current connection
+ *                 must be closed.
+ *
+ * \note           Remarks regarding event-driven DTLS:
+ *                 - If the function returns MBEDTLS_ERR_SSL_WANT_READ, no datagram
+ *                   from the underlying transport layer is currently being processed,
+ *                   and it is safe to idle until the timer or the underlying transport
+ *                   signal a new event.
+ *                 - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was
+ *                   initially available on the underlying transport, as this data may have
+ *                   been only e.g. duplicated messages or a renegotiation request.
+ *                   Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even
+ *                   when reacting to an incoming-data event from the underlying transport.
+ *                 - On success, the datagram of the underlying transport that is currently
+ *                   being processed may contain further DTLS records. You should call
+ *                   \c mbedtls_ssl_check_pending to check for remaining records.
+ *
  */
 int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len );
 
@@ -2463,15 +2614,17 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
  *                 or MBEDTLS_ERR_SSL_WANT_WRITE or MBEDTLS_ERR_SSL_WANT_READ,
  *                 or another negative error code.
  *
- * \note           If this function returns something other than a positive
- *                 value or MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context
- *                 becomes unusable, and you should either free it or call
- *                 \c mbedtls_ssl_session_reset() on it before re-using it for
- *                 a new connection; the current connection must be closed.
+ * \note           If this function returns something other than a positive value
+ *                 or MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
  *
  * \note           When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ,
  *                 it must be called later with the *same* arguments,
- *                 until it returns a positive value.
+ *                 until it returns a positive value. When the function returns
+ *                 MBEDTLS_ERR_SSL_WANT_WRITE there may be some partial
+ *                 data in the output buffer, however this is not yet sent.
  *
  * \note           If the requested length is greater than the maximum
  *                 fragment length (either the built-in limit or the one set
@@ -2494,10 +2647,10 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_
  * \return          0 if successful, or a specific SSL error code.
  *
  * \note           If this function returns something other than 0 or
- *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
- *                 becomes unusable, and you should either free it or call
- *                 \c mbedtls_ssl_session_reset() on it before re-using it for
- *                 a new connection; the current connection must be closed.
+ *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
  */
 int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
                             unsigned char level,
@@ -2510,10 +2663,10 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
  * \return          0 if successful, or a specific SSL error code.
  *
  * \note           If this function returns something other than 0 or
- *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
- *                 becomes unusable, and you should either free it or call
- *                 \c mbedtls_ssl_session_reset() on it before re-using it for
- *                 a new connection; the current connection must be closed.
+ *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
  */
 int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
 
diff --git a/crypto/mbedtls/include/mbedtls/ssl_cache.h b/crypto/mbedtls/include/mbedtls/ssl_cache.h
index 3734bb727..ec081e6d2 100644
--- a/crypto/mbedtls/include/mbedtls/ssl_cache.h
+++ b/crypto/mbedtls/include/mbedtls/ssl_cache.h
@@ -2,7 +2,8 @@
  * \file ssl_cache.h
  *
  * \brief SSL session cache implementation
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/ssl_ciphersuites.h b/crypto/mbedtls/include/mbedtls/ssl_ciphersuites.h
index 9101d9cc7..545468a51 100644
--- a/crypto/mbedtls/include/mbedtls/ssl_ciphersuites.h
+++ b/crypto/mbedtls/include/mbedtls/ssl_ciphersuites.h
@@ -2,7 +2,8 @@
  * \file ssl_ciphersuites.h
  *
  * \brief SSL Ciphersuites for mbed TLS
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/ssl_cookie.h b/crypto/mbedtls/include/mbedtls/ssl_cookie.h
index 037e1c311..80b65bbbb 100644
--- a/crypto/mbedtls/include/mbedtls/ssl_cookie.h
+++ b/crypto/mbedtls/include/mbedtls/ssl_cookie.h
@@ -2,7 +2,8 @@
  * \file ssl_cookie.h
  *
  * \brief DTLS cookie callbacks implementation
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/ssl_internal.h b/crypto/mbedtls/include/mbedtls/ssl_internal.h
index 756360b18..60b431a0f 100644
--- a/crypto/mbedtls/include/mbedtls/ssl_internal.h
+++ b/crypto/mbedtls/include/mbedtls/ssl_internal.h
@@ -1,8 +1,9 @@
 /**
- * \file ssl_ticket.h
+ * \file ssl_internal.h
  *
  * \brief Internal functions shared by the SSL modules
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -24,6 +25,7 @@
 #define MBEDTLS_SSL_INTERNAL_H
 
 #include "ssl.h"
+#include "cipher.h"
 
 #if defined(MBEDTLS_MD5_C)
 #include "md5.h"
@@ -69,6 +71,9 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1   */
 #endif /* MBEDTLS_SSL_PROTO_SSL3   */
 
+#define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1
+#define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3
+
 /* Determine maximum supported version */
 #define MBEDTLS_SSL_MAX_MAJOR_VERSION           MBEDTLS_SSL_MAJOR_VERSION_3
 
@@ -138,13 +143,33 @@
 #define MBEDTLS_SSL_PADDING_ADD              0
 #endif
 
-#define MBEDTLS_SSL_BUFFER_LEN  ( MBEDTLS_SSL_MAX_CONTENT_LEN               \
-                        + MBEDTLS_SSL_COMPRESSION_ADD               \
-                        + 29 /* counter + header + IV */    \
-                        + MBEDTLS_SSL_MAC_ADD                       \
-                        + MBEDTLS_SSL_PADDING_ADD                   \
+#define MBEDTLS_SSL_PAYLOAD_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN    \
+                        + MBEDTLS_SSL_COMPRESSION_ADD            \
+                        + MBEDTLS_MAX_IV_LENGTH                  \
+                        + MBEDTLS_SSL_MAC_ADD                    \
+                        + MBEDTLS_SSL_PADDING_ADD                \
                         )
 
+/*
+ * Check that we obey the standard's message size bounds
+ */
+
+#if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384
+#error Bad configuration - record content too large.
+#endif
+
+#if MBEDTLS_SSL_PAYLOAD_LEN > 16384 + 2048
+#error Bad configuration - protected record payload too large.
+#endif
+
+/* Note: Even though the TLS record header is only 5 bytes
+   long, we're internally using 8 bytes to store the
+   implicit sequence number. */
+#define MBEDTLS_SSL_HEADER_LEN 13
+
+#define MBEDTLS_SSL_BUFFER_LEN  \
+    ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_PAYLOAD_LEN ) )
+
 /*
  * TLS extension flags (for extensions with outgoing ServerHello content
  * that need it (e.g. for RENEGOTIATION_INFO the server already knows because
@@ -600,9 +625,9 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
 static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n )
 {
     size_t i;
-    const unsigned char *A = (const unsigned char *) a;
-    const unsigned char *B = (const unsigned char *) b;
-    unsigned char diff = 0;
+    volatile const unsigned char *A = (volatile const unsigned char *) a;
+    volatile const unsigned char *B = (volatile const unsigned char *) b;
+    volatile unsigned char diff = 0;
 
     for( i = 0; i < n; i++ )
         diff |= A[i] ^ B[i];
@@ -610,6 +635,23 @@ static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t
     return( diff );
 }
 
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
+                                        unsigned char *output,
+                                        unsigned char *data, size_t data_len );
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+                                        unsigned char *output,
+                                        unsigned char *data, size_t data_len,
+                                        mbedtls_md_type_t md_alg );
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/mbedtls/include/mbedtls/ssl_ticket.h b/crypto/mbedtls/include/mbedtls/ssl_ticket.h
index 7c6bc61bf..93ad46ac9 100644
--- a/crypto/mbedtls/include/mbedtls/ssl_ticket.h
+++ b/crypto/mbedtls/include/mbedtls/ssl_ticket.h
@@ -2,7 +2,8 @@
  * \file ssl_ticket.h
  *
  * \brief TLS server ticket callbacks implementation
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/threading.h b/crypto/mbedtls/include/mbedtls/threading.h
index b0c34ecc7..aeea5d0e1 100644
--- a/crypto/mbedtls/include/mbedtls/threading.h
+++ b/crypto/mbedtls/include/mbedtls/threading.h
@@ -2,7 +2,8 @@
  * \file threading.h
  *
  * \brief Threading abstraction layer
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -95,8 +96,12 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex );
 /*
  * Global mutexes
  */
+#if defined(MBEDTLS_FS_IO)
 extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
+#endif
+#if defined(MBEDTLS_HAVE_TIME_DATE)
 extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
+#endif
 #endif /* MBEDTLS_THREADING_C */
 
 #ifdef __cplusplus
diff --git a/crypto/mbedtls/include/mbedtls/timing.h b/crypto/mbedtls/include/mbedtls/timing.h
index ae7a713e7..bbcb90688 100644
--- a/crypto/mbedtls/include/mbedtls/timing.h
+++ b/crypto/mbedtls/include/mbedtls/timing.h
@@ -1,8 +1,9 @@
 /**
  * \file timing.h
  *
- * \brief Portable interface to the CPU cycle counter
- *
+ * \brief Portable interface to timeouts and to the CPU cycle counter
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -29,16 +30,16 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#if !defined(MBEDTLS_TIMING_ALT)
-// Regular implementation
-//
-
 #include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_TIMING_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          timer structure
  */
@@ -57,6 +58,10 @@ typedef struct
     uint32_t                        fin_ms;
 } mbedtls_timing_delay_context;
 
+#else  /* MBEDTLS_TIMING_ALT */
+#include "timing_alt.h"
+#endif /* MBEDTLS_TIMING_ALT */
+
 extern volatile int mbedtls_timing_alarmed;
 
 /**
@@ -65,6 +70,9 @@ extern volatile int mbedtls_timing_alarmed;
  * \warning        This is only a best effort! Do not rely on this!
  *                 In particular, it is known to be unreliable on virtual
  *                 machines.
+ *
+ * \note           This value starts at an unspecified origin and
+ *                 may wrap around.
  */
 unsigned long mbedtls_timing_hardclock( void );
 
@@ -72,7 +80,18 @@ unsigned long mbedtls_timing_hardclock( void );
  * \brief          Return the elapsed time in milliseconds
  *
  * \param val      points to a timer structure
- * \param reset    if set to 1, the timer is restarted
+ * \param reset    If 0, query the elapsed time. Otherwise (re)start the timer.
+ *
+ * \return         Elapsed time since the previous reset in ms. When
+ *                 restarting, this is always 0.
+ *
+ * \note           To initialize a timer, call this function with reset=1.
+ *
+ *                 Determining the elapsed time and resetting the timer is not
+ *                 atomic on all platforms, so after the sequence
+ *                 `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
+ *                 get_timer(0) }` the value time1+time2 is only approximately
+ *                 the delay since the first reset.
  */
 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset );
 
@@ -80,6 +99,7 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int
  * \brief          Setup an alarm clock
  *
  * \param seconds  delay before the "mbedtls_timing_alarmed" flag is set
+ *                 (must be >=0)
  *
  * \warning        Only one alarm at a time  is supported. In a threaded
  *                 context, this means one for the whole process, not one per
@@ -91,11 +111,15 @@ void mbedtls_set_alarm( int seconds );
  * \brief          Set a pair of delays to watch
  *                 (See \c mbedtls_timing_get_delay().)
  *
- * \param data     Pointer to timing data
+ * \param data     Pointer to timing data.
  *                 Must point to a valid \c mbedtls_timing_delay_context struct.
  * \param int_ms   First (intermediate) delay in milliseconds.
+ *                 The effect if int_ms > fin_ms is unspecified.
  * \param fin_ms   Second (final) delay in milliseconds.
  *                 Pass 0 to cancel the current delay.
+ *
+ * \note           To set a single delay, either use \c mbedtls_timing_set_timer
+ *                 directly or use this function with int_ms == fin_ms.
  */
 void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
 
@@ -106,25 +130,13 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
  * \param data     Pointer to timing data
  *                 Must point to a valid \c mbedtls_timing_delay_context struct.
  *
- * \return         -1 if cancelled (fin_ms = 0)
+ * \return         -1 if cancelled (fin_ms = 0),
  *                  0 if none of the delays are passed,
  *                  1 if only the intermediate delay is passed,
  *                  2 if the final delay is passed.
  */
 int mbedtls_timing_get_delay( void *data );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_TIMING_ALT */
-#include "timing_alt.h"
-#endif /* MBEDTLS_TIMING_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if defined(MBEDTLS_SELF_TEST)
 /**
  * \brief          Checkup routine
diff --git a/crypto/mbedtls/include/mbedtls/version.h b/crypto/mbedtls/include/mbedtls/version.h
index 3b209a6b0..aa52ce21e 100644
--- a/crypto/mbedtls/include/mbedtls/version.h
+++ b/crypto/mbedtls/include/mbedtls/version.h
@@ -2,7 +2,8 @@
  * \file version.h
  *
  * \brief Run-time version information
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -38,7 +39,7 @@
  * Major, Minor, Patchlevel
  */
 #define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  6
+#define MBEDTLS_VERSION_MINOR  9
 #define MBEDTLS_VERSION_PATCH  0
 
 /**
@@ -46,9 +47,9 @@
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02060000
-#define MBEDTLS_VERSION_STRING         "2.6.0"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.6.0"
+#define MBEDTLS_VERSION_NUMBER         0x02090000
+#define MBEDTLS_VERSION_STRING         "2.9.0"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.9.0"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/crypto/mbedtls/include/mbedtls/x509.h b/crypto/mbedtls/include/mbedtls/x509.h
index d7e318dfd..d6db9c6e3 100644
--- a/crypto/mbedtls/include/mbedtls/x509.h
+++ b/crypto/mbedtls/include/mbedtls/x509.h
@@ -2,7 +2,8 @@
  * \file x509.h
  *
  * \brief X.509 generic defines and structures
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/x509_crl.h b/crypto/mbedtls/include/mbedtls/x509_crl.h
index 798843990..08a4283a6 100644
--- a/crypto/mbedtls/include/mbedtls/x509_crl.h
+++ b/crypto/mbedtls/include/mbedtls/x509_crl.h
@@ -2,7 +2,8 @@
  * \file x509_crl.h
  *
  * \brief X.509 certificate revocation list parsing
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/x509_crt.h b/crypto/mbedtls/include/mbedtls/x509_crt.h
index 06166d8b1..ac23cffe8 100644
--- a/crypto/mbedtls/include/mbedtls/x509_crt.h
+++ b/crypto/mbedtls/include/mbedtls/x509_crt.h
@@ -2,7 +2,8 @@
  * \file x509_crt.h
  *
  * \brief X.509 certificate parsing and writing
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -286,8 +287,15 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
  *                 used to sign the certificate, CRL verification is skipped
  *                 silently, that is *without* setting any flag.
  *
+ * \note           The \c trust_ca list can contain two types of certificates:
+ *                 (1) those of trusted root CAs, so that certificates
+ *                 chaining up to those CAs will be trusted, and (2)
+ *                 self-signed end-entity certificates to be trusted (for
+ *                 specific peers you know) - in that case, the self-signed
+ *                 certificate doesn't need to have the CA bit set.
+ *
  * \param crt      a certificate (chain) to be verified
- * \param trust_ca the list of trusted CAs
+ * \param trust_ca the list of trusted CAs (see note above)
  * \param ca_crl   the list of CRLs for trusted CAs (see note above)
  * \param cn       expected Common Name (can be set to
  *                 NULL if the CN must not be verified)
@@ -373,21 +381,22 @@ int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
 
 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
 /**
- * \brief          Check usage of certificate against extentedJeyUsage.
+ * \brief           Check usage of certificate against extendedKeyUsage.
  *
- * \param crt      Leaf certificate used.
- * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or MBEDTLS_OID_CLIENT_AUTH).
+ * \param crt       Leaf certificate used.
+ * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or
+ *                  MBEDTLS_OID_CLIENT_AUTH).
  * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()).
  *
- * \return         0 if this use of the certificate is allowed,
- *                 MBEDTLS_ERR_X509_BAD_INPUT_DATA if not.
+ * \return          0 if this use of the certificate is allowed,
+ *                  MBEDTLS_ERR_X509_BAD_INPUT_DATA if not.
  *
- * \note           Usually only makes sense on leaf certificates.
+ * \note            Usually only makes sense on leaf certificates.
  */
 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
-                                       const char *usage_oid,
-                                       size_t usage_len );
-#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) */
+                                               const char *usage_oid,
+                                               size_t usage_len );
+#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
 
 #if defined(MBEDTLS_X509_CRL_PARSE_C)
 /**
diff --git a/crypto/mbedtls/include/mbedtls/x509_csr.h b/crypto/mbedtls/include/mbedtls/x509_csr.h
index fe9843cb5..0c6ccad78 100644
--- a/crypto/mbedtls/include/mbedtls/x509_csr.h
+++ b/crypto/mbedtls/include/mbedtls/x509_csr.h
@@ -2,7 +2,8 @@
  * \file x509_csr.h
  *
  * \brief X.509 certificate signing request parsing and writing
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/crypto/mbedtls/include/mbedtls/xtea.h b/crypto/mbedtls/include/mbedtls/xtea.h
index b073f84ef..8df708a3a 100644
--- a/crypto/mbedtls/include/mbedtls/xtea.h
+++ b/crypto/mbedtls/include/mbedtls/xtea.h
@@ -2,7 +2,8 @@
  * \file xtea.h
  *
  * \brief XTEA block cipher (32-bit)
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -36,15 +37,16 @@
 #define MBEDTLS_XTEA_DECRYPT     0
 
 #define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH             -0x0028  /**< The data input has an invalid length. */
-
-#if !defined(MBEDTLS_XTEA_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED                  -0x0029  /**< XTEA hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_XTEA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          XTEA context structure
  */
@@ -54,6 +56,10 @@ typedef struct
 }
 mbedtls_xtea_context;
 
+#else  /* MBEDTLS_XTEA_ALT */
+#include "xtea_alt.h"
+#endif /* MBEDTLS_XTEA_ALT */
+
 /**
  * \brief          Initialize XTEA context
  *
@@ -113,18 +119,6 @@ int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx,
                     unsigned char *output);
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_XTEA_ALT */
-#include "xtea_alt.h"
-#endif /* MBEDTLS_XTEA_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Checkup routine
  *
diff --git a/crypto/mbedtls/src/aes.c b/crypto/mbedtls/src/aes.c
index 58603849c..da94b1943 100644
--- a/crypto/mbedtls/src/aes.c
+++ b/crypto/mbedtls/src/aes.c
@@ -201,6 +201,8 @@ static const unsigned char FSb[256] =
 static const uint32_t FT0[256] = { FT };
 #undef V
 
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
 #define V(a,b,c,d) 0x##b##c##d##a
 static const uint32_t FT1[256] = { FT };
 #undef V
@@ -213,6 +215,8 @@ static const uint32_t FT2[256] = { FT };
 static const uint32_t FT3[256] = { FT };
 #undef V
 
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
 #undef FT
 
 /*
@@ -328,6 +332,8 @@ static const unsigned char RSb[256] =
 static const uint32_t RT0[256] = { RT };
 #undef V
 
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
 #define V(a,b,c,d) 0x##b##c##d##a
 static const uint32_t RT1[256] = { RT };
 #undef V
@@ -340,6 +346,8 @@ static const uint32_t RT2[256] = { RT };
 static const uint32_t RT3[256] = { RT };
 #undef V
 
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
 #undef RT
 
 /*
@@ -359,18 +367,22 @@ static const uint32_t RCON[10] =
  */
 static unsigned char FSb[256];
 static uint32_t FT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
 static uint32_t FT1[256];
 static uint32_t FT2[256];
 static uint32_t FT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
 
 /*
  * Reverse S-box & tables
  */
 static unsigned char RSb[256];
 static uint32_t RT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
 static uint32_t RT1[256];
 static uint32_t RT2[256];
 static uint32_t RT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
 
 /*
  * Round constants
@@ -445,9 +457,11 @@ static void aes_gen_tables( void )
                  ( (uint32_t) x << 16 ) ^
                  ( (uint32_t) z << 24 );
 
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
         FT1[i] = ROTL8( FT0[i] );
         FT2[i] = ROTL8( FT1[i] );
         FT3[i] = ROTL8( FT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
 
         x = RSb[i];
 
@@ -456,14 +470,48 @@ static void aes_gen_tables( void )
                  ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
                  ( (uint32_t) MUL( 0x0B, x ) << 24 );
 
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
         RT1[i] = ROTL8( RT0[i] );
         RT2[i] = ROTL8( RT1[i] );
         RT3[i] = ROTL8( RT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
     }
 }
 
+#undef ROTL8
+
 #endif /* MBEDTLS_AES_ROM_TABLES */
 
+#if defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define ROTL8(x)  ( (uint32_t)( ( x ) <<  8 ) + (uint32_t)( ( x ) >> 24 ) )
+#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
+#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >>  8 ) )
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) ROTL8(  RT0[idx] )
+#define AES_RT2(idx) ROTL16( RT0[idx] )
+#define AES_RT3(idx) ROTL24( RT0[idx] )
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) ROTL8(  FT0[idx] )
+#define AES_FT2(idx) ROTL16( FT0[idx] )
+#define AES_FT3(idx) ROTL24( FT0[idx] )
+
+#else /* MBEDTLS_AES_FEWER_TABLES */
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) RT1[idx]
+#define AES_RT2(idx) RT2[idx]
+#define AES_RT3(idx) RT3[idx]
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) FT1[idx]
+#define AES_FT2(idx) FT2[idx]
+#define AES_FT3(idx) FT3[idx]
+
+#endif /* MBEDTLS_AES_FEWER_TABLES */
+
 void mbedtls_aes_init( mbedtls_aes_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_aes_context ) );
@@ -641,10 +689,10 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
     {
         for( j = 0; j < 4; j++, SK++ )
         {
-            *RK++ = RT0[ FSb[ ( *SK       ) & 0xFF ] ] ^
-                    RT1[ FSb[ ( *SK >>  8 ) & 0xFF ] ] ^
-                    RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
-                    RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
+            *RK++ = AES_RT0( FSb[ ( *SK       ) & 0xFF ] ) ^
+                    AES_RT1( FSb[ ( *SK >>  8 ) & 0xFF ] ) ^
+                    AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
+                    AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
         }
     }
 
@@ -660,50 +708,50 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
 }
 #endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
 
-#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)     \
-{                                               \
-    X0 = *RK++ ^ FT0[ ( Y0       ) & 0xFF ] ^   \
-                 FT1[ ( Y1 >>  8 ) & 0xFF ] ^   \
-                 FT2[ ( Y2 >> 16 ) & 0xFF ] ^   \
-                 FT3[ ( Y3 >> 24 ) & 0xFF ];    \
-                                                \
-    X1 = *RK++ ^ FT0[ ( Y1       ) & 0xFF ] ^   \
-                 FT1[ ( Y2 >>  8 ) & 0xFF ] ^   \
-                 FT2[ ( Y3 >> 16 ) & 0xFF ] ^   \
-                 FT3[ ( Y0 >> 24 ) & 0xFF ];    \
-                                                \
-    X2 = *RK++ ^ FT0[ ( Y2       ) & 0xFF ] ^   \
-                 FT1[ ( Y3 >>  8 ) & 0xFF ] ^   \
-                 FT2[ ( Y0 >> 16 ) & 0xFF ] ^   \
-                 FT3[ ( Y1 >> 24 ) & 0xFF ];    \
-                                                \
-    X3 = *RK++ ^ FT0[ ( Y3       ) & 0xFF ] ^   \
-                 FT1[ ( Y0 >>  8 ) & 0xFF ] ^   \
-                 FT2[ ( Y1 >> 16 ) & 0xFF ] ^   \
-                 FT3[ ( Y2 >> 24 ) & 0xFF ];    \
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_FT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_FT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y0 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_FT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_FT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y2 >> 24 ) & 0xFF );    \
 }
 
-#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)     \
-{                                               \
-    X0 = *RK++ ^ RT0[ ( Y0       ) & 0xFF ] ^   \
-                 RT1[ ( Y3 >>  8 ) & 0xFF ] ^   \
-                 RT2[ ( Y2 >> 16 ) & 0xFF ] ^   \
-                 RT3[ ( Y1 >> 24 ) & 0xFF ];    \
-                                                \
-    X1 = *RK++ ^ RT0[ ( Y1       ) & 0xFF ] ^   \
-                 RT1[ ( Y0 >>  8 ) & 0xFF ] ^   \
-                 RT2[ ( Y3 >> 16 ) & 0xFF ] ^   \
-                 RT3[ ( Y2 >> 24 ) & 0xFF ];    \
-                                                \
-    X2 = *RK++ ^ RT0[ ( Y2       ) & 0xFF ] ^   \
-                 RT1[ ( Y1 >>  8 ) & 0xFF ] ^   \
-                 RT2[ ( Y0 >> 16 ) & 0xFF ] ^   \
-                 RT3[ ( Y3 >> 24 ) & 0xFF ];    \
-                                                \
-    X3 = *RK++ ^ RT0[ ( Y3       ) & 0xFF ] ^   \
-                 RT1[ ( Y2 >>  8 ) & 0xFF ] ^   \
-                 RT2[ ( Y1 >> 16 ) & 0xFF ] ^   \
-                 RT3[ ( Y0 >> 24 ) & 0xFF ];    \
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_RT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_RT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y2 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_RT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_RT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y0 >> 24 ) & 0xFF );    \
 }
 
 /*
@@ -765,12 +813,14 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
 }
 #endif /* !MBEDTLS_AES_ENCRYPT_ALT */
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
                           const unsigned char input[16],
                           unsigned char output[16] )
 {
     mbedtls_internal_aes_encrypt( ctx, input, output );
 }
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /*
  * AES-ECB block decryption
@@ -831,12 +881,14 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
 }
 #endif /* !MBEDTLS_AES_DECRYPT_ALT */
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
                           const unsigned char input[16],
                           unsigned char output[16] )
 {
     mbedtls_internal_aes_decrypt( ctx, input, output );
 }
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /*
  * AES-ECB block encryption/decryption
@@ -1235,9 +1287,11 @@ static const int aes_test_ctr_len[3] =
  */
 int mbedtls_aes_self_test( int verbose )
 {
-    int ret = 0, i, j, u, v;
+    int ret = 0, i, j, u, mode;
+    unsigned int keybits;
     unsigned char key[32];
     unsigned char buf[64];
+    const unsigned char *aes_tests;
 #if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
     unsigned char iv[16];
 #endif
@@ -1263,45 +1317,52 @@ int mbedtls_aes_self_test( int verbose )
     for( i = 0; i < 6; i++ )
     {
         u = i >> 1;
-        v = i  & 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
 
         if( verbose != 0 )
-            mbedtls_printf( "  AES-ECB-%3d (%s): ", 128 + u * 64,
-                             ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+            mbedtls_printf( "  AES-ECB-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
 
         memset( buf, 0, 16 );
 
-        if( v == MBEDTLS_AES_DECRYPT )
+        if( mode == MBEDTLS_AES_DECRYPT )
         {
-            mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 );
-
-            for( j = 0; j < 10000; j++ )
-                mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
-
-            if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                ret = 1;
-                goto exit;
-            }
+            ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
+            aes_tests = aes_test_ecb_dec[u];
         }
         else
         {
-            mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 );
-
-            for( j = 0; j < 10000; j++ )
-                mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
+            ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+            aes_tests = aes_test_ecb_enc[u];
+        }
 
-            if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
 
-                ret = 1;
+        for( j = 0; j < 10000; j++ )
+        {
+            ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
+            if( ret != 0 )
                 goto exit;
-            }
+        }
+
+        if( memcmp( buf, aes_tests, 16 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
         }
 
         if( verbose != 0 )
@@ -1318,55 +1379,64 @@ int mbedtls_aes_self_test( int verbose )
     for( i = 0; i < 6; i++ )
     {
         u = i >> 1;
-        v = i  & 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
 
         if( verbose != 0 )
-            mbedtls_printf( "  AES-CBC-%3d (%s): ", 128 + u * 64,
-                             ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+            mbedtls_printf( "  AES-CBC-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
 
         memset( iv , 0, 16 );
         memset( prv, 0, 16 );
         memset( buf, 0, 16 );
 
-        if( v == MBEDTLS_AES_DECRYPT )
+        if( mode == MBEDTLS_AES_DECRYPT )
         {
-            mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 );
-
-            for( j = 0; j < 10000; j++ )
-                mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
-
-            if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                ret = 1;
-                goto exit;
-            }
+            ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
+            aes_tests = aes_test_cbc_dec[u];
         }
         else
         {
-            mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 );
+            ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+            aes_tests = aes_test_cbc_enc[u];
+        }
+
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
 
-            for( j = 0; j < 10000; j++ )
+        for( j = 0; j < 10000; j++ )
+        {
+            if( mode == MBEDTLS_AES_ENCRYPT )
             {
                 unsigned char tmp[16];
 
-                mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
-
                 memcpy( tmp, prv, 16 );
                 memcpy( prv, buf, 16 );
                 memcpy( buf, tmp, 16 );
             }
 
-            if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                ret = 1;
+            ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
+            if( ret != 0 )
                 goto exit;
-            }
+
+        }
+
+        if( memcmp( buf, aes_tests, 16 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
         }
 
         if( verbose != 0 )
@@ -1384,45 +1454,52 @@ int mbedtls_aes_self_test( int verbose )
     for( i = 0; i < 6; i++ )
     {
         u = i >> 1;
-        v = i  & 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
 
         if( verbose != 0 )
-            mbedtls_printf( "  AES-CFB128-%3d (%s): ", 128 + u * 64,
-                             ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+            mbedtls_printf( "  AES-CFB128-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
 
         memcpy( iv,  aes_test_cfb128_iv, 16 );
-        memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 );
+        memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
 
         offset = 0;
-        mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 );
+        ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
 
-        if( v == MBEDTLS_AES_DECRYPT )
+        if( mode == MBEDTLS_AES_DECRYPT )
         {
             memcpy( buf, aes_test_cfb128_ct[u], 64 );
-            mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf );
-
-            if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                ret = 1;
-                goto exit;
-            }
+            aes_tests = aes_test_cfb128_pt;
         }
         else
         {
             memcpy( buf, aes_test_cfb128_pt, 64 );
-            mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf );
+            aes_tests = aes_test_cfb128_ct[u];
+        }
 
-            if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
+        ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
+        if( ret != 0 )
+            goto exit;
 
-                ret = 1;
-                goto exit;
-            }
+        if( memcmp( buf, aes_tests, 64 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
         }
 
         if( verbose != 0 )
@@ -1440,51 +1517,41 @@ int mbedtls_aes_self_test( int verbose )
     for( i = 0; i < 6; i++ )
     {
         u = i >> 1;
-        v = i  & 1;
+        mode = i & 1;
 
         if( verbose != 0 )
             mbedtls_printf( "  AES-CTR-128 (%s): ",
-                             ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
 
         memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
         memcpy( key, aes_test_ctr_key[u], 16 );
 
         offset = 0;
-        mbedtls_aes_setkey_enc( &ctx, key, 128 );
+        if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
+            goto exit;
 
-        if( v == MBEDTLS_AES_DECRYPT )
+        len = aes_test_ctr_len[u];
+
+        if( mode == MBEDTLS_AES_DECRYPT )
         {
-            len = aes_test_ctr_len[u];
             memcpy( buf, aes_test_ctr_ct[u], len );
-
-            mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
-                           buf, buf );
-
-            if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                ret = 1;
-                goto exit;
-            }
+            aes_tests = aes_test_ctr_pt[u];
         }
         else
         {
-            len = aes_test_ctr_len[u];
             memcpy( buf, aes_test_ctr_pt[u], len );
+            aes_tests = aes_test_ctr_ct[u];
+        }
 
-            mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
-                           buf, buf );
-
-            if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
+        ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
+                                     stream_block, buf, buf );
+        if( ret != 0 )
+            goto exit;
 
-                ret = 1;
-                goto exit;
-            }
+        if( memcmp( buf, aes_tests, len ) != 0 )
+        {
+            ret = 1;
+            goto exit;
         }
 
         if( verbose != 0 )
@@ -1498,6 +1565,9 @@ int mbedtls_aes_self_test( int verbose )
     ret = 0;
 
 exit:
+    if( ret != 0 && verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
     mbedtls_aes_free( &ctx );
 
     return( ret );
diff --git a/crypto/mbedtls/src/aesni.c b/crypto/mbedtls/src/aesni.c
index 1ca3c3ef5..062708b04 100644
--- a/crypto/mbedtls/src/aesni.c
+++ b/crypto/mbedtls/src/aesni.c
@@ -32,6 +32,12 @@
 
 #if defined(MBEDTLS_AESNI_C)
 
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#warning "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code."
+#endif
+#endif
+
 #include "mbedtls/aesni.h"
 
 #include <string.h>
diff --git a/crypto/mbedtls/src/bignum.c b/crypto/mbedtls/src/bignum.c
index d3a150c3c..f58af788f 100644
--- a/crypto/mbedtls/src/bignum.c
+++ b/crypto/mbedtls/src/bignum.c
@@ -63,6 +63,11 @@ static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
     volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
 }
 
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
 #define ciL    (sizeof(mbedtls_mpi_uint))         /* chars in limb  */
 #define biL    (ciL << 3)               /* bits  in limb  */
 #define biH    (ciL << 2)               /* half limb size */
@@ -179,7 +184,7 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
  */
 int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
-    int ret;
+    int ret = 0;
     size_t i;
 
     if( X == Y )
@@ -198,9 +203,15 @@ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
 
     X->s = Y->s;
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
+    if( X->n < i )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
+    }
+    else
+    {
+        memset( X->p + i, 0, ( X->n - i ) * ciL );
+    }
 
-    memset( X->p, 0, X->n * ciL );
     memcpy( X->p, Y->p, i * ciL );
 
 cleanup:
@@ -672,16 +683,20 @@ int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE
 int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
 {
     int ret;
-    size_t i, j, n;
+    size_t i, j;
+    size_t const limbs = CHARS_TO_LIMBS( buflen );
 
-    for( n = 0; n < buflen; n++ )
-        if( buf[n] != 0 )
-            break;
+    /* Ensure that target MPI has exactly the necessary number of limbs */
+    if( X->n != limbs )
+    {
+        mbedtls_mpi_free( X );
+        mbedtls_mpi_init( X );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
+    }
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
 
-    for( i = buflen, j = 0; i > n; i--, j++ )
+    for( i = buflen, j = 0; i > 0; i--, j++ )
         X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
 
 cleanup:
@@ -954,7 +969,7 @@ static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
     while( c != 0 )
     {
         z = ( *d < c ); *d -= c;
-        c = z; i++; d++;
+        c = z; d++;
     }
 }
 
@@ -1192,8 +1207,8 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
 
-    for( i++; j > 0; j-- )
-        mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
+    for( ; j > 0; j-- )
+        mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
 
     X->s = A->s * B->s;
 
@@ -1614,7 +1629,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
     int neg;
 
-    if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
+    if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
     if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
@@ -1882,6 +1897,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
 
 cleanup:
+    mbedtls_zeroize( buf, sizeof( buf ) );
     return( ret );
 }
 
@@ -2178,12 +2194,23 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
 
 /*
  * Prime number generation
+ *
+ * If dh_flag is 0 and nbits is at least 1024, then the procedure
+ * follows the RSA probably-prime generation method of FIPS 186-4.
+ * NB. FIPS 186-4 only allows the specific bit lengths of 1024 and 1536.
  */
 int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
                    int (*f_rng)(void *, unsigned char *, size_t),
                    void *p_rng )
 {
-    int ret;
+#ifdef MBEDTLS_HAVE_INT64
+// ceil(2^63.5)
+#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
+#else
+// ceil(2^31.5)
+#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
+#endif
+    int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
     size_t k, n;
     mbedtls_mpi_uint r;
     mbedtls_mpi Y;
@@ -2195,69 +2222,66 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
 
     n = BITS_TO_LIMBS( nbits );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
-
-    k = mbedtls_mpi_bitlen( X );
-    if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) );
-
-    mbedtls_mpi_set_bit( X, nbits-1, 1 );
+    while( 1 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
+        /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
+        if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
 
-    X->p[0] |= 1;
+        k = n * biL;
+        if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
+        X->p[0] |= 1;
 
-    if( dh_flag == 0 )
-    {
-        while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
+        if( dh_flag == 0 )
         {
+            ret = mbedtls_mpi_is_prime( X, f_rng, p_rng );
+
             if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
                 goto cleanup;
-
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) );
         }
-    }
-    else
-    {
-        /*
-         * An necessary condition for Y and X = 2Y + 1 to be prime
-         * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
-         * Make sure it is satisfied, while keeping X = 3 mod 4
-         */
+        else
+        {
+            /*
+             * An necessary condition for Y and X = 2Y + 1 to be prime
+             * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
+             * Make sure it is satisfied, while keeping X = 3 mod 4
+             */
 
-        X->p[0] |= 2;
+            X->p[0] |= 2;
 
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
-        if( r == 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
-        else if( r == 1 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
+            if( r == 0 )
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
+            else if( r == 1 )
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
 
-        /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
+            /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
+            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
 
-        while( 1 )
-        {
-            /*
-             * First, check small factors for X and Y
-             * before doing Miller-Rabin on any of them
-             */
-            if( ( ret = mpi_check_small_factors(  X         ) ) == 0 &&
-                ( ret = mpi_check_small_factors( &Y         ) ) == 0 &&
-                ( ret = mpi_miller_rabin(  X, f_rng, p_rng  ) ) == 0 &&
-                ( ret = mpi_miller_rabin( &Y, f_rng, p_rng  ) ) == 0 )
+            while( 1 )
             {
-                break;
+                /*
+                 * First, check small factors for X and Y
+                 * before doing Miller-Rabin on any of them
+                 */
+                if( ( ret = mpi_check_small_factors(  X         ) ) == 0 &&
+                    ( ret = mpi_check_small_factors( &Y         ) ) == 0 &&
+                    ( ret = mpi_miller_rabin(  X, f_rng, p_rng  ) ) == 0 &&
+                    ( ret = mpi_miller_rabin( &Y, f_rng, p_rng  ) ) == 0 )
+                    goto cleanup;
+
+                if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+                    goto cleanup;
+
+                /*
+                 * Next candidates. We want to preserve Y = (X-1) / 2 and
+                 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
+                 * so up Y by 6 and X by 12.
+                 */
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(  X,  X, 12 ) );
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6  ) );
             }
-
-            if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
-                goto cleanup;
-
-            /*
-             * Next candidates. We want to preserve Y = (X-1) / 2 and
-             * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
-             * so up Y by 6 and X by 12.
-             */
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(  X,  X, 12 ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6  ) );
         }
     }
 
diff --git a/crypto/mbedtls/src/ccm.c b/crypto/mbedtls/src/ccm.c
index 13a8fd1a2..9101e5f7c 100644
--- a/crypto/mbedtls/src/ccm.c
+++ b/crypto/mbedtls/src/ccm.c
@@ -49,6 +49,8 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
 
+#if !defined(MBEDTLS_CCM_ALT)
+
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
     volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
@@ -348,6 +350,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
     return( 0 );
 }
 
+#endif /* !MBEDTLS_CCM_ALT */
 
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
 /*
diff --git a/crypto/mbedtls/src/cipher.c b/crypto/mbedtls/src/cipher.c
index e9e0b223e..7369f4823 100644
--- a/crypto/mbedtls/src/cipher.c
+++ b/crypto/mbedtls/src/cipher.c
@@ -325,8 +325,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
         /*
          * If there is not enough data for a full block, cache it.
          */
-        if( ( ctx->operation == MBEDTLS_DECRYPT &&
+        if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
                 ilen <= block_size - ctx->unprocessed_len ) ||
+            ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
+                ilen < block_size - ctx->unprocessed_len ) ||
              ( ctx->operation == MBEDTLS_ENCRYPT &&
                 ilen < block_size - ctx->unprocessed_len ) )
         {
@@ -372,9 +374,17 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
                 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
             }
 
+            /* Encryption: only cache partial blocks
+             * Decryption w/ padding: always keep at least one whole block
+             * Decryption w/o padding: only cache partial blocks
+             */
             copy_len = ilen % block_size;
-            if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT )
+            if( copy_len == 0 &&
+                ctx->operation == MBEDTLS_DECRYPT &&
+                NULL != ctx->add_padding)
+            {
                 copy_len = block_size;
+            }
 
             memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
                     copy_len );
@@ -516,14 +526,14 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
     if( NULL == input || NULL == data_len )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-    bad = 0xFF;
+    bad = 0x80;
     *data_len = 0;
     for( i = input_len; i > 0; i-- )
     {
         prev_done = done;
-        done |= ( input[i-1] != 0 );
+        done |= ( input[i - 1] != 0 );
         *data_len |= ( i - 1 ) * ( done != prev_done );
-        bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done );
+        bad ^= input[i - 1] * ( done != prev_done );
     }
 
     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
diff --git a/crypto/mbedtls/src/cmac.c b/crypto/mbedtls/src/cmac.c
index 6df56aa9a..a4a2106f2 100644
--- a/crypto/mbedtls/src/cmac.c
+++ b/crypto/mbedtls/src/cmac.c
@@ -65,6 +65,8 @@
 #endif /* MBEDTLS_SELF_TEST */
 #endif /* MBEDTLS_PLATFORM_C */
 
+#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
+
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
     volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
@@ -164,7 +166,9 @@ static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
 
     return( ret );
 }
+#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
 
+#if !defined(MBEDTLS_CMAC_ALT)
 static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
                             const unsigned char *input2,
                             const size_t block_size )
@@ -468,6 +472,8 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
 }
 #endif /* MBEDTLS_AES_C */
 
+#endif /* !MBEDTLS_CMAC_ALT */
+
 #if defined(MBEDTLS_SELF_TEST)
 /*
  * CMAC test data for SP800-38B
@@ -765,7 +771,7 @@ static int cmac_test_subkeys( int verbose,
                               int block_size,
                               int num_tests )
 {
-    int i, ret;
+    int i, ret = 0;
     mbedtls_cipher_context_t ctx;
     const mbedtls_cipher_info_t *cipher_info;
     unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
@@ -847,7 +853,7 @@ static int cmac_test_wth_cipher( int verbose,
                                  int num_tests )
 {
     const mbedtls_cipher_info_t *cipher_info;
-    int i, ret;
+    int i, ret = 0;
     unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
 
     cipher_info = mbedtls_cipher_info_from_type( cipher_type );
diff --git a/crypto/mbedtls/src/ctr_drbg.c b/crypto/mbedtls/src/ctr_drbg.c
index 55612c7fc..ff532a013 100644
--- a/crypto/mbedtls/src/ctr_drbg.c
+++ b/crypto/mbedtls/src/ctr_drbg.c
@@ -19,7 +19,7 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 /*
- *  The NIST SP 800-90 DRBGs are described in the following publucation.
+ *  The NIST SP 800-90 DRBGs are described in the following publication.
  *
  *  http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
  */
@@ -94,11 +94,15 @@ int mbedtls_ctr_drbg_seed_entropy_len(
     /*
      * Initialize with an empty key
      */
-    mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );
+    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        return( ret );
+    }
 
     if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
+    {
         return( ret );
-
+    }
     return( 0 );
 }
 
@@ -148,6 +152,7 @@ static int block_cipher_df( unsigned char *output,
     unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
     unsigned char *p, *iv;
     mbedtls_aes_context aes_ctx;
+    int ret = 0;
 
     int i, j;
     size_t buf_len, use_len;
@@ -180,7 +185,10 @@ static int block_cipher_df( unsigned char *output,
     for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
         key[i] = i;
 
-    mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );
+    if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        goto exit;
+    }
 
     /*
      * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
@@ -199,7 +207,10 @@ static int block_cipher_df( unsigned char *output,
             use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
                        MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
 
-            mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain );
+            if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
+            {
+                goto exit;
+            }
         }
 
         memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
@@ -213,20 +224,40 @@ static int block_cipher_df( unsigned char *output,
     /*
      * Do final encryption with reduced data
      */
-    mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS );
+    if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        goto exit;
+    }
     iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
     p = output;
 
     for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
     {
-        mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
+        {
+            goto exit;
+        }
         memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
     }
-
+exit:
     mbedtls_aes_free( &aes_ctx );
+    /*
+    * tidy up the stack
+    */
+    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_zeroize( key, sizeof( key ) );
+    mbedtls_zeroize( chain, sizeof( chain ) );
+    if( 0 != ret )
+    {
+        /*
+        * wipe partial seed from memory
+        */
+        mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
+    }
 
-    return( 0 );
+    return( ret );
 }
 
 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
@@ -235,6 +266,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
     unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
     unsigned char *p = tmp;
     int i, j;
+    int ret = 0;
 
     memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
 
@@ -250,7 +282,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
         /*
          * Crypt counter block
          */
-        mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p );
+        if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
+        {
+            return( ret );
+        }
 
         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
     }
@@ -261,7 +296,10 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
     /*
      * Update key and counter
      */
-    mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS );
+    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        return( ret );
+    }
     memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
 
     return( 0 );
@@ -289,6 +327,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
 {
     unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
     size_t seedlen = 0;
+    int ret;
 
     if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
         len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
@@ -319,12 +358,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
     /*
      * Reduce to 384 bits
      */
-    block_cipher_df( seed, seed, seedlen );
+    if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
+    {
+        return( ret );
+    }
 
     /*
      * Update state
      */
-    ctr_drbg_update_internal( ctx, seed );
+    if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
+    {
+        return( ret );
+    }
     ctx->reseed_counter = 1;
 
     return( 0 );
@@ -354,15 +399,22 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
         ctx->prediction_resistance )
     {
         if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
+        {
             return( ret );
-
+        }
         add_len = 0;
     }
 
     if( add_len > 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 )
+        {
+            return( ret );
+        }
+        if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
+        {
+            return( ret );
+        }
     }
 
     while( output_len > 0 )
@@ -377,7 +429,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
         /*
          * Crypt counter block
          */
-        mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp );
+        if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
+        {
+            return( ret );
+        }
 
         use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
                                                        output_len;
@@ -389,7 +444,10 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
         output_len -= use_len;
     }
 
-    ctr_drbg_update_internal( ctx, add_input );
+    if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
+    {
+        return( ret );
+    }
 
     ctx->reseed_counter++;
 
@@ -430,20 +488,20 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
         goto exit;
 
     if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
-    {
         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
-        goto exit;
-    }
-
-    ret = 0;
+    else
+        ret = 0;
 
 exit:
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
     fclose( f );
     return( ret );
 }
 
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
@@ -462,14 +520,16 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char
     }
 
     if( fread( buf, 1, n, f ) != n )
-    {
-        fclose( f );
-        return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
-    }
+        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
+    else
+        mbedtls_ctr_drbg_update( ctx, buf, n );
 
     fclose( f );
 
-    mbedtls_ctr_drbg_update( ctx, buf, n );
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
+    if( ret != 0 )
+        return( ret );
 
     return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
 }
diff --git a/crypto/mbedtls/src/debug.c b/crypto/mbedtls/src/debug.c
index f9229b360..db3924ac5 100644
--- a/crypto/mbedtls/src/debug.c
+++ b/crypto/mbedtls/src/debug.c
@@ -91,7 +91,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
 
     va_start( argp, format );
 #if defined(_WIN32)
-#if defined(_TRUNCATE)
+#if defined(_TRUNCATE) && !defined(__MINGW32__)
     ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
 #else
     ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
diff --git a/crypto/mbedtls/src/dhm.c b/crypto/mbedtls/src/dhm.c
index bec52a11d..28ac31003 100644
--- a/crypto/mbedtls/src/dhm.c
+++ b/crypto/mbedtls/src/dhm.c
@@ -57,6 +57,7 @@
 #define mbedtls_free       free
 #endif
 
+#if !defined(MBEDTLS_DHM_ALT)
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
@@ -93,6 +94,9 @@ static int dhm_read_bignum( mbedtls_mpi *X,
  *
  * Parameter should be: 2 <= public_param <= P - 2
  *
+ * This means that we need to return an error if
+ *              public_param < 2 or public_param > P-2
+ *
  * For more information on the attack, see:
  *  http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
  *  http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
@@ -100,17 +104,17 @@ static int dhm_read_bignum( mbedtls_mpi *X,
 static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
 {
     mbedtls_mpi L, U;
-    int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
+    int ret = 0;
 
     mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
 
-    if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 &&
-        mbedtls_mpi_cmp_mpi( param, &U ) <= 0 )
+    if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
+        mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
     {
-        ret = 0;
+        ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
     }
 
 cleanup:
@@ -187,10 +191,15 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
     /*
      * export P, G, GX
      */
-#define DHM_MPI_EXPORT(X,n)                     \
-    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \
-    *p++ = (unsigned char)( n >> 8 );           \
-    *p++ = (unsigned char)( n      ); p += n;
+#define DHM_MPI_EXPORT( X, n )                                          \
+    do {                                                                \
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ),               \
+                                                   p + 2,               \
+                                                   ( n ) ) );           \
+        *p++ = (unsigned char)( ( n ) >> 8 );                           \
+        *p++ = (unsigned char)( ( n )      );                           \
+        p += ( n );                                                     \
+    } while( 0 )
 
     n1 = mbedtls_mpi_size( &ctx->P  );
     n2 = mbedtls_mpi_size( &ctx->G  );
@@ -201,7 +210,7 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
     DHM_MPI_EXPORT( &ctx->G , n2 );
     DHM_MPI_EXPORT( &ctx->GX, n3 );
 
-    *olen  = p - output;
+    *olen = p - output;
 
     ctx->len = n1;
 
@@ -213,6 +222,28 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
     return( 0 );
 }
 
+/*
+ * Set prime modulus and generator
+ */
+int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
+                           const mbedtls_mpi *P,
+                           const mbedtls_mpi *G )
+{
+    int ret;
+
+    if( ctx == NULL || P == NULL || G == NULL )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
+    }
+
+    ctx->len = mbedtls_mpi_size( &ctx->P );
+    return( 0 );
+}
+
 /*
  * Import the peer's public value G^Y
  */
@@ -400,10 +431,11 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
  */
 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 );
+    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_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
 }
@@ -542,7 +574,10 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
     if( fread( *buf, 1, *n, f ) != *n )
     {
         fclose( f );
+
+        mbedtls_zeroize( *buf, *n + 1 );
         mbedtls_free( *buf );
+
         return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
     }
 
@@ -577,6 +612,7 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
 }
 #endif /* MBEDTLS_FS_IO */
 #endif /* MBEDTLS_ASN1_PARSE_C */
+#endif /* MBEDTLS_DHM_ALT */
 
 #if defined(MBEDTLS_SELF_TEST)
 
diff --git a/crypto/mbedtls/src/ecdh.c b/crypto/mbedtls/src/ecdh.c
index c0a814731..61380b693 100644
--- a/crypto/mbedtls/src/ecdh.c
+++ b/crypto/mbedtls/src/ecdh.c
@@ -38,6 +38,7 @@
 
 #include <string.h>
 
+#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
 /*
  * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
  */
@@ -47,7 +48,9 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
 {
     return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
 }
+#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
 
+#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
 /*
  * Compute shared secret (SEC1 3.3.1)
  */
@@ -81,6 +84,7 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
 
     return( ret );
 }
+#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
 
 /*
  * Initialize context
diff --git a/crypto/mbedtls/src/ecdsa.c b/crypto/mbedtls/src/ecdsa.c
index 4156f3c3c..17a88bdd2 100644
--- a/crypto/mbedtls/src/ecdsa.c
+++ b/crypto/mbedtls/src/ecdsa.c
@@ -65,6 +65,7 @@ static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
     return( ret );
 }
 
+#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
 /*
  * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
  * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
@@ -81,6 +82,10 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
     if( grp->N.p == NULL )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
+    /* Make sure d is in range 1..n-1 */
+    if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
+        return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
     mbedtls_ecp_point_init( &R );
     mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
 
@@ -153,6 +158,7 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
 
     return( ret );
 }
+#endif /* MBEDTLS_ECDSA_SIGN_ALT */
 
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
 /*
@@ -192,6 +198,7 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi
 }
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
+#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
 /*
  * Verify ECDSA signature of hashed message (SEC1 4.1.4)
  * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
@@ -277,6 +284,7 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
 
     return( ret );
 }
+#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
 
 /*
  * Convert a signature (given by context) to ASN.1
@@ -392,6 +400,9 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
                               &ctx->Q, &r, &s ) ) != 0 )
         goto cleanup;
 
+    /* At this point we know that the buffer starts with a valid signature.
+     * Return 0 if the buffer just contains the signature, and a specific
+     * error code if the valid signature is followed by more data. */
     if( p != end )
         ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
 
@@ -402,6 +413,7 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
     return( ret );
 }
 
+#if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
 /*
  * Generate key pair
  */
@@ -411,6 +423,7 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
     return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
             mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
 }
+#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
 
 /*
  * Set context from an mbedtls_ecp_keypair
diff --git a/crypto/mbedtls/src/ecjpake.c b/crypto/mbedtls/src/ecjpake.c
index 1fa1c2d80..e8f40862b 100644
--- a/crypto/mbedtls/src/ecjpake.c
+++ b/crypto/mbedtls/src/ecjpake.c
@@ -36,6 +36,8 @@
 
 #include <string.h>
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+
 /*
  * Convert a mbedtls_ecjpake_role to identifier string
  */
@@ -764,6 +766,7 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
 #undef ID_MINE
 #undef ID_PEER
 
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
 
 #if defined(MBEDTLS_SELF_TEST)
 
diff --git a/crypto/mbedtls/src/ecp.c b/crypto/mbedtls/src/ecp.c
index 5ad686398..92a188b66 100644
--- a/crypto/mbedtls/src/ecp.c
+++ b/crypto/mbedtls/src/ecp.c
@@ -26,6 +26,7 @@
  * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
  * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
  * RFC 4492 for the related TLS structures and constants
+ * RFC 7748 for the Curve448 and Curve25519 curve definitions
  *
  * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
  *
@@ -99,7 +100,8 @@ static unsigned long add_count, dbl_count, mul_count;
 #define ECP_SHORTWEIERSTRASS
 #endif
 
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 #define ECP_MONTGOMERY
 #endif
 
@@ -1852,6 +1854,8 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
 static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
 {
     /* [Curve25519 p. 5] Just check X is the correct number of bytes */
+    /* Allow any public value, if it's too big then we'll just reduce it mod p
+     * (RFC 7748 sec. 5 para. 3). */
     if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
         return( MBEDTLS_ERR_ECP_INVALID_KEY );
 
@@ -1887,14 +1891,18 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *
 #if defined(ECP_MONTGOMERY)
     if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
     {
-        /* see [Curve25519] page 5 */
+        /* see RFC 7748 sec. 5 para. 5 */
         if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
             mbedtls_mpi_get_bit( d, 1 ) != 0 ||
-            mbedtls_mpi_get_bit( d, 2 ) != 0 ||
             mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */
             return( MBEDTLS_ERR_ECP_INVALID_KEY );
         else
-            return( 0 );
+
+        /* see [Curve25519] page 5 */
+        if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 )
+            return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+        return( 0 );
     }
 #endif /* ECP_MONTGOMERY */
 #if defined(ECP_SHORTWEIERSTRASS)
@@ -1941,10 +1949,14 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
         else
             MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
 
-        /* Make sure the last three bits are unset */
+        /* Make sure the last two bits are unset for Curve448, three bits for
+           Curve25519 */
         MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
+        if( grp->nbits == 254 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
+        }
     }
     else
 #endif /* ECP_MONTGOMERY */
@@ -1953,7 +1965,6 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
     {
         /* SEC1 3.2.1: Generate d such that 1 <= n < N */
         int count = 0;
-        unsigned char rnd[MBEDTLS_ECP_MAX_BYTES];
 
         /*
          * Match the procedure given in RFC 6979 (deterministic ECDSA):
@@ -1964,8 +1975,7 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
          */
         do
         {
-            MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
             MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
 
             /*
diff --git a/crypto/mbedtls/src/ecp_curves.c b/crypto/mbedtls/src/ecp_curves.c
index df5ac3eea..68e2441ae 100644
--- a/crypto/mbedtls/src/ecp_curves.c
+++ b/crypto/mbedtls/src/ecp_curves.c
@@ -627,6 +627,9 @@ static int ecp_mod_p521( mbedtls_mpi * );
 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
 static int ecp_mod_p255( mbedtls_mpi * );
 #endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+static int ecp_mod_p448( mbedtls_mpi * );
+#endif
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
 static int ecp_mod_p192k1( mbedtls_mpi * );
 #endif
@@ -670,7 +673,12 @@ static int ecp_use_curve25519( mbedtls_ecp_group *grp )
     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
     grp->pbits = mbedtls_mpi_bitlen( &grp->P );
 
-    /* Y intentionaly not set, since we use x/z coordinates.
+    /* N = 2^252 + 27742317777372353535851937790883648493 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->N, 16,
+                                              "14DEF9DEA2F79CD65812631A5CF5D3ED" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
+
+    /* Y intentionally not set, since we use x/z coordinates.
      * This is used as a marker to identify Montgomery curves! */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
@@ -687,6 +695,52 @@ static int ecp_use_curve25519( mbedtls_ecp_group *grp )
 }
 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
 
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+/*
+ * Specialized function for creating the Curve448 group
+ */
+static int ecp_use_curve448( mbedtls_ecp_group *grp )
+{
+    mbedtls_mpi Ns;
+    int ret;
+
+    mbedtls_mpi_init( &Ns );
+
+    /* Actually ( A + 2 ) / 4 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "98AA" ) );
+
+    /* P = 2^448 - 2^224 - 1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
+    grp->pbits = mbedtls_mpi_bitlen( &grp->P );
+
+    /* Y intentionally not set, since we use x/z coordinates.
+     * This is used as a marker to identify Montgomery curves! */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
+    mbedtls_mpi_free( &grp->G.Y );
+
+    /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &Ns, 16,
+                                              "8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
+
+    /* Actually, the required msb for private keys */
+    grp->nbits = 447;
+
+cleanup:
+    mbedtls_mpi_free( &Ns );
+    if( ret != 0 )
+        mbedtls_ecp_group_free( grp );
+
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
+
 /*
  * Set a group using well-known domain parameters
  */
@@ -767,6 +821,12 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
             return( ecp_use_curve25519( grp ) );
 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
 
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+        case MBEDTLS_ECP_DP_CURVE448:
+            grp->modp = ecp_mod_p448;
+            return( ecp_use_curve448( grp ) );
+#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
+
         default:
             mbedtls_ecp_group_free( grp );
             return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
@@ -1176,7 +1236,7 @@ static int ecp_mod_p255( mbedtls_mpi *N )
     M.s = 1;
     M.n = N->n - ( P255_WIDTH - 1 );
     if( M.n > P255_WIDTH + 1 )
-        M.n = P255_WIDTH + 1;
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
     M.p = Mp;
     memset( Mp, 0, sizeof Mp );
     memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
@@ -1197,6 +1257,77 @@ static int ecp_mod_p255( mbedtls_mpi *N )
 }
 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
 
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+
+/* Size of p448 in terms of mbedtls_mpi_uint */
+#define P448_WIDTH      ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
+
+/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
+#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
+#define P224_WIDTH_MIN   ( 28 / sizeof( mbedtls_mpi_uint ) )
+#define P224_WIDTH_MAX   DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
+#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
+
+/*
+ * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
+ * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
+ * A0 + A1 + B1 + (B0 + B1) * 2^224.  This is different to the reference
+ * implementation of Curve448, which uses its own special 56-bit limbs rather
+ * than a generic bignum library.  We could squeeze some extra speed out on
+ * 32-bit machines by splitting N up into 32-bit limbs and doing the
+ * arithmetic using the limbs directly as we do for the NIST primes above,
+ * but for 64-bit targets it should use half the number of operations if we do
+ * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
+ */
+static int ecp_mod_p448( mbedtls_mpi *N )
+{
+    int ret;
+    size_t i;
+    mbedtls_mpi M, Q;
+    mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
+
+    if( N->n <= P448_WIDTH )
+        return( 0 );
+
+    /* M = A1 */
+    M.s = 1;
+    M.n = N->n - ( P448_WIDTH );
+    if( M.n > P448_WIDTH )
+        /* Shouldn't be called with N larger than 2^896! */
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    M.p = Mp;
+    memset( Mp, 0, sizeof( Mp ) );
+    memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
+
+    /* N = A0 */
+    for( i = P448_WIDTH; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N += A1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
+
+    /* Q = B1, N += B1 */
+    Q = M;
+    Q.p = Qp;
+    memcpy( Qp, Mp, sizeof( Qp ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
+
+    /* M = (B0 + B1) * 2^224, N += M */
+    if( sizeof( mbedtls_mpi_uint ) > 4 )
+        Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
+    for( i = P224_WIDTH_MAX; i < M.n; ++i )
+        Mp[i] = 0;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
+    M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
+
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||   \
     defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||   \
     defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
diff --git a/crypto/mbedtls/src/entropy.c b/crypto/mbedtls/src/entropy.c
index 23de4062a..e17512e77 100644
--- a/crypto/mbedtls/src/entropy.c
+++ b/crypto/mbedtls/src/entropy.c
@@ -68,21 +68,26 @@ static void mbedtls_zeroize( void *v, size_t n ) {
 
 void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
 {
-    memset( ctx, 0, sizeof(mbedtls_entropy_context) );
+    ctx->source_count = 0;
+    memset( ctx->source, 0, sizeof( ctx->source ) );
 
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_init( &ctx->mutex );
 #endif
 
+    ctx->accumulator_started = 0;
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
-    mbedtls_sha512_starts( &ctx->accumulator, 0 );
+    mbedtls_sha512_init( &ctx->accumulator );
 #else
-    mbedtls_sha256_starts( &ctx->accumulator, 0 );
+    mbedtls_sha256_init( &ctx->accumulator );
 #endif
 #if defined(MBEDTLS_HAVEGE_C)
     mbedtls_havege_init( &ctx->havege_data );
 #endif
 
+    /* Reminder: Update ENTROPY_HAVE_STRONG in the test files
+     *           when adding more strong entropy sources here. */
+
 #if defined(MBEDTLS_TEST_NULL_ENTROPY)
     mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
                                 1, MBEDTLS_ENTROPY_SOURCE_STRONG );
@@ -113,6 +118,7 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
     mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
                                 MBEDTLS_ENTROPY_BLOCK_SIZE,
                                 MBEDTLS_ENTROPY_SOURCE_STRONG );
+    ctx->initial_entropy_run = 0;
 #endif
 #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
 }
@@ -125,7 +131,17 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_free( &ctx->mutex );
 #endif
-    mbedtls_zeroize( ctx, sizeof( mbedtls_entropy_context ) );
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+    mbedtls_sha512_free( &ctx->accumulator );
+#else
+    mbedtls_sha256_free( &ctx->accumulator );
+#endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    ctx->initial_entropy_run = 0;
+#endif
+    ctx->source_count = 0;
+    mbedtls_zeroize( ctx->source, sizeof( ctx->source ) );
+    ctx->accumulator_started = 0;
 }
 
 int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
@@ -172,13 +188,16 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id
     unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
     size_t use_len = len;
     const unsigned char *p = data;
+    int ret = 0;
 
     if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
     {
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
-        mbedtls_sha512( data, len, tmp, 0 );
+        if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 )
+            goto cleanup;
 #else
-        mbedtls_sha256( data, len, tmp, 0 );
+        if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 )
+            goto cleanup;
 #endif
         p = tmp;
         use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
@@ -187,15 +206,35 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id
     header[0] = source_id;
     header[1] = use_len & 0xFF;
 
+    /*
+     * Start the accumulator if this has not already happened. Note that
+     * it is sufficient to start the accumulator here only because all calls to
+     * gather entropy eventually execute this code.
+     */
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
-    mbedtls_sha512_update( &ctx->accumulator, header, 2 );
-    mbedtls_sha512_update( &ctx->accumulator, p, use_len );
+    if( ctx->accumulator_started == 0 &&
+        ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto cleanup;
+    else
+        ctx->accumulator_started = 1;
+    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+        goto cleanup;
+    ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len );
 #else
-    mbedtls_sha256_update( &ctx->accumulator, header, 2 );
-    mbedtls_sha256_update( &ctx->accumulator, p, use_len );
+    if( ctx->accumulator_started == 0 &&
+        ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto cleanup;
+    else
+        ctx->accumulator_started = 1;
+    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+        goto cleanup;
+    ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len );
 #endif
 
-    return( 0 );
+cleanup:
+    mbedtls_zeroize( tmp, sizeof( tmp ) );
+
+    return( ret );
 }
 
 int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
@@ -242,7 +281,7 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx )
         if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
                         buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
         {
-            return( ret );
+            goto cleanup;
         }
 
         /*
@@ -250,15 +289,20 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx )
          */
         if( olen > 0 )
         {
-            entropy_update( ctx, (unsigned char) i, buf, olen );
+            if( ( ret = entropy_update( ctx, (unsigned char) i,
+                                        buf, olen ) ) != 0 )
+                return( ret );
             ctx->source[i].size += olen;
         }
     }
 
     if( have_one_strong == 0 )
-        return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE );
+        ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
 
-    return( 0 );
+cleanup:
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
+    return( ret );
 }
 
 /*
@@ -333,33 +377,52 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
     memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
 
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
-    mbedtls_sha512_finish( &ctx->accumulator, buf );
+    /*
+     * Note that at this stage it is assumed that the accumulator was started
+     * in a previous call to entropy_update(). If this is not guaranteed, the
+     * code below will fail.
+     */
+    if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 )
+        goto exit;
 
     /*
      * Reset accumulator and counters and recycle existing entropy
      */
-    memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) );
-    mbedtls_sha512_starts( &ctx->accumulator, 0 );
-    mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_sha512_free( &ctx->accumulator );
+    mbedtls_sha512_init( &ctx->accumulator );
+    if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf,
+                                           MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        goto exit;
 
     /*
      * Perform second SHA-512 on entropy
      */
-    mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
+    if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                    buf, 0 ) ) != 0 )
+        goto exit;
 #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
-    mbedtls_sha256_finish( &ctx->accumulator, buf );
+    if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 )
+        goto exit;
 
     /*
      * Reset accumulator and counters and recycle existing entropy
      */
-    memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) );
-    mbedtls_sha256_starts( &ctx->accumulator, 0 );
-    mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    mbedtls_sha256_free( &ctx->accumulator );
+    mbedtls_sha256_init( &ctx->accumulator );
+    if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf,
+                                           MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        goto exit;
 
     /*
      * Perform second SHA-256 on entropy
      */
-    mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
+    if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                    buf, 0 ) ) != 0 )
+        goto exit;
 #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
 
     for( i = 0; i < ctx->source_count; i++ )
@@ -370,6 +433,8 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
     ret = 0;
 
 exit:
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
 #if defined(MBEDTLS_THREADING_C)
     if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
         return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
@@ -382,7 +447,7 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
 int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
 {
     int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
-    unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
 
     /* Read new seed  and write it to NV */
     if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
@@ -393,9 +458,9 @@ int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
 
     /* Manually update the remaining stream with a separator value to diverge */
     memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
-    mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
 
-    return( 0 );
+    return( ret );
 }
 #endif /* MBEDTLS_ENTROPY_NV_SEED */
 
@@ -421,12 +486,15 @@ int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *p
     ret = 0;
 
 exit:
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
     fclose( f );
     return( ret );
 }
 
 int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
@@ -442,14 +510,16 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *
         n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
 
     if( fread( buf, 1, n, f ) != n )
-    {
-        fclose( f );
-        return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
-    }
+        ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+    else
+        ret = mbedtls_entropy_update_manual( ctx, buf, n );
 
     fclose( f );
 
-    mbedtls_entropy_update_manual( ctx, buf, n );
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
+    if( ret != 0 )
+        return( ret );
 
     return( mbedtls_entropy_write_seed_file( ctx, path ) );
 }
diff --git a/crypto/mbedtls/src/entropy_poll.c b/crypto/mbedtls/src/entropy_poll.c
index a116e605d..67900c46c 100644
--- a/crypto/mbedtls/src/entropy_poll.c
+++ b/crypto/mbedtls/src/entropy_poll.c
@@ -44,7 +44,7 @@
 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
 
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
-    !defined(__APPLE__) && !defined(_WIN32)
+    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__)
 #error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
 #endif
 
diff --git a/crypto/mbedtls/src/error.c b/crypto/mbedtls/src/error.c
index db42381c4..222d85b62 100644
--- a/crypto/mbedtls/src/error.c
+++ b/crypto/mbedtls/src/error.c
@@ -45,6 +45,10 @@
 #include "mbedtls/aes.h"
 #endif
 
+#if defined(MBEDTLS_ARC4_C)
+#include "mbedtls/arc4.h"
+#endif
+
 #if defined(MBEDTLS_BASE64_C)
 #include "mbedtls/base64.h"
 #endif
@@ -69,6 +73,10 @@
 #include "mbedtls/cipher.h"
 #endif
 
+#if defined(MBEDTLS_CMAC_C)
+#include "mbedtls/cmac.h"
+#endif
+
 #if defined(MBEDTLS_CTR_DRBG_C)
 #include "mbedtls/ctr_drbg.h"
 #endif
@@ -101,6 +109,18 @@
 #include "mbedtls/md.h"
 #endif
 
+#if defined(MBEDTLS_MD2_C)
+#include "mbedtls/md2.h"
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+#include "mbedtls/md4.h"
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+#include "mbedtls/md5.h"
+#endif
+
 #if defined(MBEDTLS_NET_C)
 #include "mbedtls/net_sockets.h"
 #endif
@@ -129,10 +149,26 @@
 #include "mbedtls/pkcs5.h"
 #endif
 
+#if defined(MBEDTLS_RIPEMD160_C)
+#include "mbedtls/ripemd160.h"
+#endif
+
 #if defined(MBEDTLS_RSA_C)
 #include "mbedtls/rsa.h"
 #endif
 
+#if defined(MBEDTLS_SHA1_C)
+#include "mbedtls/sha1.h"
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+#include "mbedtls/sha256.h"
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+#include "mbedtls/sha512.h"
+#endif
+
 #if defined(MBEDTLS_SSL_TLS_C)
 #include "mbedtls/ssl.h"
 #endif
@@ -174,7 +210,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
             mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
         if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
-            mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters to function" );
+            mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" );
         if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
             mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
         if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
@@ -184,12 +220,14 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
             mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
         if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
-            mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid, eg because it was free()ed" );
+            mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" );
 #endif /* MBEDTLS_CIPHER_C */
 
 #if defined(MBEDTLS_DHM_C)
         if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
-            mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters to function" );
+            mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" );
         if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
             mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
         if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
@@ -205,7 +243,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
             mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
         if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
-            mbedtls_snprintf( buf, buflen, "DHM - Read/write of file failed" );
+            mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" );
 #endif /* MBEDTLS_DHM_C */
 
 #if defined(MBEDTLS_ECP_C)
@@ -214,17 +256,19 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
             mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
         if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
-            mbedtls_snprintf( buf, buflen, "ECP - Requested curve not available" );
+            mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" );
         if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
             mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
         if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
             mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
         if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
-            mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" );
+            mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" );
         if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
             mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
         if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
-            mbedtls_snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" );
+            mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" );
 #endif /* MBEDTLS_ECP_C */
 
 #if defined(MBEDTLS_MD_C)
@@ -236,6 +280,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
             mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
         if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
             mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
+        if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" );
 #endif /* MBEDTLS_MD_C */
 
 #if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
@@ -287,7 +333,9 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
             mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
         if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
-            mbedtls_snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" );
+            mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
+        if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
 #endif /* MBEDTLS_PK_C */
 
 #if defined(MBEDTLS_PKCS12_C)
@@ -320,7 +368,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
             mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
         if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
-            mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the library's validity check" );
+            mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" );
         if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
             mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
         if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
@@ -331,6 +379,10 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
             mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
         if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
             mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
+            mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" );
 #endif /* MBEDTLS_RSA_C */
 
 #if defined(MBEDTLS_SSL_TLS_C)
@@ -426,7 +478,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
             mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
         if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
-            mbedtls_snprintf( buf, buflen, "SSL - Connection requires a read call" );
+            mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" );
         if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
             mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
         if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
@@ -439,6 +491,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
             mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" );
         if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) )
             mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
+            mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
 #endif /* MBEDTLS_SSL_TLS_C */
 
 #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
@@ -518,8 +572,17 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
     if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
+        mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
+    if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" );
 #endif /* MBEDTLS_AES_C */
 
+#if defined(MBEDTLS_ARC4_C)
+    if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
+#endif /* MBEDTLS_ARC4_C */
+
 #if defined(MBEDTLS_ASN1_PARSE_C)
     if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
         mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
@@ -566,6 +629,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
 #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_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
 #endif /* MBEDTLS_BLOWFISH_C */
@@ -575,29 +640,40 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
     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) )
+        mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" );
 #endif /* MBEDTLS_CAMELLIA_C */
 
 #if defined(MBEDTLS_CCM_C)
     if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
-        mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to function" );
+        mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" );
     if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
         mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
+    if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
 #endif /* MBEDTLS_CCM_C */
 
+#if defined(MBEDTLS_CMAC_C)
+    if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
+#endif /* MBEDTLS_CMAC_C */
+
 #if defined(MBEDTLS_CTR_DRBG_C)
     if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
         mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
     if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
-        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" );
+        mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" );
     if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
-        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" );
+        mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" );
     if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
-        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" );
+        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" );
 #endif /* MBEDTLS_CTR_DRBG_C */
 
 #if defined(MBEDTLS_DES_C)
     if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
+    if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" );
 #endif /* MBEDTLS_DES_C */
 
 #if defined(MBEDTLS_ENTROPY_C)
@@ -616,6 +692,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
 #if defined(MBEDTLS_GCM_C)
     if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
         mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
+    if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" );
     if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
         mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
 #endif /* MBEDTLS_GCM_C */
@@ -631,6 +709,21 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
 #endif /* MBEDTLS_HMAC_DRBG_C */
 
+#if defined(MBEDTLS_MD2_C)
+    if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" );
+#endif /* MBEDTLS_MD2_C */
+
+#if defined(MBEDTLS_MD4_C)
+    if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" );
+#endif /* MBEDTLS_MD4_C */
+
+#if defined(MBEDTLS_MD5_C)
+    if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" );
+#endif /* MBEDTLS_MD5_C */
+
 #if defined(MBEDTLS_NET_C)
     if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
         mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
@@ -654,6 +747,10 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
     if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
         mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "NET - Input invalid" );
 #endif /* MBEDTLS_NET_C */
 
 #if defined(MBEDTLS_OID_C)
@@ -668,6 +765,26 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
 #endif /* MBEDTLS_PADLOCK_C */
 
+#if defined(MBEDTLS_RIPEMD160_C)
+    if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
+#endif /* MBEDTLS_RIPEMD160_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
+#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" );
+#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" );
+#endif /* MBEDTLS_SHA512_C */
+
 #if defined(MBEDTLS_THREADING_C)
     if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
         mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
@@ -680,6 +797,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
 #if defined(MBEDTLS_XTEA_C)
     if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
+    if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" );
 #endif /* MBEDTLS_XTEA_C */
     // END generated code
 
diff --git a/crypto/mbedtls/src/gcm.c b/crypto/mbedtls/src/gcm.c
index fccb092bd..294a86d3d 100644
--- a/crypto/mbedtls/src/gcm.c
+++ b/crypto/mbedtls/src/gcm.c
@@ -46,6 +46,7 @@
 #endif
 
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+#include "mbedtls/aes.h"
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
@@ -54,6 +55,8 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
 
+#if !defined(MBEDTLS_GCM_ALT)
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -508,6 +511,8 @@ void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
     mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
 }
 
+#endif /* !MBEDTLS_GCM_ALT */
+
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
 /*
  * AES-GCM test vectors from:
@@ -744,34 +749,48 @@ int mbedtls_gcm_self_test( int verbose )
     int i, j, ret;
     mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
 
-    mbedtls_gcm_init( &ctx );
-
     for( j = 0; j < 3; j++ )
     {
         int key_len = 128 + 64 * j;
 
         for( i = 0; i < MAX_TESTS; i++ )
         {
+            mbedtls_gcm_init( &ctx );
+
             if( verbose != 0 )
                 mbedtls_printf( "  AES-GCM-%3d #%d (%s): ",
-                                 key_len, i, "enc" );
-
-            mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
+                                key_len, i, "enc" );
+
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            /*
+             * AES-192 is an optional feature that may be unavailable when
+             * there is an alternative underlying implementation i.e. when
+             * MBEDTLS_AES_ALT is defined.
+             */
+            if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && key_len == 192 )
+            {
+                mbedtls_printf( "skipped\n" );
+                break;
+            }
+            else if( ret != 0 )
+            {
+                goto exit;
+            }
 
             ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
-                                     pt_len[i],
-                                     iv[iv_index[i]], iv_len[i],
-                                     additional[add_index[i]], add_len[i],
-                                     pt[pt_index[i]], buf, 16, tag_buf );
+                                        pt_len[i],
+                                        iv[iv_index[i]], iv_len[i],
+                                        additional[add_index[i]], add_len[i],
+                                        pt[pt_index[i]], buf, 16, tag_buf );
+            if( ret != 0 )
+                goto exit;
 
-            if( ret != 0 ||
-                memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
-                memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+            if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
+                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
             {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                ret = 1;
+                goto exit;
             }
 
             mbedtls_gcm_free( &ctx );
@@ -779,26 +798,31 @@ int mbedtls_gcm_self_test( int verbose )
             if( verbose != 0 )
                 mbedtls_printf( "passed\n" );
 
+            mbedtls_gcm_init( &ctx );
+
             if( verbose != 0 )
                 mbedtls_printf( "  AES-GCM-%3d #%d (%s): ",
-                                 key_len, i, "dec" );
+                                key_len, i, "dec" );
 
-            mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            if( ret != 0 )
+                goto exit;
 
             ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
-                                     pt_len[i],
-                                     iv[iv_index[i]], iv_len[i],
-                                     additional[add_index[i]], add_len[i],
-                                     ct[j * 6 + i], buf, 16, tag_buf );
+                                        pt_len[i],
+                                        iv[iv_index[i]], iv_len[i],
+                                        additional[add_index[i]], add_len[i],
+                                        ct[j * 6 + i], buf, 16, tag_buf );
+
+            if( ret != 0 )
+                goto exit;
 
-            if( ret != 0 ||
-                memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
+            if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
             {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                ret = 1;
+                goto exit;
             }
 
             mbedtls_gcm_free( &ctx );
@@ -806,66 +830,51 @@ int mbedtls_gcm_self_test( int verbose )
             if( verbose != 0 )
                 mbedtls_printf( "passed\n" );
 
+            mbedtls_gcm_init( &ctx );
+
             if( verbose != 0 )
                 mbedtls_printf( "  AES-GCM-%3d #%d split (%s): ",
-                                 key_len, i, "enc" );
+                                key_len, i, "enc" );
 
-            mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            if( ret != 0 )
+                goto exit;
 
             ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
-                              iv[iv_index[i]], iv_len[i],
-                              additional[add_index[i]], add_len[i] );
+                                      iv[iv_index[i]], iv_len[i],
+                                      additional[add_index[i]], add_len[i] );
             if( ret != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                return( 1 );
-            }
+                goto exit;
 
             if( pt_len[i] > 32 )
             {
                 size_t rest_len = pt_len[i] - 32;
                 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
                 if( ret != 0 )
-                {
-                    if( verbose != 0 )
-                        mbedtls_printf( "failed\n" );
-
-                    return( 1 );
-                }
+                    goto exit;
 
                 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
                                   buf + 32 );
                 if( ret != 0 )
-                {
-                    if( verbose != 0 )
-                        mbedtls_printf( "failed\n" );
-
-                    return( 1 );
-                }
+                    goto exit;
             }
             else
             {
                 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
                 if( ret != 0 )
-                {
-                    if( verbose != 0 )
-                        mbedtls_printf( "failed\n" );
-
-                    return( 1 );
-                }
+                    goto exit;
             }
 
             ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
-            if( ret != 0 ||
-                memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
+            if( ret != 0 )
+                goto exit;
+
+            if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
             {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                ret = 1;
+                goto exit;
             }
 
             mbedtls_gcm_free( &ctx );
@@ -873,80 +882,75 @@ int mbedtls_gcm_self_test( int verbose )
             if( verbose != 0 )
                 mbedtls_printf( "passed\n" );
 
+            mbedtls_gcm_init( &ctx );
+
             if( verbose != 0 )
                 mbedtls_printf( "  AES-GCM-%3d #%d split (%s): ",
-                                 key_len, i, "dec" );
+                                key_len, i, "dec" );
 
-            mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            if( ret != 0 )
+                goto exit;
 
             ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
                               iv[iv_index[i]], iv_len[i],
                               additional[add_index[i]], add_len[i] );
             if( ret != 0 )
-            {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                return( 1 );
-            }
+                goto exit;
 
             if( pt_len[i] > 32 )
             {
                 size_t rest_len = pt_len[i] - 32;
                 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
                 if( ret != 0 )
-                {
-                    if( verbose != 0 )
-                        mbedtls_printf( "failed\n" );
-
-                    return( 1 );
-                }
+                    goto exit;
 
                 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
-                                  buf + 32 );
+                                          buf + 32 );
                 if( ret != 0 )
-                {
-                    if( verbose != 0 )
-                        mbedtls_printf( "failed\n" );
-
-                    return( 1 );
-                }
+                    goto exit;
             }
             else
             {
-                ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
+                ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
+                                          buf );
                 if( ret != 0 )
-                {
-                    if( verbose != 0 )
-                        mbedtls_printf( "failed\n" );
-
-                    return( 1 );
-                }
+                    goto exit;
             }
 
             ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
-            if( ret != 0 ||
-                memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
+            if( ret != 0 )
+                goto exit;
+
+            if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
             {
-                if( verbose != 0 )
-                    mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                ret = 1;
+                goto exit;
             }
 
             mbedtls_gcm_free( &ctx );
 
             if( verbose != 0 )
                 mbedtls_printf( "passed\n" );
-
         }
     }
 
     if( verbose != 0 )
         mbedtls_printf( "\n" );
 
-    return( 0 );
+    ret = 0;
+
+exit:
+    if( ret != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+        mbedtls_gcm_free( &ctx );
+    }
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
diff --git a/crypto/mbedtls/src/hmac_drbg.c b/crypto/mbedtls/src/hmac_drbg.c
index bf5f9b5bd..24c609e9c 100644
--- a/crypto/mbedtls/src/hmac_drbg.c
+++ b/crypto/mbedtls/src/hmac_drbg.c
@@ -364,11 +364,14 @@ int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const cha
 
 exit:
     fclose( f );
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
     return( ret );
 }
 
 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
@@ -387,14 +390,16 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch
     }
 
     if( fread( buf, 1, n, f ) != n )
-    {
-        fclose( f );
-        return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
-    }
+        ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
+    else
+        mbedtls_hmac_drbg_update( ctx, buf, n );
 
     fclose( f );
 
-    mbedtls_hmac_drbg_update( ctx, buf, n );
+    mbedtls_zeroize( buf, sizeof( buf ) );
+
+    if( ret != 0 )
+        return( ret );
 
     return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
 }
diff --git a/crypto/mbedtls/src/md.c b/crypto/mbedtls/src/md.c
index eda98f636..00249af78 100644
--- a/crypto/mbedtls/src/md.c
+++ b/crypto/mbedtls/src/md.c
@@ -250,9 +250,7 @@ int mbedtls_md_starts( mbedtls_md_context_t *ctx )
     if( ctx == NULL || ctx->md_info == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->starts_func( ctx->md_ctx );
-
-    return( 0 );
+    return( ctx->md_info->starts_func( ctx->md_ctx ) );
 }
 
 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@@ -260,9 +258,7 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si
     if( ctx == NULL || ctx->md_info == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->update_func( ctx->md_ctx, input, ilen );
-
-    return( 0 );
+    return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
 }
 
 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@@ -270,9 +266,7 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
     if( ctx == NULL || ctx->md_info == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->finish_func( ctx->md_ctx, output );
-
-    return( 0 );
+    return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
 }
 
 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
@@ -281,9 +275,7 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si
     if( md_info == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
-    md_info->digest_func( input, ilen, output );
-
-    return( 0 );
+    return( md_info->digest_func( input, ilen, output ) );
 }
 
 #if defined(MBEDTLS_FS_IO)
@@ -306,20 +298,20 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigne
     if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
         goto cleanup;
 
-    md_info->starts_func( ctx.md_ctx );
+    if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
+        goto cleanup;
 
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
-        md_info->update_func( ctx.md_ctx, buf, n );
+        if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
+            goto cleanup;
 
     if( ferror( f ) != 0 )
-    {
         ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
-        goto cleanup;
-    }
-
-    md_info->finish_func( ctx.md_ctx, output );
+    else
+        ret = md_info->finish_func( ctx.md_ctx, output );
 
 cleanup:
+    mbedtls_zeroize( buf, sizeof( buf ) );
     fclose( f );
     mbedtls_md_free( &ctx );
 
@@ -329,6 +321,7 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigne
 
 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
 {
+    int ret;
     unsigned char sum[MBEDTLS_MD_MAX_SIZE];
     unsigned char *ipad, *opad;
     size_t i;
@@ -338,9 +331,12 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
 
     if( keylen > (size_t) ctx->md_info->block_size )
     {
-        ctx->md_info->starts_func( ctx->md_ctx );
-        ctx->md_info->update_func( ctx->md_ctx, key, keylen );
-        ctx->md_info->finish_func( ctx->md_ctx, sum );
+        if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+            goto cleanup;
+        if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
+            goto cleanup;
+        if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
+            goto cleanup;
 
         keylen = ctx->md_info->size;
         key = sum;
@@ -358,12 +354,16 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
         opad[i] = (unsigned char)( opad[i] ^ key[i] );
     }
 
-    mbedtls_zeroize( sum, sizeof( sum ) );
+    if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+        goto cleanup;
+    if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
+                                           ctx->md_info->block_size ) ) != 0 )
+        goto cleanup;
 
-    ctx->md_info->starts_func( ctx->md_ctx );
-    ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
+cleanup:
+    mbedtls_zeroize( sum, sizeof( sum ) );
 
-    return( 0 );
+    return( ret );
 }
 
 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@@ -371,13 +371,12 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->update_func( ctx->md_ctx, input, ilen );
-
-    return( 0 );
+    return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
 }
 
 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
 {
+    int ret;
     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
     unsigned char *opad;
 
@@ -386,17 +385,22 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
 
     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
 
-    ctx->md_info->finish_func( ctx->md_ctx, tmp );
-    ctx->md_info->starts_func( ctx->md_ctx );
-    ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size );
-    ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size );
-    ctx->md_info->finish_func( ctx->md_ctx, output );
-
-    return( 0 );
+    if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
+        return( ret );
+    if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+        return( ret );
+    if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
+                                           ctx->md_info->block_size ) ) != 0 )
+        return( ret );
+    if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
+                                           ctx->md_info->size ) ) != 0 )
+        return( ret );
+    return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
 }
 
 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
 {
+    int ret;
     unsigned char *ipad;
 
     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
@@ -404,15 +408,16 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
 
     ipad = (unsigned char *) ctx->hmac_ctx;
 
-    ctx->md_info->starts_func( ctx->md_ctx );
-    ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
-
-    return( 0 );
+    if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+        return( ret );
+    return( ctx->md_info->update_func( ctx->md_ctx, ipad,
+                                       ctx->md_info->block_size ) );
 }
 
-int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
-                const unsigned char *input, size_t ilen,
-                unsigned char *output )
+int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
+                     const unsigned char *key, size_t keylen,
+                     const unsigned char *input, size_t ilen,
+                     unsigned char *output )
 {
     mbedtls_md_context_t ctx;
     int ret;
@@ -423,15 +428,19 @@ int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key,
     mbedtls_md_init( &ctx );
 
     if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
-        return( ret );
+        goto cleanup;
 
-    mbedtls_md_hmac_starts( &ctx, key, keylen );
-    mbedtls_md_hmac_update( &ctx, input, ilen );
-    mbedtls_md_hmac_finish( &ctx, output );
+    if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
+        goto cleanup;
+    if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
+        goto cleanup;
+    if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
+        goto cleanup;
 
+cleanup:
     mbedtls_md_free( &ctx );
 
-    return( 0 );
+    return( ret );
 }
 
 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
@@ -439,9 +448,7 @@ int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
     if( ctx == NULL || ctx->md_info == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->process_func( ctx->md_ctx, data );
-
-    return( 0 );
+    return( ctx->md_info->process_func( ctx->md_ctx, data ) );
 }
 
 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
diff --git a/crypto/mbedtls/src/md2.c b/crypto/mbedtls/src/md2.c
index 95cbcce65..b88aa406a 100644
--- a/crypto/mbedtls/src/md2.c
+++ b/crypto/mbedtls/src/md2.c
@@ -105,16 +105,25 @@ void mbedtls_md2_clone( mbedtls_md2_context *dst,
 /*
  * MD2 context setup
  */
-void mbedtls_md2_starts( mbedtls_md2_context *ctx )
+int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
 {
     memset( ctx->cksum, 0, 16 );
     memset( ctx->state, 0, 46 );
     memset( ctx->buffer, 0, 16 );
     ctx->left = 0;
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_starts( mbedtls_md2_context *ctx )
+{
+    mbedtls_md2_starts_ret( ctx );
+}
+#endif
+
 #if !defined(MBEDTLS_MD2_PROCESS_ALT)
-void mbedtls_md2_process( mbedtls_md2_context *ctx )
+int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
 {
     int i, j;
     unsigned char t = 0;
@@ -146,14 +155,26 @@ void mbedtls_md2_process( mbedtls_md2_context *ctx )
            ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
         t  = ctx->cksum[i];
     }
+
+    return( 0 );
 }
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_process( mbedtls_md2_context *ctx )
+{
+    mbedtls_internal_md2_process( ctx );
+}
+#endif
 #endif /* !MBEDTLS_MD2_PROCESS_ALT */
 
 /*
  * MD2 process buffer
  */
-void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen )
+int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
 {
+    int ret;
     size_t fill;
 
     while( ilen > 0 )
@@ -172,16 +193,30 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, s
         if( ctx->left == 16 )
         {
             ctx->left = 0;
-            mbedtls_md2_process( ctx );
+            if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
+                return( ret );
         }
     }
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_update( mbedtls_md2_context *ctx,
+                         const unsigned char *input,
+                         size_t ilen )
+{
+    mbedtls_md2_update_ret( ctx, input, ilen );
+}
+#endif
+
 /*
  * MD2 final digest
  */
-void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] )
+int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
+                            unsigned char output[16] )
 {
+    int ret;
     size_t i;
     unsigned char x;
 
@@ -190,36 +225,70 @@ void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] )
     for( i = ctx->left; i < 16; i++ )
         ctx->buffer[i] = x;
 
-    mbedtls_md2_process( ctx );
+    if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
+        return( ret );
 
     memcpy( ctx->buffer, ctx->cksum, 16 );
-    mbedtls_md2_process( ctx );
+    if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
+        return( ret );
 
     memcpy( output, ctx->state, 16 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_finish( mbedtls_md2_context *ctx,
+                         unsigned char output[16] )
+{
+    mbedtls_md2_finish_ret( ctx, output );
 }
+#endif
 
 #endif /* !MBEDTLS_MD2_ALT */
 
 /*
  * output = MD2( input buffer )
  */
-void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
+int mbedtls_md2_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] )
 {
+    int ret;
     mbedtls_md2_context ctx;
 
     mbedtls_md2_init( &ctx );
-    mbedtls_md2_starts( &ctx );
-    mbedtls_md2_update( &ctx, input, ilen );
-    mbedtls_md2_finish( &ctx, output );
+
+    if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
     mbedtls_md2_free( &ctx );
+
+    return( ret );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2( const unsigned char *input,
+                  size_t ilen,
+                  unsigned char output[16] )
+{
+    mbedtls_md2_ret( input, ilen, output );
+}
+#endif
+
 #if defined(MBEDTLS_SELF_TEST)
 
 /*
  * RFC 1319 test vectors
  */
-static const char md2_test_str[7][81] =
+static const unsigned char md2_test_str[7][81] =
 {
     { "" },
     { "a" },
@@ -227,10 +296,15 @@ static const char md2_test_str[7][81] =
     { "message digest" },
     { "abcdefghijklmnopqrstuvwxyz" },
     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012" \
+    { "12345678901234567890123456789012345678901234567890123456789012"
       "345678901234567890" }
 };
 
+static const size_t md2_test_strlen[7] =
+{
+    0, 1, 3, 14, 26, 62, 80
+};
+
 static const unsigned char md2_test_sum[7][16] =
 {
     { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
@@ -254,7 +328,7 @@ static const unsigned char md2_test_sum[7][16] =
  */
 int mbedtls_md2_self_test( int verbose )
 {
-    int i;
+    int i, ret = 0;
     unsigned char md2sum[16];
 
     for( i = 0; i < 7; i++ )
@@ -262,15 +336,14 @@ int mbedtls_md2_self_test( int verbose )
         if( verbose != 0 )
             mbedtls_printf( "  MD2 test #%d: ", i + 1 );
 
-        mbedtls_md2( (unsigned char *) md2_test_str[i],
-             strlen( md2_test_str[i] ), md2sum );
+        ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum );
+        if( ret != 0 )
+            goto fail;
 
         if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
         {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
-            return( 1 );
+            ret = 1;
+            goto fail;
         }
 
         if( verbose != 0 )
@@ -281,6 +354,12 @@ int mbedtls_md2_self_test( int verbose )
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/crypto/mbedtls/src/md4.c b/crypto/mbedtls/src/md4.c
index 11a77e3ae..ba704f58e 100644
--- a/crypto/mbedtls/src/md4.c
+++ b/crypto/mbedtls/src/md4.c
@@ -98,7 +98,7 @@ void mbedtls_md4_clone( mbedtls_md4_context *dst,
 /*
  * MD4 context setup
  */
-void mbedtls_md4_starts( mbedtls_md4_context *ctx )
+int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -107,10 +107,20 @@ void mbedtls_md4_starts( mbedtls_md4_context *ctx )
     ctx->state[1] = 0xEFCDAB89;
     ctx->state[2] = 0x98BADCFE;
     ctx->state[3] = 0x10325476;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_starts( mbedtls_md4_context *ctx )
+{
+    mbedtls_md4_starts_ret( ctx );
 }
+#endif
 
 #if !defined(MBEDTLS_MD4_PROCESS_ALT)
-void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] )
+int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
+                                  const unsigned char data[64] )
 {
     uint32_t X[16], A, B, C, D;
 
@@ -211,19 +221,32 @@ void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64]
     ctx->state[1] += B;
     ctx->state[2] += C;
     ctx->state[3] += D;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_process( mbedtls_md4_context *ctx,
+                          const unsigned char data[64] )
+{
+    mbedtls_internal_md4_process( ctx, data );
 }
+#endif
 #endif /* !MBEDTLS_MD4_PROCESS_ALT */
 
 /*
  * MD4 process buffer
  */
-void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen )
+int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
 {
+    int ret;
     size_t fill;
     uint32_t left;
 
     if( ilen == 0 )
-        return;
+        return( 0 );
 
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
@@ -238,7 +261,10 @@ void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, s
     {
         memcpy( (void *) (ctx->buffer + left),
                 (void *) input, fill );
-        mbedtls_md4_process( ctx, ctx->buffer );
+
+        if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
         input += fill;
         ilen  -= fill;
         left = 0;
@@ -246,7 +272,9 @@ void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, s
 
     while( ilen >= 64 )
     {
-        mbedtls_md4_process( ctx, input );
+        if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
@@ -256,7 +284,18 @@ void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, s
         memcpy( (void *) (ctx->buffer + left),
                 (void *) input, ilen );
     }
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_update( mbedtls_md4_context *ctx,
+                         const unsigned char *input,
+                         size_t ilen )
+{
+    mbedtls_md4_update_ret( ctx, input, ilen );
 }
+#endif
 
 static const unsigned char md4_padding[64] =
 {
@@ -269,8 +308,10 @@ static const unsigned char md4_padding[64] =
 /*
  * MD4 final digest
  */
-void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] )
+int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
+                            unsigned char output[16] )
 {
+    int ret;
     uint32_t last, padn;
     uint32_t high, low;
     unsigned char msglen[8];
@@ -285,37 +326,74 @@ void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] )
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
 
-    mbedtls_md4_update( ctx, (unsigned char *) md4_padding, padn );
-    mbedtls_md4_update( ctx, msglen, 8 );
+    ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
+    if( ret != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
+        return( ret );
+
 
     PUT_UINT32_LE( ctx->state[0], output,  0 );
     PUT_UINT32_LE( ctx->state[1], output,  4 );
     PUT_UINT32_LE( ctx->state[2], output,  8 );
     PUT_UINT32_LE( ctx->state[3], output, 12 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_finish( mbedtls_md4_context *ctx,
+                         unsigned char output[16] )
+{
+    mbedtls_md4_finish_ret( ctx, output );
 }
+#endif
 
 #endif /* !MBEDTLS_MD4_ALT */
 
 /*
  * output = MD4( input buffer )
  */
-void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
+int mbedtls_md4_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] )
 {
+    int ret;
     mbedtls_md4_context ctx;
 
     mbedtls_md4_init( &ctx );
-    mbedtls_md4_starts( &ctx );
-    mbedtls_md4_update( &ctx, input, ilen );
-    mbedtls_md4_finish( &ctx, output );
+
+    if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
     mbedtls_md4_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4( const unsigned char *input,
+                  size_t ilen,
+                  unsigned char output[16] )
+{
+    mbedtls_md4_ret( input, ilen, output );
 }
+#endif
 
 #if defined(MBEDTLS_SELF_TEST)
 
 /*
  * RFC 1320 test vectors
  */
-static const char md4_test_str[7][81] =
+static const unsigned char md4_test_str[7][81] =
 {
     { "" },
     { "a" },
@@ -323,10 +401,15 @@ static const char md4_test_str[7][81] =
     { "message digest" },
     { "abcdefghijklmnopqrstuvwxyz" },
     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012" \
+    { "12345678901234567890123456789012345678901234567890123456789012"
       "345678901234567890" }
 };
 
+static const size_t md4_test_strlen[7] =
+{
+    0, 1, 3, 14, 26, 62, 80
+};
+
 static const unsigned char md4_test_sum[7][16] =
 {
     { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
@@ -350,7 +433,7 @@ static const unsigned char md4_test_sum[7][16] =
  */
 int mbedtls_md4_self_test( int verbose )
 {
-    int i;
+    int i, ret = 0;
     unsigned char md4sum[16];
 
     for( i = 0; i < 7; i++ )
@@ -358,15 +441,14 @@ int mbedtls_md4_self_test( int verbose )
         if( verbose != 0 )
             mbedtls_printf( "  MD4 test #%d: ", i + 1 );
 
-        mbedtls_md4( (unsigned char *) md4_test_str[i],
-             strlen( md4_test_str[i] ), md4sum );
+        ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
+        if( ret != 0 )
+            goto fail;
 
         if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
         {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
-            return( 1 );
+            ret = 1;
+            goto fail;
         }
 
         if( verbose != 0 )
@@ -377,6 +459,12 @@ int mbedtls_md4_self_test( int verbose )
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/crypto/mbedtls/src/md5.c b/crypto/mbedtls/src/md5.c
index 5d972dc9d..8440ebffc 100644
--- a/crypto/mbedtls/src/md5.c
+++ b/crypto/mbedtls/src/md5.c
@@ -97,7 +97,7 @@ void mbedtls_md5_clone( mbedtls_md5_context *dst,
 /*
  * MD5 context setup
  */
-void mbedtls_md5_starts( mbedtls_md5_context *ctx )
+int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -106,10 +106,20 @@ void mbedtls_md5_starts( mbedtls_md5_context *ctx )
     ctx->state[1] = 0xEFCDAB89;
     ctx->state[2] = 0x98BADCFE;
     ctx->state[3] = 0x10325476;
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_starts( mbedtls_md5_context *ctx )
+{
+    mbedtls_md5_starts_ret( ctx );
+}
+#endif
+
 #if !defined(MBEDTLS_MD5_PROCESS_ALT)
-void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] )
+int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
+                                  const unsigned char data[64] )
 {
     uint32_t X[16], A, B, C, D;
 
@@ -230,19 +240,32 @@ void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64]
     ctx->state[1] += B;
     ctx->state[2] += C;
     ctx->state[3] += D;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_process( mbedtls_md5_context *ctx,
+                          const unsigned char data[64] )
+{
+    mbedtls_internal_md5_process( ctx, data );
 }
+#endif
 #endif /* !MBEDTLS_MD5_PROCESS_ALT */
 
 /*
  * MD5 process buffer
  */
-void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen )
+int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
 {
+    int ret;
     size_t fill;
     uint32_t left;
 
     if( ilen == 0 )
-        return;
+        return( 0 );
 
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
@@ -256,7 +279,9 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, s
     if( left && ilen >= fill )
     {
         memcpy( (void *) (ctx->buffer + left), input, fill );
-        mbedtls_md5_process( ctx, ctx->buffer );
+        if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
         input += fill;
         ilen  -= fill;
         left = 0;
@@ -264,7 +289,9 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, s
 
     while( ilen >= 64 )
     {
-        mbedtls_md5_process( ctx, input );
+        if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
@@ -273,8 +300,19 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, s
     {
         memcpy( (void *) (ctx->buffer + left), input, ilen );
     }
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_update( mbedtls_md5_context *ctx,
+                         const unsigned char *input,
+                         size_t ilen )
+{
+    mbedtls_md5_update_ret( ctx, input, ilen );
+}
+#endif
+
 static const unsigned char md5_padding[64] =
 {
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -286,8 +324,10 @@ static const unsigned char md5_padding[64] =
 /*
  * MD5 final digest
  */
-void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
+int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
+                            unsigned char output[16] )
 {
+    int ret;
     uint32_t last, padn;
     uint32_t high, low;
     unsigned char msglen[8];
@@ -302,30 +342,65 @@ void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
 
-    mbedtls_md5_update( ctx, md5_padding, padn );
-    mbedtls_md5_update( ctx, msglen, 8 );
+    if( ( ret = mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) != 0 )
+            return( ret );
+
+    if( ( ret = mbedtls_md5_update_ret( ctx, msglen, 8 ) ) != 0 )
+            return( ret );
 
     PUT_UINT32_LE( ctx->state[0], output,  0 );
     PUT_UINT32_LE( ctx->state[1], output,  4 );
     PUT_UINT32_LE( ctx->state[2], output,  8 );
     PUT_UINT32_LE( ctx->state[3], output, 12 );
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_finish( mbedtls_md5_context *ctx,
+                         unsigned char output[16] )
+{
+    mbedtls_md5_finish_ret( ctx, output );
+}
+#endif
+
 #endif /* !MBEDTLS_MD5_ALT */
 
 /*
  * output = MD5( input buffer )
  */
-void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
+int mbedtls_md5_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] )
 {
+    int ret;
     mbedtls_md5_context ctx;
 
     mbedtls_md5_init( &ctx );
-    mbedtls_md5_starts( &ctx );
-    mbedtls_md5_update( &ctx, input, ilen );
-    mbedtls_md5_finish( &ctx, output );
+
+    if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
     mbedtls_md5_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5( const unsigned char *input,
+                  size_t ilen,
+                  unsigned char output[16] )
+{
+    mbedtls_md5_ret( input, ilen, output );
 }
+#endif
 
 #if defined(MBEDTLS_SELF_TEST)
 /*
@@ -339,11 +414,11 @@ static const unsigned char md5_test_buf[7][81] =
     { "message digest" },
     { "abcdefghijklmnopqrstuvwxyz" },
     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012" \
+    { "12345678901234567890123456789012345678901234567890123456789012"
       "345678901234567890" }
 };
 
-static const int md5_test_buflen[7] =
+static const size_t md5_test_buflen[7] =
 {
     0, 1, 3, 14, 26, 62, 80
 };
@@ -371,7 +446,7 @@ static const unsigned char md5_test_sum[7][16] =
  */
 int mbedtls_md5_self_test( int verbose )
 {
-    int i;
+    int i, ret = 0;
     unsigned char md5sum[16];
 
     for( i = 0; i < 7; i++ )
@@ -379,14 +454,14 @@ int mbedtls_md5_self_test( int verbose )
         if( verbose != 0 )
             mbedtls_printf( "  MD5 test #%d: ", i + 1 );
 
-        mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
+        ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum );
+        if( ret != 0 )
+            goto fail;
 
         if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
         {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
-            return( 1 );
+            ret = 1;
+            goto fail;
         }
 
         if( verbose != 0 )
@@ -397,6 +472,12 @@ int mbedtls_md5_self_test( int verbose )
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/crypto/mbedtls/src/md_wrap.c b/crypto/mbedtls/src/md_wrap.c
index 2cfcae200..32f087197 100644
--- a/crypto/mbedtls/src/md_wrap.c
+++ b/crypto/mbedtls/src/md_wrap.c
@@ -71,20 +71,20 @@
 
 #if defined(MBEDTLS_MD2_C)
 
-static void md2_starts_wrap( void *ctx )
+static int md2_starts_wrap( void *ctx )
 {
-    mbedtls_md2_starts( (mbedtls_md2_context *) ctx );
+    return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
 }
 
-static void md2_update_wrap( void *ctx, const unsigned char *input,
+static int md2_update_wrap( void *ctx, const unsigned char *input,
                              size_t ilen )
 {
-    mbedtls_md2_update( (mbedtls_md2_context *) ctx, input, ilen );
+    return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
 }
 
-static void md2_finish_wrap( void *ctx, unsigned char *output )
+static int md2_finish_wrap( void *ctx, unsigned char *output )
 {
-    mbedtls_md2_finish( (mbedtls_md2_context *) ctx, output );
+    return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
 }
 
 static void *md2_ctx_alloc( void )
@@ -109,11 +109,11 @@ static void md2_clone_wrap( void *dst, const void *src )
                  (const mbedtls_md2_context *) src );
 }
 
-static void md2_process_wrap( void *ctx, const unsigned char *data )
+static int md2_process_wrap( void *ctx, const unsigned char *data )
 {
     ((void) data);
 
-    mbedtls_md2_process( (mbedtls_md2_context *) ctx );
+    return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
 }
 
 const mbedtls_md_info_t mbedtls_md2_info = {
@@ -124,7 +124,7 @@ const mbedtls_md_info_t mbedtls_md2_info = {
     md2_starts_wrap,
     md2_update_wrap,
     md2_finish_wrap,
-    mbedtls_md2,
+    mbedtls_md2_ret,
     md2_ctx_alloc,
     md2_ctx_free,
     md2_clone_wrap,
@@ -135,20 +135,20 @@ const mbedtls_md_info_t mbedtls_md2_info = {
 
 #if defined(MBEDTLS_MD4_C)
 
-static void md4_starts_wrap( void *ctx )
+static int md4_starts_wrap( void *ctx )
 {
-    mbedtls_md4_starts( (mbedtls_md4_context *) ctx );
+    return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
 }
 
-static void md4_update_wrap( void *ctx, const unsigned char *input,
+static int md4_update_wrap( void *ctx, const unsigned char *input,
                              size_t ilen )
 {
-    mbedtls_md4_update( (mbedtls_md4_context *) ctx, input, ilen );
+    return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
 }
 
-static void md4_finish_wrap( void *ctx, unsigned char *output )
+static int md4_finish_wrap( void *ctx, unsigned char *output )
 {
-    mbedtls_md4_finish( (mbedtls_md4_context *) ctx, output );
+    return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
 }
 
 static void *md4_ctx_alloc( void )
@@ -170,12 +170,12 @@ static void md4_ctx_free( void *ctx )
 static void md4_clone_wrap( void *dst, const void *src )
 {
     mbedtls_md4_clone( (mbedtls_md4_context *) dst,
-                 (const mbedtls_md4_context *) src );
+                       (const mbedtls_md4_context *) src );
 }
 
-static void md4_process_wrap( void *ctx, const unsigned char *data )
+static int md4_process_wrap( void *ctx, const unsigned char *data )
 {
-    mbedtls_md4_process( (mbedtls_md4_context *) ctx, data );
+    return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
 }
 
 const mbedtls_md_info_t mbedtls_md4_info = {
@@ -186,7 +186,7 @@ const mbedtls_md_info_t mbedtls_md4_info = {
     md4_starts_wrap,
     md4_update_wrap,
     md4_finish_wrap,
-    mbedtls_md4,
+    mbedtls_md4_ret,
     md4_ctx_alloc,
     md4_ctx_free,
     md4_clone_wrap,
@@ -197,20 +197,20 @@ const mbedtls_md_info_t mbedtls_md4_info = {
 
 #if defined(MBEDTLS_MD5_C)
 
-static void md5_starts_wrap( void *ctx )
+static int md5_starts_wrap( void *ctx )
 {
-    mbedtls_md5_starts( (mbedtls_md5_context *) ctx );
+    return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
 }
 
-static void md5_update_wrap( void *ctx, const unsigned char *input,
+static int md5_update_wrap( void *ctx, const unsigned char *input,
                              size_t ilen )
 {
-    mbedtls_md5_update( (mbedtls_md5_context *) ctx, input, ilen );
+    return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
 }
 
-static void md5_finish_wrap( void *ctx, unsigned char *output )
+static int md5_finish_wrap( void *ctx, unsigned char *output )
 {
-    mbedtls_md5_finish( (mbedtls_md5_context *) ctx, output );
+    return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
 }
 
 static void *md5_ctx_alloc( void )
@@ -232,12 +232,12 @@ static void md5_ctx_free( void *ctx )
 static void md5_clone_wrap( void *dst, const void *src )
 {
     mbedtls_md5_clone( (mbedtls_md5_context *) dst,
-                 (const mbedtls_md5_context *) src );
+                       (const mbedtls_md5_context *) src );
 }
 
-static void md5_process_wrap( void *ctx, const unsigned char *data )
+static int md5_process_wrap( void *ctx, const unsigned char *data )
 {
-    mbedtls_md5_process( (mbedtls_md5_context *) ctx, data );
+    return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
 }
 
 const mbedtls_md_info_t mbedtls_md5_info = {
@@ -248,7 +248,7 @@ const mbedtls_md_info_t mbedtls_md5_info = {
     md5_starts_wrap,
     md5_update_wrap,
     md5_finish_wrap,
-    mbedtls_md5,
+    mbedtls_md5_ret,
     md5_ctx_alloc,
     md5_ctx_free,
     md5_clone_wrap,
@@ -259,20 +259,22 @@ const mbedtls_md_info_t mbedtls_md5_info = {
 
 #if defined(MBEDTLS_RIPEMD160_C)
 
-static void ripemd160_starts_wrap( void *ctx )
+static int ripemd160_starts_wrap( void *ctx )
 {
-    mbedtls_ripemd160_starts( (mbedtls_ripemd160_context *) ctx );
+    return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
 }
 
-static void ripemd160_update_wrap( void *ctx, const unsigned char *input,
+static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
                                    size_t ilen )
 {
-    mbedtls_ripemd160_update( (mbedtls_ripemd160_context *) ctx, input, ilen );
+    return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
+                                          input, ilen ) );
 }
 
-static void ripemd160_finish_wrap( void *ctx, unsigned char *output )
+static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
 {
-    mbedtls_ripemd160_finish( (mbedtls_ripemd160_context *) ctx, output );
+    return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
+                                          output ) );
 }
 
 static void *ripemd160_ctx_alloc( void )
@@ -297,9 +299,10 @@ static void ripemd160_clone_wrap( void *dst, const void *src )
                        (const mbedtls_ripemd160_context *) src );
 }
 
-static void ripemd160_process_wrap( void *ctx, const unsigned char *data )
+static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
 {
-    mbedtls_ripemd160_process( (mbedtls_ripemd160_context *) ctx, data );
+    return( mbedtls_internal_ripemd160_process(
+                                (mbedtls_ripemd160_context *) ctx, data ) );
 }
 
 const mbedtls_md_info_t mbedtls_ripemd160_info = {
@@ -310,7 +313,7 @@ const mbedtls_md_info_t mbedtls_ripemd160_info = {
     ripemd160_starts_wrap,
     ripemd160_update_wrap,
     ripemd160_finish_wrap,
-    mbedtls_ripemd160,
+    mbedtls_ripemd160_ret,
     ripemd160_ctx_alloc,
     ripemd160_ctx_free,
     ripemd160_clone_wrap,
@@ -321,20 +324,21 @@ const mbedtls_md_info_t mbedtls_ripemd160_info = {
 
 #if defined(MBEDTLS_SHA1_C)
 
-static void sha1_starts_wrap( void *ctx )
+static int sha1_starts_wrap( void *ctx )
 {
-    mbedtls_sha1_starts( (mbedtls_sha1_context *) ctx );
+    return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
 }
 
-static void sha1_update_wrap( void *ctx, const unsigned char *input,
+static int sha1_update_wrap( void *ctx, const unsigned char *input,
                               size_t ilen )
 {
-    mbedtls_sha1_update( (mbedtls_sha1_context *) ctx, input, ilen );
+    return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
+                                     input, ilen ) );
 }
 
-static void sha1_finish_wrap( void *ctx, unsigned char *output )
+static int sha1_finish_wrap( void *ctx, unsigned char *output )
 {
-    mbedtls_sha1_finish( (mbedtls_sha1_context *) ctx, output );
+    return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
 }
 
 static void *sha1_ctx_alloc( void )
@@ -359,9 +363,10 @@ static void sha1_ctx_free( void *ctx )
     mbedtls_free( ctx );
 }
 
-static void sha1_process_wrap( void *ctx, const unsigned char *data )
+static int sha1_process_wrap( void *ctx, const unsigned char *data )
 {
-    mbedtls_sha1_process( (mbedtls_sha1_context *) ctx, data );
+    return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
+                                           data ) );
 }
 
 const mbedtls_md_info_t mbedtls_sha1_info = {
@@ -372,7 +377,7 @@ const mbedtls_md_info_t mbedtls_sha1_info = {
     sha1_starts_wrap,
     sha1_update_wrap,
     sha1_finish_wrap,
-    mbedtls_sha1,
+    mbedtls_sha1_ret,
     sha1_ctx_alloc,
     sha1_ctx_free,
     sha1_clone_wrap,
@@ -386,26 +391,28 @@ const mbedtls_md_info_t mbedtls_sha1_info = {
  */
 #if defined(MBEDTLS_SHA256_C)
 
-static void sha224_starts_wrap( void *ctx )
+static int sha224_starts_wrap( void *ctx )
 {
-    mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 1 );
+    return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
 }
 
-static void sha224_update_wrap( void *ctx, const unsigned char *input,
+static int sha224_update_wrap( void *ctx, const unsigned char *input,
                                 size_t ilen )
 {
-    mbedtls_sha256_update( (mbedtls_sha256_context *) ctx, input, ilen );
+    return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
+                                       input, ilen ) );
 }
 
-static void sha224_finish_wrap( void *ctx, unsigned char *output )
+static int sha224_finish_wrap( void *ctx, unsigned char *output )
 {
-    mbedtls_sha256_finish( (mbedtls_sha256_context *) ctx, output );
+    return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
+                                       output ) );
 }
 
-static void sha224_wrap( const unsigned char *input, size_t ilen,
-                    unsigned char *output )
+static int sha224_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
 {
-    mbedtls_sha256( input, ilen, output, 1 );
+    return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
 }
 
 static void *sha224_ctx_alloc( void )
@@ -430,9 +437,10 @@ static void sha224_clone_wrap( void *dst, const void *src )
                     (const mbedtls_sha256_context *) src );
 }
 
-static void sha224_process_wrap( void *ctx, const unsigned char *data )
+static int sha224_process_wrap( void *ctx, const unsigned char *data )
 {
-    mbedtls_sha256_process( (mbedtls_sha256_context *) ctx, data );
+    return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
+                                             data ) );
 }
 
 const mbedtls_md_info_t mbedtls_sha224_info = {
@@ -450,15 +458,15 @@ const mbedtls_md_info_t mbedtls_sha224_info = {
     sha224_process_wrap,
 };
 
-static void sha256_starts_wrap( void *ctx )
+static int sha256_starts_wrap( void *ctx )
 {
-    mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 0 );
+    return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
 }
 
-static void sha256_wrap( const unsigned char *input, size_t ilen,
-                    unsigned char *output )
+static int sha256_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
 {
-    mbedtls_sha256( input, ilen, output, 0 );
+    return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
 }
 
 const mbedtls_md_info_t mbedtls_sha256_info = {
@@ -480,26 +488,28 @@ const mbedtls_md_info_t mbedtls_sha256_info = {
 
 #if defined(MBEDTLS_SHA512_C)
 
-static void sha384_starts_wrap( void *ctx )
+static int sha384_starts_wrap( void *ctx )
 {
-    mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 1 );
+    return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
 }
 
-static void sha384_update_wrap( void *ctx, const unsigned char *input,
-                                size_t ilen )
+static int sha384_update_wrap( void *ctx, const unsigned char *input,
+                               size_t ilen )
 {
-    mbedtls_sha512_update( (mbedtls_sha512_context *) ctx, input, ilen );
+    return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
+                                       input, ilen ) );
 }
 
-static void sha384_finish_wrap( void *ctx, unsigned char *output )
+static int sha384_finish_wrap( void *ctx, unsigned char *output )
 {
-    mbedtls_sha512_finish( (mbedtls_sha512_context *) ctx, output );
+    return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
+                                       output ) );
 }
 
-static void sha384_wrap( const unsigned char *input, size_t ilen,
-                    unsigned char *output )
+static int sha384_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
 {
-    mbedtls_sha512( input, ilen, output, 1 );
+    return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
 }
 
 static void *sha384_ctx_alloc( void )
@@ -524,9 +534,10 @@ static void sha384_clone_wrap( void *dst, const void *src )
                     (const mbedtls_sha512_context *) src );
 }
 
-static void sha384_process_wrap( void *ctx, const unsigned char *data )
+static int sha384_process_wrap( void *ctx, const unsigned char *data )
 {
-    mbedtls_sha512_process( (mbedtls_sha512_context *) ctx, data );
+    return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
+                                             data ) );
 }
 
 const mbedtls_md_info_t mbedtls_sha384_info = {
@@ -544,15 +555,15 @@ const mbedtls_md_info_t mbedtls_sha384_info = {
     sha384_process_wrap,
 };
 
-static void sha512_starts_wrap( void *ctx )
+static int sha512_starts_wrap( void *ctx )
 {
-    mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 0 );
+    return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
 }
 
-static void sha512_wrap( const unsigned char *input, size_t ilen,
-                    unsigned char *output )
+static int sha512_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
 {
-    mbedtls_sha512( input, ilen, output, 0 );
+    return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
 }
 
 const mbedtls_md_info_t mbedtls_sha512_info = {
diff --git a/crypto/mbedtls/src/memory_buffer_alloc.c b/crypto/mbedtls/src/memory_buffer_alloc.c
index 545d5a2c3..821ae2c70 100644
--- a/crypto/mbedtls/src/memory_buffer_alloc.c
+++ b/crypto/mbedtls/src/memory_buffer_alloc.c
@@ -113,7 +113,7 @@ static void debug_header( memory_header *hdr )
 #endif
 }
 
-static void debug_chain()
+static void debug_chain( void )
 {
     memory_header *cur = heap.first;
 
@@ -180,11 +180,11 @@ static int verify_header( memory_header *hdr )
     return( 0 );
 }
 
-static int verify_chain()
+static int verify_chain( void )
 {
-    memory_header *prv = heap.first, *cur = heap.first->next;
+    memory_header *prv = heap.first, *cur;
 
-    if( verify_header( heap.first ) != 0 )
+    if( prv == NULL || verify_header( prv ) != 0 )
     {
 #if defined(MBEDTLS_MEMORY_DEBUG)
         mbedtls_fprintf( stderr, "FATAL: verification of first header "
@@ -202,6 +202,8 @@ static int verify_chain()
         return( 1 );
     }
 
+    cur = heap.first->next;
+
     while( cur != NULL )
     {
         if( verify_header( cur ) != 0 )
@@ -245,7 +247,9 @@ static void *buffer_alloc_calloc( size_t n, size_t size )
 
     original_len = len = n * size;
 
-    if( n != 0 && len / n != size )
+    if( n == 0 || size == 0 || len / n != size )
+        return( NULL );
+    else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE )
         return( NULL );
 
     if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
@@ -386,7 +390,7 @@ static void buffer_alloc_free( void *ptr )
     if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
         return;
 
-    if( p < heap.buf || p > heap.buf + heap.len )
+    if( p < heap.buf || p >= heap.buf + heap.len )
     {
 #if defined(MBEDTLS_MEMORY_DEBUG)
         mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
@@ -500,13 +504,13 @@ void mbedtls_memory_buffer_set_verify( int verify )
     heap.verify = verify;
 }
 
-int mbedtls_memory_buffer_alloc_verify()
+int mbedtls_memory_buffer_alloc_verify( void )
 {
     return verify_chain();
 }
 
 #if defined(MBEDTLS_MEMORY_DEBUG)
-void mbedtls_memory_buffer_alloc_status()
+void mbedtls_memory_buffer_alloc_status( void )
 {
     mbedtls_fprintf( stderr,
                       "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
@@ -570,8 +574,7 @@ static void buffer_alloc_free_mutexed( void *ptr )
 
 void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
 {
-    memset( &heap, 0, sizeof(buffer_alloc_ctx) );
-    memset( buf, 0, len );
+    memset( &heap, 0, sizeof( buffer_alloc_ctx ) );
 
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_init( &heap.mutex );
@@ -581,26 +584,30 @@ void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
     mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
 #endif
 
-    if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+    if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+        return;
+    else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
     {
         /* Adjust len first since buf is used in the computation */
         len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
-             - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+             - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
         buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
-             - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+             - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
     }
 
+    memset( buf, 0, len );
+
     heap.buf = buf;
     heap.len = len;
 
-    heap.first = (memory_header *) buf;
-    heap.first->size = len - sizeof(memory_header);
+    heap.first = (memory_header *)buf;
+    heap.first->size = len - sizeof( memory_header );
     heap.first->magic1 = MAGIC1;
     heap.first->magic2 = MAGIC2;
     heap.first_free = heap.first;
 }
 
-void mbedtls_memory_buffer_alloc_free()
+void mbedtls_memory_buffer_alloc_free( void )
 {
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_free( &heap.mutex );
@@ -620,7 +627,7 @@ static int check_pointer( void *p )
     return( 0 );
 }
 
-static int check_all_free( )
+static int check_all_free( void )
 {
     if(
 #if defined(MBEDTLS_MEMORY_DEBUG)
diff --git a/crypto/mbedtls/src/net.c b/crypto/mbedtls/src/net.c
deleted file mode 100644
index a77268c55..000000000
--- a/crypto/mbedtls/src/net.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- *  TCP/IP or UDP/IP networking functions
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *  This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_NET_C)
-
-#include "mbedtls/net.h"
-
-#include <string.h>
-
-#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
-    !defined(EFI32)
-
-#ifdef _WIN32_WINNT
-#undef _WIN32_WINNT
-#endif
-/* Enables getaddrinfo() & Co */
-#define _WIN32_WINNT 0x0501
-#include <ws2tcpip.h>
-
-#include <winsock2.h>
-#include <windows.h>
-
-#if defined(_MSC_VER)
-#if defined(_WIN32_WCE)
-#pragma comment( lib, "ws2.lib" )
-#else
-#pragma comment( lib, "ws2_32.lib" )
-#endif
-#endif /* _MSC_VER */
-
-#define read(fd,buf,len)        recv(fd,(char*)buf,(int) len,0)
-#define write(fd,buf,len)       send(fd,(char*)buf,(int) len,0)
-#define close(fd)               closesocket(fd)
-
-static int wsa_init_done = 0;
-
-#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <errno.h>
-
-#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
-
-/* Some MS functions want int and MSVC warns if we pass size_t,
- * but the standard fucntions use socklen_t, so cast only for MSVC */
-#if defined(_MSC_VER)
-#define MSVC_INT_CAST   (int)
-#else
-#define MSVC_INT_CAST
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <time.h>
-
-#include <stdint.h>
-
-/*
- * Prepare for using the sockets interface
- */
-static int net_prepare( void )
-{
-#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
-    !defined(EFI32)
-    WSADATA wsaData;
-
-    if( wsa_init_done == 0 )
-    {
-        if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
-            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
-
-        wsa_init_done = 1;
-    }
-#else
-#if !defined(EFIX64) && !defined(EFI32)
-    signal( SIGPIPE, SIG_IGN );
-#endif
-#endif
-    return( 0 );
-}
-
-/*
- * Initialize a context
- */
-void mbedtls_net_init( mbedtls_net_context *ctx )
-{
-    ctx->fd = -1;
-}
-
-/*
- * Initiate a TCP connection with host:port and the given protocol
- */
-int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
-{
-    int ret;
-    struct addrinfo hints, *addr_list, *cur;
-
-    if( ( ret = net_prepare() ) != 0 )
-        return( ret );
-
-    /* Do name resolution with both IPv6 and IPv4 */
-    memset( &hints, 0, sizeof( hints ) );
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
-    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
-
-    if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
-        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
-
-    /* Try the sockaddrs until a connection succeeds */
-    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
-    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
-    {
-        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
-                            cur->ai_protocol );
-        if( ctx->fd < 0 )
-        {
-            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
-            continue;
-        }
-
-        if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
-        {
-            ret = 0;
-            break;
-        }
-
-        close( ctx->fd );
-        ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
-    }
-
-    freeaddrinfo( addr_list );
-
-    return( ret );
-}
-
-/*
- * Create a listening socket on bind_ip:port
- */
-int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
-{
-    int n, ret;
-    struct addrinfo hints, *addr_list, *cur;
-
-    if( ( ret = net_prepare() ) != 0 )
-        return( ret );
-
-    /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
-    memset( &hints, 0, sizeof( hints ) );
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
-    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
-    if( bind_ip == NULL )
-        hints.ai_flags = AI_PASSIVE;
-
-    if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
-        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
-
-    /* Try the sockaddrs until a binding succeeds */
-    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
-    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
-    {
-        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
-                            cur->ai_protocol );
-        if( ctx->fd < 0 )
-        {
-            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
-            continue;
-        }
-
-        n = 1;
-        if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
-                        (const char *) &n, sizeof( n ) ) != 0 )
-        {
-            close( ctx->fd );
-            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
-            continue;
-        }
-
-        if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
-        {
-            close( ctx->fd );
-            ret = MBEDTLS_ERR_NET_BIND_FAILED;
-            continue;
-        }
-
-        /* Listen only makes sense for TCP */
-        if( proto == MBEDTLS_NET_PROTO_TCP )
-        {
-            if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
-            {
-                close( ctx->fd );
-                ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
-                continue;
-            }
-        }
-
-        /* I we ever get there, it's a success */
-        ret = 0;
-        break;
-    }
-
-    freeaddrinfo( addr_list );
-
-    return( ret );
-
-}
-
-#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
-    !defined(EFI32)
-/*
- * Check if the requested operation would be blocking on a non-blocking socket
- * and thus 'failed' with a negative return value.
- */
-static int net_would_block( const mbedtls_net_context *ctx )
-{
-    ((void) ctx);
-    return( WSAGetLastError() == WSAEWOULDBLOCK );
-}
-#else
-/*
- * Check if the requested operation would be blocking on a non-blocking socket
- * and thus 'failed' with a negative return value.
- *
- * Note: on a blocking socket this function always returns 0!
- */
-static int net_would_block( const mbedtls_net_context *ctx )
-{
-    /*
-     * Never return 'WOULD BLOCK' on a non-blocking socket
-     */
-    if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
-        return( 0 );
-
-    switch( errno )
-    {
-#if defined EAGAIN
-        case EAGAIN:
-#endif
-#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
-        case EWOULDBLOCK:
-#endif
-            return( 1 );
-    }
-    return( 0 );
-}
-#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
-
-/*
- * Accept a connection from a remote client
- */
-int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
-                        mbedtls_net_context *client_ctx,
-                        void *client_ip, size_t buf_size, size_t *ip_len )
-{
-    int ret;
-    int type;
-
-    struct sockaddr_storage client_addr;
-
-#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) ||  \
-    defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
-    socklen_t n = (socklen_t) sizeof( client_addr );
-    socklen_t type_len = (socklen_t) sizeof( type );
-#else
-    int n = (int) sizeof( client_addr );
-    int type_len = (int) sizeof( type );
-#endif
-
-    /* Is this a TCP or UDP socket? */
-    if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
-                    (void *) &type, &type_len ) != 0 ||
-        ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
-    {
-        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
-    }
-
-    if( type == SOCK_STREAM )
-    {
-        /* TCP: actual accept() */
-        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
-                                         (struct sockaddr *) &client_addr, &n );
-    }
-    else
-    {
-        /* UDP: wait for a message, but keep it in the queue */
-        char buf[1] = { 0 };
-
-        ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
-                        (struct sockaddr *) &client_addr, &n );
-
-#if defined(_WIN32)
-        if( ret == SOCKET_ERROR &&
-            WSAGetLastError() == WSAEMSGSIZE )
-        {
-            /* We know buf is too small, thanks, just peeking here */
-            ret = 0;
-        }
-#endif
-    }
-
-    if( ret < 0 )
-    {
-        if( net_would_block( bind_ctx ) != 0 )
-            return( MBEDTLS_ERR_SSL_WANT_READ );
-
-        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
-    }
-
-    /* UDP: hijack the listening socket to communicate with the client,
-     * then bind a new socket to accept new connections */
-    if( type != SOCK_STREAM )
-    {
-        struct sockaddr_storage local_addr;
-        int one = 1;
-
-        if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
-            return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
-
-        client_ctx->fd = bind_ctx->fd;
-        bind_ctx->fd   = -1; /* In case we exit early */
-
-        n = sizeof( struct sockaddr_storage );
-        if( getsockname( client_ctx->fd,
-                         (struct sockaddr *) &local_addr, &n ) != 0 ||
-            ( bind_ctx->fd = (int) socket( local_addr.ss_family,
-                                           SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
-            setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
-                        (const char *) &one, sizeof( one ) ) != 0 )
-        {
-            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
-        }
-
-        if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
-        {
-            return( MBEDTLS_ERR_NET_BIND_FAILED );
-        }
-    }
-
-    if( client_ip != NULL )
-    {
-        if( client_addr.ss_family == AF_INET )
-        {
-            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
-            *ip_len = sizeof( addr4->sin_addr.s_addr );
-
-            if( buf_size < *ip_len )
-                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
-
-            memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
-        }
-        else
-        {
-            struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
-            *ip_len = sizeof( addr6->sin6_addr.s6_addr );
-
-            if( buf_size < *ip_len )
-                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
-
-            memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
-        }
-    }
-
-    return( 0 );
-}
-
-/*
- * Set the socket blocking or non-blocking
- */
-int mbedtls_net_set_block( mbedtls_net_context *ctx )
-{
-#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
-    !defined(EFI32)
-    u_long n = 0;
-    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
-#else
-    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) );
-#endif
-}
-
-int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
-{
-#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
-    !defined(EFI32)
-    u_long n = 1;
-    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
-#else
-    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) );
-#endif
-}
-
-/*
- * Portable usleep helper
- */
-void mbedtls_net_usleep( unsigned long usec )
-{
-#if defined(_WIN32)
-    Sleep( ( usec + 999 ) / 1000 );
-#else
-    struct timeval tv;
-    tv.tv_sec  = usec / 1000000;
-#if defined(__unix__) || defined(__unix) || \
-    ( defined(__APPLE__) && defined(__MACH__) )
-    tv.tv_usec = (suseconds_t) usec % 1000000;
-#else
-    tv.tv_usec = usec % 1000000;
-#endif
-    select( 0, NULL, NULL, NULL, &tv );
-#endif
-}
-
-/*
- * Read at most 'len' characters
- */
-int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
-{
-    int ret;
-    int fd = ((mbedtls_net_context *) ctx)->fd;
-
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
-
-    ret = (int) read( fd, buf, len );
-
-    if( ret < 0 )
-    {
-        if( net_would_block( ctx ) != 0 )
-            return( MBEDTLS_ERR_SSL_WANT_READ );
-
-#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
-    !defined(EFI32)
-        if( WSAGetLastError() == WSAECONNRESET )
-            return( MBEDTLS_ERR_NET_CONN_RESET );
-#else
-        if( errno == EPIPE || errno == ECONNRESET )
-            return( MBEDTLS_ERR_NET_CONN_RESET );
-
-        if( errno == EINTR )
-            return( MBEDTLS_ERR_SSL_WANT_READ );
-#endif
-
-        return( MBEDTLS_ERR_NET_RECV_FAILED );
-    }
-
-    return( ret );
-}
-
-/*
- * Read at most 'len' characters, blocking for at most 'timeout' ms
- */
-int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
-                      uint32_t timeout )
-{
-    int ret;
-    struct timeval tv;
-    fd_set read_fds;
-    int fd = ((mbedtls_net_context *) ctx)->fd;
-
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
-
-    FD_ZERO( &read_fds );
-    FD_SET( fd, &read_fds );
-
-    tv.tv_sec  = timeout / 1000;
-    tv.tv_usec = ( timeout % 1000 ) * 1000;
-
-    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
-
-    /* Zero fds ready means we timed out */
-    if( ret == 0 )
-        return( MBEDTLS_ERR_SSL_TIMEOUT );
-
-    if( ret < 0 )
-    {
-#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
-    !defined(EFI32)
-        if( WSAGetLastError() == WSAEINTR )
-            return( MBEDTLS_ERR_SSL_WANT_READ );
-#else
-        if( errno == EINTR )
-            return( MBEDTLS_ERR_SSL_WANT_READ );
-#endif
-
-        return( MBEDTLS_ERR_NET_RECV_FAILED );
-    }
-
-    /* This call will not block */
-    return( mbedtls_net_recv( ctx, buf, len ) );
-}
-
-/*
- * Write at most 'len' characters
- */
-int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
-{
-    int ret;
-    int fd = ((mbedtls_net_context *) ctx)->fd;
-
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
-
-    ret = (int) write( fd, buf, len );
-
-    if( ret < 0 )
-    {
-        if( net_would_block( ctx ) != 0 )
-            return( MBEDTLS_ERR_SSL_WANT_WRITE );
-
-#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
-    !defined(EFI32)
-        if( WSAGetLastError() == WSAECONNRESET )
-            return( MBEDTLS_ERR_NET_CONN_RESET );
-#else
-        if( errno == EPIPE || errno == ECONNRESET )
-            return( MBEDTLS_ERR_NET_CONN_RESET );
-
-        if( errno == EINTR )
-            return( MBEDTLS_ERR_SSL_WANT_WRITE );
-#endif
-
-        return( MBEDTLS_ERR_NET_SEND_FAILED );
-    }
-
-    return( ret );
-}
-
-/*
- * Gracefully close the connection
- */
-void mbedtls_net_free( mbedtls_net_context *ctx )
-{
-    if( ctx->fd == -1 )
-        return;
-
-    shutdown( ctx->fd, 2 );
-    close( ctx->fd );
-
-    ctx->fd = -1;
-}
-
-#endif /* MBEDTLS_NET_C */
diff --git a/crypto/mbedtls/src/net_sockets.c b/crypto/mbedtls/src/net_sockets.c
index 80be6ec6a..7b4a423cc 100644
--- a/crypto/mbedtls/src/net_sockets.c
+++ b/crypto/mbedtls/src/net_sockets.c
@@ -28,7 +28,7 @@
 #if defined(MBEDTLS_NET_C)
 
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
-    !defined(__APPLE__) && !defined(_WIN32)
+    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__)
 #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
 #endif
 
@@ -45,6 +45,8 @@
 #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
     !defined(EFI32)
 
+#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR )
+
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
@@ -63,8 +65,8 @@
 #endif
 #endif /* _MSC_VER */
 
-#define read(fd,buf,len)        recv(fd,(char*)buf,(int) len,0)
-#define write(fd,buf,len)       send(fd,(char*)buf,(int) len,0)
+#define read(fd,buf,len)        recv( fd, (char*)( buf ), (int)( len ), 0 )
+#define write(fd,buf,len)       send( fd, (char*)( buf ), (int)( len ), 0 )
 #define close(fd)               closesocket(fd)
 
 static int wsa_init_done = 0;
@@ -82,10 +84,12 @@ static int wsa_init_done = 0;
 #include <netdb.h>
 #include <errno.h>
 
+#define IS_EINTR( ret ) ( ( ret ) == EINTR )
+
 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
 
 /* Some MS functions want int and MSVC warns if we pass size_t,
- * but the standard fucntions use socklen_t, so cast only for MSVC */
+ * but the standard functions use socklen_t, so cast only for MSVC */
 #if defined(_MSC_VER)
 #define MSVC_INT_CAST   (int)
 #else
@@ -270,13 +274,18 @@ static int net_would_block( const mbedtls_net_context *ctx )
  */
 static int net_would_block( const mbedtls_net_context *ctx )
 {
+    int err = errno;
+
     /*
      * Never return 'WOULD BLOCK' on a non-blocking socket
      */
     if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
+    {
+        errno = err;
         return( 0 );
+    }
 
-    switch( errno )
+    switch( errno = err )
     {
 #if defined EAGAIN
         case EAGAIN:
@@ -433,6 +442,72 @@ int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
 #endif
 }
 
+/*
+ * Check if data is available on the socket
+ */
+
+int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
+{
+    int ret;
+    struct timeval tv;
+
+    fd_set read_fds;
+    fd_set write_fds;
+
+    int fd = ctx->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+    /* Ensure that memory sanitizers consider read_fds and write_fds as
+     * initialized even on platforms such as Glibc/x86_64 where FD_ZERO
+     * is implemented in assembly. */
+    memset( &read_fds, 0, sizeof( read_fds ) );
+    memset( &write_fds, 0, sizeof( write_fds ) );
+#endif
+#endif
+
+    FD_ZERO( &read_fds );
+    if( rw & MBEDTLS_NET_POLL_READ )
+    {
+        rw &= ~MBEDTLS_NET_POLL_READ;
+        FD_SET( fd, &read_fds );
+    }
+
+    FD_ZERO( &write_fds );
+    if( rw & MBEDTLS_NET_POLL_WRITE )
+    {
+        rw &= ~MBEDTLS_NET_POLL_WRITE;
+        FD_SET( fd, &write_fds );
+    }
+
+    if( rw != 0 )
+        return( MBEDTLS_ERR_NET_BAD_INPUT_DATA );
+
+    tv.tv_sec  = timeout / 1000;
+    tv.tv_usec = ( timeout % 1000 ) * 1000;
+
+    do
+    {
+        ret = select( fd + 1, &read_fds, &write_fds, NULL,
+                      timeout == (uint32_t) -1 ? NULL : &tv );
+    }
+    while( IS_EINTR( ret ) );
+
+    if( ret < 0 )
+        return( MBEDTLS_ERR_NET_POLL_FAILED );
+
+    ret = 0;
+    if( FD_ISSET( fd, &read_fds ) )
+        ret |= MBEDTLS_NET_POLL_READ;
+    if( FD_ISSET( fd, &write_fds ) )
+        ret |= MBEDTLS_NET_POLL_WRITE;
+
+    return( ret );
+}
+
 /*
  * Portable usleep helper
  */
@@ -492,8 +567,8 @@ int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
 /*
  * Read at most 'len' characters, blocking for at most 'timeout' ms
  */
-int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
-                      uint32_t timeout )
+int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
+                              size_t len, uint32_t timeout )
 {
     int ret;
     struct timeval tv;
diff --git a/crypto/mbedtls/src/oid.c b/crypto/mbedtls/src/oid.c
index f13826ed7..edea950f8 100644
--- a/crypto/mbedtls/src/oid.c
+++ b/crypto/mbedtls/src/oid.c
@@ -625,6 +625,51 @@ static const oid_md_alg_t oid_md_alg[] =
 FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
 FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
 FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg)
+
+/*
+ * For HMAC digestAlgorithm
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_md_type_t           md_hmac;
+} oid_md_hmac_t;
+
+static const oid_md_hmac_t oid_md_hmac[] =
+{
+#if defined(MBEDTLS_SHA1_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ),      "hmacSHA1",      "HMAC-SHA-1" },
+        MBEDTLS_MD_SHA1,
+    },
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ),    "hmacSHA224",    "HMAC-SHA-224" },
+        MBEDTLS_MD_SHA224,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ),    "hmacSHA256",    "HMAC-SHA-256" },
+        MBEDTLS_MD_SHA256,
+    },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ),    "hmacSHA384",    "HMAC-SHA-384" },
+        MBEDTLS_MD_SHA384,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ),    "hmacSHA512",    "HMAC-SHA-512" },
+        MBEDTLS_MD_SHA512,
+    },
+#endif /* MBEDTLS_SHA512_C */
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_MD_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac)
+FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac)
 #endif /* MBEDTLS_MD_C */
 
 #if defined(MBEDTLS_PKCS12_C)
diff --git a/crypto/mbedtls/src/pem.c b/crypto/mbedtls/src/pem.c
index 8dd86a4ac..13f920869 100644
--- a/crypto/mbedtls/src/pem.c
+++ b/crypto/mbedtls/src/pem.c
@@ -82,31 +82,33 @@ static int pem_get_iv( const unsigned char *s, unsigned char *iv,
     return( 0 );
 }
 
-static void pem_pbkdf1( unsigned char *key, size_t keylen,
-                        unsigned char *iv,
-                        const unsigned char *pwd, size_t pwdlen )
+static int pem_pbkdf1( unsigned char *key, size_t keylen,
+                       unsigned char *iv,
+                       const unsigned char *pwd, size_t pwdlen )
 {
     mbedtls_md5_context md5_ctx;
     unsigned char md5sum[16];
     size_t use_len;
+    int ret;
 
     mbedtls_md5_init( &md5_ctx );
 
     /*
      * key[ 0..15] = MD5(pwd || IV)
      */
-    mbedtls_md5_starts( &md5_ctx );
-    mbedtls_md5_update( &md5_ctx, pwd, pwdlen );
-    mbedtls_md5_update( &md5_ctx, iv,  8 );
-    mbedtls_md5_finish( &md5_ctx, md5sum );
+    if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv,  8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
+        goto exit;
 
     if( keylen <= 16 )
     {
         memcpy( key, md5sum, keylen );
-
-        mbedtls_md5_free( &md5_ctx );
-        mbedtls_zeroize( md5sum, 16 );
-        return;
+        goto exit;
     }
 
     memcpy( key, md5sum, 16 );
@@ -114,11 +116,16 @@ static void pem_pbkdf1( unsigned char *key, size_t keylen,
     /*
      * key[16..23] = MD5(key[ 0..15] || pwd || IV])
      */
-    mbedtls_md5_starts( &md5_ctx );
-    mbedtls_md5_update( &md5_ctx, md5sum,  16 );
-    mbedtls_md5_update( &md5_ctx, pwd, pwdlen );
-    mbedtls_md5_update( &md5_ctx, iv,  8 );
-    mbedtls_md5_finish( &md5_ctx, md5sum );
+    if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
+        goto exit;
 
     use_len = 16;
     if( keylen < 32 )
@@ -126,53 +133,68 @@ static void pem_pbkdf1( unsigned char *key, size_t keylen,
 
     memcpy( key + 16, md5sum, use_len );
 
+exit:
     mbedtls_md5_free( &md5_ctx );
     mbedtls_zeroize( md5sum, 16 );
+
+    return( ret );
 }
 
 #if defined(MBEDTLS_DES_C)
 /*
  * Decrypt with DES-CBC, using PBKDF1 for key derivation
  */
-static void pem_des_decrypt( unsigned char des_iv[8],
-                               unsigned char *buf, size_t buflen,
-                               const unsigned char *pwd, size_t pwdlen )
+static int pem_des_decrypt( unsigned char des_iv[8],
+                            unsigned char *buf, size_t buflen,
+                            const unsigned char *pwd, size_t pwdlen )
 {
     mbedtls_des_context des_ctx;
     unsigned char des_key[8];
+    int ret;
 
     mbedtls_des_init( &des_ctx );
 
-    pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen );
+    if( ( ret = pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ) ) != 0 )
+        goto exit;
 
-    mbedtls_des_setkey_dec( &des_ctx, des_key );
-    mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen,
+    if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 )
+        goto exit;
+    ret = mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen,
                      des_iv, buf, buf );
 
+exit:
     mbedtls_des_free( &des_ctx );
     mbedtls_zeroize( des_key, 8 );
+
+    return( ret );
 }
 
 /*
  * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
  */
-static void pem_des3_decrypt( unsigned char des3_iv[8],
-                               unsigned char *buf, size_t buflen,
-                               const unsigned char *pwd, size_t pwdlen )
+static int pem_des3_decrypt( unsigned char des3_iv[8],
+                             unsigned char *buf, size_t buflen,
+                             const unsigned char *pwd, size_t pwdlen )
 {
     mbedtls_des3_context des3_ctx;
     unsigned char des3_key[24];
+    int ret;
 
     mbedtls_des3_init( &des3_ctx );
 
-    pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen );
+    if( ( ret = pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ) ) != 0 )
+        goto exit;
 
-    mbedtls_des3_set3key_dec( &des3_ctx, des3_key );
-    mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
+    if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 )
+        goto exit;
+    ret = mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
                      des3_iv, buf, buf );
 
+exit:
     mbedtls_des3_free( &des3_ctx );
     mbedtls_zeroize( des3_key, 24 );
+
+    return( ret );
 }
 #endif /* MBEDTLS_DES_C */
 
@@ -180,23 +202,29 @@ static void pem_des3_decrypt( unsigned char des3_iv[8],
 /*
  * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
  */
-static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
-                               unsigned char *buf, size_t buflen,
-                               const unsigned char *pwd, size_t pwdlen )
+static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
+                            unsigned char *buf, size_t buflen,
+                            const unsigned char *pwd, size_t pwdlen )
 {
     mbedtls_aes_context aes_ctx;
     unsigned char aes_key[32];
+    int ret;
 
     mbedtls_aes_init( &aes_ctx );
 
-    pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen );
+    if( ( ret = pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ) ) != 0 )
+        goto exit;
 
-    mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 );
-    mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
+    if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 )
+        goto exit;
+    ret = mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
                      aes_iv, buf, buf );
 
+exit:
     mbedtls_aes_free( &aes_ctx );
     mbedtls_zeroize( aes_key, keylen );
+
+    return( ret );
 }
 #endif /* MBEDTLS_AES_C */
 
@@ -331,6 +359,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
 
     if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
     {
+        mbedtls_zeroize( buf, len );
         mbedtls_free( buf );
         return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
     }
@@ -341,38 +370,49 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
     ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
         if( pwd == NULL )
         {
+            mbedtls_zeroize( buf, len );
             mbedtls_free( buf );
             return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
         }
 
+        ret = 0;
+
 #if defined(MBEDTLS_DES_C)
         if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC )
-            pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
+            ret = pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
         else if( enc_alg == MBEDTLS_CIPHER_DES_CBC )
-            pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
+            ret = pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
 #endif /* MBEDTLS_DES_C */
 
 #if defined(MBEDTLS_AES_C)
         if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC )
-            pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
+            ret = pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
         else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC )
-            pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
+            ret = pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
         else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC )
-            pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
+            ret = pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
 #endif /* MBEDTLS_AES_C */
 
+        if( ret != 0 )
+        {
+            mbedtls_free( buf );
+            return( ret );
+        }
+
         /*
          * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
          * length bytes (allow 4 to be sure) in all known use cases.
          *
-         * Use that as heurisitic to try detecting password mismatchs.
+         * Use that as a heuristic to try to detect password mismatches.
          */
         if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
         {
+            mbedtls_zeroize( buf, len );
             mbedtls_free( buf );
             return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
         }
 #else
+        mbedtls_zeroize( buf, len );
         mbedtls_free( buf );
         return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
 #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
@@ -387,6 +427,8 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
 
 void mbedtls_pem_free( mbedtls_pem_context *ctx )
 {
+    if( ctx->buf != NULL )
+        mbedtls_zeroize( ctx->buf, ctx->buflen );
     mbedtls_free( ctx->buf );
     mbedtls_free( ctx->info );
 
@@ -400,7 +442,7 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
                       unsigned char *buf, size_t buf_len, size_t *olen )
 {
     int ret;
-    unsigned char *encode_buf, *c, *p = buf;
+    unsigned char *encode_buf = NULL, *c, *p = buf;
     size_t len = 0, use_len, add_len = 0;
 
     mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
@@ -412,7 +454,8 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
     }
 
-    if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL )
+    if( use_len != 0 &&
+        ( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) )
         return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
 
     if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,
diff --git a/crypto/mbedtls/src/pk.c b/crypto/mbedtls/src/pk.c
index 8d13bc5ce..b52c73fbc 100644
--- a/crypto/mbedtls/src/pk.c
+++ b/crypto/mbedtls/src/pk.c
@@ -29,8 +29,6 @@
 #include "mbedtls/pk.h"
 #include "mbedtls/pk_internal.h"
 
-#include "mbedtls/bignum.h"
-
 #if defined(MBEDTLS_RSA_C)
 #include "mbedtls/rsa.h"
 #endif
@@ -42,6 +40,7 @@
 #endif
 
 #include <limits.h>
+#include <stdint.h>
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
@@ -213,10 +212,10 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
         int ret;
         const mbedtls_pk_rsassa_pss_options *pss_opts;
 
-#if defined(MBEDTLS_HAVE_INT64)
+#if SIZE_MAX > UINT_MAX
         if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
             return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
-#endif /* MBEDTLS_HAVE_INT64 */
+#endif /* SIZE_MAX > UINT_MAX */
 
         if( options == NULL )
             return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
diff --git a/crypto/mbedtls/src/pk_wrap.c b/crypto/mbedtls/src/pk_wrap.c
index db6274cbf..5446e2350 100644
--- a/crypto/mbedtls/src/pk_wrap.c
+++ b/crypto/mbedtls/src/pk_wrap.c
@@ -30,7 +30,6 @@
 
 /* Even if RSA not activated, for the sake of RSA-alt */
 #include "mbedtls/rsa.h"
-#include "mbedtls/bignum.h"
 
 #include <string.h>
 
@@ -51,6 +50,7 @@
 #endif
 
 #include <limits.h>
+#include <stdint.h>
 
 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
 /* Implementation that should never be optimized out by the compiler */
@@ -68,7 +68,8 @@ static int rsa_can_do( mbedtls_pk_type_t type )
 
 static size_t rsa_get_bitlen( const void *ctx )
 {
-    return( 8 * ((const mbedtls_rsa_context *) ctx)->len );
+    const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
+    return( 8 * mbedtls_rsa_get_len( rsa ) );
 }
 
 static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
@@ -76,21 +77,28 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *sig, size_t sig_len )
 {
     int ret;
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+    size_t rsa_len = mbedtls_rsa_get_len( rsa );
 
-#if defined(MBEDTLS_HAVE_INT64)
+#if SIZE_MAX > UINT_MAX
     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
-#endif /* MBEDTLS_HAVE_INT64 */
+#endif /* SIZE_MAX > UINT_MAX */
 
-    if( sig_len < ((mbedtls_rsa_context *) ctx)->len )
+    if( sig_len < rsa_len )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
 
-    if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL,
+    if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
                                   MBEDTLS_RSA_PUBLIC, md_alg,
                                   (unsigned int) hash_len, hash, sig ) ) != 0 )
         return( ret );
 
-    if( sig_len > ((mbedtls_rsa_context *) ctx)->len )
+    /* The buffer contains a valid signature followed by extra data.
+     * We have a special error code for that so that so that callers can
+     * use mbedtls_pk_verify() to check "Does the buffer start with a
+     * valid signature?" and not just "Does the buffer contain a valid
+     * signature?". */
+    if( sig_len > rsa_len )
         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
 
     return( 0 );
@@ -101,14 +109,16 @@ static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    unsigned char *sig, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-#if defined(MBEDTLS_HAVE_INT64)
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+
+#if SIZE_MAX > UINT_MAX
     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
-#endif /* MBEDTLS_HAVE_INT64 */
+#endif /* SIZE_MAX > UINT_MAX */
 
-    *sig_len = ((mbedtls_rsa_context *) ctx)->len;
+    *sig_len = mbedtls_rsa_get_len( rsa );
 
-    return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
+    return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
                 md_alg, (unsigned int) hash_len, hash, sig ) );
 }
 
@@ -117,10 +127,12 @@ static int rsa_decrypt_wrap( void *ctx,
                     unsigned char *output, size_t *olen, size_t osize,
                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-    if( ilen != ((mbedtls_rsa_context *) ctx)->len )
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+
+    if( ilen != mbedtls_rsa_get_len( rsa ) )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-    return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng,
+    return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
                 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
 }
 
@@ -129,13 +141,14 @@ static int rsa_encrypt_wrap( void *ctx,
                     unsigned char *output, size_t *olen, size_t osize,
                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-    *olen = ((mbedtls_rsa_context *) ctx)->len;
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+    *olen = mbedtls_rsa_get_len( rsa );
 
     if( *olen > osize )
         return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
 
-    return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx,
-                f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) );
+    return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
+                                       ilen, input, output ) );
 }
 
 static int rsa_check_pair_wrap( const void *pub, const void *prv )
@@ -415,10 +428,10 @@ static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
 {
     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
 
-#if defined(MBEDTLS_HAVE_INT64)
+#if SIZE_MAX > UINT_MAX
     if( UINT_MAX < hash_len )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
-#endif /* MBEDTLS_HAVE_INT64 */
+#endif /* SIZE_MAX > UINT_MAX */
 
     *sig_len = rsa_alt->key_len_func( rsa_alt->key );
 
diff --git a/crypto/mbedtls/src/pkcs5.c b/crypto/mbedtls/src/pkcs5.c
index e28d5a847..440a174b5 100644
--- a/crypto/mbedtls/src/pkcs5.c
+++ b/crypto/mbedtls/src/pkcs5.c
@@ -38,9 +38,12 @@
 #if defined(MBEDTLS_PKCS5_C)
 
 #include "mbedtls/pkcs5.h"
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
 #include "mbedtls/asn1.h"
 #include "mbedtls/cipher.h"
 #include "mbedtls/oid.h"
+#endif /* MBEDTLS_ASN1_PARSE_C */
 
 #include <string.h>
 
@@ -51,6 +54,22 @@
 #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
 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 )
@@ -96,11 +115,9 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
     if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
         return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
 
-    if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 )
+    if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
         return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
 
-    *md_type = MBEDTLS_MD_SHA1;
-
     if( p != end )
         return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
@@ -213,6 +230,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
 
     return( ret );
 }
+#endif /* MBEDTLS_ASN1_PARSE_C */
 
 int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
                        size_t plen, const unsigned char *salt, size_t slen,
diff --git a/crypto/mbedtls/src/pkparse.c b/crypto/mbedtls/src/pkparse.c
index efdf43746..5ad5edf84 100644
--- a/crypto/mbedtls/src/pkparse.c
+++ b/crypto/mbedtls/src/pkparse.c
@@ -60,12 +60,15 @@
 #define mbedtls_free       free
 #endif
 
-#if defined(MBEDTLS_FS_IO)
+#if defined(MBEDTLS_FS_IO) || \
+    defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
 }
+#endif
 
+#if defined(MBEDTLS_FS_IO)
 /*
  * Load all data from a file into a given buffer.
  *
@@ -101,7 +104,10 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
     if( fread( *buf, 1, *n, f ) != *n )
     {
         fclose( f );
+
+        mbedtls_zeroize( *buf, *n );
         mbedtls_free( *buf );
+
         return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
     }
 
@@ -175,6 +181,10 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
 {
     int ret;
 
+    if ( end - *p < 1 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
     /* Tag may be either OID or SEQUENCE */
     params->tag = **p;
     if( params->tag != MBEDTLS_ASN1_OID
@@ -520,18 +530,35 @@ static int pk_get_rsapubkey( unsigned char **p,
         return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
-    if( ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
+    /* Import N */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
         return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
 
-    if( *p != end )
-        return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
-                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
+
+    *p += len;
+
+    /* Import E */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
 
-    if( ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 )
+    if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
+                                        NULL, 0, *p, len ) ) != 0 )
         return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
 
-    rsa->len = mbedtls_mpi_size( &rsa->N );
+    *p += len;
+
+    if( mbedtls_rsa_complete( rsa ) != 0 ||
+        mbedtls_rsa_check_pubkey( rsa ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
+    }
+
+    if( *p != end )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
     return( 0 );
 }
@@ -643,10 +670,13 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
                                    const unsigned char *key,
                                    size_t keylen )
 {
-    int ret;
+    int ret, version;
     size_t len;
     unsigned char *p, *end;
 
+    mbedtls_mpi T;
+    mbedtls_mpi_init( &T );
+
     p = (unsigned char *) key;
     end = p + keylen;
 
@@ -674,45 +704,88 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
 
     end = p + len;
 
-    if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
     {
         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
     }
 
-    if( rsa->ver != 0 )
+    if( version != 0 )
     {
         return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
     }
 
-    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N  ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E  ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D  ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P  ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q  ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
-    {
-        mbedtls_rsa_free( rsa );
-        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
-    }
+    /* Import N */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Import E */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
+                                        NULL, 0, p, len ) ) != 0 )
+        goto cleanup;
+    p += len;
 
-    rsa->len = mbedtls_mpi_size( &rsa->N );
+    /* Import D */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
+                                        p, len, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Import P */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Import Q */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Complete the RSA private key */
+    if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
+        goto cleanup;
+
+    /* Check optional parameters */
+    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
+        goto cleanup;
 
     if( p != end )
     {
-        mbedtls_rsa_free( rsa );
-        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
-                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+        ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+              MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
     }
 
-    if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 )
+cleanup:
+
+    mbedtls_mpi_free( &T );
+
+    if( ret != 0 )
     {
+        /* Wrap error code if it's coming from a lower level */
+        if( ( ret & 0xff80 ) == 0 )
+            ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
+        else
+            ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
+
         mbedtls_rsa_free( rsa );
-        return( ret );
     }
 
-    return( 0 );
+    return( ret );
 }
 #endif /* MBEDTLS_RSA_C */
 
@@ -788,7 +861,10 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
             mbedtls_ecp_keypair_free( eck );
             return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
         }
+    }
 
+    if( p != end )
+    {
         /*
          * Is 'publickey' present? If not, or if we can't read it (eg because it
          * is compressed), create it from the private key.
@@ -844,6 +920,16 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
 
 /*
  * Parse an unencrypted PKCS#8 encoded private key
+ *
+ * Notes:
+ *
+ * - This function does not own the key buffer. It is the
+ *   responsibility of the caller to take care of zeroizing
+ *   and freeing it after use.
+ *
+ * - The function is responsible for freeing the provided
+ *   PK context on failure.
+ *
  */
 static int pk_parse_key_pkcs8_unencrypted_der(
                                     mbedtls_pk_context *pk,
@@ -859,7 +945,7 @@ static int pk_parse_key_pkcs8_unencrypted_der(
     const mbedtls_pk_info_t *pk_info;
 
     /*
-     * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
+     * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
      *
      *    PrivateKeyInfo ::= SEQUENCE {
      *      version                   Version,
@@ -932,16 +1018,22 @@ static int pk_parse_key_pkcs8_unencrypted_der(
 
 /*
  * Parse an encrypted PKCS#8 encoded private key
+ *
+ * To save space, the decryption happens in-place on the given key buffer.
+ * Also, while this function may modify the keybuffer, it doesn't own it,
+ * and instead it is the responsibility of the caller to zeroize and properly
+ * free it after use.
+ *
  */
 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
 static int pk_parse_key_pkcs8_encrypted_der(
                                     mbedtls_pk_context *pk,
-                                    const unsigned char *key, size_t keylen,
+                                    unsigned char *key, size_t keylen,
                                     const unsigned char *pwd, size_t pwdlen )
 {
     int ret, decrypted = 0;
     size_t len;
-    unsigned char buf[2048];
+    unsigned char *buf;
     unsigned char *p, *end;
     mbedtls_asn1_buf pbe_alg_oid, pbe_params;
 #if defined(MBEDTLS_PKCS12_C)
@@ -949,16 +1041,14 @@ static int pk_parse_key_pkcs8_encrypted_der(
     mbedtls_md_type_t md_alg;
 #endif
 
-    memset( buf, 0, sizeof( buf ) );
-
-    p = (unsigned char *) key;
+    p = key;
     end = p + keylen;
 
     if( pwdlen == 0 )
         return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
 
     /*
-     * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
+     * This function parses the EncryptedPrivateKeyInfo object (PKCS#8)
      *
      *  EncryptedPrivateKeyInfo ::= SEQUENCE {
      *    encryptionAlgorithm  EncryptionAlgorithmIdentifier,
@@ -970,6 +1060,7 @@ static int pk_parse_key_pkcs8_encrypted_der(
      *  EncryptedData ::= OCTET STRING
      *
      *  The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
+     *
      */
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
@@ -985,11 +1076,10 @@ static int pk_parse_key_pkcs8_encrypted_der(
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
 
-    if( len > sizeof( buf ) )
-        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+    buf = p;
 
     /*
-     * Decrypt EncryptedData with appropriate PDE
+     * Decrypt EncryptedData with appropriate PBE
      */
 #if defined(MBEDTLS_PKCS12_C)
     if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
@@ -1081,10 +1171,8 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
 
     if( ret == 0 )
     {
-        if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
-            return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
-
-        if( ( ret = mbedtls_pk_setup( pk, pk_info                    ) ) != 0 ||
+        pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
+        if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
             ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
                                             pem.buf, pem.buflen ) ) != 0 )
         {
@@ -1113,10 +1201,9 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
                                key, pwd, pwdlen, &len );
     if( ret == 0 )
     {
-        if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL )
-            return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+        pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
 
-        if( ( ret = mbedtls_pk_setup( pk, pk_info                   ) ) != 0 ||
+        if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
             ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
                                            pem.buf, pem.buflen ) ) != 0 )
         {
@@ -1194,12 +1281,27 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
      * error
      */
 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
-    if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
-                                                  pwd, pwdlen ) ) == 0 )
     {
-        return( 0 );
+        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 );
+
+        memcpy( key_copy, key, keylen );
+
+        ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
+                                                pwd, pwdlen );
+
+        mbedtls_zeroize( key_copy, keylen );
+        mbedtls_free( key_copy );
     }
 
+    if( ret == 0 )
+        return( 0 );
+
     mbedtls_pk_free( pk );
 
     if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
@@ -1214,29 +1316,35 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
     mbedtls_pk_free( pk );
 
 #if defined(MBEDTLS_RSA_C)
-    if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
-        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
 
-    if( ( ret = mbedtls_pk_setup( pk, pk_info                           ) ) != 0 ||
-        ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) ) == 0 )
+    pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
+    if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
+        ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
+                                        key, keylen ) ) != 0 )
+    {
+        mbedtls_pk_free( pk );
+    }
+    else
     {
         return( 0 );
     }
 
-    mbedtls_pk_free( pk );
 #endif /* MBEDTLS_RSA_C */
 
 #if defined(MBEDTLS_ECP_C)
-    if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL )
-        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
 
-    if( ( ret = mbedtls_pk_setup( pk, pk_info                         ) ) != 0 ||
-        ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), key, keylen ) ) == 0 )
+    pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
+    if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
+        ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
+                                       key, keylen ) ) != 0 )
+    {
+        mbedtls_pk_free( pk );
+    }
+    else
     {
         return( 0 );
     }
 
-    mbedtls_pk_free( pk );
 #endif /* MBEDTLS_ECP_C */
 
     return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
@@ -1250,11 +1358,45 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
 {
     int ret;
     unsigned char *p;
+#if defined(MBEDTLS_RSA_C)
+    const mbedtls_pk_info_t *pk_info;
+#endif
 #if defined(MBEDTLS_PEM_PARSE_C)
     size_t len;
     mbedtls_pem_context pem;
 
     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' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN RSA PUBLIC KEY-----",
+                               "-----END RSA PUBLIC KEY-----",
+                               key, NULL, 0, &len );
+
+    if( ret == 0 )
+    {
+        p = pem.buf;
+        if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
+            return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+        if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
+            return( ret );
+
+        if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
+            mbedtls_pk_free( ctx );
+
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+    {
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+#endif /* MBEDTLS_RSA_C */
 
     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
     if( keylen == 0 || key[keylen - 1] != '\0' )
@@ -1270,23 +1412,43 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
         /*
          * Was PEM encoded
          */
-        key = pem.buf;
-        keylen = pem.buflen;
+        p = pem.buf;
+
+        ret = mbedtls_pk_parse_subpubkey( &p,  p + pem.buflen, ctx );
+        mbedtls_pem_free( &pem );
+        return( ret );
     }
     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
     {
         mbedtls_pem_free( &pem );
         return( ret );
     }
+    mbedtls_pem_free( &pem );
 #endif /* MBEDTLS_PEM_PARSE_C */
+
+#if defined(MBEDTLS_RSA_C)
+    if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
+        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+    if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
+        return( ret );
+
+    p = (unsigned char *)key;
+    ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) );
+    if( ret == 0 )
+    {
+        return( ret );
+    }
+    mbedtls_pk_free( ctx );
+    if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
+    {
+        return( ret );
+    }
+#endif /* MBEDTLS_RSA_C */
     p = (unsigned char *) key;
 
     ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx );
 
-#if defined(MBEDTLS_PEM_PARSE_C)
-    mbedtls_pem_free( &pem );
-#endif
-
     return( ret );
 }
 
diff --git a/crypto/mbedtls/src/pkwrite.c b/crypto/mbedtls/src/pkwrite.c
index 83b798c11..8eabd889b 100644
--- a/crypto/mbedtls/src/pkwrite.c
+++ b/crypto/mbedtls/src/pkwrite.c
@@ -62,13 +62,31 @@
  *  }
  */
 static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
-                                  mbedtls_rsa_context *rsa )
+                                mbedtls_rsa_context *rsa )
 {
     int ret;
     size_t len = 0;
+    mbedtls_mpi T;
 
-    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) );
-    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) );
+    mbedtls_mpi_init( &T );
+
+    /* Export E */
+    if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 ||
+         ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
+        goto end_of_export;
+    len += ret;
+
+    /* Export N */
+    if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 ||
+         ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
+        goto end_of_export;
+    len += ret;
+
+end_of_export:
+
+    mbedtls_mpi_free( &T );
+    if( ret < 0 )
+        return( ret );
 
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
@@ -83,7 +101,7 @@ static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
  * EC public key is an EC point
  */
 static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
-                                 mbedtls_ecp_keypair *ec )
+                               mbedtls_ecp_keypair *ec )
 {
     int ret;
     size_t len = 0;
@@ -111,7 +129,7 @@ static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
  * }
  */
 static int pk_write_ec_param( unsigned char **p, unsigned char *start,
-                                mbedtls_ecp_keypair *ec )
+                              mbedtls_ecp_keypair *ec )
 {
     int ret;
     size_t len = 0;
@@ -128,7 +146,7 @@ static int pk_write_ec_param( unsigned char **p, unsigned char *start,
 #endif /* MBEDTLS_ECP_C */
 
 int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
-                     const mbedtls_pk_context *key )
+                             const mbedtls_pk_context *key )
 {
     int ret;
     size_t len = 0;
@@ -205,21 +223,79 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
 #if defined(MBEDTLS_RSA_C)
     if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
     {
+        mbedtls_mpi T; /* Temporary holding the exported parameters */
         mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key );
 
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
+        /*
+         * Export the parameters one after another to avoid simultaneous copies.
+         */
+
+        mbedtls_mpi_init( &T );
+
+        /* Export QP */
+        if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 ||
+            ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export DQ */
+        if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 ||
+            ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export DP */
+        if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 ||
+            ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export Q */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
+                                         &T, NULL, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export P */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T,
+                                         NULL, NULL, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export D */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
+                                         NULL, &T, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export E */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
+                                         NULL, NULL, &T ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export N */
+        if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL,
+                                         NULL, NULL, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+    end_of_export:
+
+        mbedtls_mpi_free( &T );
+        if( ret < 0 )
+            return( ret );
 
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
-        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
-                                                    MBEDTLS_ASN1_SEQUENCE ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c,
+                                               buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                               MBEDTLS_ASN1_SEQUENCE ) );
     }
     else
 #endif /* MBEDTLS_RSA_C */
diff --git a/crypto/mbedtls/src/platform.c b/crypto/mbedtls/src/platform.c
index af3b2f15e..a295f9b9a 100644
--- a/crypto/mbedtls/src/platform.c
+++ b/crypto/mbedtls/src/platform.c
@@ -29,6 +29,14 @@
 
 #include "mbedtls/platform.h"
 
+#if defined(MBEDTLS_ENTROPY_NV_SEED) && \
+    !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
+}
+#endif
+
 #if defined(MBEDTLS_PLATFORM_MEMORY)
 #if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
 static void *platform_calloc_uninit( size_t n, size_t size )
@@ -74,7 +82,7 @@ int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
         return( -1 );
 
     va_start( argp, fmt );
-#if defined(_TRUNCATE)
+#if defined(_TRUNCATE) && !defined(__MINGW32__)
     ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
 #else
     ret = _vsnprintf( s, n, fmt, argp );
@@ -228,12 +236,13 @@ int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
     size_t n;
 
     if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
-        return -1;
+        return( -1 );
 
     if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
     {
         fclose( file );
-        return -1;
+        mbedtls_zeroize( buf, buf_len );
+        return( -1 );
     }
 
     fclose( file );
diff --git a/crypto/mbedtls/src/ripemd160.c b/crypto/mbedtls/src/ripemd160.c
index cdb0a63c0..2ba48b7fd 100644
--- a/crypto/mbedtls/src/ripemd160.c
+++ b/crypto/mbedtls/src/ripemd160.c
@@ -46,6 +46,8 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
+#if !defined(MBEDTLS_RIPEMD160_ALT)
+
 /*
  * 32-bit integer manipulation macros (little endian)
  */
@@ -96,7 +98,7 @@ void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
 /*
  * RIPEMD-160 context setup
  */
-void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
+int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -106,13 +108,23 @@ void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
     ctx->state[2] = 0x98BADCFE;
     ctx->state[3] = 0x10325476;
     ctx->state[4] = 0xC3D2E1F0;
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
+{
+    mbedtls_ripemd160_starts_ret( ctx );
+}
+#endif
+
 #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
 /*
  * Process one block
  */
-void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] )
+int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
+                                        const unsigned char data[64] )
 {
     uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
 
@@ -287,20 +299,32 @@ void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned c
     ctx->state[3] = ctx->state[4] + A + Bp;
     ctx->state[4] = ctx->state[0] + B + Cp;
     ctx->state[0] = C;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
+                                const unsigned char data[64] )
+{
+    mbedtls_internal_ripemd160_process( ctx, data );
 }
+#endif
 #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
 
 /*
  * RIPEMD-160 process buffer
  */
-void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
-                       const unsigned char *input, size_t ilen )
+int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
+                                  const unsigned char *input,
+                                  size_t ilen )
 {
+    int ret;
     size_t fill;
     uint32_t left;
 
     if( ilen == 0 )
-        return;
+        return( 0 );
 
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
@@ -314,7 +338,10 @@ void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
     if( left && ilen >= fill )
     {
         memcpy( (void *) (ctx->buffer + left), input, fill );
-        mbedtls_ripemd160_process( ctx, ctx->buffer );
+
+        if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
         input += fill;
         ilen  -= fill;
         left = 0;
@@ -322,7 +349,9 @@ void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
 
     while( ilen >= 64 )
     {
-        mbedtls_ripemd160_process( ctx, input );
+        if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
@@ -331,8 +360,19 @@ void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
     {
         memcpy( (void *) (ctx->buffer + left), input, ilen );
     }
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen )
+{
+    mbedtls_ripemd160_update_ret( ctx, input, ilen );
+}
+#endif
+
 static const unsigned char ripemd160_padding[64] =
 {
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -344,8 +384,10 @@ static const unsigned char ripemd160_padding[64] =
 /*
  * RIPEMD-160 final digest
  */
-void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] )
+int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
+                                  unsigned char output[20] )
 {
+    int ret;
     uint32_t last, padn;
     uint32_t high, low;
     unsigned char msglen[8];
@@ -360,30 +402,68 @@ void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char out
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
 
-    mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
-    mbedtls_ripemd160_update( ctx, msglen, 8 );
+    ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
+    if( ret != 0 )
+        return( ret );
 
     PUT_UINT32_LE( ctx->state[0], output,  0 );
     PUT_UINT32_LE( ctx->state[1], output,  4 );
     PUT_UINT32_LE( ctx->state[2], output,  8 );
     PUT_UINT32_LE( ctx->state[3], output, 12 );
     PUT_UINT32_LE( ctx->state[4], output, 16 );
+
+    return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
+                               unsigned char output[20] )
+{
+    mbedtls_ripemd160_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* ! MBEDTLS_RIPEMD160_ALT */
+
 /*
  * output = RIPEMD-160( input buffer )
  */
-void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
-                unsigned char output[20] )
+int mbedtls_ripemd160_ret( const unsigned char *input,
+                           size_t ilen,
+                           unsigned char output[20] )
 {
+    int ret;
     mbedtls_ripemd160_context ctx;
 
     mbedtls_ripemd160_init( &ctx );
-    mbedtls_ripemd160_starts( &ctx );
-    mbedtls_ripemd160_update( &ctx, input, ilen );
-    mbedtls_ripemd160_finish( &ctx, output );
+
+    if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
     mbedtls_ripemd160_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[20] )
+{
+    mbedtls_ripemd160_ret( input, ilen, output );
 }
+#endif
 
 #if defined(MBEDTLS_SELF_TEST)
 /*
@@ -391,18 +471,22 @@ void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
  * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
  */
 #define TESTS   8
-#define KEYS    2
-static const char *ripemd160_test_input[TESTS] =
+static const unsigned char ripemd160_test_str[TESTS][81] =
+{
+    { "" },
+    { "a" },
+    { "abc" },
+    { "message digest" },
+    { "abcdefghijklmnopqrstuvwxyz" },
+    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
+    { "12345678901234567890123456789012345678901234567890123456789012"
+      "345678901234567890" },
+};
+
+static const size_t ripemd160_test_strlen[TESTS] =
 {
-    "",
-    "a",
-    "abc",
-    "message digest",
-    "abcdefghijklmnopqrstuvwxyz",
-    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-    "1234567890123456789012345678901234567890"
-        "1234567890123456789012345678901234567890",
+    0, 1, 3, 14, 26, 56, 62, 80
 };
 
 static const unsigned char ripemd160_test_md[TESTS][20] =
@@ -430,7 +514,7 @@ static const unsigned char ripemd160_test_md[TESTS][20] =
  */
 int mbedtls_ripemd160_self_test( int verbose )
 {
-    int i;
+    int i, ret = 0;
     unsigned char output[20];
 
     memset( output, 0, sizeof output );
@@ -440,16 +524,15 @@ int mbedtls_ripemd160_self_test( int verbose )
         if( verbose != 0 )
             mbedtls_printf( "  RIPEMD-160 test #%d: ", i + 1 );
 
-        mbedtls_ripemd160( (const unsigned char *) ripemd160_test_input[i],
-                   strlen( ripemd160_test_input[i] ),
-                   output );
+        ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
+                                     ripemd160_test_strlen[i], output );
+        if( ret != 0 )
+            goto fail;
 
         if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
         {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
-            return( 1 );
+            ret = 1;
+            goto fail;
         }
 
         if( verbose != 0 )
@@ -460,6 +543,12 @@ int mbedtls_ripemd160_self_test( int verbose )
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/crypto/mbedtls/src/rsa.c b/crypto/mbedtls/src/rsa.c
index bdd2538c3..729e1f735 100644
--- a/crypto/mbedtls/src/rsa.c
+++ b/crypto/mbedtls/src/rsa.c
@@ -18,6 +18,7 @@
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
+
 /*
  *  The following sources were referenced in the design of this implementation
  *  of the RSA algorithm:
@@ -45,6 +46,7 @@
 #if defined(MBEDTLS_RSA_C)
 
 #include "mbedtls/rsa.h"
+#include "mbedtls/rsa_internal.h"
 #include "mbedtls/oid.h"
 
 #include <string.h>
@@ -66,11 +68,394 @@
 #define mbedtls_free   free
 #endif
 
+#if !defined(MBEDTLS_RSA_ALT)
+
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n ) {
     volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
 }
 
+#if defined(MBEDTLS_PKCS1_V15)
+/* constant-time buffer comparison */
+static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
+{
+    size_t i;
+    const unsigned char *A = (const unsigned char *) a;
+    const unsigned char *B = (const unsigned char *) b;
+    unsigned char diff = 0;
+
+    for( i = 0; i < n; i++ )
+        diff |= A[i] ^ B[i];
+
+    return( diff );
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
+                        const mbedtls_mpi *N,
+                        const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                        const mbedtls_mpi *D, const mbedtls_mpi *E )
+{
+    int ret;
+
+    if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+
+    if( N != NULL )
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+
+    return( 0 );
+}
+
+int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
+                            unsigned char const *N, size_t N_len,
+                            unsigned char const *P, size_t P_len,
+                            unsigned char const *Q, size_t Q_len,
+                            unsigned char const *D, size_t D_len,
+                            unsigned char const *E, size_t E_len )
+{
+    int ret = 0;
+
+    if( N != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+    }
+
+    if( P != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    return( 0 );
+}
+
+/*
+ * Checks whether the context fields are set in such a way
+ * that the RSA primitives will be able to execute without error.
+ * It does *not* make guarantees for consistency of the parameters.
+ */
+static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
+                              int blinding_needed )
+{
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* blinding_needed is only used for NO_CRT to decide whether
+     * P,Q need to be present or not. */
+    ((void) blinding_needed);
+#endif
+
+    if( ctx->len != mbedtls_mpi_size( &ctx->N ) ||
+        ctx->len > MBEDTLS_MPI_MAX_SIZE )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /*
+     * 1. Modular exponentiation needs positive, odd moduli.
+     */
+
+    /* Modular exponentiation wrt. N is always used for
+     * RSA public key operations. */
+    if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
+        mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0  )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* Modular exponentiation for P and Q is only
+     * used for private key operations and if CRT
+     * is used. */
+    if( is_priv &&
+        ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
+          mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
+          mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
+          mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0  ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* !MBEDTLS_RSA_NO_CRT */
+
+    /*
+     * 2. Exponents must be positive
+     */
+
+    /* Always need E for public key operations */
+    if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+    /* For private key operations, use D or DP & DQ
+     * as (unblinded) exponents. */
+    if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+#else
+    if( is_priv &&
+        ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
+          mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0  ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    /* Blinding shouldn't make exponents negative either,
+     * so check that P, Q >= 1 if that hasn't yet been
+     * done as part of 1. */
+#if defined(MBEDTLS_RSA_NO_CRT)
+    if( is_priv && blinding_needed &&
+        ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
+          mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif
+
+    /* It wouldn't lead to an error if it wasn't satisfied,
+     * but check for QP >= 1 nonetheless. */
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    if( is_priv &&
+        mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif
+
+    return( 0 );
+}
+
+int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
+{
+    int ret = 0;
+
+    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 );
+
+    /*
+     * Check whether provided parameters are enough
+     * to deduce all others. The following incomplete
+     * parameter sets for private keys are supported:
+     *
+     * (1) P, Q missing.
+     * (2) D and potentially N missing.
+     *
+     */
+
+    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;
+
+    /* These three alternatives are mutually exclusive */
+    const int is_priv = n_missing || pq_missing || d_missing;
+
+    if( !is_priv && !is_pub )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Step 1: Deduce N if P, Q are provided.
+     */
+
+    if( !have_N && have_P && have_Q )
+    {
+        if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
+                                         &ctx->Q ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+    }
+
+    /*
+     * Step 2: Deduce and verify all remaining core parameters.
+     */
+
+    if( pq_missing )
+    {
+        ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
+                                         &ctx->P, &ctx->Q );
+        if( ret != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    }
+    else if( d_missing )
+    {
+        if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
+                                                         &ctx->Q,
+                                                         &ctx->E,
+                                                         &ctx->D ) ) != 0 )

  (This diff was longer than 20,000 lines, and has been truncated...)


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services