Merge remote-tracking branch 'upstream-public/pr/1287' into development
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3e47224..ca4cba2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -126,8 +126,8 @@
 endif()
 
 ADD_CUSTOM_TARGET(apidoc
-    COMMAND doxygen doxygen/mbedtls.doxyfile
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+    COMMAND doxygen mbedtls.doxyfile
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doxygen)
 
 if(ENABLE_TESTING)
     enable_testing()
diff --git a/ChangeLog b/ChangeLog
index a6fa6bb..c87c146 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -28,18 +28,14 @@
      The following functions from the ECDSA module can be replaced
      with alternative implementation:
      mbedtls_ecdsa_sign(), mbedtls_ecdsa_verify() and mbedtls_ecdsa_genkey().
-   * Add support for alternative implementation for ECDH, controlled by new
-     configuration flags MBEDTLS_ECDH_COMPUTE_SHARED_ALT and
+   * Add support for alternative implementation of ECDH, controlled by the
+     new configuration flags MBEDTLS_ECDH_COMPUTE_SHARED_ALT and
      MBEDTLS_ECDH_GEN_PUBLIC_ALT in config.h.
      The following functions from the ECDH module can be replaced
      with an alternative implementation:
      mbedtls_ecdh_gen_public() and mbedtls_ecdh_compute_shared().
-
-New deprecations
-   * Deprecate usage of RSA primitives with non-matching key-type
-     (e.g., signing with a public key).
-   * Direct manipulation of structure fields of RSA contexts is deprecated.
-     Users are advised to use the extended RSA API instead.
+   * Add support for alternative implementation of ECJPAKE, controlled by
+     the new configuration flag MBEDTLS_ECJPAKE_ALT.
 
 API Changes
    * Extend RSA interface by multiple functions allowing structure-
@@ -51,6 +47,25 @@
      purpose or CRT and/or blinding.
    * The configuration option MBEDTLS_RSA_ALT can be used to define alternative
      implementations of the RSA interface declared in rsa.h.
+   * The following functions in the message digest modules (MD2, MD4, MD5,
+     SHA1, SHA256, SHA512) have been deprecated and replaced as shown below.
+     The new functions change the return type from void to int to allow
+     returning error codes when using MBEDTLS_<MODULE>_ALT.
+     mbedtls_<MODULE>_starts() -> mbedtls_<MODULE>_starts_ret()
+     mbedtls_<MODULE>_update() -> mbedtls_<MODULE>_update_ret()
+     mbedtls_<MODULE>_finish() -> mbedtls_<MODULE>_finish_ret()
+     mbedtls_<MODULE>_process() -> mbedtls_internal_<MODULE>_process()
+
+New deprecations
+   * Deprecate usage of RSA primitives with non-matching key-type
+     (e.g., signing with a public key).
+   * Direct manipulation of structure fields of RSA contexts is deprecated.
+     Users are advised to use the extended RSA API instead.
+   * Deprecate usage of message digest functions that return void
+     (mbedtls_<MODULE>_starts, mbedtls_<MODULE>_update,
+     mbedtls_<MODULE>_finish and mbedtls_<MODULE>_process where <MODULE> is
+     any of MD2, MD4, MD5, SHA1, SHA256, SHA512) in favor of functions
+     that can return an error code.
 
 Bugfix
    * Fix ssl_parse_record_header() to silently discard invalid DTLS records
@@ -101,6 +116,19 @@
      RSA test suite where the failure of CTR DRBG initialization lead to
      freeing an RSA context and several MPI's without proper initialization
      beforehand.
+   * Fix error message in programs/pkey/gen_key.c. Found and fixed by Chris Xue.
+   * Fix programs/pkey/dh_server.c so that it actually works with dh_client.c.
+     Found and fixed by Martijn de Milliano.
+   * Fix bug in cipher decryption with MBEDTLS_PADDING_ONE_AND_ZEROS that
+     sometimes accepted invalid padding. (Not used in TLS.) Found and fixed
+     by Micha Kraus.
+   * Fix the entropy.c module to not call mbedtls_sha256_starts() or
+     mbedtls_sha512_starts() in the mbedtls_entropy_init() function.
+   * Fix the entropy.c module to ensure that mbedtls_sha256_init() or
+     mbedtls_sha512_init() is called before operating on the relevant context
+     structure. Do not assume that zeroizing a context is a correct way to
+     reset it. Found independently by ccli8 on Github.
+   * In mbedtls_entropy_free(), properly free the message digest context.
 
 Changes
    * Extend cert_write example program by options to set the CRT version
@@ -113,6 +141,15 @@
    * Only run AES-192 self-test if AES-192 is available. Fixes #963.
    * Tighten the RSA PKCS#1 v1.5 signature verification code and remove the
      undeclared dependency of the RSA module on the ASN.1 module.
+   * Add mechanism to provide alternative implementation of the DHM module.
+   * Update all internal usage of deprecated message digest functions to the
+     new ones with return codes. In particular, this modifies the
+     mbedtls_md_info_t structure. Propagate errors from these functions
+     everywhere except some locations in the ssl_tls.c module.
+   * Improve CTR_DRBG error handling by propagating underlying AES errors.
+   * Add MBEDTLS_ERR_XXX_HW_ACCEL_FAILED error codes for all cryptography
+     modules where the software implementation can be replaced by a hardware
+     implementation.
 
 = mbed TLS 2.6.0 branch released 2017-08-10
 
diff --git a/Makefile b/Makefile
index d475868..c18b99b 100644
--- a/Makefile
+++ b/Makefile
@@ -103,7 +103,7 @@
 
 apidoc:
 	mkdir -p apidoc
-	doxygen doxygen/mbedtls.doxyfile
+	cd doxygen && doxygen mbedtls.doxyfile
 
 apidoc_clean:
 	rm -rf apidoc
diff --git a/configs/config-ccm-psk-tls1_2.h b/configs/config-ccm-psk-tls1_2.h
index aee10b8..a783e6b 100644
--- a/configs/config-ccm-psk-tls1_2.h
+++ b/configs/config-ccm-psk-tls1_2.h
@@ -1,6 +1,9 @@
-/*
- *  Minimal configuration for TLS 1.2 with PSK and AES-CCM ciphersuites
+/**
+ * \file config-ccm-psk-tls1_2.h
  *
+ * \brief Minimal configuration for TLS 1.2 with PSK and AES-CCM ciphersuites
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/configs/config-mini-tls1_1.h b/configs/config-mini-tls1_1.h
index e22363d..013bc03 100644
--- a/configs/config-mini-tls1_1.h
+++ b/configs/config-mini-tls1_1.h
@@ -1,6 +1,9 @@
-/*
- *  Minimal configuration for TLS 1.1 (RFC 4346)
+/**
+ * \file config-mini-tls1_1.h
  *
+ * \brief Minimal configuration for TLS 1.1 (RFC 4346)
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/configs/config-no-entropy.h b/configs/config-no-entropy.h
index 7375860..b4a0930 100644
--- a/configs/config-no-entropy.h
+++ b/configs/config-no-entropy.h
@@ -1,6 +1,9 @@
 /**
- *  Minimal configuration of features that do not require an entropy source
+ * \file config-no-entropy.h
  *
+ * \brief Minimal configuration of features that do not require an entropy source
+ */
+/*
  *  Copyright (C) 2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/configs/config-picocoin.h b/configs/config-picocoin.h
index 26b24a9..5d41f28 100644
--- a/configs/config-picocoin.h
+++ b/configs/config-picocoin.h
@@ -1,6 +1,9 @@
-/*
- *  Reduced configuration used by Picocoin.
+/**
+ * \file config-picocoin.h
  *
+ * \brief Reduced configuration used by Picocoin.
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/configs/config-suite-b.h b/configs/config-suite-b.h
index 3c4804c..18e2c40 100644
--- a/configs/config-suite-b.h
+++ b/configs/config-suite-b.h
@@ -1,6 +1,9 @@
-/*
- *  Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
+/**
+ * \file config-suite-b.h
  *
+ * \brief Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/configs/config-thread.h b/configs/config-thread.h
index 990fe08..25db16b 100644
--- a/configs/config-thread.h
+++ b/configs/config-thread.h
@@ -1,6 +1,9 @@
-/*
- *  Minimal configuration for using TLS as part of Thread
+/**
+ * \file config-thread.h
  *
+ * \brief Minimal configuration for using TLS as part of Thread
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/doxygen/input/doc_encdec.h b/doxygen/input/doc_encdec.h
index 9538ed2..b1281cb 100644
--- a/doxygen/input/doc_encdec.h
+++ b/doxygen/input/doc_encdec.h
@@ -1,6 +1,9 @@
 /**
- * @file
- * Encryption/decryption module documentation file.
+ * \file doc_encdec.h
+ *
+ * \brief Encryption/decryption module documentation file.
+ */
+/*
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
diff --git a/doxygen/input/doc_hashing.h b/doxygen/input/doc_hashing.h
index 49f15ea..e54b28e 100644
--- a/doxygen/input/doc_hashing.h
+++ b/doxygen/input/doc_hashing.h
@@ -1,6 +1,9 @@
 /**
- * @file
- * Hashing module documentation file.
+ * \file doc_hashing.h
+ *
+ * \brief Hashing module documentation file.
+ */
+/*
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 87b5041..add75f7 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -1,6 +1,9 @@
 /**
- * @file
- * Main page documentation file.
+ * \file doc_mainpage.h
+ *
+ * \brief Main page documentation file.
+ */
+/*
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
diff --git a/doxygen/input/doc_rng.h b/doxygen/input/doc_rng.h
index 0159ef3..0f212e0 100644
--- a/doxygen/input/doc_rng.h
+++ b/doxygen/input/doc_rng.h
@@ -1,6 +1,9 @@
 /**
- * @file
- * Random number generator (RNG) module documentation file.
+ * \file doc_rng.h
+ *
+ * \brief Random number generator (RNG) module documentation file.
+ */
+/*
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
diff --git a/doxygen/input/doc_ssltls.h b/doxygen/input/doc_ssltls.h
index 7f104bd..4addfb3 100644
--- a/doxygen/input/doc_ssltls.h
+++ b/doxygen/input/doc_ssltls.h
@@ -1,6 +1,9 @@
 /**
- * @file
- * SSL/TLS communication module documentation file.
+ * \file doc_ssltls.h
+ *
+ * \brief SSL/TLS communication module documentation file.
+ */
+/*
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
diff --git a/doxygen/input/doc_tcpip.h b/doxygen/input/doc_tcpip.h
index 34d3ca1..95f4586 100644
--- a/doxygen/input/doc_tcpip.h
+++ b/doxygen/input/doc_tcpip.h
@@ -1,6 +1,9 @@
 /**
- * @file
- * TCP/IP communication module documentation file.
+ * \file doc_tcpip.h
+ *
+ * \brief TCP/IP communication module documentation file.
+ */
+/*
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
diff --git a/doxygen/input/doc_x509.h b/doxygen/input/doc_x509.h
index 315f0e3..9b52569 100644
--- a/doxygen/input/doc_x509.h
+++ b/doxygen/input/doc_x509.h
@@ -1,6 +1,9 @@
 /**
- * @file
- * X.509 module documentation file.
+ * \file doc_x509.h
+ *
+ * \brief X.509 module documentation file.
+ */
+/*
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 5df1c93..d5b3abe 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -54,7 +54,7 @@
 # If a relative path is entered, it will be relative to the location
 # where doxygen was started. If left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = apidoc/
+OUTPUT_DIRECTORY       = ../apidoc/
 
 # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
 # 4096 sub-directories (in 2 levels) under the output directory of each output
@@ -664,7 +664,7 @@
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = .
+INPUT                  = ..
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -696,7 +696,7 @@
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = configs yotta/module
+EXCLUDE                = ../configs ../yotta/module
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index c8dd0f3..541fa93 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -2,7 +2,8 @@
  * \file aes.h
  *
  * \brief AES block cipher
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -40,8 +41,9 @@
 #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-0x0023 */
+/* Error codes in range 0x0023-0x0025 */
 #define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023  /**< Feature not available, e.g. 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)
diff --git a/include/mbedtls/aesni.h b/include/mbedtls/aesni.h
index b1b7f1c..746baa0 100644
--- a/include/mbedtls/aesni.h
+++ b/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/include/mbedtls/arc4.h b/include/mbedtls/arc4.h
index 5fc5395..875c574 100644
--- a/include/mbedtls/arc4.h
+++ b/include/mbedtls/arc4.h
@@ -2,7 +2,8 @@
  * \file arc4.h
  *
  * \brief The ARCFOUR stream cipher
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -31,6 +32,8 @@
 
 #include <stddef.h>
 
+#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED                  -0x0019  /**< ARC4 hardware accelerator failed. */
+
 #if !defined(MBEDTLS_ARC4_ALT)
 // Regular implementation
 //
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index e159e57..fde328a 100644
--- a/include/mbedtls/asn1.h
+++ b/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
  *
diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h
index 73ff32b..f76fc80 100644
--- a/include/mbedtls/asn1write.h
+++ b/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/include/mbedtls/base64.h b/include/mbedtls/base64.h
index 352c652..7a64f52 100644
--- a/include/mbedtls/base64.h
+++ b/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/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 0b40015..c20b367 100644
--- a/include/mbedtls/bignum.h
+++ b/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
  *
diff --git a/include/mbedtls/blowfish.h b/include/mbedtls/blowfish.h
index 34626ee..c0ef5a0 100644
--- a/include/mbedtls/blowfish.h
+++ b/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,6 +41,7 @@
 #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)
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index cac3f14..354c1cc 100644
--- a/include/mbedtls/bn_mul.h
+++ b/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/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 0424d62..cf07629 100644
--- a/include/mbedtls/camellia.h
+++ b/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,6 +38,7 @@
 
 #define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH           -0x0024  /**< Invalid key length. */
 #define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH         -0x0026  /**< Invalid data input length. */
+#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED              -0x0027  /**< Camellia hardware accelerator failed. */
 
 #if !defined(MBEDTLS_CAMELLIA_ALT)
 // Regular implementation
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index 579402f..1459eb8 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -2,7 +2,8 @@
  * \file ccm.h
  *
  * \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -27,6 +28,7 @@
 
 #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_HW_ACCEL_FAILED                   -0x0011  /**< CCM hardware accelerator failed. */
 
 #if !defined(MBEDTLS_CCM_ALT)
 // Regular implementation
diff --git a/include/mbedtls/certs.h b/include/mbedtls/certs.h
index ca49086..8dab7b5 100644
--- a/include/mbedtls/certs.h
+++ b/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/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index fa72454..1143aa2 100644
--- a/include/mbedtls/check_config.h
+++ b/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
  *
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index b12e388..97b9226 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -4,7 +4,8 @@
  * \brief Generic cipher wrapper.
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -57,7 +58,8 @@
 #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_INVALID_CONTEXT                -0x6380  /**< The context is invalid, eg because it was free()ed. */
+#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 */
diff --git a/include/mbedtls/cipher_internal.h b/include/mbedtls/cipher_internal.h
index 6c58bcc..969ff9c 100644
--- a/include/mbedtls/cipher_internal.h
+++ b/include/mbedtls/cipher_internal.h
@@ -4,7 +4,8 @@
  * \brief Cipher wrappers.
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/cmac.h b/include/mbedtls/cmac.h
index 4d3f2d2..1cac948 100644
--- a/include/mbedtls/cmac.h
+++ b/include/mbedtls/cmac.h
@@ -3,7 +3,8 @@
  *
  * \brief Cipher-based Message Authentication Code (CMAC) Mode for
  *        Authentication
- *
+ */
+/*
  *  Copyright (C) 2015-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -30,6 +31,8 @@
 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
 
diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
index bba1d2c..600a0f1 100644
--- a/include/mbedtls/compat-1.3.h
+++ b/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/include/mbedtls/config.h b/include/mbedtls/config.h
index 4933108..6f62a87 100644
--- a/include/mbedtls/config.h
+++ b/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
  *
@@ -269,6 +270,8 @@
 //#define MBEDTLS_CCM_ALT
 //#define MBEDTLS_CMAC_ALT
 //#define MBEDTLS_DES_ALT
+//#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_ECJPAKE_ALT
 //#define MBEDTLS_GCM_ALT
 //#define MBEDTLS_MD2_ALT
 //#define MBEDTLS_MD4_ALT
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 059d3c5..01cd826 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -2,7 +2,8 @@
  * \file ctr_drbg.h
  *
  * \brief CTR_DRBG based on AES-256 (NIST SP 800-90)
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index 2957996..ef8db67 100644
--- a/include/mbedtls/debug.h
+++ b/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/include/mbedtls/des.h b/include/mbedtls/des.h
index 5ca2ecf..1752898 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -2,7 +2,8 @@
  * \file des.h
  *
  * \brief DES block cipher
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -36,6 +37,7 @@
 #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
 
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index d7ab152..8a28ffa 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -2,7 +2,8 @@
  * \file dhm.h
  *
  * \brief Diffie-Hellman-Merkle key exchange
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -23,7 +24,13 @@
 #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"
+#if !defined(MBEDTLS_DHM_ALT)
 
 /*
  * DHM Error codes
@@ -37,6 +44,7 @@
 #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. */
+#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED                   -0x3500  /**< DHM hardware accelerator failed. */
 
 /**
  * RFC 3526 defines a number of standardized Diffie-Hellman groups
@@ -291,6 +299,18 @@
 #endif /* MBEDTLS_FS_IO */
 #endif /* MBEDTLS_ASN1_PARSE_C */
 
+#ifdef __cplusplus
+}
+#endif
+
+#else /* MBEDTLS_DHM_ALT */
+#include "dhm_alt.h"
+#endif /* MBEDTLS_DHM_ALT */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \brief          Checkup routine
  *
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 625a281..14a362b 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -2,7 +2,8 @@
  * \file ecdh.h
  *
  * \brief Elliptic curve Diffie-Hellman
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index a277715..6c6ae29 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -2,7 +2,8 @@
  * \file ecdsa.h
  *
  * \brief Elliptic curve DSA
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index 161a5b2..d86e820 100644
--- a/include/mbedtls/ecjpake.h
+++ b/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
  *
@@ -43,6 +44,8 @@
 #include "ecp.h"
 #include "md.h"
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -222,17 +225,31 @@
  */
 void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
 
+#ifdef __cplusplus
+}
+#endif
+
+#else  /* MBEDTLS_ECJPAKE_ALT */
+#include "ecjpake_alt.h"
+#endif /* MBEDTLS_ECJPAKE_ALT */
+
 #if defined(MBEDTLS_SELF_TEST)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if a test failed
  */
 int mbedtls_ecjpake_self_test( int verbose );
-#endif
 
 #ifdef __cplusplus
 }
 #endif
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #endif /* ecjpake.h */
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index dad9aef..b00ba4d 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -2,7 +2,8 @@
  * \file ecp.h
  *
  * \brief Elliptic curves over GF(p)
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -36,6 +37,7 @@
 #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. */
+#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED                   -0x4B80  /**< ECP hardware accelerator failed. */
 
 #if !defined(MBEDTLS_ECP_ALT)
 /*
diff --git a/include/mbedtls/ecp_internal.h b/include/mbedtls/ecp_internal.h
index 2991e26..8a6d517 100644
--- a/include/mbedtls/ecp_internal.h
+++ b/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/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index 747aca4..fcb4d02 100644
--- a/include/mbedtls/entropy.h
+++ b/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 @@
  */
 typedef struct
 {
+    int accumulator_started;
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
     mbedtls_sha512_context  accumulator;
 #else
diff --git a/include/mbedtls/entropy_poll.h b/include/mbedtls/entropy_poll.h
index 81258d5..94dd657 100644
--- a/include/mbedtls/entropy_poll.h
+++ b/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/include/mbedtls/error.h b/include/mbedtls/error.h
index 4eb7b78..cc17789 100644
--- a/include/mbedtls/error.h
+++ b/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   0x0023-0x0023
- * 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   10
- * ECP       4   8 (Started from top)
- * MD        5   4
- * CIPHER    6   6
+ * DHM       3   10
+ * 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/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index 8f3b565..c7f01c3 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -2,7 +2,8 @@
  * \file gcm.h
  *
  * \brief Galois/Counter mode for 128-bit block ciphers
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -31,6 +32,7 @@
 #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. */
 
 #if !defined(MBEDTLS_GCM_ALT)
diff --git a/include/mbedtls/havege.h b/include/mbedtls/havege.h
index dac5d31..d4cb3ed 100644
--- a/include/mbedtls/havege.h
+++ b/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/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index e010558..e0821cf 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/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/include/mbedtls/md.h b/include/mbedtls/md.h
index 89be847..57c27a6 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -4,7 +4,8 @@
  * \brief Generic message digest wrapper
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -37,6 +38,7 @@
 #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" {
diff --git a/include/mbedtls/md2.h b/include/mbedtls/md2.h
index 0f93fbf..b245b5b 100644
--- a/include/mbedtls/md2.h
+++ b/include/mbedtls/md2.h
@@ -2,7 +2,8 @@
  * \file md2.h
  *
  * \brief MD2 message digest algorithm (hash function)
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -31,6 +32,13 @@
 
 #include <stddef.h>
 
+#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED                   -0x002B  /**< MD2 hardware accelerator failed */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 #if !defined(MBEDTLS_MD2_ALT)
 // Regular implementation
 //
@@ -78,25 +86,110 @@
  * \brief          MD2 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
  */
-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
  */
-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
  */
-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] );
+
+/**
+ * \brief          MD2 process data block (internal use only)
+ *
+ * \param ctx      MD2 context
+ *
+ * \return         0 if successful
+ */
+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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md2_starts(
+                                                    mbedtls_md2_context *ctx )
+{
+    mbedtls_md2_starts_ret( ctx );
+}
+
+/**
+ * \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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md2_update(
+                                                mbedtls_md2_context *ctx,
+                                                const unsigned char *input,
+                                                size_t ilen )
+{
+    mbedtls_md2_update_ret( ctx, input, ilen );
+}
+
+/**
+ * \brief          MD2 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md2_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ * \param output   MD2 checksum result
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md2_finish(
+                                                    mbedtls_md2_context *ctx,
+                                                    unsigned char output[16] )
+{
+    mbedtls_md2_finish_ret( ctx, output );
+}
+
+/**
+ * \brief          MD2 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_md2_process() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md2_process(
+                                                    mbedtls_md2_context *ctx )
+{
+    mbedtls_internal_md2_process( ctx );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 #ifdef __cplusplus
 }
@@ -113,11 +206,38 @@
 /**
  * \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
  */
-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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md2( const unsigned char *input,
+                                                   size_t ilen,
+                                                   unsigned char output[16] )
+{
+    mbedtls_md2_ret( input, ilen, output );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
@@ -126,9 +246,6 @@
  */
 int mbedtls_md2_self_test( int verbose );
 
-/* Internal use */
-void mbedtls_md2_process( mbedtls_md2_context *ctx );
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/md4.h b/include/mbedtls/md4.h
index 45214d4..886a669 100644
--- a/include/mbedtls/md4.h
+++ b/include/mbedtls/md4.h
@@ -2,7 +2,8 @@
  * \file md4.h
  *
  * \brief MD4 message digest algorithm (hash function)
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -32,6 +33,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED                   -0x002D  /**< MD4 hardware accelerator failed */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 #if !defined(MBEDTLS_MD4_ALT)
 // Regular implementation
 //
@@ -78,25 +86,114 @@
  * \brief          MD4 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
  */
-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
  */
-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
  */
-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] );
+
+/**
+ * \brief          MD4 process data block (internal use only)
+ *
+ * \param ctx      MD4 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ */
+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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md4_starts(
+                                                    mbedtls_md4_context *ctx )
+{
+    mbedtls_md4_starts_ret( ctx );
+}
+
+/**
+ * \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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md4_update(
+                                                    mbedtls_md4_context *ctx,
+                                                    const unsigned char *input,
+                                                    size_t ilen )
+{
+    mbedtls_md4_update_ret( ctx, input, ilen );
+}
+
+/**
+ * \brief          MD4 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md4_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD4 context
+ * \param output   MD4 checksum result
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md4_finish(
+                                                    mbedtls_md4_context *ctx,
+                                                    unsigned char output[16] )
+{
+    mbedtls_md4_finish_ret( ctx, output );
+}
+
+/**
+ * \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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md4_process(
+                                                mbedtls_md4_context *ctx,
+                                                const unsigned char data[64] )
+{
+    mbedtls_internal_md4_process( ctx, data );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 #ifdef __cplusplus
 }
@@ -113,11 +210,40 @@
 /**
  * \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
+ */
+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
  */
-void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] );
+MBEDTLS_DEPRECATED static inline void mbedtls_md4( const unsigned char *input,
+                                                   size_t ilen,
+                                                   unsigned char output[16] )
+{
+    mbedtls_md4_ret( input, ilen, output );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
@@ -126,9 +252,6 @@
  */
 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/include/mbedtls/md5.h b/include/mbedtls/md5.h
index 5a64061..5734b40 100644
--- a/include/mbedtls/md5.h
+++ b/include/mbedtls/md5.h
@@ -2,7 +2,8 @@
  * \file md5.h
  *
  * \brief MD5 message digest algorithm (hash function)
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -32,10 +33,17 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED                   -0x002F  /**< MD5 hardware accelerator failed */
+
 #if !defined(MBEDTLS_MD5_ALT)
 // Regular implementation
 //
 
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -78,28 +86,114 @@
  * \brief          MD5 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
  */
-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
  */
-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
  */
-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
+ */
+int mbedtls_internal_md5_process( mbedtls_md5_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          MD5 context setup
+ *
+ * \deprecated     Superseded by mbedtls_md5_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md5_starts(
+                                                    mbedtls_md5_context *ctx )
+{
+    mbedtls_md5_starts_ret( ctx );
+}
+
+/**
+ * \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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md5_update(
+                                                    mbedtls_md5_context *ctx,
+                                                    const unsigned char *input,
+                                                    size_t ilen )
+{
+    mbedtls_md5_update_ret( ctx, input, ilen );
+}
+
+/**
+ * \brief          MD5 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md5_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD5 context
+ * \param output   MD5 checksum result
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md5_finish(
+                                                    mbedtls_md5_context *ctx,
+                                                    unsigned char output[16] )
+{
+    mbedtls_md5_finish_ret( ctx, output );
+}
+
+/**
+ * \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
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_md5_process(
+                                                mbedtls_md5_context *ctx,
+                                                const unsigned char data[64] )
+{
+    mbedtls_internal_md5_process( ctx, data );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 #ifdef __cplusplus
 }
@@ -116,11 +210,40 @@
 /**
  * \brief          Output = MD5( input buffer )
  *
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD5 checksum result
+ *
+ * \return         0 if successful
+ */
+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 )
+ *
+ * \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
  */
-void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] );
+MBEDTLS_DEPRECATED static inline void mbedtls_md5( const unsigned char *input,
+                                                   size_t ilen,
+                                                   unsigned char output[16] )
+{
+    mbedtls_md5_ret( input, ilen, output );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
diff --git a/include/mbedtls/md_internal.h b/include/mbedtls/md_internal.h
index e2441bb..04de482 100644
--- a/include/mbedtls/md_internal.h
+++ b/include/mbedtls/md_internal.h
@@ -6,7 +6,8 @@
  * \warning This in an internal header. Do not include directly.
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -58,17 +59,17 @@
     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 @@
     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/include/mbedtls/memory_buffer_alloc.h b/include/mbedtls/memory_buffer_alloc.h
index d5df316..705f9a6 100644
--- a/include/mbedtls/memory_buffer_alloc.h
+++ b/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/include/mbedtls/net.h b/include/mbedtls/net.h
index 774559b..28ae821 100644
--- a/include/mbedtls/net.h
+++ b/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/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index de33552..54e612c 100644
--- a/include/mbedtls/net_sockets.h
+++ b/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
  *
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index fcecdaf..bf2ef5e 100644
--- a/include/mbedtls/oid.h
+++ b/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
  *
diff --git a/include/mbedtls/padlock.h b/include/mbedtls/padlock.h
index 2045a5a..677936e 100644
--- a/include/mbedtls/padlock.h
+++ b/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/include/mbedtls/pem.h b/include/mbedtls/pem.h
index 54dc02d..2cf4c0a 100644
--- a/include/mbedtls/pem.h
+++ b/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/include/mbedtls/pk.h b/include/mbedtls/pk.h
index f9f9b9b..1059bda 100644
--- a/include/mbedtls/pk.h
+++ b/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
  *
@@ -63,6 +64,7 @@
 #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_HW_ACCEL_FAILED     -0x3880  /**< PK hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/pk_internal.h b/include/mbedtls/pk_internal.h
index 01d0f21..3dae0fc 100644
--- a/include/mbedtls/pk_internal.h
+++ b/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/include/mbedtls/pkcs11.h b/include/mbedtls/pkcs11.h
index 2e88928..bf65c55 100644
--- a/include/mbedtls/pkcs11.h
+++ b/include/mbedtls/pkcs11.h
@@ -4,7 +4,8 @@
  * \brief Wrapper for PKCS#11 library libpkcs11-helper
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/pkcs12.h b/include/mbedtls/pkcs12.h
index 9b2d904..a621ef5 100644
--- a/include/mbedtls/pkcs12.h
+++ b/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/include/mbedtls/pkcs5.h b/include/mbedtls/pkcs5.h
index ec5cb9e..9a3c9fd 100644
--- a/include/mbedtls/pkcs5.h
+++ b/include/mbedtls/pkcs5.h
@@ -4,7 +4,8 @@
  * \brief PKCS#5 functions
  *
  * \author Mathias Olsson <mathias@kompetensum.com>
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index 35010f8..e051751 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -2,7 +2,8 @@
  * \file platform.h
  *
  * \brief mbed TLS Platform abstraction layer
- *
+ */
+/*
  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/platform_time.h b/include/mbedtls/platform_time.h
index abb3431..2ed36f5 100644
--- a/include/mbedtls/platform_time.h
+++ b/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/include/mbedtls/ripemd160.h b/include/mbedtls/ripemd160.h
index 7083fc8..c21868b 100644
--- a/include/mbedtls/ripemd160.h
+++ b/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,6 +33,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED             -0x0031  /**< RIPEMD160 hardware accelerator failed */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 #if !defined(MBEDTLS_RIPEMD160_ALT)
 // Regular implementation
 //
@@ -78,36 +86,121 @@
  * \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] );
+
+#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 static inline void mbedtls_ripemd160_starts(
+                                            mbedtls_ripemd160_context *ctx )
+{
+    mbedtls_ripemd160_starts_ret( ctx );
+}
+
+/**
+ * \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 static inline void mbedtls_ripemd160_update(
+                                                mbedtls_ripemd160_context *ctx,
+                                                const unsigned char *input,
+                                                size_t ilen )
+{
+    mbedtls_ripemd160_update_ret( ctx, input, ilen );
+}
+
+/**
+ * \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 static inline void mbedtls_ripemd160_finish(
+                                                mbedtls_ripemd160_context *ctx,
+                                                unsigned char output[20] )
+{
+    mbedtls_ripemd160_finish_ret( ctx, output );
+}
+
+/**
+ * \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 static inline void mbedtls_ripemd160_process(
+                                            mbedtls_ripemd160_context *ctx,
+                                            const unsigned char data[64] )
+{
+    mbedtls_internal_ripemd160_process( ctx, data );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 #ifdef __cplusplus
 }
 #endif
 
 #else  /* MBEDTLS_RIPEMD160_ALT */
-#include "ripemd160.h"
+#include "ripemd160_alt.h"
 #endif /* MBEDTLS_RIPEMD160_ALT */
 
 #ifdef __cplusplus
@@ -117,12 +210,41 @@
 /**
  * \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
+ */
+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
  */
-void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
-                unsigned char output[20] );
+MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160(
+                                                    const unsigned char *input,
+                                                    size_t ilen,
+                                                    unsigned char output[20] )
+{
+    mbedtls_ripemd160_ret( input, ilen, output );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index d7503ac..7521058 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -2,7 +2,8 @@
  * \file rsa.h
  *
  * \brief The RSA public-key cryptosystem
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -49,6 +50,7 @@
 #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 doesn't offer the requested operation, e.g. because of security violations or lack of functionality */
+#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED                   -0x4580  /**< RSA hardware accelerator failed. */
 
 /*
  * RSA constants
diff --git a/include/mbedtls/rsa_internal.h b/include/mbedtls/rsa_internal.h
index 7e6a2ec..bcb3c94 100644
--- a/include/mbedtls/rsa_internal.h
+++ b/include/mbedtls/rsa_internal.h
@@ -2,7 +2,8 @@
  * \file rsa_internal.h
  *
  * \brief Context-independent RSA helper functions
- *
+ */
+/*
  *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index 7a67c6c..4d3a164 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -2,7 +2,8 @@
  * \file sha1.h
  *
  * \brief SHA-1 cryptographic hash function
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -32,6 +33,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 #if !defined(MBEDTLS_SHA1_ALT)
 // Regular implementation
 //
@@ -78,28 +86,114 @@
  * \brief          SHA-1 context setup
  *
  * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
  */
-void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
+int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
 
 /**
  * \brief          SHA-1 process buffer
  *
  * \param ctx      SHA-1 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_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
  *
  * \param ctx      SHA-1 context
  * \param output   SHA-1 checksum result
+ *
+ * \return         0 if successful
  */
-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)
+ *
+ * \param ctx      SHA-1 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ */
+int mbedtls_internal_sha1_process( mbedtls_sha1_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          SHA-1 context setup
+ *
+ * \deprecated     Superseded by mbedtls_sha1_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha1_starts(
+                                                mbedtls_sha1_context *ctx )
+{
+    mbedtls_sha1_starts_ret( ctx );
+}
+
+/**
+ * \brief          SHA-1 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_sha1_update_ret() in 2.7.0
+ *
+ * \param ctx      SHA-1 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha1_update(
+                                                mbedtls_sha1_context *ctx,
+                                                const unsigned char *input,
+                                                size_t ilen )
+{
+    mbedtls_sha1_update_ret( ctx, input, ilen );
+}
+
+/**
+ * \brief          SHA-1 final digest
+ *
+ * \deprecated     Superseded by mbedtls_sha1_finish_ret() in 2.7.0
+ *
+ * \param ctx      SHA-1 context
+ * \param output   SHA-1 checksum result
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha1_finish(
+                                                mbedtls_sha1_context *ctx,
+                                                unsigned char output[20] )
+{
+    mbedtls_sha1_finish_ret( ctx, output );
+}
+
+/**
+ * \brief          SHA-1 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_sha1_process() in 2.7.0
+ *
+ * \param ctx      SHA-1 context
+ * \param data     buffer holding one block of data
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha1_process(
+                                                mbedtls_sha1_context *ctx,
+                                                const unsigned char data[64] )
+{
+    mbedtls_internal_sha1_process( ctx, data );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 #ifdef __cplusplus
 }
@@ -116,11 +210,40 @@
 /**
  * \brief          Output = SHA-1( input buffer )
  *
- * \param input    buffer holding the  data
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   SHA-1 checksum result
+ *
+ * \return         0 if successful
+ */
+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 )
+ *
+ * \deprecated     Superseded by mbedtls_sha1_ret() in 2.7.0
+ *
+ * \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 static inline void mbedtls_sha1( const unsigned char *input,
+                                                    size_t ilen,
+                                                    unsigned char output[20] )
+{
+    mbedtls_sha1_ret( input, ilen, output );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index f8041ad..5c5d07a 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -2,7 +2,8 @@
  * \file sha256.h
  *
  * \brief SHA-224 and SHA-256 cryptographic hash function
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -32,6 +33,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 #if !defined(MBEDTLS_SHA256_ALT)
 // Regular implementation
 //
@@ -80,29 +88,116 @@
  *
  * \param ctx      context to be initialized
  * \param is224    0 = use SHA256, 1 = use SHA224
+ *
+ * \return         0 if successful
  */
-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
  *
  * \param ctx      SHA-256 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_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
  *
  * \param ctx      SHA-256 context
  * \param output   SHA-224/256 checksum result
+ *
+ * \return         0 if successful
  */
-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          SHA-256 process data block (internal use only)
+ *
+ * \param ctx      SHA-256 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ */
+int mbedtls_internal_sha256_process( mbedtls_sha256_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          SHA-256 context setup
+ *
+ * \deprecated     Superseded by mbedtls_sha256_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ * \param is224    0 = use SHA256, 1 = use SHA224
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha256_starts(
+                                                mbedtls_sha256_context *ctx,
+                                                int is224 )
+{
+    mbedtls_sha256_starts_ret( ctx, is224 );
+}
+
+/**
+ * \brief          SHA-256 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_sha256_update_ret() in 2.7.0
+ *
+ * \param ctx      SHA-256 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha256_update(
+                                                mbedtls_sha256_context *ctx,
+                                                const unsigned char *input,
+                                                size_t ilen )
+{
+    mbedtls_sha256_update_ret( ctx, input, ilen );
+}
+
+/**
+ * \brief          SHA-256 final digest
+ *
+ * \deprecated     Superseded by mbedtls_sha256_finish_ret() in 2.7.0
+ *
+ * \param ctx      SHA-256 context
+ * \param output   SHA-224/256 checksum result
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha256_finish(
+                                                mbedtls_sha256_context *ctx,
+                                                unsigned char output[32] )
+{
+    mbedtls_sha256_finish_ret( ctx, output );
+}
+
+/**
+ * \brief          SHA-256 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_sha256_process() in 2.7.0
+ *
+ * \param ctx      SHA-256 context
+ * \param data     buffer holding one block of data
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha256_process(
+                                                mbedtls_sha256_context *ctx,
+                                                const unsigned char data[64] )
+{
+    mbedtls_internal_sha256_process( ctx, data );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 #ifdef __cplusplus
 }
@@ -119,13 +214,45 @@
 /**
  * \brief          Output = SHA-256( input buffer )
  *
- * \param input    buffer holding the  data
+ * \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
+ *
+ * \return         0 if successful
+ */
+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 )
+ *
+ * \deprecated     Superseded by mbedtls_sha256_ret() in 2.7.0
+ *
+ * \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
  */
-void mbedtls_sha256( const unsigned char *input, size_t ilen,
-           unsigned char output[32], int is224 );
+MBEDTLS_DEPRECATED static inline void mbedtls_sha256(
+                                                    const unsigned char *input,
+                                                    size_t ilen,
+                                                    unsigned char output[32],
+                                                    int is224 )
+{
+    mbedtls_sha256_ret( input, ilen, output, is224 );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 627694f..7453c44 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -2,7 +2,8 @@
  * \file sha512.h
  *
  * \brief SHA-384 and SHA-512 cryptographic hash function
- *
+ */
+/*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -32,6 +33,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 #if !defined(MBEDTLS_SHA512_ALT)
 // Regular implementation
 //
@@ -80,26 +88,116 @@
  *
  * \param ctx      context to be initialized
  * \param is384    0 = use SHA512, 1 = use SHA384
+ *
+ * \return         0 if successful
  */
-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
  *
  * \param ctx      SHA-512 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_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
-                    size_t ilen );
+int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen );
 
 /**
  * \brief          SHA-512 final digest
  *
  * \param ctx      SHA-512 context
  * \param output   SHA-384/512 checksum result
+ *
+ * \return         0 if successful
  */
-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] );
+
+/**
+ * \brief          SHA-512 process data block (internal use only)
+ *
+ * \param ctx      SHA-512 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ */
+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          SHA-512 context setup
+ *
+ * \deprecated     Superseded by mbedtls_sha512_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ * \param is384    0 = use SHA512, 1 = use SHA384
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha512_starts(
+                                                mbedtls_sha512_context *ctx,
+                                                int is384 )
+{
+    mbedtls_sha512_starts_ret( ctx, is384 );
+}
+
+/**
+ * \brief          SHA-512 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_sha512_update_ret() in 2.7.0
+ *
+ * \param ctx      SHA-512 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha512_update(
+                                                mbedtls_sha512_context *ctx,
+                                                const unsigned char *input,
+                                                size_t ilen )
+{
+    mbedtls_sha512_update_ret( ctx, input, ilen );
+}
+
+/**
+ * \brief          SHA-512 final digest
+ *
+ * \deprecated     Superseded by mbedtls_sha512_finish_ret() in 2.7.0
+ *
+ * \param ctx      SHA-512 context
+ * \param output   SHA-384/512 checksum result
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha512_finish(
+                                                mbedtls_sha512_context *ctx,
+                                                unsigned char output[64] )
+{
+    mbedtls_sha512_finish_ret( ctx, output );
+}
+
+/**
+ * \brief          SHA-512 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_sha512_process() in 2.7.0
+ *
+ * \param ctx      SHA-512 context
+ * \param data     buffer holding one block of data
+ */
+MBEDTLS_DEPRECATED static inline void mbedtls_sha512_process(
+                                            mbedtls_sha512_context *ctx,
+                                            const unsigned char data[128] )
+{
+    mbedtls_internal_sha512_process( ctx, data );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 #ifdef __cplusplus
 }
@@ -116,13 +214,45 @@
 /**
  * \brief          Output = SHA-512( input buffer )
  *
- * \param input    buffer holding the  data
+ * \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
+ *
+ * \return         0 if successful
+ */
+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          Output = SHA-512( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_sha512_ret() in 2.7.0
+ *
+ * \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
  */
-void mbedtls_sha512( const unsigned char *input, size_t ilen,
-             unsigned char output[64], int is384 );
+MBEDTLS_DEPRECATED static inline void mbedtls_sha512(
+                                                    const unsigned char *input,
+                                                    size_t ilen,
+                                                    unsigned char output[64],
+                                                    int is384 )
+{
+    mbedtls_sha512_ret( input, ilen, output, is384 );
+}
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief          Checkup routine
@@ -131,9 +261,6 @@
  */
 int mbedtls_sha512_self_test( int verbose );
 
-/* Internal use */
-void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index e98101e..7ad71cc 100644
--- a/include/mbedtls/ssl.h
+++ b/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
  *
diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h
index 3734bb7..ec081e6 100644
--- a/include/mbedtls/ssl_cache.h
+++ b/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/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
index 9101d9c..545468a 100644
--- a/include/mbedtls/ssl_ciphersuites.h
+++ b/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/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h
index 037e1c3..80b65bb 100644
--- a/include/mbedtls/ssl_cookie.h
+++ b/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/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 756360b..bf7b1dc 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/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
  *
@@ -610,6 +611,23 @@
     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/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 7c6bc61..93ad46a 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/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/include/mbedtls/threading.h b/include/mbedtls/threading.h
index b0c34ec..58e6db2 100644
--- a/include/mbedtls/threading.h
+++ b/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
  *
diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h
index bfb8579..2c497bf 100644
--- a/include/mbedtls/timing.h
+++ b/include/mbedtls/timing.h
@@ -2,7 +2,8 @@
  * \file timing.h
  *
  * \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
  *
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 3b209a6..8af6f01 100644
--- a/include/mbedtls/version.h
+++ b/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
  *
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index d7e318d..d6db9c6 100644
--- a/include/mbedtls/x509.h
+++ b/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/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h
index 7988439..08a4283 100644
--- a/include/mbedtls/x509_crl.h
+++ b/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/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 06166d8..2dbb7ec 100644
--- a/include/mbedtls/x509_crt.h
+++ b/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
  *
@@ -373,21 +374,22 @@
 
 #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/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index fe9843c..0c6ccad 100644
--- a/include/mbedtls/x509_csr.h
+++ b/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/include/mbedtls/xtea.h b/include/mbedtls/xtea.h
index b073f84..34ccee3 100644
--- a/include/mbedtls/xtea.h
+++ b/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,6 +37,7 @@
 #define MBEDTLS_XTEA_DECRYPT     0
 
 #define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH             -0x0028  /**< The data input has an invalid length. */
+#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED                  -0x0029  /**< XTEA hardware accelerator failed. */
 
 #if !defined(MBEDTLS_XTEA_ALT)
 // Regular implementation
diff --git a/library/cipher.c b/library/cipher.c
index e9e0b22..ff03273 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -516,14 +516,14 @@
     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/library/ctr_drbg.c b/library/ctr_drbg.c
index 55612c7..2d2da24 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -94,11 +94,15 @@
     /*
      * 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 @@
     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 @@
     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 @@
             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 @@
     /*
      * 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 @@
     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 @@
         /*
          * 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 @@
     /*
      * 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 @@
 {
     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 @@
     /*
      * 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 @@
         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 @@
         /*
          * 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 @@
         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++;
 
diff --git a/library/dhm.c b/library/dhm.c
index bec52a1..cff0958 100644
--- a/library/dhm.c
+++ b/library/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;
@@ -577,6 +578,7 @@
 }
 #endif /* MBEDTLS_FS_IO */
 #endif /* MBEDTLS_ASN1_PARSE_C */
+#endif /* MBEDTLS_DHM_ALT */
 
 #if defined(MBEDTLS_SELF_TEST)
 
diff --git a/library/ecjpake.c b/library/ecjpake.c
index 1fa1c2d..e8f4086 100644
--- a/library/ecjpake.c
+++ b/library/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 @@
 #undef ID_MINE
 #undef ID_PEER
 
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
 
 #if defined(MBEDTLS_SELF_TEST)
 
diff --git a/library/entropy.c b/library/entropy.c
index bf943aa..20b24ff 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -68,16 +68,18 @@
 
 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 );
@@ -116,6 +118,7 @@
     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 */
 }
@@ -128,7 +131,17 @@
 #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,
@@ -175,13 +188,16 @@
     unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
     size_t use_len = len;
     const unsigned char *p = data;
+    int ret;
 
     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 )
+            return( ret );
 #else
-        mbedtls_sha256( data, len, tmp, 0 );
+        if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 )
+            return( ret );
 #endif
         p = tmp;
         use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
@@ -190,15 +206,30 @@
     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 )
+        return( ret );
+    else
+        ctx->accumulator_started = 1;
+    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+        return( ret );
+    return( 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 )
+        return( ret );
+    else
+        ctx->accumulator_started = 1;
+    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+        return( ret );
+    return( mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len ) );
 #endif
-
-    return( 0 );
 }
 
 int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
@@ -253,7 +284,9 @@
          */
         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;
         }
     }
@@ -336,33 +369,52 @@
     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++ )
diff --git a/library/error.c b/library/error.c
index 151ca4e..4f5e446 100644
--- a/library/error.c
+++ b/library/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
@@ -185,6 +221,8 @@
             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" );
+        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)
@@ -206,6 +244,8 @@
             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" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
 #endif /* MBEDTLS_DHM_C */
 
 #if defined(MBEDTLS_ECP_C)
@@ -225,6 +265,8 @@
             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" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "ECP - ECP hardware accelerator failed" );
 #endif /* MBEDTLS_ECP_C */
 
 #if defined(MBEDTLS_MD_C)
@@ -236,6 +278,8 @@
             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)
@@ -288,6 +332,8 @@
             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" );
+        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)
@@ -333,6 +379,8 @@
             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 doesn't offer the requested operation, e.g. 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)
@@ -522,8 +570,15 @@
         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, e.g. 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" );
@@ -570,6 +625,8 @@
 #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 */
@@ -579,6 +636,8 @@
         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)
@@ -586,8 +645,15 @@
         mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to 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" );
@@ -602,6 +668,8 @@
 #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)
@@ -620,6 +688,8 @@
 #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 */
@@ -635,6 +705,21 @@
         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" );
@@ -672,6 +757,26 @@
         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" );
@@ -684,6 +789,8 @@
 #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/library/md.c b/library/md.c
index eda98f6..cec4243 100644
--- a/library/md.c
+++ b/library/md.c
@@ -250,9 +250,7 @@
     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 @@
     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 @@
     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 @@
     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,10 +298,12 @@
     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 )
     {
@@ -317,7 +311,7 @@
         goto cleanup;
     }
 
-    md_info->finish_func( ctx.md_ctx, output );
+    ret = md_info->finish_func( ctx.md_ctx, output );
 
 cleanup:
     fclose( f );
@@ -329,6 +323,7 @@
 
 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 +333,12 @@
 
     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 +356,16 @@
         opad[i] = (unsigned char)( opad[i] ^ key[i] );
     }
 
+    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;
+
+cleanup:
     mbedtls_zeroize( sum, sizeof( sum ) );
 
-    ctx->md_info->starts_func( ctx->md_ctx );
-    ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
-
-    return( 0 );
+    return( ret );
 }
 
 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@@ -371,13 +373,12 @@
     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 +387,22 @@
 
     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 +410,16 @@
 
     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 +430,19 @@
     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 +450,7 @@
     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/library/md2.c b/library/md2.c
index 95cbcce..5028e8c 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -105,16 +105,18 @@
 /*
  * 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_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 +148,19 @@
            ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
         t  = ctx->cksum[i];
     }
+
+    return( 0 );
 }
 #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 +179,21 @@
         if( ctx->left == 16 )
         {
             ctx->left = 0;
-            mbedtls_md2_process( ctx );
+            if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
+                return( ret );
         }
     }
+
+    return( 0 );
 }
 
 /*
  * 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,12 +202,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 );
 }
 
 #endif /* !MBEDTLS_MD2_ALT */
@@ -203,15 +219,28 @@
 /*
  * 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_SELF_TEST)
@@ -219,7 +248,7 @@
 /*
  * RFC 1319 test vectors
  */
-static const char md2_test_str[7][81] =
+static const unsigned char md2_test_str[7][81] =
 {
     { "" },
     { "a" },
@@ -227,10 +256,15 @@
     { "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 +288,7 @@
  */
 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 +296,14 @@
         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 +314,12 @@
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/md4.c b/library/md4.c
index 11a77e3..34a4b0e 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -98,7 +98,7 @@
 /*
  * 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,13 @@
     ctx->state[1] = 0xEFCDAB89;
     ctx->state[2] = 0x98BADCFE;
     ctx->state[3] = 0x10325476;
+
+    return( 0 );
 }
 
 #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 +214,24 @@
     ctx->state[1] += B;
     ctx->state[2] += C;
     ctx->state[3] += D;
+
+    return( 0 );
 }
 #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 +246,10 @@
     {
         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 +257,9 @@
 
     while( ilen >= 64 )
     {
-        mbedtls_md4_process( ctx, input );
+        if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
@@ -256,6 +269,8 @@
         memcpy( (void *) (ctx->buffer + left),
                 (void *) input, ilen );
     }
+
+    return( 0 );
 }
 
 static const unsigned char md4_padding[64] =
@@ -269,8 +284,10 @@
 /*
  * 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,13 +302,20 @@
     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 );
 }
 
 #endif /* !MBEDTLS_MD4_ALT */
@@ -299,15 +323,28 @@
 /*
  * 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_SELF_TEST)
@@ -315,7 +352,7 @@
 /*
  * RFC 1320 test vectors
  */
-static const char md4_test_str[7][81] =
+static const unsigned char md4_test_str[7][81] =
 {
     { "" },
     { "a" },
@@ -323,10 +360,15 @@
     { "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 +392,7 @@
  */
 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 +400,14 @@
         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 +418,12 @@
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/md5.c b/library/md5.c
index 5d972dc..8872dc4 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -97,7 +97,7 @@
 /*
  * 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,13 @@
     ctx->state[1] = 0xEFCDAB89;
     ctx->state[2] = 0x98BADCFE;
     ctx->state[3] = 0x10325476;
+
+    return( 0 );
 }
 
 #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 +233,24 @@
     ctx->state[1] += B;
     ctx->state[2] += C;
     ctx->state[3] += D;
+
+    return( 0 );
 }
 #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 +264,9 @@
     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 +274,9 @@
 
     while( ilen >= 64 )
     {
-        mbedtls_md5_process( ctx, input );
+        if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
@@ -273,6 +285,8 @@
     {
         memcpy( (void *) (ctx->buffer + left), input, ilen );
     }
+
+    return( 0 );
 }
 
 static const unsigned char md5_padding[64] =
@@ -286,8 +300,10 @@
 /*
  * 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,13 +318,18 @@
     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 );
 }
 
 #endif /* !MBEDTLS_MD5_ALT */
@@ -316,15 +337,28 @@
 /*
  * 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_SELF_TEST)
@@ -339,11 +373,11 @@
     { "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 +405,7 @@
  */
 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 +413,14 @@
         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 +431,12 @@
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/md_wrap.c b/library/md_wrap.c
index 2cfcae2..32f0871 100644
--- a/library/md_wrap.c
+++ b/library/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 @@
                  (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 @@
     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 @@
 
 #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_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 @@
     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 @@
 
 #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_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 @@
     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 @@
 
 #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 @@
                        (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 @@
     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 @@
 
 #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 @@
     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 @@
     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 @@
  */
 #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 @@
                     (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 @@
     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 @@
 
 #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 @@
                     (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 @@
     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/library/pem.c b/library/pem.c
index 87401ba..bbcfd9b 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -82,31 +82,33 @@
     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 @@
     /*
      * 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,8 +133,11 @@
 
     memcpy( key + 16, md5sum, use_len );
 
+exit:
     mbedtls_md5_free( &md5_ctx );
     mbedtls_zeroize( md5sum, 16 );
+
+    return( ret );
 }
 
 #if defined(MBEDTLS_DES_C)
@@ -144,7 +154,8 @@
 
     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;
 
     if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 )
         goto exit;
@@ -171,7 +182,8 @@
 
     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;
 
     if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 )
         goto exit;
@@ -200,7 +212,8 @@
 
     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;
 
     if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 )
         goto exit;
diff --git a/library/ripemd160.c b/library/ripemd160.c
index cdb0a63..b85b117 100644
--- a/library/ripemd160.c
+++ b/library/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 @@
 /*
  * 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,16 @@
     ctx->state[2] = 0x98BADCFE;
     ctx->state[3] = 0x10325476;
     ctx->state[4] = 0xC3D2E1F0;
+
+    return( 0 );
 }
 
 #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 +292,24 @@
     ctx->state[3] = ctx->state[4] + A + Bp;
     ctx->state[4] = ctx->state[0] + B + Cp;
     ctx->state[0] = C;
+
+    return( 0 );
 }
 #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 +323,10 @@
     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 +334,9 @@
 
     while( ilen >= 64 )
     {
-        mbedtls_ripemd160_process( ctx, input );
+        if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
@@ -331,6 +345,8 @@
     {
         memcpy( (void *) (ctx->buffer + left), input, ilen );
     }
+
+    return( 0 );
 }
 
 static const unsigned char ripemd160_padding[64] =
@@ -344,8 +360,10 @@
 /*
  * 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,29 +378,50 @@
     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 );
 }
 
+#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_SELF_TEST)
@@ -391,18 +430,22 @@
  * 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",
-    "1234567890123456789012345678901234567890"
-        "1234567890123456789012345678901234567890",
+    { "" },
+    { "a" },
+    { "abc" },
+    { "message digest" },
+    { "abcdefghijklmnopqrstuvwxyz" },
+    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
+    { "12345678901234567890123456789012345678901234567890123456789012"
+      "345678901234567890" },
+};
+
+static const size_t ripemd160_test_strlen[TESTS] =
+{
+    0, 1, 3, 14, 26, 56, 62, 80
 };
 
 static const unsigned char ripemd160_test_md[TESTS][20] =
@@ -430,7 +473,7 @@
  */
 int mbedtls_ripemd160_self_test( int verbose )
 {
-    int i;
+    int i, ret = 0;
     unsigned char output[20];
 
     memset( output, 0, sizeof output );
@@ -440,16 +483,15 @@
         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 +502,12 @@
         mbedtls_printf( "\n" );
 
     return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/rsa.c b/library/rsa.c
index 8c0d8c3..1909744 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -942,7 +942,7 @@
  * \param slen      length of the source buffer
  * \param md_ctx    message digest context to use
  */
-static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
+static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
                       size_t slen, mbedtls_md_context_t *md_ctx )
 {
     unsigned char mask[MBEDTLS_MD_MAX_SIZE];
@@ -950,6 +950,7 @@
     unsigned char *p;
     unsigned int hlen;
     size_t i, use_len;
+    int ret = 0;
 
     memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
     memset( counter, 0, 4 );
@@ -965,10 +966,14 @@
         if( dlen < hlen )
             use_len = dlen;
 
-        mbedtls_md_starts( md_ctx );
-        mbedtls_md_update( md_ctx, src, slen );
-        mbedtls_md_update( md_ctx, counter, 4 );
-        mbedtls_md_finish( md_ctx, mask );
+        if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 )
+            goto exit;
 
         for( i = 0; i < use_len; ++i )
             *p++ ^= mask[i];
@@ -978,7 +983,10 @@
         dlen -= use_len;
     }
 
+exit:
     mbedtls_zeroize( mask, sizeof( mask ) );
+
+    return( ret );
 }
 #endif /* MBEDTLS_PKCS1_V21 */
 
@@ -1030,7 +1038,8 @@
     p += hlen;
 
     /* Construct DB */
-    mbedtls_md( md_info, label, label_len, p );
+    if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 )
+        return( ret );
     p += hlen;
     p += olen - 2 * hlen - 2 - ilen;
     *p++ = 1;
@@ -1038,21 +1047,24 @@
 
     mbedtls_md_init( &md_ctx );
     if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
-    {
-        mbedtls_md_free( &md_ctx );
-        return( ret );
-    }
+        goto exit;
 
     /* maskedDB: Apply dbMask to DB */
-    mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
-               &md_ctx );
+    if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
+                          &md_ctx ) ) != 0 )
+        goto exit;
 
     /* maskedSeed: Apply seedMask to seed */
-    mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
-               &md_ctx );
+    if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
+                          &md_ctx ) ) != 0 )
+        goto exit;
 
+exit:
     mbedtls_md_free( &md_ctx );
 
+    if( ret != 0 )
+        return( ret );
+
     return( ( mode == MBEDTLS_RSA_PUBLIC )
             ? mbedtls_rsa_public(  ctx, output, output )
             : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
@@ -1219,20 +1231,23 @@
         goto cleanup;
     }
 
-
-    /* Generate lHash */
-    mbedtls_md( md_info, label, label_len, lhash );
-
     /* seed: Apply seedMask to maskedSeed */
-    mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
-               &md_ctx );
-
+    if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
+                          &md_ctx ) ) != 0 ||
     /* DB: Apply dbMask to maskedDB */
-    mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
-               &md_ctx );
+        ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
+                          &md_ctx ) ) != 0 )
+    {
+        mbedtls_md_free( &md_ctx );
+        goto cleanup;
+    }
 
     mbedtls_md_free( &md_ctx );
 
+    /* Generate lHash */
+    if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 )
+        goto cleanup;
+
     /*
      * Check contents, in "constant-time"
      */
@@ -1483,28 +1498,28 @@
 
     mbedtls_md_init( &md_ctx );
     if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
-    {
-        mbedtls_md_free( &md_ctx );
-        /* No need to zeroize salt: we didn't use it. */
-        return( ret );
-    }
+        goto exit;
 
     /* Generate H = Hash( M' ) */
-    mbedtls_md_starts( &md_ctx );
-    mbedtls_md_update( &md_ctx, p, 8 );
-    mbedtls_md_update( &md_ctx, hash, hashlen );
-    mbedtls_md_update( &md_ctx, salt, slen );
-    mbedtls_md_finish( &md_ctx, p );
-    mbedtls_zeroize( salt, sizeof( salt ) );
+    if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 )
+        goto exit;
 
     /* Compensate for boundary condition when applying mask */
     if( msb % 8 == 0 )
         offset = 1;
 
     /* maskedDB: Apply dbMask to DB */
-    mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
-
-    mbedtls_md_free( &md_ctx );
+    if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
+                          &md_ctx ) ) != 0 )
+        goto exit;
 
     msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
     sig[0] &= 0xFF >> ( olen * 8 - msb );
@@ -1512,6 +1527,14 @@
     p += hlen;
     *p++ = 0xBC;
 
+    mbedtls_zeroize( salt, sizeof( salt ) );
+
+exit:
+    mbedtls_md_free( &md_ctx );
+
+    if( ret != 0 )
+        return( ret );
+
     return( ( mode == MBEDTLS_RSA_PUBLIC )
             ? mbedtls_rsa_public(  ctx, sig, sig )
             : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
@@ -1837,23 +1860,21 @@
 
     mbedtls_md_init( &md_ctx );
     if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
-    {
-        mbedtls_md_free( &md_ctx );
-        return( ret );
-    }
+        goto exit;
 
-    mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
+    if( ( ret = mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen,
+                          &md_ctx ) ) != 0 )
+        goto exit;
 
     buf[0] &= 0xFF >> ( siglen * 8 - msb );
 
     while( p < buf + siglen && *p == 0 )
         p++;
 
-    if( p == buf + siglen ||
-        *p++ != 0x01 )
+    if( p == buf + siglen || *p++ != 0x01 )
     {
-        mbedtls_md_free( &md_ctx );
-        return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+        ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
+        goto exit;
     }
 
     /* Actual salt len */
@@ -1862,25 +1883,34 @@
     if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
         slen != (size_t) expected_salt_len )
     {
-        mbedtls_md_free( &md_ctx );
-        return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+        ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
+        goto exit;
     }
 
     /*
      * Generate H = Hash( M' )
      */
-    mbedtls_md_starts( &md_ctx );
-    mbedtls_md_update( &md_ctx, zeros, 8 );
-    mbedtls_md_update( &md_ctx, hash, hashlen );
-    mbedtls_md_update( &md_ctx, p, slen );
-    mbedtls_md_finish( &md_ctx, result );
+    if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, zeros, 8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, p, slen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_finish( &md_ctx, result ) ) != 0 )
+        goto exit;
 
+    if( memcmp( p + slen, result, hlen ) != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
+        goto exit;
+    }
+
+exit:
     mbedtls_md_free( &md_ctx );
 
-    if( memcmp( p + slen, result, hlen ) == 0 )
-        return( 0 );
-    else
-        return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
+    return( ret );
 }
 
 /*
@@ -2229,7 +2259,13 @@
     if( verbose != 0 )
         mbedtls_printf( "  PKCS#1 data sign  : " );
 
-    mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
+    if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        return( 1 );
+    }
 
     if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
                                 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
diff --git a/library/sha1.c b/library/sha1.c
index 2ccf2a2..8432eba 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -97,7 +97,7 @@
 /*
  * SHA-1 context setup
  */
-void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
+int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -107,10 +107,13 @@
     ctx->state[2] = 0x98BADCFE;
     ctx->state[3] = 0x10325476;
     ctx->state[4] = 0xC3D2E1F0;
+
+    return( 0 );
 }
 
 #if !defined(MBEDTLS_SHA1_PROCESS_ALT)
-void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
+int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
+                                   const unsigned char data[64] )
 {
     uint32_t temp, W[16], A, B, C, D, E;
 
@@ -264,19 +267,24 @@
     ctx->state[2] += C;
     ctx->state[3] += D;
     ctx->state[4] += E;
+
+    return( 0 );
 }
 #endif /* !MBEDTLS_SHA1_PROCESS_ALT */
 
 /*
  * SHA-1 process buffer
  */
-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 )
 {
+    int ret;
     size_t fill;
     uint32_t left;
 
     if( ilen == 0 )
-        return;
+        return( 0 );
 
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
@@ -290,7 +298,10 @@
     if( left && ilen >= fill )
     {
         memcpy( (void *) (ctx->buffer + left), input, fill );
-        mbedtls_sha1_process( ctx, ctx->buffer );
+
+        if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
         input += fill;
         ilen  -= fill;
         left = 0;
@@ -298,13 +309,17 @@
 
     while( ilen >= 64 )
     {
-        mbedtls_sha1_process( ctx, input );
+        if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
 
     if( ilen > 0 )
         memcpy( (void *) (ctx->buffer + left), input, ilen );
+
+    return( 0 );
 }
 
 static const unsigned char sha1_padding[64] =
@@ -318,8 +333,10 @@
 /*
  * SHA-1 final digest
  */
-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] )
 {
+    int ret;
     uint32_t last, padn;
     uint32_t high, low;
     unsigned char msglen[8];
@@ -334,14 +351,18 @@
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
 
-    mbedtls_sha1_update( ctx, sha1_padding, padn );
-    mbedtls_sha1_update( ctx, msglen, 8 );
+    if( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 )
+        return( ret );
+    if( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 )
+        return( ret );
 
     PUT_UINT32_BE( ctx->state[0], output,  0 );
     PUT_UINT32_BE( ctx->state[1], output,  4 );
     PUT_UINT32_BE( ctx->state[2], output,  8 );
     PUT_UINT32_BE( ctx->state[3], output, 12 );
     PUT_UINT32_BE( ctx->state[4], output, 16 );
+
+    return( 0 );
 }
 
 #endif /* !MBEDTLS_SHA1_ALT */
@@ -349,15 +370,28 @@
 /*
  * output = SHA-1( input buffer )
  */
-void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
+int mbedtls_sha1_ret( const unsigned char *input,
+                      size_t ilen,
+                      unsigned char output[20] )
 {
+    int ret;
     mbedtls_sha1_context ctx;
 
     mbedtls_sha1_init( &ctx );
-    mbedtls_sha1_starts( &ctx );
-    mbedtls_sha1_update( &ctx, input, ilen );
-    mbedtls_sha1_finish( &ctx, output );
+
+    if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
     mbedtls_sha1_free( &ctx );
+
+    return( ret );
 }
 
 #if defined(MBEDTLS_SELF_TEST)
@@ -371,7 +405,7 @@
     { "" }
 };
 
-static const int sha1_test_buflen[3] =
+static const size_t sha1_test_buflen[3] =
 {
     3, 56, 1000
 };
@@ -406,28 +440,35 @@
         if( verbose != 0 )
             mbedtls_printf( "  SHA-1 test #%d: ", i + 1 );
 
-        mbedtls_sha1_starts( &ctx );
+        if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
+            goto fail;
 
         if( i == 2 )
         {
             memset( buf, 'a', buflen = 1000 );
 
             for( j = 0; j < 1000; j++ )
-                mbedtls_sha1_update( &ctx, buf, buflen );
+            {
+                ret = mbedtls_sha1_update_ret( &ctx, buf, buflen );
+                if( ret != 0 )
+                    goto fail;
+            }
         }
         else
-            mbedtls_sha1_update( &ctx, sha1_test_buf[i],
-                               sha1_test_buflen[i] );
+        {
+            ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i],
+                                           sha1_test_buflen[i] );
+            if( ret != 0 )
+                goto fail;
+        }
 
-        mbedtls_sha1_finish( &ctx, sha1sum );
+        if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 )
+            goto fail;
 
         if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
         {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
             ret = 1;
-            goto exit;
+            goto fail;
         }
 
         if( verbose != 0 )
@@ -437,6 +478,12 @@
     if( verbose != 0 )
         mbedtls_printf( "\n" );
 
+    goto exit;
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
 exit:
     mbedtls_sha1_free( &ctx );
 
diff --git a/library/sha256.c b/library/sha256.c
index ad25d38..abcd64d 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -100,7 +100,7 @@
 /*
  * SHA-256 context setup
  */
-void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
+int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -131,6 +131,8 @@
     }
 
     ctx->is224 = is224;
+
+    return( 0 );
 }
 
 #if !defined(MBEDTLS_SHA256_PROCESS_ALT)
@@ -179,7 +181,8 @@
     d += temp1; h = temp1 + temp2;              \
 }
 
-void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
+int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
+                                const unsigned char data[64] )
 {
     uint32_t temp1, temp2, W[64];
     uint32_t A[8];
@@ -232,20 +235,24 @@
 
     for( i = 0; i < 8; i++ )
         ctx->state[i] += A[i];
+
+    return( 0 );
 }
 #endif /* !MBEDTLS_SHA256_PROCESS_ALT */
 
 /*
  * SHA-256 process buffer
  */
-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 )
 {
+    int ret;
     size_t fill;
     uint32_t left;
 
     if( ilen == 0 )
-        return;
+        return( 0 );
 
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
@@ -259,7 +266,10 @@
     if( left && ilen >= fill )
     {
         memcpy( (void *) (ctx->buffer + left), input, fill );
-        mbedtls_sha256_process( ctx, ctx->buffer );
+
+        if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
         input += fill;
         ilen  -= fill;
         left = 0;
@@ -267,13 +277,17 @@
 
     while( ilen >= 64 )
     {
-        mbedtls_sha256_process( ctx, input );
+        if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 64;
         ilen  -= 64;
     }
 
     if( ilen > 0 )
         memcpy( (void *) (ctx->buffer + left), input, ilen );
+
+    return( 0 );
 }
 
 static const unsigned char sha256_padding[64] =
@@ -287,8 +301,10 @@
 /*
  * SHA-256 final digest
  */
-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] )
 {
+    int ret;
     uint32_t last, padn;
     uint32_t high, low;
     unsigned char msglen[8];
@@ -303,8 +319,11 @@
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
 
-    mbedtls_sha256_update( ctx, sha256_padding, padn );
-    mbedtls_sha256_update( ctx, msglen, 8 );
+    if( ( ret = mbedtls_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_sha256_update_ret( ctx, msglen, 8 ) ) != 0 )
+        return( ret );
 
     PUT_UINT32_BE( ctx->state[0], output,  0 );
     PUT_UINT32_BE( ctx->state[1], output,  4 );
@@ -316,6 +335,8 @@
 
     if( ctx->is224 == 0 )
         PUT_UINT32_BE( ctx->state[7], output, 28 );
+
+    return( 0 );
 }
 
 #endif /* !MBEDTLS_SHA256_ALT */
@@ -323,16 +344,29 @@
 /*
  * output = SHA-256( input buffer )
  */
-void mbedtls_sha256( const unsigned char *input, size_t ilen,
-             unsigned char output[32], int is224 )
+int mbedtls_sha256_ret( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[32],
+                        int is224 )
 {
+    int ret;
     mbedtls_sha256_context ctx;
 
     mbedtls_sha256_init( &ctx );
-    mbedtls_sha256_starts( &ctx, is224 );
-    mbedtls_sha256_update( &ctx, input, ilen );
-    mbedtls_sha256_finish( &ctx, output );
+
+    if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
     mbedtls_sha256_free( &ctx );
+
+    return( ret );
 }
 
 #if defined(MBEDTLS_SELF_TEST)
@@ -346,7 +380,7 @@
     { "" }
 };
 
-static const int sha256_test_buflen[3] =
+static const size_t sha256_test_buflen[3] =
 {
     3, 56, 1000
 };
@@ -415,28 +449,37 @@
         if( verbose != 0 )
             mbedtls_printf( "  SHA-%d test #%d: ", 256 - k * 32, j + 1 );
 
-        mbedtls_sha256_starts( &ctx, k );
+        if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
+            goto fail;
 
         if( j == 2 )
         {
             memset( buf, 'a', buflen = 1000 );
 
             for( j = 0; j < 1000; j++ )
-                mbedtls_sha256_update( &ctx, buf, buflen );
+            {
+                ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
+                if( ret != 0 )
+                    goto fail;
+            }
+
         }
         else
-            mbedtls_sha256_update( &ctx, sha256_test_buf[j],
-                                 sha256_test_buflen[j] );
+        {
+            ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
+                                             sha256_test_buflen[j] );
+            if( ret != 0 )
+                 goto fail;
+        }
 
-        mbedtls_sha256_finish( &ctx, sha256sum );
+        if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
+            goto fail;
+
 
         if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
         {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
             ret = 1;
-            goto exit;
+            goto fail;
         }
 
         if( verbose != 0 )
@@ -446,6 +489,12 @@
     if( verbose != 0 )
         mbedtls_printf( "\n" );
 
+    goto exit;
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
 exit:
     mbedtls_sha256_free( &ctx );
     mbedtls_free( buf );
diff --git a/library/sha512.c b/library/sha512.c
index 724522a..c99b6da 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -114,7 +114,7 @@
 /*
  * SHA-512 context setup
  */
-void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
+int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -145,6 +145,8 @@
     }
 
     ctx->is384 = is384;
+
+    return( 0 );
 }
 
 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
@@ -196,7 +198,8 @@
     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
 };
 
-void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
+int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
+                                     const unsigned char data[128] )
 {
     int i;
     uint64_t temp1, temp2, W[80];
@@ -263,20 +266,24 @@
     ctx->state[5] += F;
     ctx->state[6] += G;
     ctx->state[7] += H;
+
+    return( 0 );
 }
 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
 
 /*
  * SHA-512 process buffer
  */
-void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
-                    size_t ilen )
+int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen )
 {
+    int ret;
     size_t fill;
     unsigned int left;
 
     if( ilen == 0 )
-        return;
+        return( 0 );
 
     left = (unsigned int) (ctx->total[0] & 0x7F);
     fill = 128 - left;
@@ -289,7 +296,10 @@
     if( left && ilen >= fill )
     {
         memcpy( (void *) (ctx->buffer + left), input, fill );
-        mbedtls_sha512_process( ctx, ctx->buffer );
+
+        if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
         input += fill;
         ilen  -= fill;
         left = 0;
@@ -297,13 +307,17 @@
 
     while( ilen >= 128 )
     {
-        mbedtls_sha512_process( ctx, input );
+        if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
+            return( ret );
+
         input += 128;
         ilen  -= 128;
     }
 
     if( ilen > 0 )
         memcpy( (void *) (ctx->buffer + left), input, ilen );
+
+    return( 0 );
 }
 
 static const unsigned char sha512_padding[128] =
@@ -321,8 +335,10 @@
 /*
  * SHA-512 final digest
  */
-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] )
 {
+    int ret;
     size_t last, padn;
     uint64_t high, low;
     unsigned char msglen[16];
@@ -337,8 +353,11 @@
     last = (size_t)( ctx->total[0] & 0x7F );
     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
 
-    mbedtls_sha512_update( ctx, sha512_padding, padn );
-    mbedtls_sha512_update( ctx, msglen, 16 );
+    if( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 )
+            return( ret );
+
+    if( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 )
+            return( ret );
 
     PUT_UINT64_BE( ctx->state[0], output,  0 );
     PUT_UINT64_BE( ctx->state[1], output,  8 );
@@ -352,6 +371,8 @@
         PUT_UINT64_BE( ctx->state[6], output, 48 );
         PUT_UINT64_BE( ctx->state[7], output, 56 );
     }
+
+    return( 0 );
 }
 
 #endif /* !MBEDTLS_SHA512_ALT */
@@ -359,16 +380,29 @@
 /*
  * output = SHA-512( input buffer )
  */
-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 )
 {
+    int ret;
     mbedtls_sha512_context ctx;
 
     mbedtls_sha512_init( &ctx );
-    mbedtls_sha512_starts( &ctx, is384 );
-    mbedtls_sha512_update( &ctx, input, ilen );
-    mbedtls_sha512_finish( &ctx, output );
+
+    if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
     mbedtls_sha512_free( &ctx );
+
+    return( ret );
 }
 
 #if defined(MBEDTLS_SELF_TEST)
@@ -384,7 +418,7 @@
     { "" }
 };
 
-static const int sha512_test_buflen[3] =
+static const size_t sha512_test_buflen[3] =
 {
     3, 112, 1000
 };
@@ -471,28 +505,35 @@
         if( verbose != 0 )
             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
 
-        mbedtls_sha512_starts( &ctx, k );
+        if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
+            goto fail;
 
         if( j == 2 )
         {
             memset( buf, 'a', buflen = 1000 );
 
             for( j = 0; j < 1000; j++ )
-                mbedtls_sha512_update( &ctx, buf, buflen );
+            {
+                ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
+                if( ret != 0 )
+                    goto fail;
+            }
         }
         else
-            mbedtls_sha512_update( &ctx, sha512_test_buf[j],
-                                 sha512_test_buflen[j] );
+        {
+            ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
+                                             sha512_test_buflen[j] );
+            if( ret != 0 )
+                goto fail;
+        }
 
-        mbedtls_sha512_finish( &ctx, sha512sum );
+        if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
+            goto fail;
 
         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
         {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
             ret = 1;
-            goto exit;
+            goto fail;
         }
 
         if( verbose != 0 )
@@ -502,6 +543,12 @@
     if( verbose != 0 )
         mbedtls_printf( "\n" );
 
+    goto exit;
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
 exit:
     mbedtls_sha512_free( &ctx );
     mbedtls_free( buf );
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 554348f..2534346 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -2498,39 +2498,11 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
         if( md_alg == MBEDTLS_MD_NONE )
         {
-            mbedtls_md5_context mbedtls_md5;
-            mbedtls_sha1_context mbedtls_sha1;
-
-            mbedtls_md5_init(  &mbedtls_md5  );
-            mbedtls_sha1_init( &mbedtls_sha1 );
-
             hashlen = 36;
-
-            /*
-             * digitally-signed struct {
-             *     opaque md5_hash[16];
-             *     opaque sha_hash[20];
-             * };
-             *
-             * md5_hash
-             *     MD5(ClientHello.random + ServerHello.random
-             *                            + ServerParams);
-             * sha_hash
-             *     SHA(ClientHello.random + ServerHello.random
-             *                            + ServerParams);
-             */
-            mbedtls_md5_starts( &mbedtls_md5 );
-            mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
-            mbedtls_md5_update( &mbedtls_md5, params, params_len );
-            mbedtls_md5_finish( &mbedtls_md5, hash );
-
-            mbedtls_sha1_starts( &mbedtls_sha1 );
-            mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
-            mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
-            mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
-
-            mbedtls_md5_free(  &mbedtls_md5  );
-            mbedtls_sha1_free( &mbedtls_sha1 );
+            ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, params,
+                                                           params_len );
+            if( ret != 0 )
+                return( ret );
         }
         else
 #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
@@ -2539,34 +2511,12 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
         if( md_alg != MBEDTLS_MD_NONE )
         {
-            mbedtls_md_context_t ctx;
-
-            mbedtls_md_init( &ctx );
-
             /* Info from md_alg will be used instead */
             hashlen = 0;
-
-            /*
-             * digitally-signed struct {
-             *     opaque client_random[32];
-             *     opaque server_random[32];
-             *     ServerDHParams params;
-             * };
-             */
-            if( ( ret = mbedtls_md_setup( &ctx,
-                                     mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
-            {
-                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+            ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params,
+                                                          params_len, md_alg );
+            if( ret != 0 )
                 return( ret );
-            }
-
-            mbedtls_md_starts( &ctx );
-            mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
-            mbedtls_md_update( &ctx, params, params_len );
-            mbedtls_md_finish( &ctx, hash );
-            mbedtls_md_free( &ctx );
         }
         else
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 37f415d..2b79188 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2042,7 +2042,7 @@
     const mbedtls_ssl_ciphersuite_t *suite = NULL;
     const mbedtls_cipher_info_t *cipher = NULL;
 
-    if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+    if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
         ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         *olen = 0;
@@ -3093,40 +3093,12 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
         if( md_alg == MBEDTLS_MD_NONE )
         {
-            mbedtls_md5_context mbedtls_md5;
-            mbedtls_sha1_context mbedtls_sha1;
-
-            mbedtls_md5_init(  &mbedtls_md5  );
-            mbedtls_sha1_init( &mbedtls_sha1 );
-
-            /*
-             * digitally-signed struct {
-             *     opaque md5_hash[16];
-             *     opaque sha_hash[20];
-             * };
-             *
-             * md5_hash
-             *     MD5(ClientHello.random + ServerHello.random
-             *                            + ServerParams);
-             * sha_hash
-             *     SHA(ClientHello.random + ServerHello.random
-             *                            + ServerParams);
-             */
-
-            mbedtls_md5_starts( &mbedtls_md5 );
-            mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes,  64 );
-            mbedtls_md5_update( &mbedtls_md5, dig_signed, dig_signed_len );
-            mbedtls_md5_finish( &mbedtls_md5, hash );
-
-            mbedtls_sha1_starts( &mbedtls_sha1 );
-            mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes,  64 );
-            mbedtls_sha1_update( &mbedtls_sha1, dig_signed, dig_signed_len );
-            mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
-
             hashlen = 36;
-
-            mbedtls_md5_free(  &mbedtls_md5  );
-            mbedtls_sha1_free( &mbedtls_sha1 );
+            ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash,
+                                                           dig_signed,
+                                                           dig_signed_len );
+            if( ret != 0 )
+                return( ret );
         }
         else
 #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
@@ -3135,32 +3107,14 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
         if( md_alg != MBEDTLS_MD_NONE )
         {
-            mbedtls_md_context_t ctx;
-            const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
-
-            mbedtls_md_init( &ctx );
-
             /* Info from md_alg will be used instead */
             hashlen = 0;
-
-            /*
-             * digitally-signed struct {
-             *     opaque client_random[32];
-             *     opaque server_random[32];
-             *     ServerDHParams params;
-             * };
-             */
-            if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
-            {
-                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
+            ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash,
+                                                          dig_signed,
+                                                          dig_signed_len,
+                                                          md_alg );
+            if( ret != 0 )
                 return( ret );
-            }
-
-            mbedtls_md_starts( &ctx );
-            mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
-            mbedtls_md_update( &ctx, dig_signed, dig_signed_len );
-            mbedtls_md_finish( &ctx, hash );
-            mbedtls_md_free( &ctx );
         }
         else
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 2690e46..4f9a084 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -221,6 +221,7 @@
                      const unsigned char *random, size_t rlen,
                      unsigned char *dstbuf, size_t dlen )
 {
+    int ret = 0;
     size_t i;
     mbedtls_md5_context md5;
     mbedtls_sha1_context sha1;
@@ -243,25 +244,35 @@
     {
         memset( padding, (unsigned char) ('A' + i), 1 + i );
 
-        mbedtls_sha1_starts( &sha1 );
-        mbedtls_sha1_update( &sha1, padding, 1 + i );
-        mbedtls_sha1_update( &sha1, secret, slen );
-        mbedtls_sha1_update( &sha1, random, rlen );
-        mbedtls_sha1_finish( &sha1, sha1sum );
+        if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_update_ret( &sha1, padding, 1 + i ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_update_ret( &sha1, secret, slen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_update_ret( &sha1, random, rlen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_finish_ret( &sha1, sha1sum ) ) != 0 )
+            goto exit;
 
-        mbedtls_md5_starts( &md5 );
-        mbedtls_md5_update( &md5, secret, slen );
-        mbedtls_md5_update( &md5, sha1sum, 20 );
-        mbedtls_md5_finish( &md5, dstbuf + i * 16 );
+        if( ( ret = mbedtls_md5_starts_ret( &md5 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md5_update_ret( &md5, secret, slen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md5_update_ret( &md5, sha1sum, 20 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md5_finish_ret( &md5, dstbuf + i * 16 ) ) != 0 )
+            goto exit;
     }
 
+exit:
     mbedtls_md5_free(  &md5  );
     mbedtls_sha1_free( &sha1 );
 
     mbedtls_zeroize( padding, sizeof( padding ) );
     mbedtls_zeroize( sha1sum, sizeof( sha1sum ) );
 
-    return( 0 );
+    return( ret );
 }
 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
 
@@ -978,25 +989,25 @@
     memset( pad_1, 0x36, 48 );
     memset( pad_2, 0x5C, 48 );
 
-    mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 );
-    mbedtls_md5_update( &md5, pad_1, 48 );
-    mbedtls_md5_finish( &md5, hash );
+    mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
+    mbedtls_md5_update_ret( &md5, pad_1, 48 );
+    mbedtls_md5_finish_ret( &md5, hash );
 
-    mbedtls_md5_starts( &md5 );
-    mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 );
-    mbedtls_md5_update( &md5, pad_2, 48 );
-    mbedtls_md5_update( &md5, hash,  16 );
-    mbedtls_md5_finish( &md5, hash );
+    mbedtls_md5_starts_ret( &md5 );
+    mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
+    mbedtls_md5_update_ret( &md5, pad_2, 48 );
+    mbedtls_md5_update_ret( &md5, hash,  16 );
+    mbedtls_md5_finish_ret( &md5, hash );
 
-    mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 );
-    mbedtls_sha1_update( &sha1, pad_1, 40 );
-    mbedtls_sha1_finish( &sha1, hash + 16 );
+    mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, pad_1, 40 );
+    mbedtls_sha1_finish_ret( &sha1, hash + 16 );
 
-    mbedtls_sha1_starts( &sha1 );
-    mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 );
-    mbedtls_sha1_update( &sha1, pad_2, 40 );
-    mbedtls_sha1_update( &sha1, hash + 16, 20 );
-    mbedtls_sha1_finish( &sha1, hash + 16 );
+    mbedtls_sha1_starts_ret( &sha1 );
+    mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, pad_2, 40 );
+    mbedtls_sha1_update_ret( &sha1, hash + 16, 20 );
+    mbedtls_sha1_finish_ret( &sha1, hash + 16 );
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
@@ -1022,8 +1033,8 @@
     mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
     mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
 
-     mbedtls_md5_finish( &md5,  hash );
-    mbedtls_sha1_finish( &sha1, hash + 16 );
+     mbedtls_md5_finish_ret( &md5,  hash );
+    mbedtls_sha1_finish_ret( &sha1, hash + 16 );
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
@@ -1046,7 +1057,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
 
     mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
-    mbedtls_sha256_finish( &sha256, hash );
+    mbedtls_sha256_finish_ret( &sha256, hash );
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
@@ -1067,7 +1078,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
 
     mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
-    mbedtls_sha512_finish( &sha512, hash );
+    mbedtls_sha512_finish_ret( &sha512, hash );
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
@@ -4843,15 +4854,15 @@
 {
 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
-     mbedtls_md5_starts( &ssl->handshake->fin_md5  );
-    mbedtls_sha1_starts( &ssl->handshake->fin_sha1 );
+     mbedtls_md5_starts_ret( &ssl->handshake->fin_md5  );
+    mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 );
 #endif
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
-    mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 );
+    mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
 #endif
 #if defined(MBEDTLS_SHA512_C)
-    mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 );
+    mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 }
@@ -4861,15 +4872,15 @@
 {
 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
-     mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len );
-    mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len );
+     mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
+    mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
 #endif
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
-    mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
+    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
 #endif
 #if defined(MBEDTLS_SHA512_C)
-    mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
+    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 }
@@ -4879,8 +4890,8 @@
 static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf, size_t len )
 {
-     mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len );
-    mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len );
+     mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
+    mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
 }
 #endif
 
@@ -4889,7 +4900,7 @@
 static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
                                         const unsigned char *buf, size_t len )
 {
-    mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
+    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
 }
 #endif
 
@@ -4897,7 +4908,7 @@
 static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
                                         const unsigned char *buf, size_t len )
 {
-    mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
+    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
 }
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -4950,29 +4961,29 @@
 
     memset( padbuf, 0x36, 48 );
 
-    mbedtls_md5_update( &md5, (const unsigned char *) sender, 4 );
-    mbedtls_md5_update( &md5, session->master, 48 );
-    mbedtls_md5_update( &md5, padbuf, 48 );
-    mbedtls_md5_finish( &md5, md5sum );
+    mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 );
+    mbedtls_md5_update_ret( &md5, session->master, 48 );
+    mbedtls_md5_update_ret( &md5, padbuf, 48 );
+    mbedtls_md5_finish_ret( &md5, md5sum );
 
-    mbedtls_sha1_update( &sha1, (const unsigned char *) sender, 4 );
-    mbedtls_sha1_update( &sha1, session->master, 48 );
-    mbedtls_sha1_update( &sha1, padbuf, 40 );
-    mbedtls_sha1_finish( &sha1, sha1sum );
+    mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 );
+    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, padbuf, 40 );
+    mbedtls_sha1_finish_ret( &sha1, sha1sum );
 
     memset( padbuf, 0x5C, 48 );
 
-    mbedtls_md5_starts( &md5 );
-    mbedtls_md5_update( &md5, session->master, 48 );
-    mbedtls_md5_update( &md5, padbuf, 48 );
-    mbedtls_md5_update( &md5, md5sum, 16 );
-    mbedtls_md5_finish( &md5, buf );
+    mbedtls_md5_starts_ret( &md5 );
+    mbedtls_md5_update_ret( &md5, session->master, 48 );
+    mbedtls_md5_update_ret( &md5, padbuf, 48 );
+    mbedtls_md5_update_ret( &md5, md5sum, 16 );
+    mbedtls_md5_finish_ret( &md5, buf );
 
-    mbedtls_sha1_starts( &sha1 );
-    mbedtls_sha1_update( &sha1, session->master, 48 );
-    mbedtls_sha1_update( &sha1, padbuf , 40 );
-    mbedtls_sha1_update( &sha1, sha1sum, 20 );
-    mbedtls_sha1_finish( &sha1, buf + 16 );
+    mbedtls_sha1_starts_ret( &sha1 );
+    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, padbuf , 40 );
+    mbedtls_sha1_update_ret( &sha1, sha1sum, 20 );
+    mbedtls_sha1_finish_ret( &sha1, buf + 16 );
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
 
@@ -5029,8 +5040,8 @@
              ? "client finished"
              : "server finished";
 
-    mbedtls_md5_finish(  &md5, padbuf );
-    mbedtls_sha1_finish( &sha1, padbuf + 16 );
+    mbedtls_md5_finish_ret(  &md5, padbuf );
+    mbedtls_sha1_finish_ret( &sha1, padbuf + 16 );
 
     ssl->handshake->tls_prf( session->master, 48, sender,
                              padbuf, 36, buf, len );
@@ -5081,7 +5092,7 @@
              ? "client finished"
              : "server finished";
 
-    mbedtls_sha256_finish( &sha256, padbuf );
+    mbedtls_sha256_finish_ret( &sha256, padbuf );
 
     ssl->handshake->tls_prf( session->master, 48, sender,
                              padbuf, 32, buf, len );
@@ -5130,7 +5141,7 @@
              ? "client finished"
              : "server finished";
 
-    mbedtls_sha512_finish( &sha512, padbuf );
+    mbedtls_sha512_finish_ret( &sha512, padbuf );
 
     ssl->handshake->tls_prf( session->master, 48, sender,
                              padbuf, 48, buf, len );
@@ -5444,17 +5455,17 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
      mbedtls_md5_init(   &handshake->fin_md5  );
     mbedtls_sha1_init(   &handshake->fin_sha1 );
-     mbedtls_md5_starts( &handshake->fin_md5  );
-    mbedtls_sha1_starts( &handshake->fin_sha1 );
+     mbedtls_md5_starts_ret( &handshake->fin_md5  );
+    mbedtls_sha1_starts_ret( &handshake->fin_sha1 );
 #endif
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
     mbedtls_sha256_init(   &handshake->fin_sha256    );
-    mbedtls_sha256_starts( &handshake->fin_sha256, 0 );
+    mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
 #endif
 #if defined(MBEDTLS_SHA512_C)
     mbedtls_sha512_init(   &handshake->fin_sha512    );
-    mbedtls_sha512_starts( &handshake->fin_sha512, 1 );
+    mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
@@ -8058,4 +8069,148 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 }
 
+#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 )
+{
+    int ret = 0;
+    mbedtls_md5_context mbedtls_md5;
+    mbedtls_sha1_context mbedtls_sha1;
+
+    mbedtls_md5_init( &mbedtls_md5 );
+    mbedtls_sha1_init( &mbedtls_sha1 );
+
+    /*
+     * digitally-signed struct {
+     *     opaque md5_hash[16];
+     *     opaque sha_hash[20];
+     * };
+     *
+     * md5_hash
+     *     MD5(ClientHello.random + ServerHello.random
+     *                            + ServerParams);
+     * sha_hash
+     *     SHA(ClientHello.random + ServerHello.random
+     *                            + ServerParams);
+     */
+    if( ( ret = mbedtls_md5_starts_ret( &mbedtls_md5 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_starts_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5,
+                                        ssl->handshake->randbytes, 64 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, data, data_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md5_finish_ret( &mbedtls_md5, output ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_finish_ret", ret );
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_sha1_starts_ret( &mbedtls_sha1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_starts_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1,
+                                         ssl->handshake->randbytes, 64 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, data,
+                                         data_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_sha1_finish_ret( &mbedtls_sha1,
+                                         output + 16 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_finish_ret", ret );
+        goto exit;
+    }
+
+exit:
+    mbedtls_md5_free( &mbedtls_md5 );
+    mbedtls_sha1_free( &mbedtls_sha1 );
+
+    if( ret != 0 )
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+    return( ret );
+
+}
+#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 )
+{
+    int ret = 0;
+    mbedtls_md_context_t ctx;
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+
+    mbedtls_md_init( &ctx );
+
+    /*
+     * digitally-signed struct {
+     *     opaque client_random[32];
+     *     opaque server_random[32];
+     *     ServerDHParams params;
+     * };
+     */
+    if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_finish( &ctx, output ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
+        goto exit;
+    }
+
+exit:
+    mbedtls_md_free( &ctx );
+
+    if( ret != 0 )
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/version_features.c b/library/version_features.c
index 172cf12..72afec2 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -105,6 +105,12 @@
 #if defined(MBEDTLS_DES_ALT)
     "MBEDTLS_DES_ALT",
 #endif /* MBEDTLS_DES_ALT */
+#if defined(MBEDTLS_DHM_ALT)
+    "MBEDTLS_DHM_ALT",
+#endif /* MBEDTLS_DHM_ALT */
+#if defined(MBEDTLS_ECJPAKE_ALT)
+    "MBEDTLS_ECJPAKE_ALT",
+#endif /* MBEDTLS_ECJPAKE_ALT */
 #if defined(MBEDTLS_GCM_ALT)
     "MBEDTLS_GCM_ALT",
 #endif /* MBEDTLS_GCM_ALT */
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 0af23d7..41dfe87 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -177,8 +177,11 @@
     memset( buf, 0, sizeof(buf) );
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
 
-    mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
-    c = buf + sizeof(buf) - 20;
+    ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
+                            buf + sizeof( buf ) - 20 );
+    if( ret != 0 )
+        return( ret );
+    c = buf + sizeof( buf ) - 20;
     len = 20;
 
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
@@ -199,7 +202,10 @@
     memset( buf, 0, sizeof(buf) );
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
 
-    mbedtls_sha1( buf + sizeof( buf ) - len, len, buf + sizeof( buf ) - 20 );
+    ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
+                            buf + sizeof( buf ) - 20 );
+    if( ret != 0 )
+        return( ret );
     c = buf + sizeof( buf ) - 20;
     len = 20;
 
@@ -414,7 +420,11 @@
     /*
      * Make signature
      */
-    mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
+    if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c,
+                            len, hash ) ) != 0 )
+    {
+        return( ret );
+    }
 
     if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
                          f_rng, p_rng ) ) != 0 )
diff --git a/programs/hash/hello.c b/programs/hash/hello.c
index df420f2..2e8c224 100644
--- a/programs/hash/hello.c
+++ b/programs/hash/hello.c
@@ -28,8 +28,11 @@
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
+#include <stdlib.h>
 #include <stdio.h>
-#define mbedtls_printf     printf
+#define mbedtls_printf       printf
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
 #endif
 
 #if defined(MBEDTLS_MD5_C)
@@ -45,13 +48,14 @@
 #else
 int main( void )
 {
-    int i;
+    int i, ret;
     unsigned char digest[16];
     char str[] = "Hello, world!";
 
     mbedtls_printf( "\n  MD5('%s') = ", str );
 
-    mbedtls_md5( (unsigned char *) str, 13, digest );
+    if( ( ret = mbedtls_md5_ret( (unsigned char *) str, 13, digest ) ) != 0 )
+        return( MBEDTLS_EXIT_FAILURE );
 
     for( i = 0; i < 16; i++ )
         mbedtls_printf( "%02x", digest[i] );
@@ -63,6 +67,6 @@
     fflush( stdout ); getchar();
 #endif
 
-    return( 0 );
+    return( MBEDTLS_EXIT_SUCCESS );
 }
 #endif /* MBEDTLS_MD5_C */
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index 875d0b08..0978408 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -212,7 +212,11 @@
         goto exit;
     }
 
-    mbedtls_sha1( buf, (int)( p - 2 - buf ), hash );
+    if( ( ret = mbedtls_sha1_ret( buf, (int)( p - 2 - buf ), hash ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_sha1_ret returned %d\n\n", ret );
+        goto exit;
+    }
 
     if( ( ret = mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC,
                                   MBEDTLS_MD_SHA256, 0, hash, p ) ) != 0 )
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index a8ee8fd..4304231 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -217,7 +217,11 @@
     /*
      * 5. Sign the parameters and send them
      */
-    mbedtls_sha1( buf, n, hash );
+    if( ( ret = mbedtls_sha1_ret( buf, n, hash ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_sha1_ret returned %d\n\n", ret );
+        goto exit;
+    }
 
     buf[n    ] = (unsigned char)( rsa.len >> 8 );
     buf[n + 1] = (unsigned char)( rsa.len      );
@@ -248,6 +252,7 @@
 
     memset( buf, 0, sizeof( buf ) );
 
+    n = dhm.len;
     if( ( ret = mbedtls_net_recv( &client_fd, buf, n ) ) != (int) n )
     {
         mbedtls_printf( " failed\n  ! mbedtls_net_recv returned %d\n\n", ret );
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index c3ce56a..b474060 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -102,7 +102,6 @@
     mbedtls_ecdsa_context ctx_sign, ctx_verify;
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
-    mbedtls_sha256_context sha256_ctx;
     unsigned char message[100];
     unsigned char hash[32];
     unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
@@ -113,7 +112,6 @@
     mbedtls_ecdsa_init( &ctx_sign );
     mbedtls_ecdsa_init( &ctx_verify );
     mbedtls_ctr_drbg_init( &ctr_drbg );
-    mbedtls_sha256_init( &sha256_ctx );
 
     memset( sig, 0, sizeof( sig ) );
     memset( message, 0x25, sizeof( message ) );
@@ -165,9 +163,11 @@
     mbedtls_printf( "  . Computing message hash..." );
     fflush( stdout );
 
-    mbedtls_sha256_starts( &sha256_ctx, 0 );
-    mbedtls_sha256_update( &sha256_ctx, message, sizeof( message ) );
-    mbedtls_sha256_finish( &sha256_ctx, hash );
+    if( ( ret = mbedtls_sha256_ret( message, sizeof( message ), hash, 0 ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_sha256_ret returned %d\n", ret );
+        goto exit;
+    }
 
     mbedtls_printf( " ok\n" );
 
@@ -242,7 +242,6 @@
     mbedtls_ecdsa_free( &ctx_sign );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
-    mbedtls_sha256_free( &sha256_ctx );
 
     return( ret );
 }
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index ed6ed30..a7f5c90 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -345,7 +345,7 @@
                                    mbedtls_ctr_drbg_random, &ctr_drbg );
         if( ret != 0 )
         {
-            mbedtls_printf( " failed\n  !  mbedtls_rsa_gen_key returned -0x%04x", -ret );
+            mbedtls_printf( " failed\n  !  mbedtls_ecp_gen_key returned -0x%04x", -ret );
             goto exit;
         }
     }
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index a2677af..c1eaf2a 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -131,15 +131,6 @@
                      ( mbedtls_timing_hardclock() - tsc ) / ( jj * BUFSIZE ) );         \
 } while( 0 )
 
-#if defined(MBEDTLS_ERROR_C)
-#define PRINT_ERROR                                                     \
-        mbedtls_strerror( ret, ( char * )tmp, sizeof( tmp ) );          \
-        mbedtls_printf( "FAILED: %s\n", tmp );
-#else
-#define PRINT_ERROR                                                     \
-        mbedtls_printf( "FAILED: -0x%04x\n", -ret );
-#endif
-
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG)
 
 #define MEMORY_MEASURE_INIT                                             \
@@ -327,32 +318,32 @@
 
 #if defined(MBEDTLS_MD4_C)
     if( todo.md4 )
-        TIME_AND_TSC( "MD4", mbedtls_md4( buf, BUFSIZE, tmp ) );
+        TIME_AND_TSC( "MD4", mbedtls_md4_ret( buf, BUFSIZE, tmp ) );
 #endif
 
 #if defined(MBEDTLS_MD5_C)
     if( todo.md5 )
-        TIME_AND_TSC( "MD5", mbedtls_md5( buf, BUFSIZE, tmp ) );
+        TIME_AND_TSC( "MD5", mbedtls_md5_ret( buf, BUFSIZE, tmp ) );
 #endif
 
 #if defined(MBEDTLS_RIPEMD160_C)
     if( todo.ripemd160 )
-        TIME_AND_TSC( "RIPEMD160", mbedtls_ripemd160( buf, BUFSIZE, tmp ) );
+        TIME_AND_TSC( "RIPEMD160", mbedtls_ripemd160_ret( buf, BUFSIZE, tmp ) );
 #endif
 
 #if defined(MBEDTLS_SHA1_C)
     if( todo.sha1 )
-        TIME_AND_TSC( "SHA-1", mbedtls_sha1( buf, BUFSIZE, tmp ) );
+        TIME_AND_TSC( "SHA-1", mbedtls_sha1_ret( buf, BUFSIZE, tmp ) );
 #endif
 
 #if defined(MBEDTLS_SHA256_C)
     if( todo.sha256 )
-        TIME_AND_TSC( "SHA-256", mbedtls_sha256( buf, BUFSIZE, tmp, 0 ) );
+        TIME_AND_TSC( "SHA-256", mbedtls_sha256_ret( buf, BUFSIZE, tmp, 0 ) );
 #endif
 
 #if defined(MBEDTLS_SHA512_C)
     if( todo.sha512 )
-        TIME_AND_TSC( "SHA-512", mbedtls_sha512( buf, BUFSIZE, tmp, 0 ) );
+        TIME_AND_TSC( "SHA-512", mbedtls_sha512_ret( buf, BUFSIZE, tmp, 0 ) );
 #endif
 
 #if defined(MBEDTLS_ARC4_C)
diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl
index cfcf07c..59618d4 100755
--- a/scripts/generate_errors.pl
+++ b/scripts/generate_errors.pl
@@ -29,13 +29,14 @@
 
 my $error_format_file = $data_dir.'/error.fmt';
 
-my @low_level_modules = ( "AES", "ASN1", "BLOWFISH", "CAMELLIA", "BIGNUM",
-                          "BASE64", "XTEA", "PBKDF2", "OID",
-                          "PADLOCK", "DES", "NET", "CTR_DRBG", "ENTROPY",
-                          "HMAC_DRBG", "MD2", "MD4", "MD5", "RIPEMD160",
-                          "SHA1", "SHA256", "SHA512", "GCM", "THREADING", "CCM" );
-my @high_level_modules = ( "PEM", "X509", "DHM", "RSA", "ECP", "MD", "CIPHER", "SSL",
-                           "PK", "PKCS12", "PKCS5" );
+my @low_level_modules = qw( AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH
+                            CAMELLIA CCM CMAC CTR_DRBG DES
+                            ENTROPY GCM HMAC_DRBG MD2 MD4 MD5
+                            NET OID PADLOCK PBKDF2 RIPEMD160
+                            SHA1 SHA256 SHA512 THREADING XTEA );
+my @high_level_modules = qw( CIPHER DHM ECP MD
+                             PEM PK PKCS12 PKCS5
+                             RSA SSL X509 );
 
 my $line_separator = $/;
 undef $/;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index dc27979..16e19a9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -31,7 +31,7 @@
     include_directories(${CMAKE_CURRENT_SOURCE_DIR})
     add_executable(test_suite_${data_name} test_suite_${data_name}.c)
     target_link_libraries(test_suite_${data_name} ${libs})
-    add_test(${data_name}-suite test_suite_${data_name})
+    add_test(${data_name}-suite test_suite_${data_name} --verbose)
 endfunction(add_test_suite)
 
 if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
diff --git a/tests/compat.sh b/tests/compat.sh
index 958d618..672bdab 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -887,8 +887,9 @@
         done
     }
 else
+    echo "Warning: lsof not available, wait_server_start = sleep"
     wait_server_start() {
-        sleep 1
+        sleep 2
     }
 fi
 
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index fa785a4..f13c38f 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -308,6 +308,7 @@
         done
     }
 else
+    echo "Warning: lsof not available, wait_server_start = sleep $START_DELAY"
     wait_server_start() {
         sleep "$START_DELAY"
     }
@@ -656,14 +657,28 @@
 # used by watchdog
 MAIN_PID="$$"
 
-# be more patient with valgrind
+# We use somewhat arbitrary delays for tests:
+# - how long do we wait for the server to start (when lsof not available)?
+# - how long do we allow for the client to finish?
+#   (not to check performance, just to avoid waiting indefinitely)
+# Things are slower with valgrind, so give extra time here.
+#
+# Note: without lsof, there is a trade-off between the running time of this
+# script and the risk of spurious errors because we didn't wait long enough.
+# The watchdog delay on the other hand doesn't affect normal running time of
+# the script, only the case where a client or server gets stuck.
 if [ "$MEMCHECK" -gt 0 ]; then
-    START_DELAY=3
-    DOG_DELAY=30
+    START_DELAY=6
+    DOG_DELAY=60
 else
-    START_DELAY=1
-    DOG_DELAY=10
+    START_DELAY=2
+    DOG_DELAY=20
 fi
+
+# some particular tests need more time:
+# - for the client, we multiply the usual watchdog limit by a factor
+# - for the server, we sleep for a number of seconds after the client exits
+# see client_need_more_time() and server_needs_more_time()
 CLI_DELAY_FACTOR=1
 SRV_DELAY_SECONDS=0
 
diff --git a/tests/suites/test_suite_cipher.padding.data b/tests/suites/test_suite_cipher.padding.data
index d6fc266..1c0ba09 100644
--- a/tests/suites/test_suite_cipher.padding.data
+++ b/tests/suites/test_suite_cipher.padding.data
@@ -184,6 +184,10 @@
 depends_on:MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
 check_padding:MBEDTLS_PADDING_ONE_AND_ZEROS:"0000000000":MBEDTLS_ERR_CIPHER_INVALID_PADDING:4
 
+Check one and zeros padding #8 (last byte 0x80 | x)
+depends_on:MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+check_padding:MBEDTLS_PADDING_ONE_AND_ZEROS:"0000000082":MBEDTLS_ERR_CIPHER_INVALID_PADDING:4
+
 Check zeros and len padding #1 (correct)
 depends_on:MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
 check_padding:MBEDTLS_PADDING_ZEROS_AND_LEN:"DABBAD0001":0:4
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 883cfe0..d8ffebe 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -1,8 +1,8 @@
 /* BEGIN_HEADER */
 #include "mbedtls/ctr_drbg.h"
 
-int test_offset_idx;
-int mbedtls_entropy_func( void *data, unsigned char *buf, size_t len )
+static int test_offset_idx;
+static int mbedtls_test_entropy_func( void *data, unsigned char *buf, size_t len )
 {
     const unsigned char *p = (unsigned char *) data;
     memcpy( buf, p + test_offset_idx, len );
@@ -72,7 +72,7 @@
     add2_len = unhexify( add2, add2_string );
 
     test_offset_idx = 0;
-    TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 );
+    TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_test_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 );
     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
 
     TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 );
@@ -110,7 +110,7 @@
     add2_len = unhexify( add2, add2_string );
 
     test_offset_idx = 0;
-    TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 );
+    TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_test_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 );
 
     TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 );
     TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, add_reseed, add_reseed_len ) == 0 );
@@ -141,7 +141,7 @@
 
     /* Init must use entropy */
     last_idx = test_offset_idx;
-    TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_entropy_func, entropy, NULL, 0 ) == 0 );
+    TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
     TEST_ASSERT( last_idx < test_offset_idx );
 
     /* By default, PR is off and reseed_interval is large,
diff --git a/tests/suites/test_suite_hmac_drbg.function b/tests/suites/test_suite_hmac_drbg.function
index 5209470..a413f5e 100644
--- a/tests/suites/test_suite_hmac_drbg.function
+++ b/tests/suites/test_suite_hmac_drbg.function
@@ -7,7 +7,7 @@
     size_t len;
 } entropy_ctx;
 
-int mbedtls_entropy_func( void *data, unsigned char *buf, size_t len )
+static int mbedtls_test_entropy_func( void *data, unsigned char *buf, size_t len )
 {
     entropy_ctx *ctx = (entropy_ctx *) data;
 
@@ -50,7 +50,7 @@
 
     /* Init must use entropy */
     last_len = entropy.len;
-    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &entropy,
+    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &entropy,
                                  NULL, 0 ) == 0 );
     TEST_ASSERT( entropy.len < last_len );
 
@@ -206,7 +206,7 @@
     TEST_ASSERT( memcmp( my_output, output, out_len ) == 0 );
 
     /* And now the normal entropy-based variant */
-    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &p_entropy,
+    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &p_entropy,
                                  custom, custom_len ) == 0 );
     TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                             add1, add1_len ) == 0 );
@@ -251,7 +251,7 @@
     md_info = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
 
-    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &p_entropy,
+    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &p_entropy,
                                  custom, custom_len ) == 0 );
     TEST_ASSERT( mbedtls_hmac_drbg_reseed( &ctx, add1, add1_len ) == 0 );
     TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
@@ -296,7 +296,7 @@
     md_info = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
 
-    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &p_entropy,
+    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &p_entropy,
                                  custom, custom_len ) == 0 );
     mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
     TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
diff --git a/tests/suites/test_suite_mdx.function b/tests/suites/test_suite_mdx.function
index 9d0ee47..648a9cc 100644
--- a/tests/suites/test_suite_mdx.function
+++ b/tests/suites/test_suite_mdx.function
@@ -8,6 +8,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_MD2_C */
 void md2_text( char *text_src_string, char *hex_hash_string )
 {
+    int ret;
     unsigned char src_str[100];
     unsigned char hash_str[33];
     unsigned char output[16];
@@ -18,7 +19,8 @@
 
     strncpy( (char *) src_str, text_src_string, sizeof(src_str) - 1 );
 
-    mbedtls_md2( src_str, strlen( (char *) src_str ), output );
+    ret = mbedtls_md2_ret( src_str, strlen( (char *) src_str ), output );
+    TEST_ASSERT( ret == 0 ) ;
     hexify( hash_str, output, sizeof  output );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
@@ -28,6 +30,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_MD4_C */
 void md4_text( char *text_src_string, char *hex_hash_string )
 {
+    int ret;
     unsigned char src_str[100];
     unsigned char hash_str[33];
     unsigned char output[16];
@@ -38,7 +41,8 @@
 
     strncpy( (char *) src_str, text_src_string, sizeof(src_str) - 1 );
 
-    mbedtls_md4( src_str, strlen( (char *) src_str ), output );
+    ret = mbedtls_md4_ret( src_str, strlen( (char *) src_str ), output );
+    TEST_ASSERT( ret == 0 );
     hexify( hash_str, output, sizeof  output );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
@@ -48,6 +52,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_MD5_C */
 void md5_text( char *text_src_string, char *hex_hash_string )
 {
+    int ret;
     unsigned char src_str[100];
     unsigned char hash_str[33];
     unsigned char output[16];
@@ -58,7 +63,8 @@
 
     strncpy( (char *) src_str, text_src_string, sizeof(src_str) - 1 );
 
-    mbedtls_md5( src_str, strlen( (char *) src_str ), output );
+    ret = mbedtls_md5_ret( src_str, strlen( (char *) src_str ), output );
+    TEST_ASSERT( ret == 0 );
     hexify( hash_str, output, sizeof  output );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
@@ -68,6 +74,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_RIPEMD160_C */
 void ripemd160_text( char *text_src_string, char *hex_hash_string )
 {
+    int ret;
     unsigned char src_str[100];
     unsigned char hash_str[41];
     unsigned char output[20];
@@ -78,7 +85,8 @@
 
     strncpy( (char *) src_str, text_src_string, sizeof(src_str) - 1 );
 
-    mbedtls_ripemd160( src_str, strlen( (char *) src_str ), output );
+    ret = mbedtls_ripemd160_ret( src_str, strlen( (char *) src_str ), output );
+    TEST_ASSERT( ret == 0 );
     hexify( hash_str, output, sizeof output );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
diff --git a/tests/suites/test_suite_shax.function b/tests/suites/test_suite_shax.function
index 6b3ee9c..d704b38 100644
--- a/tests/suites/test_suite_shax.function
+++ b/tests/suites/test_suite_shax.function
@@ -18,7 +18,7 @@
 
     src_len = unhexify( src_str, hex_src_string );
 
-    mbedtls_sha1( src_str, src_len, output );
+    TEST_ASSERT( mbedtls_sha1_ret( src_str, src_len, output ) == 0 );
     hexify( hash_str, output, 20 );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
@@ -39,7 +39,7 @@
 
     src_len = unhexify( src_str, hex_src_string );
 
-    mbedtls_sha256( src_str, src_len, output, 1 );
+    TEST_ASSERT( mbedtls_sha256_ret( src_str, src_len, output, 1 ) == 0 );
     hexify( hash_str, output, 28 );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
@@ -60,7 +60,7 @@
 
     src_len = unhexify( src_str, hex_src_string );
 
-    mbedtls_sha256( src_str, src_len, output, 0 );
+    TEST_ASSERT( mbedtls_sha256_ret( src_str, src_len, output, 0 ) == 0 );
     hexify( hash_str, output, 32 );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
@@ -81,7 +81,7 @@
 
     src_len = unhexify( src_str, hex_src_string );
 
-    mbedtls_sha512( src_str, src_len, output, 1 );
+    TEST_ASSERT( mbedtls_sha512_ret( src_str, src_len, output, 1 ) == 0 );
     hexify( hash_str, output, 48 );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );
@@ -102,7 +102,7 @@
 
     src_len = unhexify( src_str, hex_src_string );
 
-    mbedtls_sha512( src_str, src_len, output, 0);
+    TEST_ASSERT( mbedtls_sha512_ret( src_str, src_len, output, 0 ) == 0 );
     hexify( hash_str, output, 64 );
 
     TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 );