Merge remote-tracking branch 'public/pr/1555' into development
diff --git a/.travis.yml b/.travis.yml
index fa01e5a..4d23652 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,7 @@
 - tests/scripts/check-generated-files.sh
 - tests/scripts/check-doxy-blocks.pl
 - tests/scripts/check-names.sh
+- tests/scripts/check-files.py
 - tests/scripts/doxygen.sh
 - cmake -D CMAKE_BUILD_TYPE:String="Check" .
 - make
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2018d35..3538b80 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,8 +8,13 @@
 
 option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
 
+string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
+string(REGEX MATCH "GNU" CMAKE_COMPILER_IS_GNU "${CMAKE_C_COMPILER_ID}")
+string(REGEX MATCH "IAR" CMAKE_COMPILER_IS_IAR "${CMAKE_C_COMPILER_ID}")
+string(REGEX MATCH "MSVC" CMAKE_COMPILER_IS_MSVC "${CMAKE_C_COMPILER_ID}")
+
 # the test suites currently have compile errors with MSVC
-if(MSVC)
+if(CMAKE_COMPILER_IS_MSVC)
     option(ENABLE_TESTING "Build mbed TLS tests." OFF)
 else()
     option(ENABLE_TESTING "Build mbed TLS tests." ON)
@@ -56,9 +61,37 @@
     CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
     FORCE)
 
+# Create a symbolic link from ${base_name} in the binary directory
+# to the corresponding path in the source directory.
+function(link_to_source base_name)
+    # Get OS dependent path to use in `execute_process`
+    file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${base_name}" link)
+    file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}" target)
+
+    if (NOT EXISTS ${link})
+        if (CMAKE_HOST_UNIX)
+            set(command ln -s ${target} ${link})
+        else()
+            if (IS_DIRECTORY ${target})
+                set(command cmd.exe /c mklink /j ${link} ${target})
+            else()
+                set(command cmd.exe /c mklink /h ${link} ${target})
+            endif()
+        endif()
+
+        execute_process(COMMAND ${command}
+            RESULT_VARIABLE result
+            ERROR_VARIABLE output)
+
+        if (NOT ${result} EQUAL 0)
+            message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
+        endif()
+    endif()
+endfunction(link_to_source)
+
 string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
 
-if(CMAKE_COMPILER_IS_GNUCC)
+if(CMAKE_COMPILER_IS_GNU)
     # some warnings we want are not available with old GCC versions
     # note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
     execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
@@ -77,7 +110,7 @@
     set(CMAKE_C_FLAGS_ASANDBG     "-Werror -fsanitize=address -fno-common -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
     set(CMAKE_C_FLAGS_CHECK       "-Werror -Os")
     set(CMAKE_C_FLAGS_CHECKFULL   "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
-endif(CMAKE_COMPILER_IS_GNUCC)
+endif(CMAKE_COMPILER_IS_GNU)
 
 if(CMAKE_COMPILER_IS_CLANG)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow")
@@ -91,16 +124,20 @@
     set(CMAKE_C_FLAGS_CHECK       "-Werror -Os")
 endif(CMAKE_COMPILER_IS_CLANG)
 
-if(MSVC)
+if(CMAKE_COMPILER_IS_IAR)
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts --warnings_are_errors -Ohz")
+endif(CMAKE_COMPILER_IS_IAR)
+
+if(CMAKE_COMPILER_IS_MSVC)
     # Strictest warnings, and treat as errors
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
-endif(MSVC)
+endif(CMAKE_COMPILER_IS_MSVC)
 
 if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
-    if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
+    if(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
         set(CMAKE_SHARED_LINKER_FLAGS "--coverage")
-    endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
+    endif(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
 endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
 
 if(LIB_INSTALL_DIR)
@@ -164,3 +201,12 @@
         )
     endif(UNIX)
 endif()
+
+# Make scripts needed for testing available in an out-of-source build.
+if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+    link_to_source(scripts)
+    # Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
+    # keep things simple with the sed commands in the memcheck target.
+    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
+                   ${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
+endif()
diff --git a/ChangeLog b/ChangeLog
index 9ee82c6..8061792 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,33 +2,89 @@
 
 = mbed TLS x.x.x branch released xxxx-xx-xx
 
-Security
-   * Fix a bug in the X.509 module potentially leading to a buffer overread
-     during CRT verification or to invalid or omitted checks for certificate
-     validity. The former can be triggered remotely, while the latter requires
-     a non DER-compliant certificate correctly signed by a trusted CA, or a
-     trusted CA with a non DER-compliant certificate. Found by luocm on GitHub.
-     Fixes #825.
+Features
+   * Add additional block mode, OFB (Output Feedback), to the AES module and
+     cipher abstraction module.
+   * Implement the HMAC-based extract-and-expand key derivation function
+     (HKDF) per RFC 5869. Contributed by Thomas Fossati.
+   * Add support for the CCM* block cipher mode as defined in IEEE Std. 802.15.4.
+
+Bugfix
+   * Fix the cert_write example to handle certificates signed with elliptic
+     curves as well as RSA. Fixes #777 found by dbedev.
+
+Changes
+   * Changed CMake defaults for IAR to treat all compiler warnings as errors.
+
+= mbed TLS 2.10.0 branch released 2018-06-06
 
 Features
-   * Add option MBEDTLS_AES_FEWER_TABLES to dynamically compute 3/4 of the AES tables
-     during runtime, thereby reducing the RAM/ROM footprint by ~6kb. Suggested
-     and contributed by jkivilin in #394.
+   * Add support for ARIA cipher (RFC 5794) and associated TLS ciphersuites
+     (RFC 6209). Disabled by default, see MBEDTLS_ARIA_C in config.h
+
+API Changes
+   * Extend the platform module with a util component that contains
+     functionality shared by multiple Mbed TLS modules. At this stage
+     platform_util.h (and its associated platform_util.c) only contain
+     mbedtls_platform_zeroize(), which is a critical function from a security
+     point of view. mbedtls_platform_zeroize() needs to be regularly tested
+     against compilers to ensure that calls to it are not removed from the
+     output binary as part of redundant code elimination optimizations.
+     Therefore, mbedtls_platform_zeroize() is moved to the platform module to
+     facilitate testing and maintenance.
+
+Bugfix
+   * Fix an issue with MicroBlaze support in bn_mul.h which was causing the
+     build to fail. Found by zv-io. Fixes #1651.
+
+Changes
+   * Support TLS testing in out-of-source builds using cmake. Fixes #1193.
+   * Fix redundant declaration of mbedtls_ssl_list_ciphersuites. Raised by
+     TrinityTonic. #1359.
+
+= mbed TLS 2.9.0 branch released 2018-04-30
+
+Security
+   * Fix an issue in the X.509 module which could lead to a buffer overread
+     during certificate validation. Additionally, the issue could also lead to
+     unnecessary callback checks being made or to some validation checks to be
+     omitted. The overread could be triggered remotely, while the other issues
+     would require a non DER-compliant certificate to be correctly signed by a
+     trusted CA, or a trusted CA with a non DER-compliant certificate. Found by
+     luocm. Fixes #825.
+   * Fix the buffer length assertion in the ssl_parse_certificate_request()
+     function which led to an arbitrary overread of the message buffer. The
+     overreads could be caused by receiving a malformed message at the point
+     where an optional signature algorithms list is expected when the signature
+     algorithms section is too short. In builds with debug output, the overread
+     data is output with the debug data.
+   * Fix a client-side bug in the validation of the server's ciphersuite choice
+     which could potentially lead to the client accepting a ciphersuite it didn't
+     offer or a ciphersuite that cannot be used with the TLS or DTLS version
+     chosen by the server. This could lead to corruption of internal data
+     structures for some configurations.
+
+Features
+   * Add an option, MBEDTLS_AES_FEWER_TABLES, to dynamically compute smaller AES
+     tables during runtime, thereby reducing the RAM/ROM footprint by ~6KiB.
+     Suggested and contributed by jkivilin in pull request #394.
    * Add initial support for Curve448 (RFC 7748). Only mbedtls_ecp_mul() and
      ECDH primitive functions (mbedtls_ecdh_gen_public(),
      mbedtls_ecdh_compute_shared()) are supported for now. Contributed by
-     Nicholas Wilson (#348).
+     Nicholas Wilson in pull request #348.
 
 API Changes
-   * Add function mbedtls_net_poll to public API allowing to wait for a
-     network context to become ready for reading or writing.
-   * Add function mbedtls_ssl_check_pending to public API allowing to check
-     if more data is pending to be processed in the internal message buffers.
+   * Extend the public API with the function of mbedtls_net_poll() to allow user
+     applications to wait for a network context to become ready before reading
+     or writing.
+   * Add function mbedtls_ssl_check_pending() to the public API to allow
+     a check for whether more more data is pending to be processed in the
+     internal message buffers.
      This function is necessary to determine when it is safe to idle on the
      underlying transport in case event-driven IO is used.
 
 Bugfix
-   * Fix spurious uninitialized variable warning in cmac.c. Fix independently
+   * Fix a spurious uninitialized variable warning in cmac.c. Fix independently
      contributed by Brian J Murray and David Brown.
    * Add missing dependencies in test suites that led to build failures
      in configurations that omit certain hashes or public-key algorithms.
@@ -36,15 +92,16 @@
    * Fix C89 incompatibility in benchmark.c. Contributed by Brendan Shanks.
      #1353
    * Add missing dependencies for MBEDTLS_HAVE_TIME_DATE and
-     MBEDTLS_VERSION_FEATURES in test suites. Contributed by Deomid Ryabkov.
-     Fixes #1299, #1475.
-   * Fix dynamic library building process with Makefile on Mac OS X. Fixed by
-     mnacamura.
+     MBEDTLS_VERSION_FEATURES in some test suites. Contributed by
+     Deomid Ryabkov. Fixes #1299, #1475.
+   * Fix the Makefile build process for building shared libraries on Mac OS X.
+     Fixed by mnacamura.
    * Fix parsing of PKCS#8 encoded Elliptic Curve keys. Previously Mbed TLS was
-     unable to parse keys with only the optional parameters field of the
-     ECPrivateKey structure. Found by jethrogb, fixed in #1379.
-   * Return plaintext data sooner on unpadded CBC decryption, as stated in
-     the mbedtls_cipher_update() documentation. Contributed by Andy Leiserson.
+     unable to parse keys which had only the optional parameters field of the
+     ECPrivateKey structure. Found by Jethro Beekman, fixed in #1379.
+   * Return the plaintext data more quickly on unpadded CBC decryption, as
+     stated in the mbedtls_cipher_update() documentation. Contributed by
+     Andy Leiserson.
    * Fix overriding and ignoring return values when parsing and writing to
      a file in pk_sign program. Found by kevlut in #1142.
    * Restrict usage of error code MBEDTLS_ERR_SSL_WANT_READ to situations
@@ -52,24 +109,32 @@
      to make progress. Previously, this error code was also occasionally
      returned when unexpected messages were being discarded, ignoring that
      further messages could potentially already be pending to be processed
-     in the internal buffers; these cases lead to deadlocks in case
-     event-driven I/O was used.
-     Found and reported by Hubert Mis in #772.
+     in the internal buffers; these cases led to deadlocks when event-driven
+     I/O was used. Found and reported by Hubert Mis in #772.
+   * Fix buffer length assertions in the ssl_parse_certificate_request()
+     function which leads to a potential one byte overread of the message
+     buffer.
+   * Fix invalid buffer sizes passed to zlib during record compression and
+     decompression.
+   * Fix the soversion of libmbedcrypto to match the soversion of the
+     maintained 2.7 branch. The soversion was increased in Mbed TLS
+     version 2.7.1 to reflect breaking changes in that release, but the
+     increment was missed in 2.8.0 and later releases outside of the 2.7 branch.
 
 Changes
    * Remove some redundant code in bignum.c. Contributed by Alexey Skalozub.
-   * Support cmake build where Mbed TLS is a subproject. Fix
-     contributed independently by Matthieu Volat and Arne Schwabe.
+   * Support cmake builds where Mbed TLS is a subproject. Fix contributed
+     independently by Matthieu Volat and Arne Schwabe.
    * Improve testing in configurations that omit certain hashes or
      public-key algorithms. Includes contributions by Gert van Dijk.
    * Improve negative testing of X.509 parsing.
    * Do not define global mutexes around readdir() and gmtime() in
      configurations where the feature is disabled. Found and fixed by Gergely
      Budai.
-   * Harden mbedtls_ssl_config_free() against misuse, so that it doesn't
-     leak memory in case the user doesn't use mbedtls_ssl_conf_psk() and
-     instead incorrectly manipulates conf->psk and/or conf->psk_identity
-     directly. Found and fix submitted by junyeonLEE in #1220.
+   * Harden the function mbedtls_ssl_config_free() against misuse, so that it
+     doesn't leak memory if the user doesn't use mbedtls_ssl_conf_psk() and
+     instead incorrectly manipulates the configuration structure directly.
+     Found and fix submitted by junyeonLEE in #1220.
    * Provide an empty implementation of mbedtls_pkcs5_pbes2() when
      MBEDTLS_ASN1_PARSE_C is not enabled. This allows the use of PBKDF2
      without PBES2. Fixed by Marcos Del Sol Vives.
@@ -80,7 +145,7 @@
      Krylov.
    * Improve the documentation of mbedtls_ssl_write(). Suggested by
      Paul Sokolovsky in #1356.
-   * Add an option in the makefile to support ar utilities where the operation
+   * Add an option in the Makefile to support ar utilities where the operation
      letter must not be prefixed by '-', such as LLVM. Found and fixed by
      Alex Hixon.
    * Allow configuring the shared library extension by setting the DLEXT
@@ -93,6 +158,14 @@
    * Improve robustness of mbedtls_ssl_derive_keys against the use of
      HMAC functions with non-HMAC ciphersuites. Independently contributed
      by Jiayuan Chen in #1377. Fixes #1437.
+   * Improve security of RSA key generation by including criteria from
+     FIPS 186-4. Contributed by Jethro Beekman. #1380
+   * Declare functions in header files even when an alternative implementation
+     of the corresponding module is activated by defining the corresponding
+     MBEDTLS_XXX_ALT macro. This means that alternative implementations do
+     not need to copy the declarations, and ensures that they will have the
+     same API.
+   * Add platform setup and teardown calls in test suites.
 
 = mbed TLS 2.8.0 branch released 2018-03-16
 
@@ -290,7 +363,7 @@
    * Fix ssl_parse_record_header() to silently discard invalid DTLS records
      as recommended in RFC 6347 Section 4.1.2.7.
    * Fix memory leak in mbedtls_ssl_set_hostname() when called multiple times.
-     Found by projectgus and jethrogb, #836.
+     Found by projectgus and Jethro Beekman, #836.
    * Fix usage help in ssl_server2 example. Found and fixed by Bei Lin.
    * Parse signature algorithm extension when renegotiating. Previously,
      renegotiated handshakes would only accept signatures using SHA-1
@@ -484,8 +557,7 @@
      Previous behaviour was to keep processing data even after the alert has
      been sent.
    * Accept empty trusted CA chain in authentication mode
-     MBEDTLS_SSL_VERIFY_OPTIONAL.
-     Found by jethrogb. #864
+     MBEDTLS_SSL_VERIFY_OPTIONAL. Found by Jethro Beekman. #864
    * Fix implementation of mbedtls_ssl_parse_certificate() to not annihilate
      fatal errors in authentication mode MBEDTLS_SSL_VERIFY_OPTIONAL and to
      reflect bad EC curves within verification result.
@@ -1687,7 +1759,7 @@
      issuer_key_identifier, etc)
    * Optional blinding for RSA, DHM and EC
    * Support for multiple active certificate / key pairs in SSL servers for
-   	 the same host (Not to be confused with SNI!)
+     the same host (Not to be confused with SNI!)
 
 Changes
    * Ability to enable / disable SSL v3 / TLS 1.0 / TLS 1.1 / TLS 1.2
@@ -1918,7 +1990,7 @@
      PKCS#8 private key formats
    * Added mechanism to provide alternative implementations for all
      symmetric cipher and hash algorithms (e.g. POLARSSL_AES_ALT in
-	 config.h)
+     config.h)
    * PKCS#5 module added. Moved PBKDF2 functionality inside and deprecated
      old PBKDF2 module
 
@@ -1930,7 +2002,7 @@
    * x509parse_crt() now better handles PEM error situations
    * ssl_parse_certificate() now calls x509parse_crt_der() directly
      instead of the x509parse_crt() wrapper that can also parse PEM
-	 certificates
+     certificates
    * x509parse_crtpath() is now reentrant and uses more portable stat()
    * Fixed bignum.c and bn_mul.h to support Thumb2 and LLVM compiler
    * Fixed values for 2-key Triple DES in cipher layer
@@ -2088,7 +2160,7 @@
    * mpi_exp_mod() now correctly handles negative base numbers (Closes ticket
      #52)
    * Handle encryption with private key and decryption with public key as per
-   	 RFC 2313
+     RFC 2313
    * Handle empty certificate subject names
    * Prevent reading over buffer boundaries on X509 certificate parsing
    * mpi_add_abs() now correctly handles adding short numbers to long numbers
@@ -2119,7 +2191,7 @@
    * x509parse_crt() now better handles PEM error situations
    * ssl_parse_certificate() now calls x509parse_crt_der() directly
      instead of the x509parse_crt() wrapper that can also parse PEM
-	 certificates
+     certificates
    * Fixed values for 2-key Triple DES in cipher layer
    * ssl_write_certificate_request() can handle empty ca_chain
 
@@ -2200,16 +2272,16 @@
 Features
    * Added ssl_session_reset() to allow better multi-connection pools of
      SSL contexts without needing to set all non-connection-specific
-	 data and pointers again. Adapted ssl_server to use this functionality.
+     data and pointers again. Adapted ssl_server to use this functionality.
    * Added ssl_set_max_version() to allow clients to offer a lower maximum
      supported version to a server to help buggy server implementations.
-	 (Closes ticket #36)
+     (Closes ticket #36)
    * Added cipher_get_cipher_mode() and cipher_get_cipher_operation()
      introspection functions (Closes ticket #40)
    * Added CTR_DRBG based on AES-256-CTR (NIST SP 800-90) random generator
    * Added a generic entropy accumulator that provides support for adding
      custom entropy sources and added some generic and platform dependent
-	 entropy sources
+     entropy sources
 
 Changes
    * Documentation for AES and Camellia in modes CTR and CFB128 clarified.
@@ -2342,7 +2414,7 @@
    * Corrected parsing of UTCTime dates before 1990 and
      after 1950
    * Support more exotic OID's when parsing certificates
-   	 (found by Mads Kiilerich)
+     (found by Mads Kiilerich)
    * Support more exotic name representations when parsing
      certificates (found by Mads Kiilerich)
    * Replaced the expired test certificates
@@ -2372,7 +2444,7 @@
          status, objects and configuration
        + Added verification callback on certificate chain
          verification to allow external blacklisting
-	   + Additional example programs to show usage
+       + Additional example programs to show usage
    * Added support for PKCS#11 through the use of the
      libpkcs11-helper library
 
diff --git a/Makefile b/Makefile
index c18b99b..a0fcb2b 100644
--- a/Makefile
+++ b/Makefile
@@ -24,12 +24,12 @@
 install: no_test
 	mkdir -p $(DESTDIR)/include/mbedtls
 	cp -r include/mbedtls $(DESTDIR)/include
-	
+
 	mkdir -p $(DESTDIR)/lib
 	cp -RP library/libmbedtls.*    $(DESTDIR)/lib
 	cp -RP library/libmbedx509.*   $(DESTDIR)/lib
 	cp -RP library/libmbedcrypto.* $(DESTDIR)/lib
-	
+
 	mkdir -p $(DESTDIR)/bin
 	for p in programs/*/* ; do              \
 	    if [ -x $$p ] && [ ! -d $$p ] ;     \
@@ -44,7 +44,7 @@
 	rm -f $(DESTDIR)/lib/libmbedtls.*
 	rm -f $(DESTDIR)/lib/libmbedx509.*
 	rm -f $(DESTDIR)/lib/libmbedcrypto.*
-	
+
 	for p in programs/*/* ; do              \
 	    if [ -x $$p ] && [ ! -d $$p ] ;     \
 	    then                                \
diff --git a/configs/config-no-entropy.h b/configs/config-no-entropy.h
index b4a0930..7d34ad5 100644
--- a/configs/config-no-entropy.h
+++ b/configs/config-no-entropy.h
@@ -82,6 +82,7 @@
 #define MBEDTLS_X509_USE_C
 #define MBEDTLS_X509_CRT_PARSE_C
 #define MBEDTLS_X509_CRL_PARSE_C
+//#define MBEDTLS_CMAC_C
 
 /* Miscellaneous options */
 #define MBEDTLS_AES_ROM_TABLES
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 7952cbc..9449cbb 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -24,7 +24,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.8.0 source code documentation
+ * @mainpage mbed TLS v2.10.0 source code documentation
  *
  * This documentation describes the internal structure of mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 3592af2..ddcbc2e 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.8.0"
+PROJECT_NAME           = "mbed TLS v2.10.0"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
@@ -702,7 +702,7 @@
 # directories that are symbolic links (a Unix file system feature) are excluded
 # from the input.
 
-EXCLUDE_SYMLINKS       = NO
+EXCLUDE_SYMLINKS       = YES
 
 # If the value of the INPUT tag contains directories, you can use the
 # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 985a353..1b581a5 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -9,3 +9,8 @@
         PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 
 endif(INSTALL_MBEDTLS_HEADERS)
+
+# Make config.h available in an out-of-source build. ssl-opt.sh requires it.
+if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+    link_to_source(mbedtls)
+endif()
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index 46016dc..e48981a 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -1,7 +1,9 @@
 /**
  * \file aes.h
  *
- * \brief   The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ * \brief   This file contains AES definitions and functions.
+ *
+ *          The Advanced Encryption Standard (AES) specifies a FIPS-approved
  *          cryptographic algorithm that can be used to protect electronic
  *          data.
  *
@@ -12,6 +14,7 @@
  *          techniques -- Encryption algorithms -- Part 2: Asymmetric
  *          ciphers</em>.
  */
+
 /*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -50,7 +53,8 @@
 #define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH                -0x0020  /**< Invalid key length. */
 #define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH              -0x0022  /**< Invalid data input length. */
 
-/* Error codes in range 0x0023-0x0025 */
+/* Error codes in range 0x0021-0x0025 */
+#define MBEDTLS_ERR_AES_BAD_INPUT_DATA                    -0x0021  /**< Invalid input data. */
 #define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023  /**< Feature not available. For example, an unsupported AES key size. */
 #define MBEDTLS_ERR_AES_HW_ACCEL_FAILED                   -0x0025  /**< AES hardware accelerator failed. */
 
@@ -59,14 +63,14 @@
 #define inline __inline
 #endif
 
-#if !defined(MBEDTLS_AES_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_AES_ALT)
+// Regular implementation
+//
+
 /**
  * \brief The AES context-type definition.
  */
@@ -85,6 +89,10 @@
 }
 mbedtls_aes_context;
 
+#else  /* MBEDTLS_AES_ALT */
+#include "aes_alt.h"
+#endif /* MBEDTLS_AES_ALT */
+
 /**
  * \brief          This function initializes the specified AES context.
  *
@@ -112,8 +120,8 @@
  *                 <li>192 bits</li>
  *                 <li>256 bits</li></ul>
  *
- * \return         \c 0 on success or #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
 int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
@@ -128,7 +136,8 @@
  *                 <li>192 bits</li>
  *                 <li>256 bits</li></ul>
  *
- * \return         \c 0 on success, or #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
 int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
@@ -192,7 +201,8 @@
  * \param input    The buffer holding the input data.
  * \param output   The buffer holding the output data.
  *
- * \return         \c 0 on success, or #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
  *                 on failure.
  */
 int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
@@ -286,6 +296,56 @@
                     unsigned char *output );
 #endif /*MBEDTLS_CIPHER_MODE_CFB */
 
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/**
+ * \brief       This function performs an AES-OFB (Output Feedback Mode)
+ *              encryption or decryption operation.
+ *
+ *              For OFB, you must set up the context with
+ *              mbedtls_aes_setkey_enc(), regardless of whether you are
+ *              performing an encryption or decryption operation. This is
+ *              because OFB mode uses the same key schedule for encryption and
+ *              decryption.
+ *
+ *              The OFB operation is identical for encryption or decryption,
+ *              therefore no operation mode needs to be specified.
+ *
+ * \note        Upon exit, the content of iv, the Initialisation Vector, is
+ *              updated so that you can call the same function again on the next
+ *              block(s) of data and get the same result as if it was encrypted
+ *              in one call. This allows a "streaming" usage, by initialising
+ *              iv_off to 0 before the first call, and preserving its value
+ *              between calls.
+ *
+ *              For non-streaming use, the iv should be initialised on each call
+ *              to a unique value, and iv_off set to 0 on each call.
+ *
+ *              If you need to retain the contents of the initialisation vector,
+ *              you must either save it manually or use the cipher module
+ *              instead.
+ *
+ * \warning     For the OFB mode, the initialisation vector must be unique
+ *              every encryption operation. Reuse of an initialisation vector
+ *              will compromise security.
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ * \param length   The length of the input data.
+ * \param iv_off   The offset in IV (updated after use).
+ * \param iv       The initialization vector (updated after use).
+ * \param input    The buffer holding the input data.
+ * \param output   The buffer holding the output data.
+ *
+ * \return         \c 0 on success.
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /**
  * \brief      This function performs an AES-CTR encryption or decryption
@@ -300,7 +360,49 @@
  *             must use the context initialized with mbedtls_aes_setkey_enc()
  *             for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
  *
- * \warning    You must keep the maximum use of your counter in mind.
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**128
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first 12 bytes for the
+ *             per-message nonce, and the last 4 bytes for internal use. In that
+ *             case, before calling this function on a new message you need to
+ *             set the first 12 bytes of \p nonce_counter to your chosen nonce
+ *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ *             stream_block to be ignored). That way, you can encrypt at most
+ *             2**96 messages of up to 2**32 blocks each with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be unique.
+ *             The recommended way to ensure uniqueness is to use a message
+ *             counter. An alternative is to generate random nonces, but this
+ *             limits the number of messages that can be securely encrypted:
+ *             for example, with 96-bit random nonces, you should not encrypt
+ *             more than 2**32 messages with the same key.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that an AES block is 16 bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
  *
  * \param ctx              The AES context to use for encryption or decryption.
  * \param length           The length of the input data.
@@ -313,7 +415,7 @@
  * \param input            The buffer holding the input data.
  * \param output           The buffer holding the output data.
  *
- * \return     \c 0 on success.
+ * \return                 \c 0 on success.
  */
 int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
                        size_t length,
@@ -391,22 +493,11 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_AES_ALT */
-#include "aes_alt.h"
-#endif /* MBEDTLS_AES_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_aes_self_test( int verbose );
 
diff --git a/include/mbedtls/arc4.h b/include/mbedtls/arc4.h
index f9d93f8..f11fc5b 100644
--- a/include/mbedtls/arc4.h
+++ b/include/mbedtls/arc4.h
@@ -38,14 +38,14 @@
 
 #define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED                  -0x0019  /**< ARC4 hardware accelerator failed. */
 
-#if !defined(MBEDTLS_ARC4_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_ARC4_ALT)
+// Regular implementation
+//
+
 /**
  * \brief     ARC4 context structure
  *
@@ -61,6 +61,10 @@
 }
 mbedtls_arc4_context;
 
+#else  /* MBEDTLS_ARC4_ALT */
+#include "arc4_alt.h"
+#endif /* MBEDTLS_ARC4_ALT */
+
 /**
  * \brief          Initialize ARC4 context
  *
@@ -118,18 +122,6 @@
 int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
                 unsigned char *output );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_ARC4_ALT */
-#include "arc4_alt.h"
-#endif /* MBEDTLS_ARC4_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Checkup routine
  *
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
new file mode 100644
index 0000000..bae0621
--- /dev/null
+++ b/include/mbedtls/aria.h
@@ -0,0 +1,331 @@
+/**
+ * \file aria.h
+ *
+ * \brief ARIA block cipher
+ *
+ *        The ARIA algorithm is a symmetric block cipher that can encrypt and
+ *        decrypt information. It is defined by the Korean Agency for
+ *        Technology and Standards (KATS) in <em>KS X 1213:2004</em> (in
+ *        Korean, but see http://210.104.33.10/ARIA/index-e.html in English)
+ *        and also described by the IETF in <em>RFC 5794</em>.
+ */
+/*  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_ARIA_H
+#define MBEDTLS_ARIA_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDTLS_ARIA_ENCRYPT     1 /**< ARIA encryption. */
+#define MBEDTLS_ARIA_DECRYPT     0 /**< ARIA decryption. */
+
+#define MBEDTLS_ARIA_BLOCKSIZE   16 /**< ARIA block size in bytes. */
+#define MBEDTLS_ARIA_MAX_ROUNDS  16 /**< Maxiumum number of rounds in ARIA. */
+#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
+
+#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH   -0x005C  /**< Invalid key length. */
+#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E  /**< Invalid data input length. */
+#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE  -0x005A  /**< Feature not available. For example, an unsupported ARIA key size. */
+#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED      -0x0058  /**< ARIA hardware accelerator failed. */
+
+#if !defined(MBEDTLS_ARIA_ALT)
+// Regular implementation
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief The ARIA context-type definition.
+ */
+typedef struct
+{
+    unsigned char nr;           /*!< The number of rounds (12, 14 or 16) */
+    /*! The ARIA round keys. */
+    uint32_t rk[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4];
+}
+mbedtls_aria_context;
+
+#else  /* MBEDTLS_ARIA_ALT */
+#include "aria_alt.h"
+#endif /* MBEDTLS_ARIA_ALT */
+
+/**
+ * \brief          This function initializes the specified ARIA context.
+ *
+ *                 It must be the first API called before using
+ *                 the context.
+ *
+ * \param ctx      The ARIA context to initialize.
+ */
+void mbedtls_aria_init( mbedtls_aria_context *ctx );
+
+/**
+ * \brief          This function releases and clears the specified ARIA context.
+ *
+ * \param ctx      The ARIA context to clear.
+ */
+void mbedtls_aria_free( mbedtls_aria_context *ctx );
+
+/**
+ * \brief          This function sets the encryption key.
+ *
+ * \param ctx      The ARIA context to which the key should be bound.
+ * \param key      The encryption key.
+ * \param keybits  The size of data passed in bits. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success or #MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH
+ *                 on failure.
+ */
+int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
+                             const unsigned char *key,
+                             unsigned int keybits );
+
+/**
+ * \brief          This function sets the decryption key.
+ *
+ * \param ctx      The ARIA context to which the key should be bound.
+ * \param key      The decryption key.
+ * \param keybits  The size of data passed. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success, or #MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
+                             const unsigned char *key,
+                             unsigned int keybits );
+
+/**
+ * \brief          This function performs an ARIA single-block encryption or
+ *                 decryption operation.
+ *
+ *                 It performs encryption or decryption (depending on whether
+ *                 the key was set for encryption on decryption) on the input
+ *                 data buffer defined in the \p input parameter.
+ *
+ *                 mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or
+ *                 mbedtls_aria_setkey_dec() must be called before the first
+ *                 call to this API with the same context.
+ *
+ * \param ctx      The ARIA context to use for encryption or decryption.
+ * \param input    The 16-Byte buffer holding the input data.
+ * \param output   The 16-Byte buffer holding the output data.
+
+ * \return         \c 0 on success.
+ */
+int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
+                            const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief  This function performs an ARIA-CBC encryption or decryption operation
+ *         on full blocks.
+ *
+ *         It performs the operation defined in the \p mode
+ *         parameter (encrypt/decrypt), on the input data buffer defined in
+ *         the \p input parameter.
+ *
+ *         It can be called as many times as needed, until all the input
+ *         data is processed. mbedtls_aria_init(), and either
+ *         mbedtls_aria_setkey_enc() or mbedtls_aria_setkey_dec() must be called
+ *         before the first call to this API with the same context.
+ *
+ * \note   This function operates on aligned blocks, that is, the input size
+ *         must be a multiple of the ARIA block size of 16 Bytes.
+ *
+ * \note   Upon exit, the content of the IV is updated so that you can
+ *         call the same function again on the next
+ *         block(s) of data and get the same result as if it was
+ *         encrypted in one call. This allows a "streaming" usage.
+ *         If you need to retain the contents of the IV, you should
+ *         either save it manually or use the cipher module instead.
+ *
+ *
+ * \param ctx      The ARIA context to use for encryption or decryption.
+ * \param mode     The ARIA operation: #MBEDTLS_ARIA_ENCRYPT or
+ *                 #MBEDTLS_ARIA_DECRYPT.
+ * \param length   The length of the input data in Bytes. This must be a
+ *                 multiple of the block size (16 Bytes).
+ * \param iv       Initialization vector (updated after use).
+ * \param input    The buffer holding the input data.
+ * \param output   The buffer holding the output data.
+ *
+ * \return         \c 0 on success, or #MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH
+ *                 on failure.
+ */
+int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
+                            int mode,
+                            size_t length,
+                            unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/**
+ * \brief This function performs an ARIA-CFB128 encryption or decryption
+ *        operation.
+ *
+ *        It performs the operation defined in the \p mode
+ *        parameter (encrypt or decrypt), on the input data buffer
+ *        defined in the \p input parameter.
+ *
+ *        For CFB, you must set up the context with mbedtls_aria_setkey_enc(),
+ *        regardless of whether you are performing an encryption or decryption
+ *        operation, that is, regardless of the \p mode parameter. This is
+ *        because CFB mode uses the same key schedule for encryption and
+ *        decryption.
+ *
+ * \note  Upon exit, the content of the IV is updated so that you can
+ *        call the same function again on the next
+ *        block(s) of data and get the same result as if it was
+ *        encrypted in one call. This allows a "streaming" usage.
+ *        If you need to retain the contents of the
+ *        IV, you must either save it manually or use the cipher
+ *        module instead.
+ *
+ *
+ * \param ctx      The ARIA context to use for encryption or decryption.
+ * \param mode     The ARIA operation: #MBEDTLS_ARIA_ENCRYPT or
+ *                 #MBEDTLS_ARIA_DECRYPT.
+ * \param length   The length of the input data.
+ * \param iv_off   The offset in IV (updated after use).
+ * \param iv       The initialization vector (updated after use).
+ * \param input    The buffer holding the input data.
+ * \param output   The buffer holding the output data.
+ *
+ * \return         \c 0 on success.
+ */
+int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
+                               int mode,
+                               size_t length,
+                               size_t *iv_off,
+                               unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                               const unsigned char *input,
+                               unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/**
+ * \brief      This function performs an ARIA-CTR encryption or decryption
+ *             operation.
+ *
+ *             This function performs the operation defined in the \p mode
+ *             parameter (encrypt/decrypt), on the input data buffer
+ *             defined in the \p input parameter.
+ *
+ *             Due to the nature of CTR, you must use the same key schedule
+ *             for both encryption and decryption operations. Therefore, you
+ *             must use the context initialized with mbedtls_aria_setkey_enc()
+ *             for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT.
+ *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**128
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first 12 bytes for the
+ *             per-message nonce, and the last 4 bytes for internal use. In that
+ *             case, before calling this function on a new message you need to
+ *             set the first 12 bytes of \p nonce_counter to your chosen nonce
+ *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ *             stream_block to be ignored). That way, you can encrypt at most
+ *             2**96 messages of up to 2**32 blocks each with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be unique.
+ *             The recommended way to ensure uniqueness is to use a message
+ *             counter. An alternative is to generate random nonces, but this
+ *             limits the number of messages that can be securely encrypted:
+ *             for example, with 96-bit random nonces, you should not encrypt
+ *             more than 2**32 messages with the same key.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that an ARIA block is 16 bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
+ *
+ * \param ctx              The ARIA context to use for encryption or decryption.
+ * \param length           The length of the input data.
+ * \param nc_off           The offset in the current \p stream_block, for
+ *                         resuming within the current cipher stream. The
+ *                         offset pointer should be 0 at the start of a stream.
+ * \param nonce_counter    The 128-bit nonce and counter.
+ * \param stream_block     The saved stream block for resuming. This is
+ *                         overwritten by the function.
+ * \param input            The buffer holding the input data.
+ * \param output           The buffer holding the output data.
+ *
+ * \return     \c 0 on success.
+ */
+int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
+                            size_t length,
+                            size_t *nc_off,
+                            unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine.
+ *
+ * \return         \c 0 on success, or \c 1 on failure.
+ */
+int mbedtls_aria_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aria.h */
diff --git a/include/mbedtls/blowfish.h b/include/mbedtls/blowfish.h
index c0ef5a0..985faa4 100644
--- a/include/mbedtls/blowfish.h
+++ b/include/mbedtls/blowfish.h
@@ -44,14 +44,14 @@
 #define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED                   -0x0017  /**< Blowfish hardware accelerator failed. */
 #define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH              -0x0018  /**< Invalid data input length. */
 
-#if !defined(MBEDTLS_BLOWFISH_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_BLOWFISH_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          Blowfish context structure
  */
@@ -62,6 +62,10 @@
 }
 mbedtls_blowfish_context;
 
+#else  /* MBEDTLS_BLOWFISH_ALT */
+#include "blowfish_alt.h"
+#endif /* MBEDTLS_BLOWFISH_ALT */
+
 /**
  * \brief          Initialize Blowfish context
  *
@@ -170,7 +174,46 @@
 /**
  * \brief               Blowfish-CTR buffer encryption/decryption
  *
- * Warning: You have to keep the maximum use of your counter in mind!
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**64
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first 4 bytes for the
+ *             per-message nonce, and the last 4 bytes for internal use. In that
+ *             case, before calling this function on a new message you need to
+ *             set the first 4 bytes of \p nonce_counter to your chosen nonce
+ *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ *             stream_block to be ignored). That way, you can encrypt at most
+ *             2**32 messages of up to 2**32 blocks each with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be unique.
+ *             The recommended way to ensure uniqueness is to use a message
+ *             counter.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that a Blowfish block is 8 bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
  *
  * \param ctx           Blowfish context
  * \param length        The length of the data
@@ -198,8 +241,4 @@
 }
 #endif
 
-#else  /* MBEDTLS_BLOWFISH_ALT */
-#include "blowfish_alt.h"
-#endif /* MBEDTLS_BLOWFISH_ALT */
-
 #endif /* blowfish.h */
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index 354c1cc..f4b2b56 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -521,7 +521,7 @@
         "swi   r3,   %2         \n\t"   \
         : "=m" (c), "=m" (d), "=m" (s)              \
         : "m" (s), "m" (d), "m" (c), "m" (b)        \
-        : "r3", "r4"  "r5", "r6", "r7", "r8",       \
+        : "r3", "r4", "r5", "r6", "r7", "r8",       \
           "r9", "r10", "r11", "r12", "r13"          \
     );
 
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index cf07629..7e4721a 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -40,14 +40,14 @@
 #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
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_CAMELLIA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          CAMELLIA context structure
  */
@@ -58,6 +58,10 @@
 }
 mbedtls_camellia_context;
 
+#else  /* MBEDTLS_CAMELLIA_ALT */
+#include "camellia_alt.h"
+#endif /* MBEDTLS_CAMELLIA_ALT */
+
 /**
  * \brief          Initialize CAMELLIA context
  *
@@ -183,12 +187,54 @@
 /**
  * \brief               CAMELLIA-CTR buffer encryption/decryption
  *
- * Warning: You have to keep the maximum use of your counter in mind!
- *
  * Note: Due to the nature of CTR you should use the same key schedule for
  * both encryption and decryption. So a context initialized with
  * mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and MBEDTLS_CAMELLIA_DECRYPT.
  *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**128
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first 12 bytes for the
+ *             per-message nonce, and the last 4 bytes for internal use. In that
+ *             case, before calling this function on a new message you need to
+ *             set the first 12 bytes of \p nonce_counter to your chosen nonce
+ *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ *             stream_block to be ignored). That way, you can encrypt at most
+ *             2**96 messages of up to 2**32 blocks each with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be unique.
+ *             The recommended way to ensure uniqueness is to use a message
+ *             counter. An alternative is to generate random nonces, but this
+ *             limits the number of messages that can be securely encrypted:
+ *             for example, with 96-bit random nonces, you should not encrypt
+ *             more than 2**32 messages with the same key.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that a CAMELLIA block is 16 bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
+ *
  * \param ctx           CAMELLIA context
  * \param length        The length of the data
  * \param nc_off        The offset in the current stream_block (for resuming
@@ -211,18 +257,6 @@
                        unsigned char *output );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_CAMELLIA_ALT */
-#include "camellia_alt.h"
-#endif /* MBEDTLS_CAMELLIA_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Checkup routine
  *
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index 630b7fd..5d727e7 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -1,8 +1,11 @@
 /**
  * \file ccm.h
  *
- * \brief CCM combines Counter mode encryption with CBC-MAC authentication
- *        for 128-bit block ciphers.
+ * \brief This file provides an API for the CCM authenticated encryption
+ *        mode for block ciphers.
+ *
+ * CCM combines Counter mode encryption with CBC-MAC authentication
+ * for 128-bit block ciphers.
  *
  * Input to CCM includes the following elements:
  * <ul><li>Payload - data that is both authenticated and encrypted.</li>
@@ -11,6 +14,18 @@
  * <li>Nonce - A unique value that is assigned to the payload and the
  * associated data.</li></ul>
  *
+ * Definition of CCM:
+ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
+ * RFC 3610 "Counter with CBC-MAC (CCM)"
+ *
+ * Related:
+ * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
+ *
+ * Definition of CCM*:
+ * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
+ * Integer representation is fixed most-significant-octet-first order and
+ * the representation of octets is most-significant-bit-first order. This is
+ * consistent with RFC 3610.
  */
 /*
  *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@@ -40,14 +55,15 @@
 #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
-//
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_CCM_ALT)
+// Regular implementation
+//
+
 /**
  * \brief    The CCM context-type definition. The CCM context is passed
  *           to the APIs called.
@@ -57,6 +73,10 @@
 }
 mbedtls_ccm_context;
 
+#else  /* MBEDTLS_CCM_ALT */
+#include "ccm_alt.h"
+#endif /* MBEDTLS_CCM_ALT */
+
 /**
  * \brief           This function initializes the specified CCM context,
  *                  to make references valid, and prepare the context
@@ -75,7 +95,8 @@
  * \param key       The encryption key.
  * \param keybits   The key size in bits. This must be acceptable by the cipher.
  *
- * \return          \c 0 on success, or a cipher-specific error code.
+ * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
  */
 int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
                         mbedtls_cipher_id_t cipher,
@@ -93,29 +114,73 @@
 /**
  * \brief           This function encrypts a buffer using CCM.
  *
+ * \note            The tag is written to a separate buffer. To concatenate
+ *                  the \p tag with the \p output, as done in <em>RFC-3610:
+ *                  Counter with CBC-MAC (CCM)</em>, use
+ *                  \p tag = \p output + \p length, and make sure that the
+ *                  output buffer is at least \p length + \p tag_len wide.
+ *
  * \param ctx       The CCM context to use for encryption.
  * \param length    The length of the input data in Bytes.
  * \param iv        Initialization vector (nonce).
- * \param iv_len    The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
  * \param add       The additional data field.
  * \param add_len   The length of additional data in Bytes.
  *                  Must be less than 2^16 - 2^8.
  * \param input     The buffer holding the input data.
  * \param output    The buffer holding the output data.
  *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the tag.
- * \param tag_len   The length of the tag to generate in Bytes:
+ * \param tag       The buffer holding the authentication field.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  4, 6, 8, 10, 12, 14 or 16.
  *
+ * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
+ */
+int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *add, size_t add_len,
+                         const unsigned char *input, unsigned char *output,
+                         unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief           This function encrypts a buffer using CCM*.
+ *
  * \note            The tag is written to a separate buffer. To concatenate
  *                  the \p tag with the \p output, as done in <em>RFC-3610:
  *                  Counter with CBC-MAC (CCM)</em>, use
  *                  \p tag = \p output + \p length, and make sure that the
  *                  output buffer is at least \p length + \p tag_len wide.
  *
+ * \note            When using this function in a variable tag length context,
+ *                  the tag length has to be encoded into the \p iv passed to
+ *                  this function.
+ *
+ * \param ctx       The CCM context to use for encryption.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        Initialization vector (nonce).
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field.
+ * \param add_len   The length of additional data in Bytes.
+ *                  Must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data.
+ * \param output    The buffer holding the output data.
+ *                  Must be at least \p length Bytes wide.
+ * \param tag       The buffer holding the authentication field.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
+ *                  0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning         Passing 0 as \p tag_len means that the message is no
+ *                  longer authenticated.
+ *
  * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
  */
-int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
                          const unsigned char *iv, size_t iv_len,
                          const unsigned char *add, size_t add_len,
                          const unsigned char *input, unsigned char *output,
@@ -127,20 +192,23 @@
  *
  * \param ctx       The CCM context to use for decryption.
  * \param length    The length of the input data in Bytes.
- * \param iv        Initialization vector.
- * \param iv_len    The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
+ * \param iv        Initialization vector (nonce).
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
  * \param add       The additional data field.
  * \param add_len   The length of additional data in Bytes.
  *                  Must be less than 2^16 - 2^8.
  * \param input     The buffer holding the input data.
  * \param output    The buffer holding the output data.
  *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the tag.
- * \param tag_len   The length of the tag in Bytes.
+ * \param tag       The buffer holding the authentication field.
+ * \param tag_len   The length of the authentication field in Bytes.
  *                  4, 6, 8, 10, 12, 14 or 16.
  *
- * \return          0 if successful and authenticated, or
- *                  #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return          \c 0 on success. This indicates that the message is authentic.
+ * \return          #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return          A cipher-specific error code on calculation failure.
  */
 int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                       const unsigned char *iv, size_t iv_len,
@@ -148,23 +216,50 @@
                       const unsigned char *input, unsigned char *output,
                       const unsigned char *tag, size_t tag_len );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_CCM_ALT */
-#include "ccm_alt.h"
-#endif /* MBEDTLS_CCM_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief           This function performs a CCM* authenticated decryption of a
+ *                  buffer.
+ *
+ * \note            When using this function in a variable tag length context,
+ *                  the tag length has to be decoded from \p iv and passed to
+ *                  this function as \p tag_len. (\p tag needs to be adjusted
+ *                  accordingly.)
+ *
+ * \param ctx       The CCM context to use for decryption.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        Initialization vector (nonce).
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field.
+ * \param add_len   The length of additional data in Bytes.
+ *                  Must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data.
+ * \param output    The buffer holding the output data.
+ *                  Must be at least \p length Bytes wide.
+ * \param tag       The buffer holding the authentication field.
+ * \param tag_len   The length of the authentication field in Bytes.
+ *                  0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning         Passing 0 as \p tag_len means that the message is no
+ *                  longer authenticated.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return          A cipher-specific error code on calculation failure.
+ */
+int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len );
 
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
 /**
  * \brief          The CCM checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_ccm_self_test( int verbose );
 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index be80332..4689f3a 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -4,7 +4,7 @@
  * \brief Consistency checks for configuration options
  */
 /*
- *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -191,6 +191,10 @@
 #error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_HKDF_C defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
 #error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
 #endif
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index d1f4efe..cde2fbd 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -1,7 +1,9 @@
 /**
  * \file cipher.h
  *
- * \brief The generic cipher wrapper.
+ * \brief This file contains an abstraction interface for use with the cipher
+ * primitives provided by the library. It provides a common interface to all of
+ * the available cipher operations.
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  */
@@ -69,93 +71,115 @@
 #endif
 
 /**
- * \brief     An enumeration of supported ciphers.
+ * \brief     Supported cipher types.
  *
- * \warning   ARC4 and DES are considered weak ciphers and their use
- *            constitutes a security risk. We recommend considering stronger
+ * \warning   RC4 and DES are considered weak ciphers and their use
+ *            constitutes a security risk. Arm recommends considering stronger
  *            ciphers instead.
  */
 typedef enum {
-    MBEDTLS_CIPHER_ID_NONE = 0,
-    MBEDTLS_CIPHER_ID_NULL,
-    MBEDTLS_CIPHER_ID_AES,
-    MBEDTLS_CIPHER_ID_DES,
-    MBEDTLS_CIPHER_ID_3DES,
-    MBEDTLS_CIPHER_ID_CAMELLIA,
-    MBEDTLS_CIPHER_ID_BLOWFISH,
-    MBEDTLS_CIPHER_ID_ARC4,
+    MBEDTLS_CIPHER_ID_NONE = 0,  /**< Placeholder to mark the end of cipher ID lists. */
+    MBEDTLS_CIPHER_ID_NULL,      /**< The identity cipher, treated as a stream cipher. */
+    MBEDTLS_CIPHER_ID_AES,       /**< The AES cipher. */
+    MBEDTLS_CIPHER_ID_DES,       /**< The DES cipher. */
+    MBEDTLS_CIPHER_ID_3DES,      /**< The Triple DES cipher. */
+    MBEDTLS_CIPHER_ID_CAMELLIA,  /**< The Camellia cipher. */
+    MBEDTLS_CIPHER_ID_BLOWFISH,  /**< The Blowfish cipher. */
+    MBEDTLS_CIPHER_ID_ARC4,      /**< The RC4 cipher. */
+    MBEDTLS_CIPHER_ID_ARIA,      /**< The Aria cipher. */
 } mbedtls_cipher_id_t;
 
 /**
- * \brief     An enumeration of supported (cipher, mode) pairs.
+ * \brief     Supported {cipher type, cipher mode} pairs.
  *
- * \warning   ARC4 and DES are considered weak ciphers and their use
- *            constitutes a security risk. We recommend considering stronger
+ * \warning   RC4 and DES are considered weak ciphers and their use
+ *            constitutes a security risk. Arm recommends considering stronger
  *            ciphers instead.
  */
 typedef enum {
-    MBEDTLS_CIPHER_NONE = 0,
-    MBEDTLS_CIPHER_NULL,
-    MBEDTLS_CIPHER_AES_128_ECB,
-    MBEDTLS_CIPHER_AES_192_ECB,
-    MBEDTLS_CIPHER_AES_256_ECB,
-    MBEDTLS_CIPHER_AES_128_CBC,
-    MBEDTLS_CIPHER_AES_192_CBC,
-    MBEDTLS_CIPHER_AES_256_CBC,
-    MBEDTLS_CIPHER_AES_128_CFB128,
-    MBEDTLS_CIPHER_AES_192_CFB128,
-    MBEDTLS_CIPHER_AES_256_CFB128,
-    MBEDTLS_CIPHER_AES_128_CTR,
-    MBEDTLS_CIPHER_AES_192_CTR,
-    MBEDTLS_CIPHER_AES_256_CTR,
-    MBEDTLS_CIPHER_AES_128_GCM,
-    MBEDTLS_CIPHER_AES_192_GCM,
-    MBEDTLS_CIPHER_AES_256_GCM,
-    MBEDTLS_CIPHER_CAMELLIA_128_ECB,
-    MBEDTLS_CIPHER_CAMELLIA_192_ECB,
-    MBEDTLS_CIPHER_CAMELLIA_256_ECB,
-    MBEDTLS_CIPHER_CAMELLIA_128_CBC,
-    MBEDTLS_CIPHER_CAMELLIA_192_CBC,
-    MBEDTLS_CIPHER_CAMELLIA_256_CBC,
-    MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
-    MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
-    MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
-    MBEDTLS_CIPHER_CAMELLIA_128_CTR,
-    MBEDTLS_CIPHER_CAMELLIA_192_CTR,
-    MBEDTLS_CIPHER_CAMELLIA_256_CTR,
-    MBEDTLS_CIPHER_CAMELLIA_128_GCM,
-    MBEDTLS_CIPHER_CAMELLIA_192_GCM,
-    MBEDTLS_CIPHER_CAMELLIA_256_GCM,
-    MBEDTLS_CIPHER_DES_ECB,
-    MBEDTLS_CIPHER_DES_CBC,
-    MBEDTLS_CIPHER_DES_EDE_ECB,
-    MBEDTLS_CIPHER_DES_EDE_CBC,
-    MBEDTLS_CIPHER_DES_EDE3_ECB,
-    MBEDTLS_CIPHER_DES_EDE3_CBC,
-    MBEDTLS_CIPHER_BLOWFISH_ECB,
-    MBEDTLS_CIPHER_BLOWFISH_CBC,
-    MBEDTLS_CIPHER_BLOWFISH_CFB64,
-    MBEDTLS_CIPHER_BLOWFISH_CTR,
-    MBEDTLS_CIPHER_ARC4_128,
-    MBEDTLS_CIPHER_AES_128_CCM,
-    MBEDTLS_CIPHER_AES_192_CCM,
-    MBEDTLS_CIPHER_AES_256_CCM,
-    MBEDTLS_CIPHER_CAMELLIA_128_CCM,
-    MBEDTLS_CIPHER_CAMELLIA_192_CCM,
-    MBEDTLS_CIPHER_CAMELLIA_256_CCM,
+    MBEDTLS_CIPHER_NONE = 0,             /**< Placeholder to mark the end of cipher-pair lists. */
+    MBEDTLS_CIPHER_NULL,                 /**< The identity stream cipher. */
+    MBEDTLS_CIPHER_AES_128_ECB,          /**< AES cipher with 128-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_192_ECB,          /**< AES cipher with 192-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_256_ECB,          /**< AES cipher with 256-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_128_CBC,          /**< AES cipher with 128-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_192_CBC,          /**< AES cipher with 192-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_256_CBC,          /**< AES cipher with 256-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_128_CFB128,       /**< AES cipher with 128-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_192_CFB128,       /**< AES cipher with 192-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_256_CFB128,       /**< AES cipher with 256-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_128_CTR,          /**< AES cipher with 128-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_192_CTR,          /**< AES cipher with 192-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_256_CTR,          /**< AES cipher with 256-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_128_GCM,          /**< AES cipher with 128-bit GCM mode. */
+    MBEDTLS_CIPHER_AES_192_GCM,          /**< AES cipher with 192-bit GCM mode. */
+    MBEDTLS_CIPHER_AES_256_GCM,          /**< AES cipher with 256-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_ECB,     /**< Camellia cipher with 128-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_ECB,     /**< Camellia cipher with 192-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_ECB,     /**< Camellia cipher with 256-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CBC,     /**< Camellia cipher with 128-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CBC,     /**< Camellia cipher with 192-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CBC,     /**< Camellia cipher with 256-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CFB128,  /**< Camellia cipher with 128-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CFB128,  /**< Camellia cipher with 192-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CFB128,  /**< Camellia cipher with 256-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CTR,     /**< Camellia cipher with 128-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CTR,     /**< Camellia cipher with 192-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CTR,     /**< Camellia cipher with 256-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_GCM,     /**< Camellia cipher with 128-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_GCM,     /**< Camellia cipher with 192-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_GCM,     /**< Camellia cipher with 256-bit GCM mode. */
+    MBEDTLS_CIPHER_DES_ECB,              /**< DES cipher with ECB mode. */
+    MBEDTLS_CIPHER_DES_CBC,              /**< DES cipher with CBC mode. */
+    MBEDTLS_CIPHER_DES_EDE_ECB,          /**< DES cipher with EDE ECB mode. */
+    MBEDTLS_CIPHER_DES_EDE_CBC,          /**< DES cipher with EDE CBC mode. */
+    MBEDTLS_CIPHER_DES_EDE3_ECB,         /**< DES cipher with EDE3 ECB mode. */
+    MBEDTLS_CIPHER_DES_EDE3_CBC,         /**< DES cipher with EDE3 CBC mode. */
+    MBEDTLS_CIPHER_BLOWFISH_ECB,         /**< Blowfish cipher with ECB mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CBC,         /**< Blowfish cipher with CBC mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CFB64,       /**< Blowfish cipher with CFB64 mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CTR,         /**< Blowfish cipher with CTR mode. */
+    MBEDTLS_CIPHER_ARC4_128,             /**< RC4 cipher with 128-bit mode. */
+    MBEDTLS_CIPHER_AES_128_CCM,          /**< AES cipher with 128-bit CCM mode. */
+    MBEDTLS_CIPHER_AES_192_CCM,          /**< AES cipher with 192-bit CCM mode. */
+    MBEDTLS_CIPHER_AES_256_CCM,          /**< AES cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CCM,     /**< Camellia cipher with 128-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CCM,     /**< Camellia cipher with 192-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CCM,     /**< Camellia cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_ARIA_128_ECB,         /**< Aria cipher with 128-bit key and ECB mode. */
+    MBEDTLS_CIPHER_ARIA_192_ECB,         /**< Aria cipher with 192-bit key and ECB mode. */
+    MBEDTLS_CIPHER_ARIA_256_ECB,         /**< Aria cipher with 256-bit key and ECB mode. */
+    MBEDTLS_CIPHER_ARIA_128_CBC,         /**< Aria cipher with 128-bit key and CBC mode. */
+    MBEDTLS_CIPHER_ARIA_192_CBC,         /**< Aria cipher with 192-bit key and CBC mode. */
+    MBEDTLS_CIPHER_ARIA_256_CBC,         /**< Aria cipher with 256-bit key and CBC mode. */
+    MBEDTLS_CIPHER_ARIA_128_CFB128,      /**< Aria cipher with 128-bit key and CFB-128 mode. */
+    MBEDTLS_CIPHER_ARIA_192_CFB128,      /**< Aria cipher with 192-bit key and CFB-128 mode. */
+    MBEDTLS_CIPHER_ARIA_256_CFB128,      /**< Aria cipher with 256-bit key and CFB-128 mode. */
+    MBEDTLS_CIPHER_ARIA_128_CTR,         /**< Aria cipher with 128-bit key and CTR mode. */
+    MBEDTLS_CIPHER_ARIA_192_CTR,         /**< Aria cipher with 192-bit key and CTR mode. */
+    MBEDTLS_CIPHER_ARIA_256_CTR,         /**< Aria cipher with 256-bit key and CTR mode. */
+    MBEDTLS_CIPHER_ARIA_128_GCM,         /**< Aria cipher with 128-bit key and GCM mode. */
+    MBEDTLS_CIPHER_ARIA_192_GCM,         /**< Aria cipher with 192-bit key and GCM mode. */
+    MBEDTLS_CIPHER_ARIA_256_GCM,         /**< Aria cipher with 256-bit key and GCM mode. */
+    MBEDTLS_CIPHER_ARIA_128_CCM,         /**< Aria cipher with 128-bit key and CCM mode. */
+    MBEDTLS_CIPHER_ARIA_192_CCM,         /**< Aria cipher with 192-bit key and CCM mode. */
+    MBEDTLS_CIPHER_ARIA_256_CCM,         /**< Aria cipher with 256-bit key and CCM mode. */
+    MBEDTLS_CIPHER_AES_128_OFB,          /**< AES 128-bit cipher in OFB mode. */
+    MBEDTLS_CIPHER_AES_192_OFB,          /**< AES 192-bit cipher in OFB mode. */
+    MBEDTLS_CIPHER_AES_256_OFB,          /**< AES 256-bit cipher in OFB mode. */
 } mbedtls_cipher_type_t;
 
 /** Supported cipher modes. */
 typedef enum {
-    MBEDTLS_MODE_NONE = 0,
-    MBEDTLS_MODE_ECB,
-    MBEDTLS_MODE_CBC,
-    MBEDTLS_MODE_CFB,
-    MBEDTLS_MODE_OFB, /* Unused! */
-    MBEDTLS_MODE_CTR,
-    MBEDTLS_MODE_GCM,
-    MBEDTLS_MODE_STREAM,
-    MBEDTLS_MODE_CCM,
+    MBEDTLS_MODE_NONE = 0,               /**< None. */
+    MBEDTLS_MODE_ECB,                    /**< The ECB cipher mode. */
+    MBEDTLS_MODE_CBC,                    /**< The CBC cipher mode. */
+    MBEDTLS_MODE_CFB,                    /**< The CFB cipher mode. */
+    MBEDTLS_MODE_OFB,                    /**< The OFB cipher mode. */
+    MBEDTLS_MODE_CTR,                    /**< The CTR cipher mode. */
+    MBEDTLS_MODE_GCM,                    /**< The GCM cipher mode. */
+    MBEDTLS_MODE_STREAM,                 /**< The stream cipher mode. */
+    MBEDTLS_MODE_CCM,                    /**< The CCM cipher mode. */
 } mbedtls_cipher_mode_t;
 
 /** Supported cipher padding types. */
@@ -163,8 +187,8 @@
     MBEDTLS_PADDING_PKCS7 = 0,     /**< PKCS7 padding (default).        */
     MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding.         */
     MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding.             */
-    MBEDTLS_PADDING_ZEROS,         /**< zero padding (not reversible). */
-    MBEDTLS_PADDING_NONE,          /**< never pad (full blocks only).   */
+    MBEDTLS_PADDING_ZEROS,         /**< Zero padding (not reversible). */
+    MBEDTLS_PADDING_NONE,          /**< Never pad (full blocks only).   */
 } mbedtls_cipher_padding_t;
 
 /** Type of operation. */
@@ -228,7 +252,10 @@
      */
     unsigned int iv_size;
 
-    /** Flags to set. For example, if the cipher supports variable IV sizes or variable key sizes. */
+    /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
+     *  MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
+     *  cipher supports variable IV or variable key sizes, respectively.
+     */
     int flags;
 
     /** The block size, in Bytes. */
@@ -299,7 +326,8 @@
  * \param cipher_name   Name of the cipher to search for.
  *
  * \return              The cipher information structure associated with the
- *                      given \p cipher_name, or NULL if not found.
+ *                      given \p cipher_name.
+ * \return              NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
 
@@ -310,7 +338,8 @@
  * \param cipher_type   Type of the cipher to search for.
  *
  * \return              The cipher information structure associated with the
- *                      given \p cipher_type, or NULL if not found.
+ *                      given \p cipher_type.
+ * \return              NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
 
@@ -325,7 +354,8 @@
  * \param mode          The cipher mode. For example, #MBEDTLS_MODE_CBC.
  *
  * \return              The cipher information structure associated with the
- *                      given \p cipher_id, or NULL if not found.
+ *                      given \p cipher_id.
+ * \return              NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
                                               int key_bitlen,
@@ -352,10 +382,11 @@
  * \param ctx           The context to initialize. May not be NULL.
  * \param cipher_info   The cipher to use.
  *
- * \return              \c 0 on success,
- *                      #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
- *                      #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
- *                      cipher-specific context failed.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
+ *                      cipher-specific context fails.
  *
  * \internal Currently, the function also clears the structure.
  * In future versions, the caller will be required to call
@@ -368,8 +399,8 @@
  *
  * \param ctx    The context of the cipher. Must be initialized.
  *
- * \return       The size of the blocks of the cipher, or zero if \p ctx
- *               has not been initialized.
+ * \return       The size of the blocks of the cipher.
+ * \return       0 if \p ctx has not been initialized.
  */
 static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
 {
@@ -385,8 +416,8 @@
  *
  * \param ctx    The context of the cipher. Must be initialized.
  *
- * \return       The mode of operation, or #MBEDTLS_MODE_NONE if
- *               \p ctx has not been initialized.
+ * \return       The mode of operation.
+ * \return       #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
  */
 static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx )
 {
@@ -402,9 +433,9 @@
  *
  * \param ctx   The context of the cipher. Must be initialized.
  *
- * \return      <ul><li>If no IV has been set: the recommended IV size.
- *              0 for ciphers not using IV or nonce.</li>
- *              <li>If IV has already been set: the actual size.</li></ul>
+ * \return      The recommended IV size if no IV has been set.
+ * \return      \c 0 for ciphers not using an IV or a nonce.
+ * \return      The actual size if an IV has been set.
  */
 static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx )
 {
@@ -422,8 +453,8 @@
  *
  * \param ctx           The context of the cipher. Must be initialized.
  *
- * \return              The type of the cipher, or #MBEDTLS_CIPHER_NONE if
- *                      \p ctx has not been initialized.
+ * \return              The type of the cipher.
+ * \return              #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
  */
 static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx )
 {
@@ -439,8 +470,8 @@
  *
  * \param ctx           The context of the cipher. Must be initialized.
  *
- * \return              The name of the cipher, or NULL if \p ctx has not
- *                      been not initialized.
+ * \return              The name of the cipher.
+ * \return              NULL if \p ctx has not been not initialized.
  */
 static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx )
 {
@@ -455,8 +486,8 @@
  *
  * \param ctx           The context of the cipher. Must be initialized.
  *
- * \return              The key length of the cipher in bits, or
- *                      #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
+ * \return              The key length of the cipher in bits.
+ * \return              #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
  *                      initialized.
  */
 static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx )
@@ -472,9 +503,8 @@
  *
  * \param ctx      The context of the cipher. Must be initialized.
  *
- * \return         The type of operation: #MBEDTLS_ENCRYPT or
- *                 #MBEDTLS_DECRYPT, or #MBEDTLS_OPERATION_NONE if \p ctx
- *                 has not been initialized.
+ * \return         The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
+ * \return         #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
  */
 static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx )
 {
@@ -495,9 +525,10 @@
  * \param operation     The operation that the key will be used for:
  *                      #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
  *
- * \returns             \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
- *                      parameter verification fails, or a cipher-specific
- *                      error code.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
                    int key_bitlen, const mbedtls_operation_t operation );
@@ -512,9 +543,10 @@
  * \param ctx           The generic cipher context.
  * \param mode          The padding mode.
  *
- * \returns             \c 0 on success, #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
- *                      if the selected padding mode is not supported, or
- *                      #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
+ *                      if the selected padding mode is not supported.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
  *                      does not support padding.
  */
 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode );
@@ -524,15 +556,17 @@
  * \brief           This function sets the initialization vector (IV)
  *                  or nonce.
  *
+ * \note            Some ciphers do not use IVs nor nonce. For these
+ *                  ciphers, this function has no effect.
+ *
  * \param ctx       The generic cipher context.
  * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
  * \param iv_len    The IV length for ciphers with variable-size IV.
  *                  This parameter is discarded by ciphers with fixed-size IV.
  *
- * \returns         \c 0 on success, or #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
- *
- * \note            Some ciphers do not use IVs nor nonce. For these
- *                  ciphers, this function has no effect.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                  parameter-verification failure.
  */
 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
                    const unsigned char *iv, size_t iv_len );
@@ -542,8 +576,9 @@
  *
  * \param ctx     The generic cipher context.
  *
- * \returns       \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
- *                if parameter verification fails.
+ * \return        \c 0 on success.
+ * \return        #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                parameter-verification failure.
  */
 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
 
@@ -557,7 +592,8 @@
  * \param ad            The additional data to use.
  * \param ad_len        the Length of \p ad.
  *
- * \return              \c 0 on success, or a specific error code on failure.
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
  */
 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
                       const unsigned char *ad, size_t ad_len );
@@ -573,6 +609,11 @@
  *                      Exception: For MBEDTLS_MODE_ECB, expects a single block
  *                      in size. For example, 16 Bytes for AES.
  *
+ * \note                If the underlying cipher is used in GCM mode, all calls
+ *                      to this function, except for the last one before
+ *                      mbedtls_cipher_finish(), must have \p ilen as a
+ *                      multiple of the block size of the cipher.
+ *
  * \param ctx           The generic cipher context.
  * \param input         The buffer holding the input data.
  * \param ilen          The length of the input data.
@@ -582,16 +623,12 @@
  * \param olen          The length of the output data, to be updated with the
  *                      actual number of Bytes written.
  *
- * \returns             \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
- *                      parameter verification fails,
- *                      #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
- *                      unsupported mode for a cipher, or a cipher-specific
- *                      error code.
- *
- * \note                If the underlying cipher is GCM, all calls to this
- *                      function, except the last one before
- *                      mbedtls_cipher_finish(). Must have \p ilen as a
- *                      multiple of the block_size.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
+ *                      unsupported mode for a cipher.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
                    size_t ilen, unsigned char *output, size_t *olen );
@@ -606,13 +643,14 @@
  * \param output        The buffer to write data to. Needs block_size available.
  * \param olen          The length of the data written to the \p output buffer.
  *
- * \returns             \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
- *                      parameter verification fails,
- *                      #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
- *                      expected a full block but was not provided one,
- *                      #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
- *                      while decrypting, or a cipher-specific error code
- *                      on failure for any other reason.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ *                      expecting a full block but not receiving one.
+ * \return              #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ *                      while decrypting.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
                    unsigned char *output, size_t *olen );
@@ -627,7 +665,8 @@
  * \param tag           The buffer to write the tag to.
  * \param tag_len       The length of the tag to write.
  *
- * \return              \c 0 on success, or a specific error code on failure.
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
  */
 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
                       unsigned char *tag, size_t tag_len );
@@ -641,7 +680,8 @@
  * \param tag           The buffer holding the tag.
  * \param tag_len       The length of the tag to check.
  *
- * \return              \c 0 on success, or a specific error code on failure.
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
  */
 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
                       const unsigned char *tag, size_t tag_len );
@@ -667,13 +707,14 @@
  * \note                Some ciphers do not use IVs nor nonce. For these
  *                      ciphers, use \p iv = NULL and \p iv_len = 0.
  *
- * \returns             \c 0 on success, or
- *                      #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
- *                      #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
- *                      expected a full block but was not provided one, or
- *                      #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
- *                      while decrypting, or a cipher-specific error code on
- *                      failure for any other reason.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ *                      expecting a full block but not receiving one.
+ * \return              #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ *                      while decrypting.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
                   const unsigned char *iv, size_t iv_len,
@@ -699,9 +740,10 @@
  * \param tag           The buffer for the authentication tag.
  * \param tag_len       The desired length of the authentication tag.
  *
- * \returns             \c 0 on success, or
- *                      #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
- *                      a cipher-specific error code.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
                          const unsigned char *iv, size_t iv_len,
@@ -713,6 +755,10 @@
 /**
  * \brief               The generic autenticated decryption (AEAD) function.
  *
+ * \note                If the data is not authentic, then the output buffer
+ *                      is zeroed out to prevent the unauthentic plaintext being
+ *                      used, making this interface safer.
+ *
  * \param ctx           The generic cipher context.
  * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
  * \param iv_len        The IV length for ciphers with variable-size IV.
@@ -728,14 +774,11 @@
  * \param tag           The buffer holding the authentication tag.
  * \param tag_len       The length of the authentication tag.
  *
- * \returns             \c 0 on success, or
- *                      #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
- *                      #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic,
- *                      or a cipher-specific error code on failure for any other reason.
- *
- * \note                If the data is not authentic, then the output buffer
- *                      is zeroed out to prevent the unauthentic plaintext being
- *                      used, making this interface safer.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
                          const unsigned char *iv, size_t iv_len,
diff --git a/include/mbedtls/cipher_internal.h b/include/mbedtls/cipher_internal.h
index 969ff9c..e02b7f1 100644
--- a/include/mbedtls/cipher_internal.h
+++ b/include/mbedtls/cipher_internal.h
@@ -64,6 +64,14 @@
                      unsigned char *output );
 #endif
 
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    /** Encrypt using OFB (Full length) */
+    int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
+                     unsigned char *iv,
+                     const unsigned char *input,
+                     unsigned char *output );
+#endif
+
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     /** Encrypt using CTR */
     int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
diff --git a/include/mbedtls/cmac.h b/include/mbedtls/cmac.h
index 628c9da..913c05f 100644
--- a/include/mbedtls/cmac.h
+++ b/include/mbedtls/cmac.h
@@ -1,8 +1,10 @@
 /**
  * \file cmac.h
  *
- * \brief The Cipher-based Message Authentication Code (CMAC) Mode for
- *        Authentication.
+ * \brief This file contains CMAC definitions and functions.
+ *
+ * The Cipher-based Message Authentication Code (CMAC) Mode for
+ * Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
  */
 /*
  *  Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
@@ -38,9 +40,9 @@
 #define MBEDTLS_DES3_BLOCK_SIZE         8
 
 #if defined(MBEDTLS_AES_C)
-#define MBEDTLS_CIPHER_BLKSIZE_MAX      16  /* The longest block used by CMAC is that of AES. */
+#define MBEDTLS_CIPHER_BLKSIZE_MAX      16  /**< The longest block used by CMAC is that of AES. */
 #else
-#define MBEDTLS_CIPHER_BLKSIZE_MAX      8   /* The longest block used by CMAC is that of 3DES. */
+#define MBEDTLS_CIPHER_BLKSIZE_MAX      8   /**< The longest block used by CMAC is that of 3DES. */
 #endif
 
 #if !defined(MBEDTLS_CMAC_ALT)
@@ -61,22 +63,25 @@
     size_t              unprocessed_len;
 };
 
+#else  /* !MBEDTLS_CMAC_ALT */
+#include "cmac_alt.h"
+#endif /* !MBEDTLS_CMAC_ALT */
+
 /**
  * \brief               This function sets the CMAC key, and prepares to authenticate
  *                      the input data.
  *                      Must be called with an initialized cipher context.
  *
  * \param ctx           The cipher context used for the CMAC operation, initialized
- *                      as one of the following types:<ul>
- *                      <li>MBEDTLS_CIPHER_AES_128_ECB</li>
- *                      <li>MBEDTLS_CIPHER_AES_192_ECB</li>
- *                      <li>MBEDTLS_CIPHER_AES_256_ECB</li>
- *                      <li>MBEDTLS_CIPHER_DES_EDE3_ECB</li></ul>
+ *                      as one of the following types: MBEDTLS_CIPHER_AES_128_ECB,
+ *                      MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
+ *                      or MBEDTLS_CIPHER_DES_EDE3_ECB.
  * \param key           The CMAC key.
  * \param keybits       The length of the CMAC key in bits.
  *                      Must be supported by the cipher.
  *
- * \return              \c 0 on success, or a cipher-specific error code.
+ * \return              \c 0 on success.
+ * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
                                 const unsigned char *key, size_t keybits );
@@ -93,8 +98,9 @@
  * \param input         The buffer holding the input data.
  * \param ilen          The length of the input data.
  *
- * \returns             \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
- *                      if parameter verification fails.
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                     if parameter verification fails.
  */
 int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
                                 const unsigned char *input, size_t ilen );
@@ -110,7 +116,8 @@
  * \param ctx           The cipher context used for the CMAC operation.
  * \param output        The output buffer for the CMAC checksum result.
  *
- * \returns             \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
  *                      if parameter verification fails.
  */
 int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
@@ -126,7 +133,8 @@
  *
  * \param ctx           The cipher context used for the CMAC operation.
  *
- * \returns             \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
  *                      if parameter verification fails.
  */
 int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
@@ -149,7 +157,8 @@
  * \param ilen          The length of the input data.
  * \param output        The buffer for the generic CMAC result.
  *
- * \returns             \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
  *                      if parameter verification fails.
  */
 int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
@@ -180,23 +189,12 @@
                               unsigned char output[16] );
 #endif /* MBEDTLS_AES_C */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* !MBEDTLS_CMAC_ALT */
-#include "cmac_alt.h"
-#endif /* !MBEDTLS_CMAC_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
 /**
  * \brief          The CMAC checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_cmac_self_test( int verbose );
 #endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 9585e69..709f6cf 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -8,7 +8,7 @@
  *  memory footprint.
  */
 /*
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -48,10 +48,14 @@
  * Requires support for asm() in compiler.
  *
  * Used in:
+ *      library/aria.c
  *      library/timing.c
- *      library/padlock.c
  *      include/mbedtls/bn_mul.h
  *
+ * Required by:
+ *      MBEDTLS_AESNI_C
+ *      MBEDTLS_PADLOCK_C
+ *
  * Comment to disable the use of assembly code.
  */
 #define MBEDTLS_HAVE_ASM
@@ -271,6 +275,7 @@
  */
 //#define MBEDTLS_AES_ALT
 //#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_ARIA_ALT
 //#define MBEDTLS_BLOWFISH_ALT
 //#define MBEDTLS_CAMELLIA_ALT
 //#define MBEDTLS_CCM_ALT
@@ -288,6 +293,7 @@
 //#define MBEDTLS_SHA256_ALT
 //#define MBEDTLS_SHA512_ALT
 //#define MBEDTLS_XTEA_ALT
+
 /*
  * When replacing the elliptic curve module, pleace consider, that it is
  * implemented with two .c files:
@@ -496,6 +502,13 @@
 #define MBEDTLS_CIPHER_MODE_CBC
 
 /**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback mode (OFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
  * \def MBEDTLS_CIPHER_MODE_CFB
  *
  * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
@@ -1617,7 +1630,7 @@
  * Enable the AES block cipher.
  *
  * Module:  library/aes.c
- * Caller:  library/ssl_tls.c
+ * Caller:  library/cipher.c
  *          library/pem.c
  *          library/ctr_drbg.c
  *
@@ -1692,7 +1705,7 @@
  * Enable the ARCFOUR stream cipher.
  *
  * Module:  library/arc4.c
- * Caller:  library/ssl_tls.c
+ * Caller:  library/cipher.c
  *
  * This module enables the following ciphersuites (if other requisites are
  * enabled as well):
@@ -1786,7 +1799,7 @@
  * Enable the Camellia block cipher.
  *
  * Module:  library/camellia.c
- * Caller:  library/ssl_tls.c
+ * Caller:  library/cipher.c
  *
  * This module enables the following ciphersuites (if other requisites are
  * enabled as well):
@@ -1836,6 +1849,58 @@
 #define MBEDTLS_CAMELLIA_C
 
 /**
+ * \def MBEDTLS_ARIA_C
+ *
+ * Enable the ARIA block cipher.
+ *
+ * Module:  library/aria.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
+ */
+//#define MBEDTLS_ARIA_C
+
+/**
  * \def MBEDTLS_CCM_C
  *
  * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
@@ -1921,7 +1986,7 @@
  *
  * Module:  library/des.c
  * Caller:  library/pem.c
- *          library/ssl_tls.c
+ *          library/cipher.c
  *
  * This module enables the following ciphersuites (if other requisites are
  * enabled as well):
@@ -2092,6 +2157,21 @@
 //#define MBEDTLS_HAVEGE_C
 
 /**
+ * \def MBEDTLS_HKDF_C
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Module:  library/hkdf.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the Hashed Message Authentication Code
+ * (HMAC)-based key derivation function (HKDF).
+ */
+#define MBEDTLS_HKDF_C
+
+/**
  * \def MBEDTLS_HMAC_DRBG_C
  *
  * Enable the HMAC_DRBG random generator.
@@ -2852,6 +2932,26 @@
  */
 #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
 
+/**
+ * Uncomment the macro to let mbed TLS use your alternate implementation of
+ * mbedtls_platform_zeroize(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * mbedtls_platform_zeroize() is a widely used function across the library to
+ * zero a block of memory. The implementation is expected to be secure in the
+ * sense that it has been written to prevent the compiler from removing calls
+ * to mbedtls_platform_zeroize() as part of redundant code elimination
+ * optimizations. However, it is difficult to guarantee that calls to
+ * mbedtls_platform_zeroize() will not be optimized by the compiler as older
+ * versions of the C language standards do not provide a secure implementation
+ * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to
+ * configure their own implementation of mbedtls_platform_zeroize(), for
+ * example by using directives specific to their compiler, features from newer
+ * C standards (e.g using memset_s() in C11) or calling a secure memset() from
+ * their system (e.g explicit_bzero() in BSD).
+ */
+//#define MBEDTLS_PLATFORM_ZEROIZE_ALT
+
 /* \} name SECTION: Customisation configuration options */
 
 /* Target and application specific configurations */
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 121575a..dcbc047 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -1,10 +1,15 @@
 /**
  * \file ctr_drbg.h
  *
- * \brief    CTR_DRBG is based on AES-256, as defined in <em>NIST SP 800-90A:
- *           Recommendation for Random Number Generation Using Deterministic
- *           Random Bit Generators</em>.
+ * \brief    This file contains CTR_DRBG definitions and functions.
  *
+ * CTR_DRBG is a standardized way of building a PRNG from a block-cipher
+ * in counter mode operation, as defined in <em>NIST SP 800-90A:
+ * Recommendation for Random Number Generation Using Deterministic Random
+ * Bit Generators</em>.
+ *
+ * The Mbed TLS implementation of CTR_DRBG uses AES-256 as the underlying
+ * block cipher.
  */
 /*
  *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@@ -156,8 +161,8 @@
                         identifiers. Can be NULL.
  * \param len           The length of the personalization data.
  *
- * \return              \c 0 on success, or
- *                      #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
  */
 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
                    int (*f_entropy)(void *, unsigned char *, size_t),
@@ -216,22 +221,24 @@
  * \param additional    Additional data to add to the state. Can be NULL.
  * \param len           The length of the additional data.
  *
- * \return   \c 0 on success, or
- *           #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
  */
 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
                      const unsigned char *additional, size_t len );
 
 /**
- * \brief               This function updates the state of the CTR_DRBG context.
+ * \brief              This function updates the state of the CTR_DRBG context.
  *
- * \param ctx           The CTR_DRBG context.
- * \param additional    The data to update the state with.
- * \param add_len       Length of \p additional data.
+ * \note               If \p add_len is greater than
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
+ *                     The remaining Bytes are silently discarded.
  *
- * \note     If \p add_len is greater than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT,
- *           only the first #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
- *           The remaining Bytes are silently discarded.
+ * \param ctx          The CTR_DRBG context.
+ * \param additional   The data to update the state with.
+ * \param add_len      Length of \p additional data.
+ *
  */
 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
                       const unsigned char *additional, size_t add_len );
@@ -249,8 +256,8 @@
  * \param additional    Additional data to update. Can be NULL.
  * \param add_len       The length of the additional data.
  *
- * \return    \c 0 on success, or
- *            #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * \return    \c 0 on success.
+ * \return    #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
  *            #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
  */
 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
@@ -267,8 +274,8 @@
  * \param output        The buffer to fill.
  * \param output_len    The length of the buffer.
  *
- * \return              \c 0 on success, or
- *                      #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
  *                      #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
  */
 int mbedtls_ctr_drbg_random( void *p_rng,
@@ -281,9 +288,9 @@
  * \param ctx           The CTR_DRBG context.
  * \param path          The name of the file.
  *
- * \return              \c 0 on success,
- *                      #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or
- *                      #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
  *                      failure.
  */
 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
@@ -295,9 +302,9 @@
  * \param ctx           The CTR_DRBG context.
  * \param path          The name of the file.
  *
- * \return              \c 0 on success,
- *                      #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error,
- *                      #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
  *                      #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
  */
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
@@ -306,7 +313,8 @@
 /**
  * \brief               The CTR_DRBG checkup routine.
  *
- * \return              \c 0 on success, or \c 1 on failure.
+ * \return              \c 0 on success.
+ * \return              \c 1 on failure.
  */
 int mbedtls_ctr_drbg_self_test( int verbose );
 
diff --git a/include/mbedtls/des.h b/include/mbedtls/des.h
index 5a1a636..6eb7d03 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -46,14 +46,14 @@
 
 #define MBEDTLS_DES_KEY_SIZE    8
 
-#if !defined(MBEDTLS_DES_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_DES_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          DES context structure
  *
@@ -76,6 +76,10 @@
 }
 mbedtls_des3_context;
 
+#else  /* MBEDTLS_DES_ALT */
+#include "des_alt.h"
+#endif /* MBEDTLS_DES_ALT */
+
 /**
  * \brief          Initialize DES context
  *
@@ -331,17 +335,6 @@
  */
 void mbedtls_des_setkey( uint32_t SK[32],
                          const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_DES_ALT */
-#include "des_alt.h"
-#endif /* MBEDTLS_DES_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
 
 /**
  * \brief          Checkup routine
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index 00fafd8..75317a8 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -1,7 +1,13 @@
 /**
  * \file dhm.h
  *
- * \brief Diffie-Hellman-Merkle key exchange.
+ * \brief   This file contains Diffie-Hellman-Merkle (DHM) key exchange
+ *          definitions and functions.
+ *
+ * Diffie-Hellman-Merkle (DHM) key exchange is defined in
+ * <em>RFC-2631: Diffie-Hellman Key Agreement Method</em> and
+ * <em>Public-Key Cryptography Standards (PKCS) #3: Diffie
+ * Hellman Key Agreement Standard</em>.
  *
  * <em>RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for
  * Internet Key Exchange (IKE)</em> defines a number of standardized
@@ -65,7 +71,6 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 #include "bignum.h"
-#if !defined(MBEDTLS_DHM_ALT)
 
 /*
  * DHM Error codes
@@ -86,6 +91,8 @@
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_DHM_ALT)
+
 /**
  * \brief          The DHM context structure.
  */
@@ -105,6 +112,10 @@
 }
 mbedtls_dhm_context;
 
+#else /* MBEDTLS_DHM_ALT */
+#include "dhm_alt.h"
+#endif /* MBEDTLS_DHM_ALT */
+
 /**
  * \brief          This function initializes the DHM context.
  *
@@ -125,8 +136,8 @@
  *                 failures.
  * \param end      The end of the input buffer.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
                      unsigned char **p,
@@ -136,13 +147,6 @@
  * \brief          This function sets up and writes the ServerKeyExchange
  *                 parameters.
  *
- * \param ctx      The DHM context.
- * \param x_size   The private value size in Bytes.
- * \param olen     The number of characters written.
- * \param output   The destination buffer.
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG parameter.
- *
  * \note           The destination buffer must be large enough to hold
  *                 the reduced binary presentation of the modulus, the generator
  *                 and the public key, each wrapped with a 2-byte length field.
@@ -155,8 +159,15 @@
  *                 mbedtls_dhm_set_group() below in conjunction with
  *                 mbedtls_mpi_read_binary() and mbedtls_mpi_read_string().
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \param ctx      The DHM context.
+ * \param x_size   The private key size in Bytes.
+ * \param olen     The number of characters written.
+ * \param output   The destination buffer.
+ * \param f_rng    The RNG function.
+ * \param p_rng    The RNG context.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
                      unsigned char *output, size_t *olen,
@@ -164,54 +175,54 @@
                      void *p_rng );
 
 /**
- * \brief          Set prime modulus and generator
+ * \brief          This function sets the prime modulus and generator.
+ *
+ * \note           This function can be used to set \p P, \p G
+ *                 in preparation for mbedtls_dhm_make_params().
  *
  * \param ctx      The DHM context.
- * \param P        The MPI holding DHM prime modulus.
- * \param G        The MPI holding DHM generator.
+ * \param P        The MPI holding the DHM prime modulus.
+ * \param G        The MPI holding the DHM generator.
  *
- * \note           This function can be used to set P, G
- *                 in preparation for \c mbedtls_dhm_make_params.
- *
- * \return         \c 0 if successful, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \return         \c 0 if successful.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
                            const mbedtls_mpi *P,
                            const mbedtls_mpi *G );
 
 /**
- * \brief          This function imports the public value G^Y of the peer.
+ * \brief          This function imports the public value of the peer, G^Y.
  *
  * \param ctx      The DHM context.
- * \param input    The input buffer.
+ * \param input    The input buffer containing the G^Y value of the peer.
  * \param ilen     The size of the input buffer.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
                      const unsigned char *input, size_t ilen );
 
 /**
- * \brief          This function creates its own private value \c X and
+ * \brief          This function creates its own private key, \c X, and
  *                 exports \c G^X.
  *
+ * \note           The destination buffer is always fully written
+ *                 so as to contain a big-endian representation of G^X mod P.
+ *                 If it is larger than ctx->len, it is padded accordingly
+ *                 with zero-bytes at the beginning.
+ *
  * \param ctx      The DHM context.
- * \param x_size   The private value size in Bytes.
+ * \param x_size   The private key size in Bytes.
  * \param output   The destination buffer.
  * \param olen     The length of the destination buffer. Must be at least
-                   equal to ctx->len (the size of \c P).
+ *                  equal to ctx->len (the size of \c P).
  * \param f_rng    The RNG function.
- * \param p_rng    The RNG parameter.
+ * \param p_rng    The RNG context.
  *
- * \note           The destination buffer will always be fully written
- *                 so as to contain a big-endian presentation of G^X mod P.
- *                 If it is larger than ctx->len, it will accordingly be
- *                 padded with zero-bytes in the beginning.
- *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
                      unsigned char *output, size_t olen,
@@ -222,22 +233,22 @@
  * \brief               This function derives and exports the shared secret
  *                      \c (G^Y)^X mod \c P.
  *
+ * \note                If \p f_rng is not NULL, it is used to blind the input as
+ *                      a countermeasure against timing attacks. Blinding is used
+ *                      only if our private key \c X is re-used, and not used
+ *                      otherwise. We recommend always passing a non-NULL
+ *                      \p f_rng argument.
+ *
  * \param ctx           The DHM context.
  * \param output        The destination buffer.
  * \param output_size   The size of the destination buffer. Must be at least
- *                      the size of ctx->len.
+ *                      the size of ctx->len (the size of \c P).
  * \param olen          On exit, holds the actual number of Bytes written.
  * \param f_rng         The RNG function, for blinding purposes.
- * \param p_rng         The RNG parameter.
+ * \param p_rng         The RNG context.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
- *
- * \note           If non-NULL, \p f_rng is used to blind the input as
- *                 a countermeasure against timing attacks. Blinding is used
- *                 only if our secret value \p X is re-used and omitted
- *                 otherwise. Therefore, we recommend always passing a
- *                 non-NULL \p f_rng argument.
+ * \return              \c 0 on success.
+ * \return              An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
                      unsigned char *output, size_t output_size, size_t *olen,
@@ -245,7 +256,7 @@
                      void *p_rng );
 
 /**
- * \brief          This function frees and clears the components of a DHM key.
+ * \brief          This function frees and clears the components of a DHM context.
  *
  * \param ctx      The DHM context to free and clear.
  */
@@ -261,8 +272,9 @@
  * \param dhminlen    The size of the buffer, including the terminating null
  *                    Byte for PEM data.
  *
- * \return            \c 0 on success, or a specific DHM or PEM error code
- *                    on failure.
+ * \return            \c 0 on success.
+ * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error code
+ *                    error code on failure.
  */
 int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
                    size_t dhminlen );
@@ -275,29 +287,19 @@
  * \param dhm      The DHM context to load the parameters to.
  * \param path     The filename to read the DHM parameters from.
  *
- * \return         \c 0 on success, or a specific DHM or PEM error code
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error code
+ *                    error code on failure.
  */
 int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path );
 #endif /* MBEDTLS_FS_IO */
 #endif /* MBEDTLS_ASN1_PARSE_C */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else /* MBEDTLS_DHM_ALT */
-#include "dhm_alt.h"
-#endif /* MBEDTLS_DHM_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          The DMH checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_dhm_self_test( int verbose );
 
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 99cfde0..5fdf55a 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -1,10 +1,11 @@
 /**
  * \file ecdh.h
  *
- * \brief The Elliptic Curve Diffie-Hellman (ECDH) protocol APIs.
+ * \brief This file contains ECDH definitions and functions.
  *
- * ECDH is an anonymous key agreement protocol allowing two parties to
- * establish a shared secret over an insecure channel. Each party must have an
+ * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous
+ * key agreement protocol allowing two parties to establish a shared
+ * secret over an insecure channel. Each party must have an
  * elliptic-curve public–private key pair.
  *
  * For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
@@ -40,14 +41,12 @@
 #endif
 
 /**
- * Defines the source of the imported EC key:
- * <ul><li>Our key.</li>
- * <li>The key of the peer.</li></ul>
+ * Defines the source of the imported EC key.
  */
 typedef enum
 {
-    MBEDTLS_ECDH_OURS,
-    MBEDTLS_ECDH_THEIRS,
+    MBEDTLS_ECDH_OURS,   /**< Our key. */
+    MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
 } mbedtls_ecdh_side;
 
 /**
@@ -75,16 +74,18 @@
  *                  implemented during the ECDH key exchange. The second core
  *                  computation is performed by mbedtls_ecdh_compute_shared().
  *
+ * \see             ecp.h
+ *
  * \param grp       The ECP group.
  * \param d         The destination MPI (private key).
  * \param Q         The destination point (public key).
  * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \param p_rng     The RNG context.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or
  *                  \c MBEDTLS_MPI_XXX error code on failure.
  *
- * \see             ecp.h
  */
 int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
                      int (*f_rng)(void *, unsigned char *, size_t),
@@ -97,21 +98,22 @@
  *                  implemented during the ECDH key exchange. The first core
  *                  computation is performed by mbedtls_ecdh_gen_public().
  *
+ * \see             ecp.h
+ *
+ * \note            If \p f_rng is not NULL, it is used to implement
+ *                  countermeasures against side-channel attacks.
+ *                  For more information, see mbedtls_ecp_mul().
+ *
  * \param grp       The ECP group.
  * \param z         The destination MPI (shared secret).
  * \param Q         The public key from another party.
  * \param d         Our secret exponent (private key).
  * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \param p_rng     The RNG context.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or
  *                  \c MBEDTLS_MPI_XXX error code on failure.
- *
- * \see             ecp.h
- *
- * \note            If \p f_rng is not NULL, it is used to implement
- *                  countermeasures against potential elaborate timing
- *                  attacks. For more information, see mbedtls_ecp_mul().
  */
 int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
                          const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
@@ -139,21 +141,21 @@
  *                  This is the first function used by a TLS server for ECDHE
  *                  ciphersuites.
  *
+ * \note            This function assumes that the ECP group (grp) of the
+ *                  \p ctx context has already been properly set,
+ *                  for example, using mbedtls_ecp_group_load().
+ *
+ * \see             ecp.h
+ *
  * \param ctx       The ECDH context.
  * \param olen      The number of characters written.
  * \param buf       The destination buffer.
  * \param blen      The length of the destination buffer.
  * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \param p_rng     The RNG context.
  *
- * \note            This function assumes that the ECP group (grp) of the
- *                  \p ctx context has already been properly set,
- *                  for example, using mbedtls_ecp_group_load().
- *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
- *
- * \see             ecp.h
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
                       unsigned char *buf, size_t blen,
@@ -167,14 +169,15 @@
  *                  This is the first function used by a TLS client for ECDHE
  *                  ciphersuites.
  *
+ * \see             ecp.h
+ *
  * \param ctx       The ECDH context.
  * \param buf       The pointer to the start of the input buffer.
  * \param end       The address for one Byte past the end of the buffer.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  *
- * \see             ecp.h
  */
 int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
                       const unsigned char **buf, const unsigned char *end );
@@ -186,16 +189,16 @@
  *                  ServerKeyEchange for static ECDH, and imports ECDH
  *                  parameters from the EC key information of a certificate.
  *
+ * \see             ecp.h
+ *
  * \param ctx       The ECDH context to set up.
  * \param key       The EC key to use.
- * \param side      Defines the source of the key:
- *                  <ul><li>1: Our key.</li>
-                    <li>0: The key of the peer.</li></ul>
+ * \param side      Defines the source of the key: 1: Our key, or
+ *                  0: The key of the peer.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  *
- * \see             ecp.h
  */
 int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
                      mbedtls_ecdh_side side );
@@ -207,17 +210,17 @@
  *                  This is the second function used by a TLS client for ECDH(E)
  *                  ciphersuites.
  *
+ * \see             ecp.h
+ *
  * \param ctx       The ECDH context.
  * \param olen      The number of Bytes written.
  * \param buf       The destination buffer.
  * \param blen      The size of the destination buffer.
  * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \param p_rng     The RNG context.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
- *
- * \see             ecp.h
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
                       unsigned char *buf, size_t blen,
@@ -231,14 +234,14 @@
  *              This is the second function used by a TLS server for ECDH(E)
  *              ciphersuites.
  *
+ * \see         ecp.h
+ *
  * \param ctx   The ECDH context.
  * \param buf   The start of the input buffer.
  * \param blen  The length of the input buffer.
  *
- * \return      \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *              on failure.
- *
- * \see         ecp.h
+ * \return      \c 0 on success.
+ * \return      An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
                       const unsigned char *buf, size_t blen );
@@ -249,21 +252,21 @@
  *                  This is the last function used by both TLS client
  *                  and servers.
  *
+ * \note            If \p f_rng is not NULL, it is used to implement
+ *                  countermeasures against side-channel attacks.
+ *                  For more information, see mbedtls_ecp_mul().
+ *
+ * \see             ecp.h
+ *
  * \param ctx       The ECDH context.
  * \param olen      The number of Bytes written.
  * \param buf       The destination buffer.
  * \param blen      The length of the destination buffer.
  * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \param p_rng     The RNG context.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
- *
- * \see             ecp.h
- *
- * \note            If \p f_rng is not NULL, it is used to implement
- *                  countermeasures against potential elaborate timing
- *                  attacks. For more information, see mbedtls_ecp_mul().
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
  */
 int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
                       unsigned char *buf, size_t blen,
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index ff6efbc..ce1a03d 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -1,9 +1,10 @@
 /**
  * \file ecdsa.h
  *
- * \brief The Elliptic Curve Digital Signature Algorithm (ECDSA).
+ * \brief This file contains ECDSA definitions and functions.
  *
- * ECDSA is defined in <em>Standards for Efficient Cryptography Group (SECG):
+ * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG):
  * SEC1 Elliptic Curve Cryptography</em>.
  * The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
  * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
@@ -69,6 +70,14 @@
  *
  * \note            The deterministic version is usually preferred.
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated
+ *                  as defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
  * \param grp       The ECP group.
  * \param r         The first output integer.
  * \param s         The second output integer.
@@ -76,18 +85,11 @@
  * \param buf       The message hash.
  * \param blen      The length of \p buf.
  * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \param p_rng     The RNG context.
  *
- * \note            If the bitlength of the message hash is larger than the
- *                  bitlength of the group order, then the hash is truncated
- *                  as defined in <em>Standards for Efficient Cryptography Group
- *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
- *                  4.1.3, step 5.
- *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX
  *                  or \c MBEDTLS_MPI_XXX error code on failure.
- *
- * \see             ecp.h
  */
 int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
@@ -97,10 +99,19 @@
 /**
  * \brief           This function computes the ECDSA signature of a
  *                  previously-hashed message, deterministic version.
+ *
  *                  For more information, see <em>RFC-6979: Deterministic
  *                  Usage of the Digital Signature Algorithm (DSA) and Elliptic
  *                  Curve Digital Signature Algorithm (ECDSA)</em>.
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
  * \param grp       The ECP group.
  * \param r         The first output integer.
  * \param s         The second output integer.
@@ -109,17 +120,9 @@
  * \param blen      The length of \p buf.
  * \param md_alg    The MD algorithm used to hash the message.
  *
- * \note            If the bitlength of the message hash is larger than the
- *                  bitlength of the group order, then the hash is truncated as
- *                  defined in <em>Standards for Efficient Cryptography Group
- *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
- *                  4.1.3, step 5.
- *
- * \return          \c 0 on success,
- *                  or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
  *                  error code on failure.
- *
- * \see             ecp.h
  */
 int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
                     const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
@@ -130,6 +133,14 @@
  * \brief           This function verifies the ECDSA signature of a
  *                  previously-hashed message.
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.4, step 3.
+ *
+ * \see             ecp.h
+ *
  * \param grp       The ECP group.
  * \param buf       The message hash.
  * \param blen      The length of \p buf.
@@ -137,18 +148,11 @@
  * \param r         The first integer of the signature.
  * \param s         The second integer of the signature.
  *
- * \note            If the bitlength of the message hash is larger than the
- *                  bitlength of the group order, then the hash is truncated as
- *                  defined in <em>Standards for Efficient Cryptography Group
- *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
- *                  4.1.4, step 3.
- *
- * \return          \c 0 on success,
- *                  #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
- *                  or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
+ *                  is invalid.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
  *                  error code on failure for any other reason.
- *
- * \see             ecp.h
  */
 int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
                   const unsigned char *buf, size_t blen,
@@ -169,15 +173,6 @@
  *                  of the Digital Signature Algorithm (DSA) and Elliptic
  *                  Curve Digital Signature Algorithm (ECDSA)</em>.
  *
- * \param ctx       The ECDSA context.
- * \param md_alg    The message digest that was used to hash the message.
- * \param hash      The message hash.
- * \param hlen      The length of the hash.
- * \param sig       The buffer that holds the signature.
- * \param slen      The length of the signature written.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
- *
  * \note            The \p sig buffer must be at least twice as large as the
  *                  size of the curve used, plus 9. For example, 73 Bytes if
  *                  a 256-bit curve is used. A buffer length of
@@ -189,11 +184,20 @@
  *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
  *                  4.1.3, step 5.
  *
- * \return          \c 0 on success,
- *                  or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
- *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
- *
  * \see             ecp.h
+ *
+ * \param ctx       The ECDSA context.
+ * \param md_alg    The message digest that was used to hash the message.
+ * \param hash      The message hash.
+ * \param hlen      The length of the hash.
+ * \param sig       The buffer that holds the signature.
+ * \param slen      The length of the signature written.
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
+ *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
 int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
                            const unsigned char *hash, size_t hlen,
@@ -209,26 +213,17 @@
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief   This function computes an ECDSA signature and writes it to a buffer,
- *          serialized as defined in <em>RFC-4492: Elliptic Curve Cryptography
- *          (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
+ * \brief           This function computes an ECDSA signature and writes
+ *                  it to a buffer, serialized as defined in <em>RFC-4492:
+ *                  Elliptic Curve Cryptography (ECC) Cipher Suites for
+ *                  Transport Layer Security (TLS)</em>.
  *
- *          The deterministic version is defined in <em>RFC-6979:
- *          Deterministic Usage of the Digital Signature Algorithm (DSA) and
- *          Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
+ *                  The deterministic version is defined in <em>RFC-6979:
+ *                  Deterministic Usage of the Digital Signature Algorithm (DSA)
+ *                  and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
  *
  * \warning         It is not thread-safe to use the same context in
  *                  multiple threads.
-
- *
- * \deprecated      Superseded by mbedtls_ecdsa_write_signature() in 2.0.0
- *
- * \param ctx       The ECDSA context.
- * \param hash      The Message hash.
- * \param hlen      The length of the hash.
- * \param sig       The buffer that holds the signature.
- * \param slen      The length of the signature written.
- * \param md_alg    The MD algorithm used to hash the message.
  *
  * \note            The \p sig buffer must be at least twice as large as the
  *                  size of the curve used, plus 9. For example, 73 Bytes if a
@@ -241,11 +236,21 @@
  *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
  *                  4.1.3, step 5.
  *
- * \return          \c 0 on success,
- *                  or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
- *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
- *
  * \see             ecp.h
+ *
+ * \deprecated      Superseded by mbedtls_ecdsa_write_signature() in
+ *                  Mbed TLS version 2.0 and later.
+ *
+ * \param ctx       The ECDSA context.
+ * \param hash      The message hash.
+ * \param hlen      The length of the hash.
+ * \param sig       The buffer that holds the signature.
+ * \param slen      The length of the signature written.
+ * \param md_alg    The MD algorithm used to hash the message.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
+ *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
 int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
                                const unsigned char *hash, size_t hlen,
@@ -258,26 +263,26 @@
 /**
  * \brief           This function reads and verifies an ECDSA signature.
  *
- * \param ctx       The ECDSA context.
- * \param hash      The message hash.
- * \param hlen      The size of the hash.
- * \param sig       The signature to read and verify.
- * \param slen      The size of \p sig.
- *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
  *                  defined in <em>Standards for Efficient Cryptography Group
  *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
  *                  4.1.4, step 3.
  *
- * \return          \c 0 on success,
- *                  #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
- *                  #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
- *                  signature in sig but its length is less than \p siglen,
- *                  or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
- *                  error code on failure for any other reason.
- *
  * \see             ecp.h
+ *
+ * \param ctx       The ECDSA context.
+ * \param hash      The message hash.
+ * \param hlen      The size of the hash.
+ * \param sig       The signature to read and verify.
+ * \param slen      The size of \p sig.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+ * \return          #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in \p sig, but its length is less than \p siglen.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on failure for any other reason.
  */
 int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
                           const unsigned char *hash, size_t hlen,
@@ -286,16 +291,16 @@
 /**
  * \brief          This function generates an ECDSA keypair on the given curve.
  *
+ * \see            ecp.h
+ *
  * \param ctx      The ECDSA context to store the keypair in.
  * \param gid      The elliptic curve to use. One of the various
  *                 \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
  * \param f_rng    The RNG function.
- * \param p_rng    The RNG parameter.
+ * \param p_rng    The RNG context.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on
- *                 failure.
- *
- * \see            ecp.h
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_ECP_XXX code on failure.
  */
 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
@@ -303,13 +308,13 @@
 /**
  * \brief           This function sets an ECDSA context from an EC key pair.
  *
+ * \see             ecp.h
+ *
  * \param ctx       The ECDSA context to set.
  * \param key       The EC key to use.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on
- *                  failure.
- *
- * \see             ecp.h
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX code on failure.
  */
 int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
 
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index d86e820..cc2b316 100644
--- a/include/mbedtls/ecjpake.h
+++ b/include/mbedtls/ecjpake.h
@@ -44,8 +44,6 @@
 #include "ecp.h"
 #include "md.h"
 
-#if !defined(MBEDTLS_ECJPAKE_ALT)
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -58,6 +56,7 @@
     MBEDTLS_ECJPAKE_SERVER,             /**< Server                         */
 } mbedtls_ecjpake_role;
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
 /**
  * EC J-PAKE context structure.
  *
@@ -88,6 +87,10 @@
     mbedtls_mpi s;                      /**< Pre-shared secret (passphrase) */
 } mbedtls_ecjpake_context;
 
+#else  /* MBEDTLS_ECJPAKE_ALT */
+#include "ecjpake_alt.h"
+#endif /* MBEDTLS_ECJPAKE_ALT */
+
 /**
  * \brief           Initialize a context
  *                  (just makes it ready for setup() or free()).
@@ -225,20 +228,10 @@
  */
 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
  *
@@ -246,10 +239,11 @@
  */
 int mbedtls_ecjpake_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* MBEDTLS_SELF_TEST */
 
 #endif /* ecjpake.h */
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index e024da8..3a40798 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -1,10 +1,21 @@
 /**
  * \file ecp.h
  *
- * \brief Elliptic curves over GF(p)
+ * \brief This file provides an API for Elliptic Curves over GF(P) (ECP).
+ *
+ * The use of ECP in cryptography and TLS is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG): SEC1
+ * Elliptic Curve Cryptography</em> and
+ * <em>RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites
+ * for Transport Layer Security (TLS)</em>.
+ *
+ * <em>RFC-2409: The Internet Key Exchange (IKE)</em> defines ECP
+ * group types.
+ *
  */
+
 /*
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -19,8 +30,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- *  This file is part of mbed TLS (https://tls.mbed.org)
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
  */
+
 #ifndef MBEDTLS_ECP_H
 #define MBEDTLS_ECP_H
 
@@ -31,13 +43,81 @@
  */
 #define MBEDTLS_ERR_ECP_BAD_INPUT_DATA                    -0x4F80  /**< Bad input parameters to function. */
 #define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00  /**< The buffer is too small to write to. */
-#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< Requested curve not available. */
+#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< The requested feature is not available, for example, the requested curve is not supported. */
 #define MBEDTLS_ERR_ECP_VERIFY_FAILED                     -0x4E00  /**< The signature is not valid. */
 #define MBEDTLS_ERR_ECP_ALLOC_FAILED                      -0x4D80  /**< Memory allocation failed. */
-#define MBEDTLS_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as (ephemeral) key, failed. */
+#define MBEDTLS_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as ephemeral key, failed. */
 #define MBEDTLS_ERR_ECP_INVALID_KEY                       -0x4C80  /**< Invalid private or public key. */
 #define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH                  -0x4C00  /**< The buffer contains a valid signature followed by more data. */
-#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED                   -0x4B80  /**< ECP hardware accelerator failed. */
+#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED                   -0x4B80  /**< The ECP hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Domain-parameter identifiers: curve, subgroup, and generator.
+ *
+ * \note Only curves over prime fields are supported.
+ *
+ * \warning This library does not support validation of arbitrary domain
+ * parameters. Therefore, only standardized domain parameters from trusted
+ * sources should be used. See mbedtls_ecp_group_load().
+ */
+typedef enum
+{
+    MBEDTLS_ECP_DP_NONE = 0,       /*!< Curve not defined. */
+    MBEDTLS_ECP_DP_SECP192R1,      /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP224R1,      /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP256R1,      /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP384R1,      /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP521R1,      /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_BP256R1,        /*!< Domain parameters for 256-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_BP384R1,        /*!< Domain parameters for 384-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_BP512R1,        /*!< Domain parameters for 512-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_CURVE25519,     /*!< Domain parameters for Curve25519. */
+    MBEDTLS_ECP_DP_SECP192K1,      /*!< Domain parameters for 192-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_SECP224K1,      /*!< Domain parameters for 224-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_SECP256K1,      /*!< Domain parameters for 256-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_CURVE448,       /*!< Domain parameters for Curve448. */
+} mbedtls_ecp_group_id;
+
+/**
+ * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE.
+ *
+ * \note Montgomery curves are currently excluded.
+ */
+#define MBEDTLS_ECP_DP_MAX     12
+
+/**
+ * Curve information, for use by other modules.
+ */
+typedef struct
+{
+    mbedtls_ecp_group_id grp_id;    /*!< An internal identifier. */
+    uint16_t tls_id;                /*!< The TLS NamedCurve identifier. */
+    uint16_t bit_size;              /*!< The curve size in bits. */
+    const char *name;               /*!< A human-friendly name. */
+} mbedtls_ecp_curve_info;
+
+/**
+ * \brief           The ECP point structure, in Jacobian coordinates.
+ *
+ * \note            All functions expect and return points satisfying
+ *                  the following condition: <code>Z == 0</code> or
+ *                  <code>Z == 1</code>. Other values of \p Z are
+ *                  used only by internal functions.
+ *                  The point is zero, or "at infinity", if <code>Z == 0</code>.
+ *                  Otherwise, \p X and \p Y are its standard (affine)
+ *                  coordinates.
+ */
+typedef struct
+{
+    mbedtls_mpi X;          /*!< The X coordinate of the ECP point. */
+    mbedtls_mpi Y;          /*!< The Y coordinate of the ECP point. */
+    mbedtls_mpi Z;          /*!< The Z coordinate of the ECP point. */
+}
+mbedtls_ecp_point;
 
 #if !defined(MBEDTLS_ECP_ALT)
 /*
@@ -48,144 +128,72 @@
  * one.)
  */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
- * Domain parameters (curve, subgroup and generator) identifiers.
+ * \brief           The ECP group structure.
  *
- * Only curves over prime fields are supported.
+ * We consider two types of curve equations:
+ * <ul><li>Short Weierstrass: <code>y^2 = x^3 + A x + B mod P</code>
+ * (SEC1 + RFC-4492)</li>
+ * <li>Montgomery: <code>y^2 = x^3 + A x^2 + x mod P</code> (Curve25519,
+ * Curve448)</li></ul>
+ * In both cases, the generator (\p G) for a prime-order subgroup is fixed.
  *
- * \warning This library does not support validation of arbitrary domain
- * parameters. Therefore, only well-known domain parameters from trusted
- * sources should be used. See mbedtls_ecp_group_load().
- */
-typedef enum
-{
-    MBEDTLS_ECP_DP_NONE = 0,
-    MBEDTLS_ECP_DP_SECP192R1,      /*!< 192-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP224R1,      /*!< 224-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP256R1,      /*!< 256-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP384R1,      /*!< 384-bits NIST curve  */
-    MBEDTLS_ECP_DP_SECP521R1,      /*!< 521-bits NIST curve  */
-    MBEDTLS_ECP_DP_BP256R1,        /*!< 256-bits Brainpool curve */
-    MBEDTLS_ECP_DP_BP384R1,        /*!< 384-bits Brainpool curve */
-    MBEDTLS_ECP_DP_BP512R1,        /*!< 512-bits Brainpool curve */
-    MBEDTLS_ECP_DP_CURVE25519,     /*!< Curve25519               */
-    MBEDTLS_ECP_DP_CURVE448,       /*!< Curve448                 */
-    MBEDTLS_ECP_DP_SECP192K1,      /*!< 192-bits "Koblitz" curve */
-    MBEDTLS_ECP_DP_SECP224K1,      /*!< 224-bits "Koblitz" curve */
-    MBEDTLS_ECP_DP_SECP256K1,      /*!< 256-bits "Koblitz" curve */
-} mbedtls_ecp_group_id;
-
-/**
- * Number of supported curves (plus one for NONE).
+ * For Short Weierstrass, this subgroup is the whole curve, and its
+ * cardinality is denoted by \p N. Our code requires that \p N is an
+ * odd prime as mbedtls_ecp_mul() requires an odd number, and
+ * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes.
  *
- * (Montgomery curves excluded for now.)
- */
-#define MBEDTLS_ECP_DP_MAX     12
-
-/**
- * Curve information for use by other modules
+ * For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>,
+ * which is the quantity used in the formulas. Additionally, \p nbits is
+ * not the size of \p N but the required size for private keys.
+ *
+ * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm.
+ * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the
+ * range of <code>0..2^(2*pbits)-1</code>, and transforms it in-place to an integer
+ * which is congruent mod \p P to the given MPI, and is close enough to \p pbits
+ * in size, so that it may be efficiently brought in the 0..P-1 range by a few
+ * additions or subtractions. Therefore, it is only an approximative modular
+ * reduction. It must return 0 on success and non-zero on failure.
+ *
  */
 typedef struct
 {
-    mbedtls_ecp_group_id grp_id;    /*!< Internal identifier        */
-    uint16_t tls_id;                /*!< TLS NamedCurve identifier  */
-    uint16_t bit_size;              /*!< Curve size in bits         */
-    const char *name;               /*!< Human-friendly name        */
-} mbedtls_ecp_curve_info;
-
-/**
- * \brief           ECP point structure (jacobian coordinates)
- *
- * \note            All functions expect and return points satisfying
- *                  the following condition: Z == 0 or Z == 1. (Other
- *                  values of Z are used by internal functions only.)
- *                  The point is zero, or "at infinity", if Z == 0.
- *                  Otherwise, X and Y are its standard (affine) coordinates.
- */
-typedef struct
-{
-    mbedtls_mpi X;          /*!<  the point's X coordinate  */
-    mbedtls_mpi Y;          /*!<  the point's Y coordinate  */
-    mbedtls_mpi Z;          /*!<  the point's Z coordinate  */
-}
-mbedtls_ecp_point;
-
-/**
- * \brief           ECP group structure
- *
- * We consider two types of curves equations:
- * 1. Short Weierstrass y^2 = x^3 + A x + B     mod P   (SEC1 + RFC 4492)
- * 2. Montgomery,       y^2 = x^3 + A x^2 + x   mod P   (Curve25519 + draft)
- * In both cases, a generator G for a prime-order subgroup is fixed. In the
- * short weierstrass, this subgroup is actually the whole curve, and its
- * cardinal is denoted by N.
- *
- * In the case of Short Weierstrass curves, our code requires that N is an odd
- * prime. (Use odd in mbedtls_ecp_mul() and prime in mbedtls_ecdsa_sign() for blinding.)
- *
- * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
- * the quantity actually used in the formulas. Also, nbits is not the size of N
- * but the required size for private keys.
- *
- * If modp is NULL, reduction modulo P is done using a generic algorithm.
- * Otherwise, it must point to a function that takes an mbedtls_mpi in the range
- * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more
- * than pbits, so that the integer may be efficiently brought in the 0..P-1
- * range by a few additions or substractions. It must return 0 on success and
- * non-zero on failure.
- */
-typedef struct
-{
-    mbedtls_ecp_group_id id;    /*!<  internal group identifier                     */
-    mbedtls_mpi P;              /*!<  prime modulus of the base field               */
-    mbedtls_mpi A;              /*!<  1. A in the equation, or 2. (A + 2) / 4       */
-    mbedtls_mpi B;              /*!<  1. B in the equation, or 2. unused            */
-    mbedtls_ecp_point G;        /*!<  generator of the (sub)group used              */
-    mbedtls_mpi N;              /*!<  the order of G                                */
-    size_t pbits;       /*!<  number of bits in P                           */
-    size_t nbits;       /*!<  number of bits in 1. P, or 2. private keys    */
-    unsigned int h;     /*!<  internal: 1 if the constants are static       */
-    int (*modp)(mbedtls_mpi *); /*!<  function for fast reduction mod P             */
-    int (*t_pre)(mbedtls_ecp_point *, void *);  /*!< unused                         */
-    int (*t_post)(mbedtls_ecp_point *, void *); /*!< unused                         */
-    void *t_data;                       /*!< unused                         */
-    mbedtls_ecp_point *T;       /*!<  pre-computed points for ecp_mul_comb()        */
-    size_t T_size;      /*!<  number for pre-computed points                */
+    mbedtls_ecp_group_id id;    /*!< An internal group identifier. */
+    mbedtls_mpi P;              /*!< The prime modulus of the base field. */
+    mbedtls_mpi A;              /*!< For Short Weierstrass: \p A in the equation. For
+                                     Montgomery curves: <code>(A + 2) / 4</code>. */
+    mbedtls_mpi B;              /*!< For Short Weierstrass: \p B in the equation.
+                                     For Montgomery curves: unused. */
+    mbedtls_ecp_point G;        /*!< The generator of the subgroup used. */
+    mbedtls_mpi N;              /*!< The order of \p G. */
+    size_t pbits;               /*!< The number of bits in \p P.*/
+    size_t nbits;               /*!< For Short Weierstrass: The number of bits in \p P.
+                                     For Montgomery curves: the number of bits in the
+                                     private keys. */
+    unsigned int h;             /*!< \internal 1 if the constants are static. */
+    int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction
+                                     mod \p P (see above).*/
+    int (*t_pre)(mbedtls_ecp_point *, void *);  /*!< Unused. */
+    int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */
+    void *t_data;               /*!< Unused. */
+    mbedtls_ecp_point *T;       /*!< Pre-computed points for ecp_mul_comb(). */
+    size_t T_size;              /*!< The number of pre-computed points. */
 }
 mbedtls_ecp_group;
 
 /**
- * \brief           ECP key pair structure
- *
- * A generic key pair that could be used for ECDSA, fixed ECDH, etc.
- *
- * \note Members purposefully in the same order as struc mbedtls_ecdsa_context.
- */
-typedef struct
-{
-    mbedtls_ecp_group grp;      /*!<  Elliptic curve and base point     */
-    mbedtls_mpi d;              /*!<  our secret value                  */
-    mbedtls_ecp_point Q;        /*!<  our public value                  */
-}
-mbedtls_ecp_keypair;
-
-/**
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in config.h, or define them using the compiler command line.
  * \{
  */
 
 #if !defined(MBEDTLS_ECP_MAX_BITS)
 /**
- * Maximum size of the groups (that is, of N and P)
+ * The maximum size of the groups, that is, of \c N and \c P.
  */
-#define MBEDTLS_ECP_MAX_BITS     521   /**< Maximum bit size of groups */
+#define MBEDTLS_ECP_MAX_BITS     521   /**< The maximum size of groups, in bits. */
 #endif
 
 #define MBEDTLS_ECP_MAX_BYTES    ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
@@ -208,11 +216,10 @@
  *      521       145     141     135     120      97
  *      384       214     209     198     177     146
  *      256       320     320     303     262     226
-
  *      224       475     475     453     398     342
  *      192       640     640     633     587     476
  */
-#define MBEDTLS_ECP_WINDOW_SIZE    6   /**< Maximum window size used */
+#define MBEDTLS_ECP_WINDOW_SIZE    6   /**< The maximum window size used. */
 #endif /* MBEDTLS_ECP_WINDOW_SIZE */
 
 #if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
@@ -227,33 +234,55 @@
  *
  * Change this value to 0 to reduce peak memory usage.
  */
-#define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up */
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up. */
 #endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
 
 /* \} name SECTION: Module settings */
 
+#else  /* MBEDTLS_ECP_ALT */
+#include "ecp_alt.h"
+#endif /* MBEDTLS_ECP_ALT */
+
+/**
+ * \brief    The ECP key-pair structure.
+ *
+ * A generic key-pair that may be used for ECDSA and fixed ECDH, for example.
+ *
+ * \note    Members are deliberately in the same order as in the
+ *          ::mbedtls_ecdsa_context structure.
+ */
+typedef struct
+{
+    mbedtls_ecp_group grp;      /*!<  Elliptic curve and base point     */
+    mbedtls_mpi d;              /*!<  our secret value                  */
+    mbedtls_ecp_point Q;        /*!<  our public value                  */
+}
+mbedtls_ecp_keypair;
+
 /*
  * Point formats, from RFC 4492's enum ECPointFormat
  */
-#define MBEDTLS_ECP_PF_UNCOMPRESSED    0   /**< Uncompressed point format */
-#define MBEDTLS_ECP_PF_COMPRESSED      1   /**< Compressed point format */
+#define MBEDTLS_ECP_PF_UNCOMPRESSED    0   /**< Uncompressed point format. */
+#define MBEDTLS_ECP_PF_COMPRESSED      1   /**< Compressed point format. */
 
 /*
  * Some other constants from RFC 4492
  */
-#define MBEDTLS_ECP_TLS_NAMED_CURVE    3   /**< ECCurveType's named_curve */
+#define MBEDTLS_ECP_TLS_NAMED_CURVE    3   /**< The named_curve of ECCurveType. */
 
 /**
- * \brief           Get the list of supported curves in order of preferrence
- *                  (full information)
+ * \brief           This function retrieves the information defined in
+ *                  mbedtls_ecp_curve_info() for all supported curves in order
+ *                  of preference.
  *
- * \return          A statically allocated array, the last entry is 0.
+ * \return          A statically allocated array. The last entry is 0.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
 
 /**
- * \brief           Get the list of supported curves in order of preferrence
- *                  (grp_id only)
+ * \brief           This function retrieves the list of internal group
+ *                  identifiers of all supported curves in the order of
+ *                  preference.
  *
  * \return          A statically allocated array,
  *                  terminated with MBEDTLS_ECP_DP_NONE.
@@ -261,357 +290,400 @@
 const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void );
 
 /**
- * \brief           Get curve information from an internal group identifier
+ * \brief           This function retrieves curve information from an internal
+ *                  group identifier.
  *
- * \param grp_id    A MBEDTLS_ECP_DP_XXX value
+ * \param grp_id    An \c MBEDTLS_ECP_DP_XXX value.
  *
- * \return          The associated curve information or NULL
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id );
 
 /**
- * \brief           Get curve information from a TLS NamedCurve value
+ * \brief           This function retrieves curve information from a TLS
+ *                  NamedCurve value.
  *
- * \param tls_id    A MBEDTLS_ECP_DP_XXX value
+ * \param tls_id    An \c MBEDTLS_ECP_DP_XXX value.
  *
- * \return          The associated curve information or NULL
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id );
 
 /**
- * \brief           Get curve information from a human-readable name
+ * \brief           This function retrieves curve information from a
+ *                  human-readable name.
  *
- * \param name      The name
+ * \param name      The human-readable name.
  *
- * \return          The associated curve information or NULL
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
  */
 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name );
 
 /**
- * \brief           Initialize a point (as zero)
+ * \brief           This function initializes a point as zero.
+ *
+ * \param pt        The point to initialize.
  */
 void mbedtls_ecp_point_init( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Initialize a group (to something meaningless)
+ * \brief           This function initializes an ECP group context
+ *                  without loading any domain parameters.
+ *
+ * \note            After this function is called, domain parameters
+ *                  for various ECP groups can be loaded through the
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group()
+ *                  functions.
  */
 void mbedtls_ecp_group_init( mbedtls_ecp_group *grp );
 
 /**
- * \brief           Initialize a key pair (as an invalid one)
+ * \brief           This function initializes a key pair as an invalid one.
+ *
+ * \param key       The key pair to initialize.
  */
 void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key );
 
 /**
- * \brief           Free the components of a point
+ * \brief           This function frees the components of a point.
+ *
+ * \param pt        The point to free.
  */
 void mbedtls_ecp_point_free( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Free the components of an ECP group
+ * \brief           This function frees the components of an ECP group.
+ * \param grp       The group to free.
  */
 void mbedtls_ecp_group_free( mbedtls_ecp_group *grp );
 
 /**
- * \brief           Free the components of a key pair
+ * \brief           This function frees the components of a key pair.
+ * \param key       The key pair to free.
  */
 void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key );
 
 /**
- * \brief           Copy the contents of point Q into P
+ * \brief           This function copies the contents of point \p Q into
+ *                  point \p P.
  *
- * \param P         Destination point
- * \param Q         Source point
+ * \param P         The destination point.
+ * \param Q         The source point.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q );
 
 /**
- * \brief           Copy the contents of a group object
+ * \brief           This function copies the contents of group \p src into
+ *                  group \p dst.
  *
- * \param dst       Destination group
- * \param src       Source group
+ * \param dst       The destination group.
+ * \param src       The source group.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src );
 
 /**
- * \brief           Set a point to zero
+ * \brief           This function sets a point to zero.
  *
- * \param pt        Destination point
+ * \param pt        The point to set.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Tell if a point is zero
+ * \brief           This function checks if a point is zero.
  *
- * \param pt        Point to test
+ * \param pt        The point to test.
  *
- * \return          1 if point is zero, 0 otherwise
+ * \return          \c 1 if the point is zero.
+ * \return          \c 0 if the point is non-zero.
  */
 int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
 
 /**
- * \brief           Compare two points
+ * \brief           This function compares two points.
  *
- * \note            This assumes the points are normalized. Otherwise,
+ * \note            This assumes that the points are normalized. Otherwise,
  *                  they may compare as "not equal" even if they are.
  *
- * \param P         First point to compare
- * \param Q         Second point to compare
+ * \param P         The first point to compare.
+ * \param Q         The second point to compare.
  *
- * \return          0 if the points are equal,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
+ * \return          \c 0 if the points are equal.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal.
  */
 int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
                            const mbedtls_ecp_point *Q );
 
 /**
- * \brief           Import a non-zero point from two ASCII strings
+ * \brief           This function imports a non-zero point from two ASCII
+ *                  strings.
  *
- * \param P         Destination point
- * \param radix     Input numeric base
- * \param x         First affine coordinate as a null-terminated string
- * \param y         Second affine coordinate as a null-terminated string
+ * \param P         The destination point.
+ * \param radix     The numeric base of the input.
+ * \param x         The first affine coordinate, as a null-terminated string.
+ * \param y         The second affine coordinate, as a null-terminated string.
  *
- * \return          0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on failure.
  */
 int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
                            const char *x, const char *y );
 
 /**
- * \brief           Export a point into unsigned binary data
+ * \brief           This function exports a point into unsigned binary data.
  *
- * \param grp       Group to which the point should belong
- * \param P         Point to export
- * \param format    Point format, should be a MBEDTLS_ECP_PF_XXX macro
- * \param olen      Length of the actual output
- * \param buf       Output buffer
- * \param buflen    Length of the output buffer
+ * \param grp       The group to which the point should belong.
+ * \param P         The point to export.
+ * \param format    The point format. Should be an \c MBEDTLS_ECP_PF_XXX macro.
+ * \param olen      The length of the output.
+ * \param buf       The output buffer.
+ * \param buflen    The length of the output buffer.
  *
- * \return          0 if successful,
- *                  or MBEDTLS_ERR_ECP_BAD_INPUT_DATA
- *                  or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+ *                  or #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
  */
 int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
                             int format, size_t *olen,
                             unsigned char *buf, size_t buflen );
 
 /**
- * \brief           Import a point from unsigned binary data
+ * \brief           This function imports a point from unsigned binary data.
  *
- * \param grp       Group to which the point should belong
- * \param P         Point to import
- * \param buf       Input buffer
- * \param ilen      Actual length of input
+ * \note            This function does not check that the point actually
+ *                  belongs to the given group, see mbedtls_ecp_check_pubkey()
+ *                  for that.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
+ * \param grp       The group to which the point should belong.
+ * \param P         The point to import.
+ * \param buf       The input buffer.
+ * \param ilen      The length of the input.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
  *                  is not implemented.
  *
- * \note            This function does NOT check that the point actually
- *                  belongs to the given group, see mbedtls_ecp_check_pubkey() for
- *                  that.
  */
 int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
                            const unsigned char *buf, size_t ilen );
 
 /**
- * \brief           Import a point from a TLS ECPoint record
+ * \brief           This function imports a point from a TLS ECPoint record.
  *
- * \param grp       ECP group used
- * \param pt        Destination point
- * \param buf       $(Start of input buffer)
- * \param len       Buffer length
+ * \note            On function return, \p buf is updated to point to immediately
+ *                  after the ECPoint record.
  *
- * \note            buf is updated to point right after the ECPoint on exit
+ * \param grp       The ECP group used.
+ * \param pt        The destination point.
+ * \param buf       The address of the pointer to the start of the input buffer.
+ * \param len       The length of the buffer.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_XXX if initialization failed
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
  */
 int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
                         const unsigned char **buf, size_t len );
 
 /**
- * \brief           Export a point as a TLS ECPoint record
+ * \brief           This function exports a point as a TLS ECPoint record.
  *
- * \param grp       ECP group used
- * \param pt        Point to export
- * \param format    Export format
- * \param olen      length of data written
- * \param buf       Buffer to write to
- * \param blen      Buffer length
+ * \param grp       The ECP group used.
+ * \param pt        The point format to export to. The point format is an
+ *                  \c MBEDTLS_ECP_PF_XXX constant.
+ * \param format    The export format.
+ * \param olen      The length of the data written.
+ * \param buf       The buffer to write to.
+ * \param blen      The length of the buffer.
  *
- * \return          0 if successful,
- *                  or MBEDTLS_ERR_ECP_BAD_INPUT_DATA
- *                  or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA or
+ *                  #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
  */
 int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
                          int format, size_t *olen,
                          unsigned char *buf, size_t blen );
 
 /**
- * \brief           Set a group using well-known domain parameters
+ * \brief           This function sets a group using standardized domain parameters.
  *
- * \param grp       Destination group
- * \param id        Index in the list of well-known domain parameters
+ * \note            The index should be a value of the NamedCurve enum,
+ *                  as defined in <em>RFC-4492: Elliptic Curve Cryptography
+ *                  (ECC) Cipher Suites for Transport Layer Security (TLS)</em>,
+ *                  usually in the form of an \c MBEDTLS_ECP_DP_XXX macro.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_XXX if initialization failed
- *                  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
+ * \param grp       The destination group.
+ * \param id        The identifier of the domain parameter set to load.
  *
- * \note            Index should be a value of RFC 4492's enum NamedCurve,
- *                  usually in the form of a MBEDTLS_ECP_DP_XXX macro.
+ * \return          \c 0 on success,
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups.
+
  */
 int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id );
 
 /**
- * \brief           Set a group from a TLS ECParameters record
+ * \brief           This function sets a group from a TLS ECParameters record.
  *
- * \param grp       Destination group
- * \param buf       &(Start of input buffer)
- * \param len       Buffer length
+ * \note            \p buf is updated to point right after the ECParameters record
+ *                  on exit.
  *
- * \note            buf is updated to point right after ECParameters on exit
+ * \param grp       The destination group.
+ * \param buf       The address of the pointer to the start of the input buffer.
+ * \param len       The length of the buffer.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_MPI_XXX if initialization failed
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
  */
 int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len );
 
 /**
- * \brief           Write the TLS ECParameters record for a group
+ * \brief           This function writes the TLS ECParameters record for a group.
  *
- * \param grp       ECP group used
- * \param olen      Number of bytes actually written
- * \param buf       Buffer to write to
- * \param blen      Buffer length
+ * \param grp       The ECP group used.
+ * \param olen      The number of Bytes written.
+ * \param buf       The buffer to write to.
+ * \param blen      The length of the buffer.
  *
- * \return          0 if successful,
- *                  or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
  */
 int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
                          unsigned char *buf, size_t blen );
 
 /**
- * \brief           Multiplication by an integer: R = m * P
- *                  (Not thread-safe to use same group in multiple threads)
+ * \brief           This function performs multiplication of a point by
+ *                  an integer: \p R = \p m * \p P.
  *
- * \note            In order to prevent timing attacks, this function
- *                  executes the exact same sequence of (base field)
- *                  operations for any valid m. It avoids any if-branch or
- *                  array index depending on the value of m.
+ *                  It is not thread-safe to use same group in multiple threads.
  *
- * \note            If f_rng is not NULL, it is used to randomize intermediate
- *                  results in order to prevent potential timing attacks
- *                  targeting these results. It is recommended to always
- *                  provide a non-NULL f_rng (the overhead is negligible).
+ * \note            To prevent timing attacks, this function
+ *                  executes the exact same sequence of base-field
+ *                  operations for any valid \p m. It avoids any if-branch or
+ *                  array index depending on the value of \p m.
  *
- * \param grp       ECP group
- * \param R         Destination point
- * \param m         Integer by which to multiply
- * \param P         Point to multiply
- * \param f_rng     RNG function (see notes)
- * \param p_rng     RNG parameter
+ * \note            If \p f_rng is not NULL, it is used to randomize
+ *                  intermediate results to prevent potential timing attacks
+ *                  targeting these results. We recommend always providing
+ *                  a non-NULL \p f_rng. The overhead is negligible.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY if m is not a valid privkey
- *                  or P is not a valid pubkey,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \param grp       The ECP group.
+ * \param R         The destination point.
+ * \param m         The integer by which to multiply.
+ * \param P         The point to multiply.
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private
+ *                  key, or \p P is not a valid public key.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 /**
- * \brief           Multiplication and addition of two points by integers:
- *                  R = m * P + n * Q
- *                  (Not thread-safe to use same group in multiple threads)
+ * \brief           This function performs multiplication and addition of two
+ *                  points by integers: \p R = \p m * \p P + \p n * \p Q
  *
- * \note            In contrast to mbedtls_ecp_mul(), this function does not guarantee
- *                  a constant execution flow and timing.
+ *                  It is not thread-safe to use same group in multiple threads.
  *
- * \param grp       ECP group
- * \param R         Destination point
- * \param m         Integer by which to multiply P
- * \param P         Point to multiply by m
- * \param n         Integer by which to multiply Q
- * \param Q         Point to be multiplied by n
+ * \note            In contrast to mbedtls_ecp_mul(), this function does not
+ *                  guarantee a constant execution flow and timing.
  *
- * \return          0 if successful,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY if m or n is not a valid privkey
- *                  or P or Q is not a valid pubkey,
- *                  MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \param grp       The ECP group.
+ * \param R         The destination point.
+ * \param m         The integer by which to multiply \p P.
+ * \param P         The point to multiply by \p m.
+ * \param n         The integer by which to multiply \p Q.
+ * \param Q         The point to be multiplied by \p n.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not
+ *                  valid private keys, or \p P or \p Q are not valid public
+ *                  keys.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
              const mbedtls_mpi *n, const mbedtls_ecp_point *Q );
 
 /**
- * \brief           Check that a point is a valid public key on this curve
+ * \brief           This function checks that a point is a valid public key
+ *                  on this curve.
  *
- * \param grp       Curve/group the point should belong to
- * \param pt        Point to check
+ *                  It only checks that the point is non-zero, has
+ *                  valid coordinates and lies on the curve. It does not verify
+ *                  that it is indeed a multiple of \p G. This additional
+ *                  check is computationally more expensive, is not required
+ *                  by standards, and should not be necessary if the group
+ *                  used has a small cofactor. In particular, it is useless for
+ *                  the NIST groups which all have a cofactor of 1.
  *
- * \return          0 if point is a valid public key,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY otherwise.
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure, to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
  *
- * \note            This function only checks the point is non-zero, has valid
- *                  coordinates and lies on the curve, but not that it is
- *                  indeed a multiple of G. This is additional check is more
- *                  expensive, isn't required by standards, and shouldn't be
- *                  necessary if the group used has a small cofactor. In
- *                  particular, it is useless for the NIST groups which all
- *                  have a cofactor of 1.
+ * \param grp       The curve the point should lie on.
+ * \param pt        The point to check.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \return          \c 0 if the point is a valid public key.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
  */
 int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt );
 
 /**
- * \brief           Check that an mbedtls_mpi is a valid private key for this curve
+ * \brief           This function checks that an \p mbedtls_mpi is a valid private
+ *                  key for this curve.
  *
- * \param grp       Group used
- * \param d         Integer to check
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
  *
- * \return          0 if point is a valid private key,
- *                  MBEDTLS_ERR_ECP_INVALID_KEY otherwise.
+ * \param grp       The group used.
+ * \param d         The integer to check.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \return          \c 0 if the point is a valid private key.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
  */
 int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
 
 /**
- * \brief           Generate a keypair with configurable base point
+ * \brief           This function generates a keypair with a configurable base
+ *                  point.
  *
- * \param grp       ECP group
- * \param G         Chosen base point
- * \param d         Destination MPI (secret part)
- * \param Q         Destination point (public part)
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ * \param grp       The ECP group.
+ * \param G         The chosen base point.
+ * \param d         The destination MPI (secret part).
+ * \param Q         The destination point (public part).
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+ *                  on failure.
  */
 int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
                      const mbedtls_ecp_point *G,
@@ -620,57 +692,66 @@
                      void *p_rng );
 
 /**
- * \brief           Generate a keypair
+ * \brief           This function generates an ECP keypair.
  *
- * \param grp       ECP group
- * \param d         Destination MPI (secret part)
- * \param Q         Destination point (public part)
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ * \param grp       The ECP group.
+ * \param d         The destination MPI (secret part).
+ * \param Q         The destination point (public part).
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
  *
- * \note            Uses bare components rather than an mbedtls_ecp_keypair structure
- *                  in order to ease use with other structures such as
- *                  mbedtls_ecdh_context of mbedtls_ecdsa_context.
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+ *                  on failure.
  */
 int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng );
 
 /**
- * \brief           Generate a keypair
+ * \brief           This function generates an ECP key.
  *
- * \param grp_id    ECP group identifier
- * \param key       Destination keypair
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param grp_id    The ECP group identifier.
+ * \param key       The destination key.
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context.
  *
- * \return          0 if successful,
- *                  or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+ *                  on failure.
  */
 int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 /**
- * \brief           Check a public-private key pair
+ * \brief           This function checks that the keypair objects
+ *                  \p pub and \p prv have the same group and the
+ *                  same public point, and that the private key in
+ *                  \p prv is consistent with the public key.
  *
- * \param pub       Keypair structure holding a public key
- * \param prv       Keypair structure holding a private (plus public) key
+ * \param pub       The keypair structure holding the public key.
+ *                  If it contains a private key, that part is ignored.
+ * \param prv       The keypair structure holding the full keypair.
  *
- * \return          0 if successful (keys are valid and match), or
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA, or
- *                  a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX code.
+ * \return          \c 0 on success, meaning that the keys are valid and match.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on calculation failure.
  */
 int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv );
 
 #if defined(MBEDTLS_SELF_TEST)
 
 /**
- * \brief          Checkup routine
+ * \brief          The ECP checkup routine.
  *
- * \return         0 if successful, or 1 if a test failed
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_ecp_self_test( int verbose );
 
@@ -680,8 +761,4 @@
 }
 #endif
 
-#else  /* MBEDTLS_ECP_ALT */
-#include "ecp_alt.h"
-#endif /* MBEDTLS_ECP_ALT */
-
 #endif /* ecp.h */
diff --git a/include/mbedtls/ecp_internal.h b/include/mbedtls/ecp_internal.h
index 8a6d517..1804069 100644
--- a/include/mbedtls/ecp_internal.h
+++ b/include/mbedtls/ecp_internal.h
@@ -48,7 +48,7 @@
  * [6] Digital Signature Standard (DSS), FIPS 186-4.
  *     <http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>
  *
- * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer 
+ * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
  *     Security (TLS), RFC 4492.
  *     <https://tools.ietf.org/search/rfc4492>
  *
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index fcb4d02..a5cb05a 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -166,7 +166,7 @@
  * \param threshold Minimum required from source before entropy is released
  *                  ( with mbedtls_entropy_func() ) (in bytes)
  * \param strong    MBEDTLS_ENTROPY_SOURCE_STRONG or
- *                  MBEDTSL_ENTROPY_SOURCE_WEAK.
+ *                  MBEDTLS_ENTROPY_SOURCE_WEAK.
  *                  At least one strong source needs to be added.
  *                  Weaker sources (such as the cycle counter) can be used as
  *                  a complement.
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 8b4d3a8..2bde87a 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -4,7 +4,7 @@
  * \brief Error to string translation
  */
 /*
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -53,7 +53,7 @@
  * GCM       3  0x0012-0x0014   0x0013-0x0013
  * BLOWFISH  3  0x0016-0x0018   0x0017-0x0017
  * THREADING 3  0x001A-0x001E
- * AES       4  0x0020-0x0022   0x0023-0x0025
+ * AES       5  0x0020-0x0022   0x0021-0x0025
  * CAMELLIA  3  0x0024-0x0026   0x0027-0x0027
  * XTEA      2  0x0028-0x0028   0x0029-0x0029
  * BASE64    2  0x002A-0x002C
@@ -63,6 +63,7 @@
  * CTR_DBRG  4  0x0034-0x003A
  * ENTROPY   3  0x003C-0x0040   0x003D-0x003F
  * NET      11  0x0042-0x0052   0x0043-0x0045
+ * ARIA      4  0x0058-0x005E
  * ASN1      7  0x0060-0x006C
  * CMAC      1  0x007A-0x007A
  * PBKDF2    1  0x007C-0x007C
@@ -88,6 +89,7 @@
  * RSA       4   11
  * ECP       4   9 (Started from top)
  * MD        5   5
+ * HKDF      5   1 (Started from top)
  * 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 1e5a507..87535ab 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -1,9 +1,11 @@
 /**
  * \file gcm.h
  *
- * \brief Galois/Counter Mode (GCM) for 128-bit block ciphers, as defined
- *        in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
- *        (GCM), Natl. Inst. Stand. Technol.</em>
+ * \brief This file contains GCM definitions and functions.
+ *
+ * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
+ * in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
+ * (GCM), Natl. Inst. Stand. Technol.</em>
  *
  * For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
  * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
@@ -42,12 +44,12 @@
 #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)
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_GCM_ALT)
+
 /**
  * \brief          The GCM context structure.
  */
@@ -66,6 +68,10 @@
 }
 mbedtls_gcm_context;
 
+#else  /* !MBEDTLS_GCM_ALT */
+#include "gcm_alt.h"
+#endif /* !MBEDTLS_GCM_ALT */
+
 /**
  * \brief           This function initializes the specified GCM context,
  *                  to make references valid, and prepares the context
@@ -91,7 +97,8 @@
  *                  <li>192 bits</li>
  *                  <li>256 bits</li></ul>
  *
- * \return          \c 0 on success, or a cipher specific error code.
+ * \return          \c 0 on success.
+ * \return          A cipher-specific error code on failure.
  */
 int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
                         mbedtls_cipher_id_t cipher,
@@ -101,25 +108,46 @@
 /**
  * \brief           This function performs GCM encryption or decryption of a buffer.
  *
- * \note For encryption, the output buffer can be the same as the input buffer.
- *       For decryption, the output buffer cannot be the same as input buffer.
- *       If the buffers overlap, the output buffer must trail at least 8 Bytes
- *       behind the input buffer.
+ * \note            For encryption, the output buffer can be the same as the
+ *                  input buffer. For decryption, the output buffer cannot be
+ *                  the same as input buffer. If the buffers overlap, the output
+ *                  buffer must trail at least 8 Bytes behind the input buffer.
+ *
+ * \warning         When this function performs a decryption, it outputs the
+ *                  authentication tag and does not verify that the data is
+ *                  authentic. You should use this function to perform encryption
+ *                  only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
  *
  * \param ctx       The GCM context to use for encryption or decryption.
- * \param mode      The operation to perform: #MBEDTLS_GCM_ENCRYPT or
- *                  #MBEDTLS_GCM_DECRYPT.
- * \param length    The length of the input data. This must be a multiple of 16 except in the last call before mbedtls_gcm_finish().
+ * \param mode      The operation to perform:
+ *                  - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
+ *                    The ciphertext is written to \p output and the
+ *                    authentication tag is written to \p tag.
+ *                  - #MBEDTLS_GCM_DECRYPT to perform decryption.
+ *                    The plaintext is written to \p output and the
+ *                    authentication tag is written to \p tag.
+ *                    Note that this mode is not recommended, because it does
+ *                    not verify the authenticity of the data. For this reason,
+ *                    you should use mbedtls_gcm_auth_decrypt() instead of
+ *                    calling this function in decryption mode.
+ * \param length    The length of the input data, which is equal to the length
+ *                  of the output data.
  * \param iv        The initialization vector.
  * \param iv_len    The length of the IV.
  * \param add       The buffer holding the additional data.
  * \param add_len   The length of the additional data.
- * \param input     The buffer holding the input data.
- * \param output    The buffer for holding the output data.
+ * \param input     The buffer holding the input data. Its size is \b length.
+ * \param output    The buffer for holding the output data. It must have room
+ *                  for \b length bytes.
  * \param tag_len   The length of the tag to generate.
  * \param tag       The buffer for holding the tag.
  *
- * \return         \c 0 on success.
+ * \return          \c 0 if the encryption or decryption was performed
+ *                  successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
+ *                  this does not indicate that the data is authentic.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
+ * \return          #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
+ *                  error code if the encryption or decryption failed.
  */
 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
                        int mode,
@@ -137,23 +165,28 @@
  * \brief           This function performs a GCM authenticated decryption of a
  *                  buffer.
  *
- * \note For decryption, the output buffer cannot be the same as input buffer.
- *       If the buffers overlap, the output buffer must trail at least 8 Bytes
- *       behind the input buffer.
+ * \note            For decryption, the output buffer cannot be the same as
+ *                  input buffer. If the buffers overlap, the output buffer
+ *                  must trail at least 8 Bytes behind the input buffer.
  *
  * \param ctx       The GCM context.
- * \param length    The length of the input data. This must be a multiple of 16 except in the last call before mbedtls_gcm_finish().
+ * \param length    The length of the ciphertext to decrypt, which is also
+ *                  the length of the decrypted plaintext.
  * \param iv        The initialization vector.
  * \param iv_len    The length of the IV.
  * \param add       The buffer holding the additional data.
  * \param add_len   The length of the additional data.
- * \param tag       The buffer holding the tag.
- * \param tag_len   The length of the tag.
- * \param input     The buffer holding the input data.
- * \param output    The buffer for holding the output data.
+ * \param tag       The buffer holding the tag to verify.
+ * \param tag_len   The length of the tag to verify.
+ * \param input     The buffer holding the ciphertext. Its size is \b length.
+ * \param output    The buffer for holding the decrypted plaintext. It must
+ *                  have room for \b length bytes.
  *
- * \return         0 if successful and authenticated, or
- *                 #MBEDTLS_ERR_GCM_AUTH_FAILED if tag does not match.
+ * \return          \c 0 if successful and authenticated.
+ * \return          #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
+ * \return          #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
+ *                  error code if the decryption failed.
  */
 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
                       size_t length,
@@ -175,10 +208,12 @@
  *                  #MBEDTLS_GCM_DECRYPT.
  * \param iv        The initialization vector.
  * \param iv_len    The length of the IV.
- * \param add       The buffer holding the additional data, or NULL if \p add_len is 0.
- * \param add_len   The length of the additional data. If 0, \p  add is NULL.
+ * \param add       The buffer holding the additional data, or NULL
+ *                  if \p add_len is 0.
+ * \param add_len   The length of the additional data. If 0,
+ *                  \p add is NULL.
  *
- * \return         \c 0 on success.
+ * \return          \c 0 on success.
  */
 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
                 int mode,
@@ -195,16 +230,18 @@
  *                  Bytes. Only the last call before calling
  *                  mbedtls_gcm_finish() can be less than 16 Bytes.
  *
- * \note For decryption, the output buffer cannot be the same as input buffer.
- *       If the buffers overlap, the output buffer must trail at least 8 Bytes
- *       behind the input buffer.
+ * \note            For decryption, the output buffer cannot be the same as
+ *                  input buffer. If the buffers overlap, the output buffer
+ *                  must trail at least 8 Bytes behind the input buffer.
  *
  * \param ctx       The GCM context.
- * \param length    The length of the input data. This must be a multiple of 16 except in the last call before mbedtls_gcm_finish().
+ * \param length    The length of the input data. This must be a multiple of
+ *                  16 except in the last call before mbedtls_gcm_finish().
  * \param input     The buffer holding the input data.
  * \param output    The buffer for holding the output data.
  *
- * \return         \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
  */
 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
                 size_t length,
@@ -222,7 +259,8 @@
  * \param tag       The buffer for holding the tag.
  * \param tag_len   The length of the tag to generate. Must be at least four.
  *
- * \return          \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
  */
 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
                 unsigned char *tag,
@@ -236,22 +274,11 @@
  */
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* !MBEDTLS_GCM_ALT */
-#include "gcm_alt.h"
-#endif /* !MBEDTLS_GCM_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          The GCM checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_gcm_self_test( int verbose );
 
diff --git a/include/mbedtls/hkdf.h b/include/mbedtls/hkdf.h
new file mode 100644
index 0000000..6833e72
--- /dev/null
+++ b/include/mbedtls/hkdf.h
@@ -0,0 +1,125 @@
+/**
+ * \file hkdf.h
+ *
+ * \brief   This file contains the HKDF interface.
+ *
+ *          The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is
+ *          specified by RFC 5869.
+ */
+/*
+ * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_HKDF_H
+#define MBEDTLS_HKDF_H
+
+#include "md.h"
+
+/**
+ *  \name HKDF Error codes
+ *  \{
+ */
+#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA  -0x5F80  /**< Bad input parameters to function. */
+/* \} name */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *  \brief  This is the HMAC-based Extract-and-Expand Key Derivation Function
+ *          (HKDF).
+ *
+ *  \param  md        A hash function; md.size denotes the length of the hash
+ *                    function output in bytes.
+ *  \param  salt      An optional salt value (a non-secret random value);
+ *                    if the salt is not provided, a string of all zeros of
+ *                    md.size length is used as the salt.
+ *  \param  salt_len  The length in bytes of the optional \p salt.
+ *  \param  ikm       The input keying material.
+ *  \param  ikm_len   The length in bytes of \p ikm.
+ *  \param  info      An optional context and application specific information
+ *                    string. This can be a zero-length string.
+ *  \param  info_len  The length of \p info in bytes.
+ *  \param  okm       The output keying material of \p okm_len bytes.
+ *  \param  okm_len   The length of the output keying material in bytes. This
+ *                    must be less than or equal to 255 * md.size bytes.
+ *
+ *  \return 0 on success.
+ *  \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ *  \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ *          MD layer.
+ */
+int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
+                  size_t salt_len, const unsigned char *ikm, size_t ikm_len,
+                  const unsigned char *info, size_t info_len,
+                  unsigned char *okm, size_t okm_len );
+
+/**
+ *  \brief  Take the input keying material \p ikm and extract from it a
+ *          fixed-length pseudorandom key \p prk.
+ *
+ *  \param       md        A hash function; md.size denotes the length of the
+ *                         hash function output in bytes.
+ *  \param       salt      An optional salt value (a non-secret random value);
+ *                         if the salt is not provided, a string of all zeros
+ *                         of md.size length is used as the salt.
+ *  \param       salt_len  The length in bytes of the optional \p salt.
+ *  \param       ikm       The input keying material.
+ *  \param       ikm_len   The length in bytes of \p ikm.
+ *  \param[out]  prk       A pseudorandom key of at least md.size bytes.
+ *
+ *  \return 0 on success.
+ *  \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ *  \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ *          MD layer.
+ */
+int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
+                          const unsigned char *salt, size_t salt_len,
+                          const unsigned char *ikm, size_t ikm_len,
+                          unsigned char *prk );
+
+/**
+ *  \brief  Expand the supplied \p prk into several additional pseudorandom
+ *          keys, which is the output of the HKDF.
+ *
+ *  \param  md        A hash function; md.size denotes the length of the hash
+ *                    function output in bytes.
+ *  \param  prk       A pseudorandom key of at least md.size bytes. \p prk is usually,
+ *                    the output from the HKDF extract step.
+ *  \param  prk_len   The length in bytes of \p prk.
+ *  \param  info      An optional context and application specific information
+ *                    string. This can be a zero-length string.
+ *  \param  info_len  The length of \p info in bytes.
+ *  \param  okm       The output keying material of \p okm_len bytes.
+ *  \param  okm_len   The length of the output keying material in bytes. This
+ *                    must be less than or equal to 255 * md.size bytes.
+ *
+ *  \return 0 on success.
+ *  \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ *  \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ *          MD layer.
+ */
+int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
+                         size_t prk_len, const unsigned char *info,
+                         size_t info_len, unsigned char *okm, size_t okm_len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* hkdf.h */
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index 06538c3..6b6f5c5 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -1,7 +1,7 @@
  /**
  * \file md.h
  *
- * \brief The generic message-digest wrapper.
+ * \brief This file contains the generic message-digest wrapper.
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  */
@@ -46,7 +46,7 @@
 #endif
 
 /**
- * \brief     Enumeration of supported message digests
+ * \brief     Supported message digests.
  *
  * \warning   MD2, MD4, MD5 and SHA-1 are considered weak message digests and
  *            their use constitutes a security risk. We recommend considering
@@ -54,16 +54,16 @@
  *
  */
 typedef enum {
-    MBEDTLS_MD_NONE=0,
-    MBEDTLS_MD_MD2,
-    MBEDTLS_MD_MD4,
-    MBEDTLS_MD_MD5,
-    MBEDTLS_MD_SHA1,
-    MBEDTLS_MD_SHA224,
-    MBEDTLS_MD_SHA256,
-    MBEDTLS_MD_SHA384,
-    MBEDTLS_MD_SHA512,
-    MBEDTLS_MD_RIPEMD160,
+    MBEDTLS_MD_NONE=0,    /**< None. */
+    MBEDTLS_MD_MD2,       /**< The MD2 message digest. */
+    MBEDTLS_MD_MD4,       /**< The MD4 message digest. */
+    MBEDTLS_MD_MD5,       /**< The MD5 message digest. */
+    MBEDTLS_MD_SHA1,      /**< The SHA-1 message digest. */
+    MBEDTLS_MD_SHA224,    /**< The SHA-224 message digest. */
+    MBEDTLS_MD_SHA256,    /**< The SHA-256 message digest. */
+    MBEDTLS_MD_SHA384,    /**< The SHA-384 message digest. */
+    MBEDTLS_MD_SHA512,    /**< The SHA-512 message digest. */
+    MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
 } mbedtls_md_type_t;
 
 #if defined(MBEDTLS_SHA512_C)
@@ -108,8 +108,8 @@
  *
  * \param md_name   The name of the digest to search for.
  *
- * \return          The message-digest information associated with \p md_name,
- *                  or NULL if not found.
+ * \return          The message-digest information associated with \p md_name.
+ * \return          NULL if the associated message-digest information is not found.
  */
 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
 
@@ -119,8 +119,8 @@
  *
  * \param md_type   The type of digest to search for.
  *
- * \return          The message-digest information associated with \p md_type,
- *                  or NULL if not found.
+ * \return          The message-digest information associated with \p md_type.
+ * \return          NULL if the associated message-digest information is not found.
  */
 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
 
@@ -168,9 +168,10 @@
  * \param md_info   The information structure of the message-digest algorithm
  *                  to use.
  *
- * \returns         \c 0 on success,
- *                  #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
- *                  #MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ * \return          #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
 #undef MBEDTLS_DEPRECATED
@@ -187,12 +188,13 @@
  * \param ctx       The context to set up.
  * \param md_info   The information structure of the message-digest algorithm
  *                  to use.
- * \param hmac      <ul><li>0: HMAC is not used. Saves some memory.</li>
- *                  <li>non-zero: HMAC is used with this context.</li></ul>
+ * \param hmac      Defines if HMAC is used. 0: HMAC is not used (saves some memory),
+ *                  or non-zero: HMAC is used with this context.
  *
- * \returns         \c 0 on success,
- *                  #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure, or
- *                  #MBEDTLS_ERR_MD_ALLOC_FAILED on memory allocation failure.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ * \return          #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
  */
 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
 
@@ -212,8 +214,8 @@
  * \param dst       The destination context.
  * \param src       The context to be cloned.
  *
- * \return          \c 0 on success,
- *                  #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
  */
 int mbedtls_md_clone( mbedtls_md_context_t *dst,
                       const mbedtls_md_context_t *src );
@@ -260,8 +262,9 @@
  *
  * \param ctx       The generic message-digest context.
  *
- * \returns         \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                  parameter verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_starts( mbedtls_md_context_t *ctx );
 
@@ -277,8 +280,9 @@
  * \param input     The buffer holding the input data.
  * \param ilen      The length of the input data.
  *
- * \returns         \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                  parameter verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
 
@@ -296,8 +300,9 @@
  * \param ctx       The generic message-digest context.
  * \param output    The buffer for the generic message-digest checksum result.
  *
- * \returns         \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                  parameter verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
 
@@ -315,8 +320,9 @@
  * \param ilen     The length of the input data.
  * \param output   The generic message-digest checksum result.
  *
- * \returns        \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                 parameter verification fails.
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                 failure.
  */
 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
         unsigned char *output );
@@ -334,9 +340,10 @@
  * \param path     The input file name.
  * \param output   The generic message-digest checksum result.
  *
- * \return         \c 0 on success,
- *                 #MBEDTLS_ERR_MD_FILE_IO_ERROR if file input failed, or
- *                 #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
+ *                 the file pointed by \p path.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
  */
 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
                      unsigned char *output );
@@ -356,8 +363,9 @@
  * \param key       The HMAC secret key.
  * \param keylen    The length of the HMAC key in Bytes.
  *
- * \returns         \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                  parameter verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
                     size_t keylen );
@@ -377,8 +385,9 @@
  * \param input     The buffer holding the input data.
  * \param ilen      The length of the input data.
  *
- * \returns         \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                  parameter verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
                     size_t ilen );
@@ -397,8 +406,9 @@
  *                  context.
  * \param output    The generic HMAC checksum result.
  *
- * \returns         \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                  parameter verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
 
@@ -413,8 +423,9 @@
  * \param ctx       The message digest context containing an embedded HMAC
  *                  context.
  *
- * \returns         \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                  parameter verification fails.
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
  */
 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
 
@@ -436,8 +447,9 @@
  * \param ilen     The length of the input data.
  * \param output   The generic HMAC result.
  *
- * \returns        \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if
- *                 parameter verification fails.
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                 failure.
  */
 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
                 const unsigned char *input, size_t ilen,
diff --git a/include/mbedtls/md2.h b/include/mbedtls/md2.h
index 0fd8b5a..08e75b2 100644
--- a/include/mbedtls/md2.h
+++ b/include/mbedtls/md2.h
@@ -39,14 +39,14 @@
 
 #define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED                   -0x002B  /**< MD2 hardware accelerator failed */
 
-#if !defined(MBEDTLS_MD2_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_MD2_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          MD2 context structure
  *
@@ -64,6 +64,10 @@
 }
 mbedtls_md2_context;
 
+#else  /* MBEDTLS_MD2_ALT */
+#include "md2_alt.h"
+#endif /* MBEDTLS_MD2_ALT */
+
 /**
  * \brief          Initialize MD2 context
  *
@@ -235,18 +239,6 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_MD2_ALT */
-#include "md2_alt.h"
-#endif /* MBEDTLS_MD2_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Output = MD2( input buffer )
  *
diff --git a/include/mbedtls/md4.h b/include/mbedtls/md4.h
index 23fa95e..8ee4e5c 100644
--- a/include/mbedtls/md4.h
+++ b/include/mbedtls/md4.h
@@ -40,14 +40,14 @@
 
 #define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED                   -0x002D  /**< MD4 hardware accelerator failed */
 
-#if !defined(MBEDTLS_MD4_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_MD4_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          MD4 context structure
  *
@@ -64,6 +64,10 @@
 }
 mbedtls_md4_context;
 
+#else  /* MBEDTLS_MD4_ALT */
+#include "md4_alt.h"
+#endif /* MBEDTLS_MD4_ALT */
+
 /**
  * \brief          Initialize MD4 context
  *
@@ -238,18 +242,6 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_MD4_ALT */
-#include "md4_alt.h"
-#endif /* MBEDTLS_MD4_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Output = MD4( input buffer )
  *
diff --git a/include/mbedtls/md5.h b/include/mbedtls/md5.h
index 06ea4c5..43ead4b 100644
--- a/include/mbedtls/md5.h
+++ b/include/mbedtls/md5.h
@@ -39,14 +39,14 @@
 
 #define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED                   -0x002F  /**< MD5 hardware accelerator failed */
 
-#if !defined(MBEDTLS_MD5_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_MD5_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          MD5 context structure
  *
@@ -63,6 +63,10 @@
 }
 mbedtls_md5_context;
 
+#else  /* MBEDTLS_MD5_ALT */
+#include "md5_alt.h"
+#endif /* MBEDTLS_MD5_ALT */
+
 /**
  * \brief          Initialize MD5 context
  *
@@ -238,18 +242,6 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_MD5_ALT */
-#include "md5_alt.h"
-#endif /* MBEDTLS_MD5_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Output = MD5( input buffer )
  *
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index ed10775..bba7709 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -1,7 +1,16 @@
 /**
  * \file platform.h
  *
- * \brief The Mbed TLS platform abstraction layer.
+ * \brief This file contains the definitions and functions of the
+ *        Mbed TLS platform abstraction layer.
+ *
+ *        The platform abstraction layer removes the need for the library
+ *        to directly link to standard C library functions or operating
+ *        system services, making the library easier to port and embed.
+ *        Application developers and users of the library can provide their own
+ *        implementations of these functions, or implementations specific to
+ *        their platform, which can be statically linked to the library or
+ *        dynamically configured at runtime.
  */
 /*
  *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@@ -102,7 +111,7 @@
 /* \} name SECTION: Module settings */
 
 /*
- * The function pointers for calloc and free
+ * The function pointers for calloc and free.
  */
 #if defined(MBEDTLS_PLATFORM_MEMORY)
 #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
@@ -116,7 +125,8 @@
 extern void (*mbedtls_free)( void *ptr );
 
 /**
- * \brief   This function allows configuring custom memory-management functions.
+ * \brief               This function dynamically sets the memory-management
+ *                      functions used by the library, during runtime.
  *
  * \param calloc_func   The \c calloc function implementation.
  * \param free_func     The \c free function implementation.
@@ -140,7 +150,9 @@
 extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
 
 /**
- * \brief   This function allows configuring a custom \p fprintf function pointer.
+ * \brief                This function dynamically configures the fprintf
+ *                       function that is called when the
+ *                       mbedtls_fprintf() function is invoked by the library.
  *
  * \param fprintf_func   The \c fprintf function implementation.
  *
@@ -163,8 +175,9 @@
 extern int (*mbedtls_printf)( const char *format, ... );
 
 /**
- * \brief    This function allows configuring a custom \c printf function
- *           pointer.
+ * \brief               This function dynamically configures the snprintf
+ *                      function that is called when the mbedtls_snprintf()
+ *                      function is invoked by the library.
  *
  * \param printf_func   The \c printf function implementation.
  *
@@ -197,12 +210,12 @@
 extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
 
 /**
- * \brief   This function allows configuring a custom \c snprintf function
- *          pointer.
+ * \brief                 This function allows configuring a custom
+ *                        \c snprintf function pointer.
  *
  * \param snprintf_func   The \c snprintf function implementation.
  *
- * \return    \c 0 on success.
+ * \return                \c 0 on success.
  */
 int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
                                                  const char * format, ... ) );
@@ -210,7 +223,7 @@
 #if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
 #define mbedtls_snprintf   MBEDTLS_PLATFORM_SNPRINTF_MACRO
 #else
-#define mbedtls_snprintf   snprintf
+#define mbedtls_snprintf   MBEDTLS_PLATFORM_STD_SNPRINTF
 #endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
 #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
 
@@ -221,12 +234,13 @@
 extern void (*mbedtls_exit)( int status );
 
 /**
- * \brief   This function allows configuring a custom \c exit function
- *          pointer.
+ * \brief             This function dynamically configures the exit
+ *                    function that is called when the mbedtls_exit()
+ *                    function is invoked by the library.
  *
  * \param exit_func   The \c exit function implementation.
  *
- * \return  \c 0 on success.
+ * \return            \c 0 on success.
  */
 int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
 #else
@@ -302,7 +316,7 @@
  *          setup or teardown operations.
  */
 typedef struct {
-    char dummy; /**< Placeholder member, as empty structs are not portable. */
+    char dummy; /**< A placeholder member, as empty structs are not portable. */
 }
 mbedtls_platform_context;
 
@@ -311,33 +325,34 @@
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
 /**
- * \brief   This function performs any platform initialization operations.
+ * \brief   This function performs any platform-specific initialization
+ *          operations.
  *
- * \param   ctx     The Mbed TLS context.
+ * \note    This function should be called before any other library functions.
  *
- * \return  \c 0 on success.
- *
- * \note    This function is intended to allow platform-specific initialization,
- *          and should be called before any other library functions. Its
- *          implementation is platform-specific, and unless
+ *          Its implementation is platform-specific, and unless
  *          platform-specific code is provided, it does nothing.
  *
- *          Its use and whether it is necessary to call it is dependent on the
- *          platform.
+ * \note    The usage and necessity of this function is dependent on the platform.
+ *
+ * \param   ctx     The platform context.
+ *
+ * \return  \c 0 on success.
  */
 int mbedtls_platform_setup( mbedtls_platform_context *ctx );
 /**
  * \brief   This function performs any platform teardown operations.
  *
- * \param   ctx     The Mbed TLS context.
- *
  * \note    This function should be called after every other Mbed TLS module
  *          has been correctly freed using the appropriate free function.
+ *
  *          Its implementation is platform-specific, and unless
  *          platform-specific code is provided, it does nothing.
  *
- *          Its use and whether it is necessary to call it is dependent on the
- *          platform.
+ * \note    The usage and necessity of this function is dependent on the platform.
+ *
+ * \param   ctx     The platform context.
+ *
  */
 void mbedtls_platform_teardown( mbedtls_platform_context *ctx );
 
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
new file mode 100644
index 0000000..84f0732
--- /dev/null
+++ b/include/mbedtls/platform_util.h
@@ -0,0 +1,62 @@
+/**
+ * \file platform_util.h
+ *
+ * \brief Common and shared functions used by multiple modules in the Mbed TLS
+ *        library.
+ */
+/*
+ *  Copyright (C) 2018, Arm Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PLATFORM_UTIL_H
+#define MBEDTLS_PLATFORM_UTIL_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief       Securely zeroize a buffer
+ *
+ *              The function is meant to wipe the data contained in a buffer so
+ *              that it can no longer be recovered even if the program memory
+ *              is later compromised. Call this function on sensitive data
+ *              stored on the stack before returning from a function, and on
+ *              sensitive data stored on the heap before freeing the heap
+ *              object.
+ *
+ *              It is extremely difficult to guarantee that calls to
+ *              mbedtls_platform_zeroize() are not removed by aggressive
+ *              compiler optimizations in a portable way. For this reason, Mbed
+ *              TLS provides the configuration option
+ *              MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
+ *              mbedtls_platform_zeroize() to use a suitable implementation for
+ *              their platform and needs
+ *
+ * \param buf   Buffer to be zeroized
+ * \param len   Length of the buffer in bytes
+ *
+ */
+void mbedtls_platform_zeroize( void *buf, size_t len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_PLATFORM_UTIL_H */
diff --git a/include/mbedtls/ripemd160.h b/include/mbedtls/ripemd160.h
index 3a8b50a..a0dac0c 100644
--- a/include/mbedtls/ripemd160.h
+++ b/include/mbedtls/ripemd160.h
@@ -35,14 +35,14 @@
 
 #define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED             -0x0031  /**< RIPEMD160 hardware accelerator failed */
 
-#if !defined(MBEDTLS_RIPEMD160_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_RIPEMD160_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          RIPEMD-160 context structure
  */
@@ -54,6 +54,10 @@
 }
 mbedtls_ripemd160_context;
 
+#else  /* MBEDTLS_RIPEMD160_ALT */
+#include "ripemd160.h"
+#endif /* MBEDTLS_RIPEMD160_ALT */
+
 /**
  * \brief          Initialize RIPEMD-160 context
  *
@@ -178,18 +182,6 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_RIPEMD160_ALT */
-#include "ripemd160_alt.h"
-#endif /* MBEDTLS_RIPEMD160_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Output = RIPEMD-160( input buffer )
  *
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index 5548f3c..19eb2ee 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -1,11 +1,12 @@
 /**
  * \file rsa.h
  *
- * \brief The RSA public-key cryptosystem.
+ * \brief This file provides an API for the RSA public-key cryptosystem.
  *
- * For more information, see <em>Public-Key Cryptography Standards (PKCS)
- * #1 v1.5: RSA Encryption</em> and <em>Public-Key Cryptography Standards
- * (PKCS) #1 v2.1: RSA Cryptography Specifications</em>.
+ * The RSA public-key cryptosystem is defined in <em>Public-Key
+ * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption</em>
+ * and <em>Public-Key Cryptography Standards (PKCS) #1 v2.1:
+ * RSA Cryptography Specifications</em>.
  *
  */
 /*
@@ -63,8 +64,8 @@
 #define MBEDTLS_RSA_PUBLIC      0 /**< Request private key operation. */
 #define MBEDTLS_RSA_PRIVATE     1 /**< Request public key operation. */
 
-#define MBEDTLS_RSA_PKCS_V15    0 /**< Use PKCS-1 v1.5 encoding. */
-#define MBEDTLS_RSA_PKCS_V21    1 /**< Use PKCS-1 v2.1 encoding. */
+#define MBEDTLS_RSA_PKCS_V15    0 /**< Use PKCS#1 v1.5 encoding. */
+#define MBEDTLS_RSA_PKCS_V21    1 /**< Use PKCS#1 v2.1 encoding. */
 
 #define MBEDTLS_RSA_SIGN        1 /**< Identifier for RSA signature operations. */
 #define MBEDTLS_RSA_CRYPT       2 /**< Identifier for RSA encryption and decryption operations. */
@@ -76,14 +77,14 @@
  * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
  */
 
-#if !defined(MBEDTLS_RSA_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_RSA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief   The RSA context structure.
  *
@@ -96,24 +97,24 @@
     int ver;                    /*!<  Always 0.*/
     size_t len;                 /*!<  The size of \p N in Bytes. */
 
-    mbedtls_mpi N;                      /*!<  The public modulus. */
-    mbedtls_mpi E;                      /*!<  The public exponent. */
+    mbedtls_mpi N;              /*!<  The public modulus. */
+    mbedtls_mpi E;              /*!<  The public exponent. */
 
-    mbedtls_mpi D;                      /*!<  The private exponent. */
-    mbedtls_mpi P;                      /*!<  The first prime factor. */
-    mbedtls_mpi Q;                      /*!<  The second prime factor. */
+    mbedtls_mpi D;              /*!<  The private exponent. */
+    mbedtls_mpi P;              /*!<  The first prime factor. */
+    mbedtls_mpi Q;              /*!<  The second prime factor. */
 
-    mbedtls_mpi DP;                     /*!<  \p D % (P - 1)       */
-    mbedtls_mpi DQ;                     /*!<  \p D % (Q - 1)       */
-    mbedtls_mpi QP;                     /*!<  1 / (Q % P)       */
+    mbedtls_mpi DP;             /*!<  <code>D % (P - 1)</code>. */
+    mbedtls_mpi DQ;             /*!<  <code>D % (Q - 1)</code>. */
+    mbedtls_mpi QP;             /*!<  <code>1 / (Q % P)</code>. */
 
-    mbedtls_mpi RN;                     /*!<  cached R^2 mod \p N  */
+    mbedtls_mpi RN;             /*!<  cached <code>R^2 mod N</code>. */
 
-    mbedtls_mpi RP;                     /*!<  cached R^2 mod \p P  */
-    mbedtls_mpi RQ;                     /*!<  cached R^2 mod \p Q  */
+    mbedtls_mpi RP;             /*!<  cached <code>R^2 mod P</code>. */
+    mbedtls_mpi RQ;             /*!<  cached <code>R^2 mod Q</code>. */
 
-    mbedtls_mpi Vi;                     /*!<  The cached blinding value. */
-    mbedtls_mpi Vf;                     /*!<  The cached un-blinding value. */
+    mbedtls_mpi Vi;             /*!<  The cached blinding value. */
+    mbedtls_mpi Vf;             /*!<  The cached un-blinding value. */
 
     int padding;                /*!< Selects padding mode:
                                      #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and
@@ -128,18 +129,16 @@
 }
 mbedtls_rsa_context;
 
+#else  /* MBEDTLS_RSA_ALT */
+#include "rsa_alt.h"
+#endif /* MBEDTLS_RSA_ALT */
+
 /**
  * \brief          This function initializes an RSA context.
  *
  * \note           Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP
  *                 encryption scheme and the RSASSA-PSS signature scheme.
  *
- * \param ctx      The RSA context to initialize.
- * \param padding  Selects padding mode: #MBEDTLS_RSA_PKCS_V15 or
- *                 #MBEDTLS_RSA_PKCS_V21.
- * \param hash_id  The hash identifier of #mbedtls_md_type_t type, if
- *                 \p padding is #MBEDTLS_RSA_PKCS_V21.
- *
  * \note           The \p hash_id parameter is ignored when using
  *                 #MBEDTLS_RSA_PKCS_V15 padding.
  *
@@ -153,6 +152,12 @@
  *                 encryption. For PSS signatures, it is always used for
  *                 making signatures, but can be overriden for verifying them.
  *                 If set to #MBEDTLS_MD_NONE, it is always overriden.
+ *
+ * \param ctx      The RSA context to initialize.
+ * \param padding  Selects padding mode: #MBEDTLS_RSA_PKCS_V15 or
+ *                 #MBEDTLS_RSA_PKCS_V21.
+ * \param hash_id  The hash identifier of #mbedtls_md_type_t type, if
+ *                 \p padding is #MBEDTLS_RSA_PKCS_V21.
  */
 void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
                        int padding,
@@ -162,13 +167,6 @@
  * \brief          This function imports a set of core parameters into an
  *                 RSA context.
  *
- * \param ctx      The initialized RSA context to store the parameters in.
- * \param N        The RSA modulus, or NULL.
- * \param P        The first prime factor of \p N, or NULL.
- * \param Q        The second prime factor of \p N, or NULL.
- * \param D        The private exponent, or NULL.
- * \param E        The public exponent, or NULL.
- *
  * \note           This function can be called multiple times for successive
  *                 imports, if the parameters are not simultaneously present.
  *
@@ -184,7 +182,15 @@
  * \note           The imported parameters are copied and need not be preserved
  *                 for the lifetime of the RSA context being set up.
  *
- * \return         \c 0 on success, or a non-zero error code on failure.
+ * \param ctx      The initialized RSA context to store the parameters in.
+ * \param N        The RSA modulus, or NULL.
+ * \param P        The first prime factor of \p N, or NULL.
+ * \param Q        The second prime factor of \p N, or NULL.
+ * \param D        The private exponent, or NULL.
+ * \param E        The public exponent, or NULL.
+ *
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
  */
 int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
                         const mbedtls_mpi *N,
@@ -195,6 +201,21 @@
  * \brief          This function imports core RSA parameters, in raw big-endian
  *                 binary format, into an RSA context.
  *
+ * \note           This function can be called multiple times for successive
+ *                 imports, if the parameters are not simultaneously present.
+ *
+ *                 Any sequence of calls to this function should be followed
+ *                 by a call to mbedtls_rsa_complete(), which checks and
+ *                 completes the provided information to a ready-for-use
+ *                 public or private RSA key.
+ *
+ * \note           See mbedtls_rsa_complete() for more information on which
+ *                 parameters are necessary to set up a private or public
+ *                 RSA key.
+ *
+ * \note           The imported parameters are copied and need not be preserved
+ *                 for the lifetime of the RSA context being set up.
+ *
  * \param ctx      The initialized RSA context to store the parameters in.
  * \param N        The RSA modulus, or NULL.
  * \param N_len    The Byte length of \p N, ignored if \p N == NULL.
@@ -207,22 +228,8 @@
  * \param E        The public exponent, or NULL.
  * \param E_len    The Byte length of \p E, ignored if \p E == NULL.
  *
- * \note           This function can be called multiple times for successive
- *                 imports, if the parameters are not simultaneously present.
- *
- *                 Any sequence of calls to this function should be followed
- *                 by a call to mbedtls_rsa_complete(), which checks and
- *                 completes the provided information to a ready-for-use
- *                 public or private RSA key.
- *
- * \note           See mbedtls_rsa_complete() for more information on which
- *                 parameters are necessary to set up a private or public
- *                 RSA key.
- *
- * \note           The imported parameters are copied and need not be preserved
- *                 for the lifetime of the RSA context being set up.
- *
- * \return         \c 0 on success, or a non-zero error code on failure.
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
  */
 int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
                             unsigned char const *N, size_t N_len,
@@ -250,17 +257,18 @@
  *                 the RSA context can be used for RSA operations without
  *                 the risk of failure or crash.
  *
- * \param ctx      The initialized RSA context holding imported parameters.
- *
- * \return         \c 0 on success, or #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the
- *                 attempted derivations failed.
- *
  * \warning        This function need not perform consistency checks
  *                 for the imported parameters. In particular, parameters that
  *                 are not needed by the implementation might be silently
  *                 discarded and left unchecked. To check the consistency
  *                 of the key material, see mbedtls_rsa_check_privkey().
  *
+ * \param ctx      The initialized RSA context holding imported parameters.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations
+ *                 failed.
+ *
  */
 int mbedtls_rsa_complete( mbedtls_rsa_context *ctx );
 
@@ -292,11 +300,11 @@
  * \param D        The MPI to hold the private exponent, or NULL.
  * \param E        The MPI to hold the public exponent, or NULL.
  *
- * \return         \c 0 on success,
- *                 #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
  *                 requested parameters cannot be done due to missing
- *                 functionality or because of security policies,
- *                 or a non-zero return code on any other failure.
+ *                 functionality or because of security policies.
+ * \return         A non-zero return code on any other failure.
  *
  */
 int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
@@ -324,6 +332,9 @@
  *                 If the function fails due to an unsupported operation,
  *                 the RSA context stays intact and remains usable.
  *
+ * \note           The length parameters are ignored if the corresponding
+ *                 buffer pointers are NULL.
+ *
  * \param ctx      The initialized RSA context.
  * \param N        The Byte array to store the RSA modulus, or NULL.
  * \param N_len    The size of the buffer for the modulus.
@@ -331,21 +342,18 @@
  *                 NULL.
  * \param P_len    The size of the buffer for the first prime factor.
  * \param Q        The Byte array to hold the second prime factor of \p N, or
-                   NULL.
+ *                 NULL.
  * \param Q_len    The size of the buffer for the second prime factor.
  * \param D        The Byte array to hold the private exponent, or NULL.
  * \param D_len    The size of the buffer for the private exponent.
  * \param E        The Byte array to hold the public exponent, or NULL.
  * \param E_len    The size of the buffer for the public exponent.
  *
- * \note           The length fields are ignored if the corresponding
- *                 buffer pointers are NULL.
- *
- * \return         \c 0 on success,
- *                 #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the
  *                 requested parameters cannot be done due to missing
- *                 functionality or because of security policies,
- *                 or a non-zero return code on any other failure.
+ *                 functionality or because of security policies.
+ * \return         A non-zero return code on any other failure.
  */
 int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
                             unsigned char *N, size_t N_len,
@@ -357,16 +365,17 @@
 /**
  * \brief          This function exports CRT parameters of a private RSA key.
  *
+ * \note           Alternative RSA implementations not using CRT-parameters
+ *                 internally can implement this function based on
+ *                 mbedtls_rsa_deduce_opt().
+ *
  * \param ctx      The initialized RSA context.
  * \param DP       The MPI to hold D modulo P-1, or NULL.
  * \param DQ       The MPI to hold D modulo Q-1, or NULL.
  * \param QP       The MPI to hold modular inverse of Q modulo P, or NULL.
  *
- * \return         \c 0 on success, non-zero error code otherwise.
- *
- * \note           Alternative RSA implementations not using CRT-parameters
- *                 internally can implement this function based on
- *                 mbedtls_rsa_deduce_opt().
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
  *
  */
 int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
@@ -397,17 +406,17 @@
 /**
  * \brief          This function generates an RSA keypair.
  *
- * \param ctx      The RSA context used to hold the key.
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG parameter.
- * \param nbits    The size of the public key in bits.
- * \param exponent The public exponent. For example, 65537.
- *
  * \note           mbedtls_rsa_init() must be called before this function,
  *                 to set up the RSA context.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
-                   on failure.
+ * \param ctx      The RSA context used to hold the key.
+ * \param f_rng    The RNG function.
+ * \param p_rng    The RNG context.
+ * \param nbits    The size of the public key in bits.
+ * \param exponent The public exponent. For example, 65537.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
                          int (*f_rng)(void *, unsigned char *, size_t),
@@ -424,8 +433,8 @@
  *
  * \param ctx      The RSA context to check.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  *
  */
 int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx );
@@ -434,11 +443,6 @@
  * \brief      This function checks if a context contains an RSA private key
  *             and perform basic consistency checks.
  *
- * \param ctx  The RSA context to check.
- *
- * \return     \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code on
- *             failure.
- *
  * \note       The consistency checks performed by this function not only
  *             ensure that mbedtls_rsa_private() can be called successfully
  *             on the given context, but that the various parameters are
@@ -465,6 +469,11 @@
  *             user to ensure the trustworthiness of the source of his RSA
  *             parameters, which goes beyond what is effectively checkable
  *             by the library.</li></ul>
+ *
+ * \param ctx  The RSA context to check.
+ *
+ * \return     \c 0 on success.
+ * \return     An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx );
 
@@ -476,8 +485,8 @@
  * \param pub      The RSA context holding the public key.
  * \param prv      The RSA context holding the private key.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
                                 const mbedtls_rsa_context *prv );
@@ -485,13 +494,6 @@
 /**
  * \brief          This function performs an RSA public key operation.
  *
- * \param ctx      The RSA context.
- * \param input    The input buffer.
- * \param output   The output buffer.
- *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
- *
  * \note           This function does not handle message padding.
  *
  * \note           Make sure to set \p input[0] = 0 or ensure that
@@ -499,6 +501,13 @@
  *
  * \note           The input and output buffers must be large
  *                 enough. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \param ctx      The RSA context.
+ * \param input    The input buffer.
+ * \param output   The output buffer.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
                 const unsigned char *input,
@@ -507,15 +516,6 @@
 /**
  * \brief          This function performs an RSA private key operation.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for blinding.
- * \param p_rng    The RNG parameter.
- * \param input    The input buffer.
- * \param output   The output buffer.
- *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
- *
  * \note           The input and output buffers must be large
  *                 enough. For example, 128 Bytes if RSA-1024 is used.
  *
@@ -530,6 +530,15 @@
  *                 Future versions of the library may enforce the presence
  *                 of a PRNG.
  *
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Needed for blinding.
+ * \param p_rng    The RNG context.
+ * \param input    The input buffer.
+ * \param output   The output buffer.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
  */
 int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -544,15 +553,8 @@
  *                 It is the generic wrapper for performing a PKCS#1 encryption
  *                 operation using the \p mode from the context.
  *
- *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for padding, PKCS#1 v2.1
- *                 encoding, and #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param ilen     The length of the plaintext.
- * \param input    The buffer holding the data to encrypt.
- * \param output   The buffer used to hold the ciphertext.
+ * \note           The input and output buffers must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
@@ -563,11 +565,17 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Needed for padding, PKCS#1 v2.1
+ *                 encoding, and #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ilen     The length of the plaintext.
+ * \param input    The buffer holding the data to encrypt.
+ * \param output   The buffer used to hold the ciphertext.
  *
- * \note           The input and output buffers must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
                        int (*f_rng)(void *, unsigned char *, size_t),
@@ -580,14 +588,8 @@
  * \brief          This function performs a PKCS#1 v1.5 encryption operation
  *                 (RSAES-PKCS1-v1_5-ENCRYPT).
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for padding and
- *                 #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param ilen     The length of the plaintext.
- * \param input    The buffer holding the data to encrypt.
- * \param output   The buffer used to hold the ciphertext.
+ * \note           The output buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
@@ -598,11 +600,17 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Needed for padding and
+ *                 #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param ilen     The length of the plaintext.
+ * \param input    The buffer holding the data to encrypt.
+ * \param output   The buffer used to hold the ciphertext.
  *
- * \note           The output buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
                                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -615,10 +623,22 @@
  * \brief            This function performs a PKCS#1 v2.1 OAEP encryption
  *                   operation (RSAES-OAEP-ENCRYPT).
  *
+ * \note             The output buffer must be as large as the size
+ *                   of ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated       It is deprecated and discouraged to call this function
+ *                   in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                   are likely to remove the \p mode argument and have it
+ *                   implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note             Alternative implementations of RSA need not support
+ *                   mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                   return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \param ctx        The RSA context.
  * \param f_rng      The RNG function. Needed for padding and PKCS#1 v2.1
  *                   encoding and #MBEDTLS_RSA_PRIVATE.
- * \param p_rng      The RNG parameter.
+ * \param p_rng      The RNG context.
  * \param mode       #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
  * \param label      The buffer holding the custom label to use.
  * \param label_len  The length of the label.
@@ -626,20 +646,8 @@
  * \param input      The buffer holding the data to encrypt.
  * \param output     The buffer used to hold the ciphertext.
  *
- * \deprecated     It is deprecated and discouraged to call this function
- *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
- *                 are likely to remove the \p mode argument and have it
- *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
- *
- * \note           Alternative implementations of RSA need not support
- *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
- *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
- *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
- *
- * \note           The output buffer must be as large as the size
- *                 of ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ * \return           \c 0 on success.
+ * \return           An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
                             int (*f_rng)(void *, unsigned char *, size_t),
@@ -657,14 +665,15 @@
  *                 It is the generic wrapper for performing a PKCS#1 decryption
  *                 operation using the \p mode from the context.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param olen     The length of the plaintext.
- * \param input    The buffer holding the encrypted data.
- * \param output   The buffer used to hold the plaintext.
- * \param output_max_len    The maximum length of the output buffer.
+ * \note           The output buffer length \c output_max_len should be
+ *                 as large as the size \p ctx->len of \p ctx->N (for example,
+ *                 128 Bytes if RSA-1024 is used) to be able to hold an
+ *                 arbitrary decrypted message. If it is not large enough to
+ *                 hold the decryption of the particular ciphertext provided,
+ *                 the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \note           The input buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
@@ -675,18 +684,17 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param olen     The length of the plaintext.
+ * \param input    The buffer holding the encrypted data.
+ * \param output   The buffer used to hold the plaintext.
+ * \param output_max_len    The maximum length of the output buffer.
  *
- * \note           The output buffer length \c output_max_len should be
- *                 as large as the size \p ctx->len of \p ctx->N (for example,
- *                 128 Bytes if RSA-1024 is used) to be able to hold an
- *                 arbitrary decrypted message. If it is not large enough to
- *                 hold the decryption of the particular ciphertext provided,
- *                 the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
- *
- * \note           The input buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
                        int (*f_rng)(void *, unsigned char *, size_t),
@@ -700,14 +708,15 @@
  * \brief          This function performs a PKCS#1 v1.5 decryption
  *                 operation (RSAES-PKCS1-v1_5-DECRYPT).
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param olen     The length of the plaintext.
- * \param input    The buffer holding the encrypted data.
- * \param output   The buffer to hold the plaintext.
- * \param output_max_len    The maximum length of the output buffer.
+ * \note           The output buffer length \c output_max_len should be
+ *                 as large as the size \p ctx->len of \p ctx->N, for example,
+ *                 128 Bytes if RSA-1024 is used, to be able to hold an
+ *                 arbitrary decrypted message. If it is not large enough to
+ *                 hold the decryption of the particular ciphertext provided,
+ *                 the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \note           The input buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
@@ -718,18 +727,18 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param olen     The length of the plaintext.
+ * \param input    The buffer holding the encrypted data.
+ * \param output   The buffer to hold the plaintext.
+ * \param output_max_len    The maximum length of the output buffer.
  *
- * \note           The output buffer length \c output_max_len should be
- *                 as large as the size \p ctx->len of \p ctx->N, for example,
- *                 128 Bytes if RSA-1024 is used, to be able to hold an
- *                 arbitrary decrypted message. If it is not large enough to
- *                 hold the decryption of the particular ciphertext provided,
- *                 the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  *
- * \note           The input buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
                                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -740,12 +749,32 @@
                                  size_t output_max_len );
 
 /**
- * \brief          This function performs a PKCS#1 v2.1 OAEP decryption
- *                 operation (RSAES-OAEP-DECRYPT).
+ * \brief            This function performs a PKCS#1 v2.1 OAEP decryption
+ *                   operation (RSAES-OAEP-DECRYPT).
+ *
+ * \note             The output buffer length \c output_max_len should be
+ *                   as large as the size \p ctx->len of \p ctx->N, for
+ *                   example, 128 Bytes if RSA-1024 is used, to be able to
+ *                   hold an arbitrary decrypted message. If it is not
+ *                   large enough to hold the decryption of the particular
+ *                   ciphertext provided, the function returns
+ *                   #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \note             The input buffer must be as large as the size
+ *                   of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated       It is deprecated and discouraged to call this function
+ *                   in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
+ *                   are likely to remove the \p mode argument and have it
+ *                   implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note             Alternative implementations of RSA need not support
+ *                   mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                   return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
  * \param ctx        The RSA context.
  * \param f_rng      The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng      The RNG parameter.
+ * \param p_rng      The RNG context.
  * \param mode       #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
  * \param label      The buffer holding the custom label to use.
  * \param label_len  The length of the label.
@@ -754,28 +783,8 @@
  * \param output     The buffer to hold the plaintext.
  * \param output_max_len    The maximum length of the output buffer.
  *
- * \deprecated     It is deprecated and discouraged to call this function
- *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
- *                 are likely to remove the \p mode argument and have it
- *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
- *
- * \note           Alternative implementations of RSA need not support
- *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
- *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
- *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
- *
- * \note           The output buffer length \c output_max_len should be
- *                 as large as the size \p ctx->len of \p ctx->N, for
- *                 example, 128 Bytes if RSA-1024 is used, to be able to
- *                 hold an arbitrary decrypted message. If it is not
- *                 large enough to hold the decryption of the particular
- *                 ciphertext provided, the function returns
- *                 #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
- *
- * \note           The input buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
                             int (*f_rng)(void *, unsigned char *, size_t),
@@ -794,16 +803,12 @@
  *                 It is the generic wrapper for performing a PKCS#1
  *                 signature using the \p mode from the context.
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for PKCS#1 v2.1 encoding and for
- *                 #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param md_alg   The message-digest algorithm used to hash the original data.
- *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer to hold the ciphertext.
+ * \note           The \p sig buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note           For PKCS#1 v2.1 encoding, see comments on
+ *                 mbedtls_rsa_rsassa_pss_sign() for details on
+ *                 \p md_alg and \p hash_id.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
@@ -814,15 +819,19 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 if the signing operation was successful,
- *                 or an \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Needed for PKCS#1 v2.1 encoding and for
+ *                 #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest.
+ * \param sig      The buffer to hold the ciphertext.
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
- * \note           For PKCS#1 v2.1 encoding, see comments on
- *                 mbedtls_rsa_rsassa_pss_sign() for details on
- *                 \p md_alg and \p hash_id.
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
                     int (*f_rng)(void *, unsigned char *, size_t),
@@ -837,15 +846,8 @@
  * \brief          This function performs a PKCS#1 v1.5 signature
  *                 operation (RSASSA-PKCS1-v1_5-SIGN).
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param md_alg   The message-digest algorithm used to hash the original data.
- *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer to hold the ciphertext.
+ * \note           The \p sig buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
@@ -856,12 +858,18 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 if the signing operation was successful,
- *                 or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest.
+ * \param sig      The buffer to hold the ciphertext.
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
                                int (*f_rng)(void *, unsigned char *, size_t),
@@ -876,16 +884,15 @@
  * \brief          This function performs a PKCS#1 v2.1 PSS signature
  *                 operation (RSASSA-PSS-SIGN).
  *
- * \param ctx      The RSA context.
- * \param f_rng    The RNG function. Needed for PKCS#1 v2.1 encoding and for
- *                 #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param md_alg   The message-digest algorithm used to hash the original data.
- *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer to hold the ciphertext.
+ * \note           The \p sig buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note           The \p hash_id in the RSA context is the one used for the
+ *                 encoding. \p md_alg in the function call is the type of hash
+ *                 that is encoded. According to <em>RFC-3447: Public-Key
+ *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ *                 Specifications</em> it is advised to keep both hashes the
+ *                 same.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
@@ -896,19 +903,19 @@
  *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 if the signing operation was successful,
- *                 or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA context.
+ * \param f_rng    The RNG function. Needed for PKCS#1 v2.1 encoding and for
+ *                 #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest.
+ * \param sig      The buffer to hold the ciphertext.
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
- * \note           The \p hash_id in the RSA context is the one used for the
- *                 encoding. \p md_alg in the function call is the type of hash
- *                 that is encoded. According to <em>RFC-3447: Public-Key
- *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
- *                 Specifications</em> it is advised to keep both hashes the
- *                 same.
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
                          int (*f_rng)(void *, unsigned char *, size_t),
@@ -926,15 +933,12 @@
  *                 This is the generic wrapper for performing a PKCS#1
  *                 verification using the mode from the context.
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param md_alg   The message-digest algorithm used to hash the original data.
- *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer holding the ciphertext.
+ * \note           The \p sig buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note           For PKCS#1 v2.1 encoding, see comments on
+ *                 mbedtls_rsa_rsassa_pss_verify() about \p md_alg and
+ *                 \p hash_id.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
@@ -945,16 +949,18 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 if the verify operation was successful,
- *                 or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA public key context.
+ * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest.
+ * \param sig      The buffer holding the ciphertext.
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
- *
- * \note           For PKCS#1 v2.1 encoding, see comments on
- *                 mbedtls_rsa_rsassa_pss_verify() about \p md_alg and
- *                 \p hash_id.
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
                       int (*f_rng)(void *, unsigned char *, size_t),
@@ -969,15 +975,8 @@
  * \brief          This function performs a PKCS#1 v1.5 verification
  *                 operation (RSASSA-PKCS1-v1_5-VERIFY).
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param md_alg   The message-digest algorithm used to hash the original data.
- *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer holding the ciphertext.
+ * \note           The \p sig buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
  * \deprecated     It is deprecated and discouraged to call this function
  *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
@@ -988,12 +987,18 @@
  *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
  *
- * \return         \c 0 if the verify operation was successful,
- *                 or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
+ * \param ctx      The RSA public key context.
+ * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest.
+ * \param sig      The buffer holding the ciphertext.
  *
- * \note           The \p sig buffer must be as large as the size
- *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
                                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -1011,29 +1016,6 @@
  *                 The hash function for the MGF mask generating function
  *                 is that specified in the RSA context.
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param md_alg   The message-digest algorithm used to hash the original data.
- *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param sig      The buffer holding the ciphertext.
- *
- * \deprecated     It is deprecated and discouraged to call this function
- *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
- *                 are likely to remove the \p mode argument and have it
- *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
- *
- * \note           Alternative implementations of RSA need not support
- *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
- *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
- *
- * \return         \c 0 if the verify operation was successful,
- *                 or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
- *
  * \note           The \p sig buffer must be as large as the size
  *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
@@ -1044,6 +1026,28 @@
  *                 Specifications</em> it is advised to keep both hashes the
  *                 same. If \p hash_id in the RSA context is unset,
  *                 the \p md_alg from the function call is used.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
+ * \param ctx      The RSA public key context.
+ * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest.
+ * \param sig      The buffer holding the ciphertext.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
                            int (*f_rng)(void *, unsigned char *, size_t),
@@ -1061,27 +1065,27 @@
  *                 The hash function for the MGF mask generating function
  *                 is that specified in \p mgf1_hash_id.
  *
- * \param ctx      The RSA public key context.
- * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
- * \param p_rng    The RNG parameter.
- * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
- * \param md_alg   The message-digest algorithm used to hash the original data.
- *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE.
- * \param hash     The buffer holding the message digest.
- * \param mgf1_hash_id The message digest used for mask generation.
- * \param expected_salt_len The length of the salt used in padding. Use
- *                 #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
- * \param sig      The buffer holding the ciphertext.
- *
- * \return         \c 0 if the verify operation was successful,
- *                 or an \c MBEDTLS_ERR_RSA_XXX error code
- *                 on failure.
- *
  * \note           The \p sig buffer must be as large as the size
  *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
  * \note           The \p hash_id in the RSA context is ignored.
+ *
+ * \param ctx      The RSA public key context.
+ * \param f_rng    The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE.
+ * \param p_rng    The RNG context.
+ * \param mode     #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest. Only used if \p md_alg is
+ *                 #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest.
+ * \param mgf1_hash_id       The message digest used for mask generation.
+ * \param expected_salt_len  The length of the salt used in padding. Use
+ *                           #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
+ * \param sig      The buffer holding the ciphertext.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
                                int (*f_rng)(void *, unsigned char *, size_t),
@@ -1100,8 +1104,8 @@
  * \param dst      The destination context.
  * \param src      The source context.
  *
- * \return         \c 0 on success,
- *                 #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure.
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure.
  */
 int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src );
 
@@ -1112,22 +1116,11 @@
  */
 void mbedtls_rsa_free( mbedtls_rsa_context *ctx );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_RSA_ALT */
-#include "rsa_alt.h"
-#endif /* MBEDTLS_RSA_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          The RSA checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_rsa_self_test( int verbose );
 
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index 05540cd..65a124c 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -1,7 +1,10 @@
 /**
  * \file sha1.h
  *
- * \brief The SHA-1 cryptographic hash function.
+ * \brief This file contains SHA-1 definitions and functions.
+ *
+ * The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in
+ * <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
  *
  * \warning   SHA-1 is considered a weak message digest and its use constitutes
  *            a security risk. We recommend considering stronger message
@@ -39,14 +42,14 @@
 
 #define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
 
-#if !defined(MBEDTLS_SHA1_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA1_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          The SHA-1 context structure.
  *
@@ -63,40 +66,44 @@
 }
 mbedtls_sha1_context;
 
+#else  /* MBEDTLS_SHA1_ALT */
+#include "sha1_alt.h"
+#endif /* MBEDTLS_SHA1_ALT */
+
 /**
  * \brief          This function initializes a SHA-1 context.
  *
- * \param ctx      The SHA-1 context to initialize.
- *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \param ctx      The SHA-1 context to initialize.
+ *
  */
 void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
 
 /**
  * \brief          This function clears a SHA-1 context.
  *
- * \param ctx      The SHA-1 context to clear.
- *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \param ctx      The SHA-1 context to clear.
+ *
  */
 void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
 
 /**
  * \brief          This function clones the state of a SHA-1 context.
  *
- * \param dst      The destination context.
- * \param src      The context to clone.
- *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \param dst      The SHA-1 context to clone to.
+ * \param src      The SHA-1 context to clone from.
+ *
  */
 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
                          const mbedtls_sha1_context *src );
@@ -104,14 +111,14 @@
 /**
  * \brief          This function starts a SHA-1 checksum calculation.
  *
- * \param ctx      The context to initialize.
- *
- * \return         \c 0 if successful
- *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \param ctx      The SHA-1 context to initialize.
+ *
+ * \return         \c 0 on success.
+ *
  */
 int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
 
@@ -119,16 +126,15 @@
  * \brief          This function feeds an input buffer into an ongoing SHA-1
  *                 checksum calculation.
  *
- * \param ctx      The SHA-1 context.
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
- *
- * \return         \c 0 if successful
- *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \param ctx      The SHA-1 context.
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ *
+ * \return         \c 0 on success.
  */
 int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
                              const unsigned char *input,
@@ -138,31 +144,30 @@
  * \brief          This function finishes the SHA-1 operation, and writes
  *                 the result to the output buffer.
  *
- * \param ctx      The SHA-1 context.
- * \param output   The SHA-1 checksum result.
- *
- * \return         \c 0 if successful
- *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \param ctx      The SHA-1 context.
+ * \param output   The SHA-1 checksum result.
+ *
+ * \return         \c 0 on success.
  */
 int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
                              unsigned char output[20] );
 
 /**
- * \brief          SHA-1 process data block (internal use only)
- *
- * \param ctx      SHA-1 context
- * \param data     The data block being processed.
- *
- * \return         \c 0 if successful
+ * \brief          SHA-1 process data block (internal use only).
  *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \param ctx      The SHA-1 context.
+ * \param data     The data block being processed.
+ *
+ * \return         \c 0 on success.
+ *
  */
 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
                                    const unsigned char data[64] );
@@ -174,65 +179,67 @@
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief          SHA-1 context setup
- *
- * \deprecated     Superseded by mbedtls_sha1_starts_ret() in 2.7.0
- *
- * \param ctx      The SHA-1 context to be initialized.
+ * \brief          This function starts a SHA-1 checksum calculation.
  *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \deprecated     Superseded by mbedtls_sha1_starts_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context to initialize.
+ *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
 
 /**
- * \brief          SHA-1 process buffer
- *
- * \deprecated     Superseded by mbedtls_sha1_update_ret() in 2.7.0
- *
- * \param ctx      The SHA-1 context.
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ * \brief          This function feeds an input buffer into an ongoing SHA-1
+ *                 checksum calculation.
  *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \deprecated     Superseded by mbedtls_sha1_update_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context.
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
                                              const unsigned char *input,
                                              size_t ilen );
 
 /**
- * \brief          SHA-1 final digest
- *
- * \deprecated     Superseded by mbedtls_sha1_finish_ret() in 2.7.0
- *
- * \param ctx      The SHA-1 context.
- * \param output   The SHA-1 checksum result.
+ * \brief          This function finishes the SHA-1 operation, and writes
+ *                 the result to the output buffer.
  *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \deprecated     Superseded by mbedtls_sha1_finish_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context.
+ * \param output   The SHA-1 checksum result.
+ *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
                                              unsigned char output[20] );
 
 /**
- * \brief          SHA-1 process data block (internal use only)
- *
- * \deprecated     Superseded by mbedtls_internal_sha1_process() in 2.7.0
- *
- * \param ctx      The SHA-1 context.
- * \param data     The data block being processed.
+ * \brief          SHA-1 process data block (internal use only).
  *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \deprecated     Superseded by mbedtls_internal_sha1_process() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context.
+ * \param data     The data block being processed.
+ *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
                                               const unsigned char data[64] );
@@ -240,18 +247,6 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_SHA1_ALT */
-#include "sha1_alt.h"
-#endif /* MBEDTLS_SHA1_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          This function calculates the SHA-1 checksum of a buffer.
  *
@@ -261,15 +256,15 @@
  *                 The SHA-1 result is calculated as
  *                 output = SHA-1(input buffer).
  *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
  * \param input    The buffer holding the input data.
  * \param ilen     The length of the input data.
  * \param output   The SHA-1 checksum result.
  *
- * \return         \c 0 if successful
- *
- * \warning        SHA-1 is considered a weak message digest and its use
- *                 constitutes a security risk. We recommend considering
- *                 stronger message digests instead.
+ * \return         \c 0 on success.
  *
  */
 int mbedtls_sha1_ret( const unsigned char *input,
@@ -283,7 +278,17 @@
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief          Output = SHA-1( input buffer )
+ * \brief          This function calculates the SHA-1 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-1 result is calculated as
+ *                 output = SHA-1(input buffer).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
  *
  * \deprecated     Superseded by mbedtls_sha1_ret() in 2.7.0
  *
@@ -291,10 +296,6 @@
  * \param ilen     The length of the input data.
  * \param output   The SHA-1 checksum result.
  *
- * \warning        SHA-1 is considered a weak message digest and its use
- *                 constitutes a security risk. We recommend considering
- *                 stronger message digests instead.
- *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input,
                                       size_t ilen,
@@ -306,12 +307,13 @@
 /**
  * \brief          The SHA-1 checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
- *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ *
  */
 int mbedtls_sha1_self_test( int verbose );
 
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index ffb16c2..adf31a8 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -1,7 +1,10 @@
 /**
  * \file sha256.h
  *
- * \brief The SHA-224 and SHA-256 cryptographic hash function.
+ * \brief This file contains SHA-224 and SHA-256 definitions and functions.
+ *
+ * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
  */
 /*
  *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@@ -35,14 +38,14 @@
 
 #define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
 
-#if !defined(MBEDTLS_SHA256_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA256_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          The SHA-256 context structure.
  *
@@ -55,12 +58,15 @@
     uint32_t total[2];          /*!< The number of Bytes processed.  */
     uint32_t state[8];          /*!< The intermediate digest state.  */
     unsigned char buffer[64];   /*!< The data block being processed. */
-    int is224;                  /*!< Determines which function to use.
-                                     <ul><li>0: Use SHA-256.</li>
-                                     <li>1: Use SHA-224.</li></ul> */
+    int is224;                  /*!< Determines which function to use:
+                                     0: Use SHA-256, or 1: Use SHA-224. */
 }
 mbedtls_sha256_context;
 
+#else  /* MBEDTLS_SHA256_ALT */
+#include "sha256_alt.h"
+#endif /* MBEDTLS_SHA256_ALT */
+
 /**
  * \brief          This function initializes a SHA-256 context.
  *
@@ -89,9 +95,8 @@
  *                 calculation.
  *
  * \param ctx      The context to initialize.
- * \param is224    Determines which function to use.
- *                 <ul><li>0: Use SHA-256.</li>
- *                 <li>1: Use SHA-224.</li></ul>
+ * \param is224    Determines which function to use:
+ *                 0: Use SHA-256, or 1: Use SHA-224.
  *
  * \return         \c 0 on success.
  */
@@ -101,9 +106,9 @@
  * \brief          This function feeds an input buffer into an ongoing
  *                 SHA-256 checksum calculation.
  *
- * \param ctx      SHA-256 context
- * \param input    buffer holding the data
- * \param ilen     length of the input data
+ * \param ctx      The SHA-256 context.
+ * \param input    The buffer holding the data.
+ * \param ilen     The length of the input data.
  *
  * \return         \c 0 on success.
  */
@@ -143,14 +148,15 @@
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief          This function starts a SHA-256 checksum calculation.
+ * \brief          This function starts a SHA-224 or SHA-256 checksum
+ *                 calculation.
+ *
  *
  * \deprecated     Superseded by mbedtls_sha256_starts_ret() in 2.7.0.
  *
- * \param ctx      The SHA-256 context to initialize.
- * \param is224    Determines which function to use.
- *                 <ul><li>0: Use SHA-256.</li>
- *                 <li>1: Use SHA-224.</li></ul>
+ * \param ctx      The context to initialize.
+ * \param is224    Determines which function to use:
+ *                 0: Use SHA-256, or 1: Use SHA-224.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
                                                int is224 );
@@ -176,7 +182,7 @@
  * \deprecated     Superseded by mbedtls_sha256_finish_ret() in 2.7.0.
  *
  * \param ctx      The SHA-256 context.
- * \param output   The SHA-224or SHA-256 checksum result.
+ * \param output   The SHA-224 or SHA-256 checksum result.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
                                                unsigned char output[32] );
@@ -196,17 +202,6 @@
 
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_SHA256_ALT */
-#include "sha256_alt.h"
-#endif /* MBEDTLS_SHA256_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
 
 /**
  * \brief          This function calculates the SHA-224 or SHA-256
@@ -221,9 +216,8 @@
  * \param input    The buffer holding the input data.
  * \param ilen     The length of the input data.
  * \param output   The SHA-224 or SHA-256 checksum result.
- * \param is224    Determines which function to use.
- *                 <ul><li>0: Use SHA-256.</li>
- *                 <li>1: Use SHA-224.</li></ul>
+ * \param is224    Determines which function to use:
+ *                 0: Use SHA-256, or 1: Use SHA-224.
  */
 int mbedtls_sha256_ret( const unsigned char *input,
                         size_t ilen,
@@ -252,9 +246,8 @@
  * \param input    The buffer holding the data.
  * \param ilen     The length of the input data.
  * \param output   The SHA-224 or SHA-256 checksum result.
- * \param is224    Determines which function to use.
- *                 <ul><li>0: Use SHA-256.</li>
- *                 <li>1: Use SHA-224.</li></ul>
+ * \param is224    Determines which function to use:
+ *                 0: Use SHA-256, or 1: Use SHA-224.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input,
                                         size_t ilen,
@@ -267,7 +260,8 @@
 /**
  * \brief          The SHA-224 and SHA-256 checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_sha256_self_test( int verbose );
 
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 8404a2d..5bb83f4 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -1,7 +1,9 @@
 /**
  * \file sha512.h
+ * \brief This file contains SHA-384 and SHA-512 definitions and functions.
  *
- * \brief The SHA-384 and SHA-512 cryptographic hash function.
+ * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
  */
 /*
  *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@@ -35,14 +37,14 @@
 
 #define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
 
-#if !defined(MBEDTLS_SHA512_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA512_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          The SHA-512 context structure.
  *
@@ -55,12 +57,15 @@
     uint64_t total[2];          /*!< The number of Bytes processed. */
     uint64_t state[8];          /*!< The intermediate digest state. */
     unsigned char buffer[128];  /*!< The data block being processed. */
-    int is384;                  /*!< Determines which function to use.
-                                 *   <ul><li>0: Use SHA-512.</li>
-                                 *   <li>1: Use SHA-384.</li></ul> */
+    int is384;                  /*!< Determines which function to use:
+                                     0: Use SHA-512, or 1: Use SHA-384. */
 }
 mbedtls_sha512_context;
 
+#else  /* MBEDTLS_SHA512_ALT */
+#include "sha512_alt.h"
+#endif /* MBEDTLS_SHA512_ALT */
+
 /**
  * \brief          This function initializes a SHA-512 context.
  *
@@ -89,9 +94,8 @@
  *                 calculation.
  *
  * \param ctx      The SHA-512 context to initialize.
- * \param is384    Determines which function to use.
- *                 <ul><li>0: Use SHA-512.</li>
- *                 <li>1: Use SHA-384.</li></ul>
+ * \param is384    Determines which function to use:
+ *                 0: Use SHA-512, or 1: Use SHA-384.
  *
  * \return         \c 0 on success.
  */
@@ -148,9 +152,8 @@
  * \deprecated     Superseded by mbedtls_sha512_starts_ret() in 2.7.0
  *
  * \param ctx      The SHA-512 context to initialize.
- * \param is384    Determines which function to use.
- *                 <ul><li>0: Use SHA-512.</li>
- *                 <li>1: Use SHA-384.</li></ul>
+ * \param is384    Determines which function to use:
+ *                 0: Use SHA-512, or 1: Use SHA-384.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
                                                int is384 );
@@ -159,7 +162,7 @@
  * \brief          This function feeds an input buffer into an ongoing
  *                 SHA-512 checksum calculation.
  *
- * \deprecated     Superseded by mbedtls_sha512_update_ret() in 2.7.0
+ * \deprecated     Superseded by mbedtls_sha512_update_ret() in 2.7.0.
  *
  * \param ctx      The SHA-512 context.
  * \param input    The buffer holding the data.
@@ -173,7 +176,7 @@
  * \brief          This function finishes the SHA-512 operation, and writes
  *                 the result to the output buffer.
  *
- * \deprecated     Superseded by mbedtls_sha512_finish_ret() in 2.7.0
+ * \deprecated     Superseded by mbedtls_sha512_finish_ret() in 2.7.0.
  *
  * \param ctx      The SHA-512 context.
  * \param output   The SHA-384 or SHA-512 checksum result.
@@ -186,7 +189,7 @@
  *                 the ongoing SHA-512 computation. This function is for
  *                 internal use only.
  *
- * \deprecated     Superseded by mbedtls_internal_sha512_process() in 2.7.0
+ * \deprecated     Superseded by mbedtls_internal_sha512_process() in 2.7.0.
  *
  * \param ctx      The SHA-512 context.
  * \param data     The buffer holding one block of data.
@@ -198,18 +201,6 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_SHA512_ALT */
-#include "sha512_alt.h"
-#endif /* MBEDTLS_SHA512_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          This function calculates the SHA-512 or SHA-384
  *                 checksum of a buffer.
@@ -223,9 +214,8 @@
  * \param input    The buffer holding the input data.
  * \param ilen     The length of the input data.
  * \param output   The SHA-384 or SHA-512 checksum result.
- * \param is384    Determines which function to use.
- *                 <ul><li>0: Use SHA-512.</li>
- *                 <li>1: Use SHA-384.</li></ul>
+ * \param is384    Determines which function to use:
+ *                 0: Use SHA-512, or 1: Use SHA-384.
  *
  * \return         \c 0 on success.
  */
@@ -255,9 +245,8 @@
  * \param input    The buffer holding the data.
  * \param ilen     The length of the input data.
  * \param output   The SHA-384 or SHA-512 checksum result.
- * \param is384    Determines which function to use.
- *                 <ul><li>0: Use SHA-512.</li>
- *                 <li>1: Use SHA-384.</li></ul>
+ * \param is384    Determines which function to use:
+ *                 0: Use SHA-512, or 1: Use SHA-384.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input,
                                         size_t ilen,
@@ -269,7 +258,8 @@
  /**
  * \brief          The SHA-384 or SHA-512 checkup routine.
  *
- * \return         \c 0 on success, or \c 1 on failure.
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
  */
 int mbedtls_sha512_self_test( int verbose );
 
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index bb9c02d..250031a 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -947,14 +947,6 @@
 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
 
 /**
- * \brief Returns the list of ciphersuites supported by the SSL/TLS module.
- *
- * \return              a statically allocated array of ciphersuites, the last
- *                      entry is 0.
- */
-const int *mbedtls_ssl_list_ciphersuites( void );
-
-/**
  * \brief               Return the name of the ciphersuite associated with the
  *                      given ID
  *
@@ -1854,21 +1846,21 @@
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 /**
- * \brief          Set or reset the hostname to check against the received 
- *                 server certificate. It sets the ServerName TLS extension, 
+ * \brief          Set or reset the hostname to check against the received
+ *                 server certificate. It sets the ServerName TLS extension,
  *                 too, if that extension is enabled. (client-side only)
  *
  * \param ssl      SSL context
  * \param hostname the server hostname, may be NULL to clear hostname
- 
+
  * \note           Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN.
  *
- * \return         0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on 
- *                 allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on 
+ * \return         0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on
+ *                 allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on
  *                 too long input hostname.
  *
  *                 Hostname set to the one provided on success (cleared
- *                 when NULL). On allocation failure hostname is cleared. 
+ *                 when NULL). On allocation failure hostname is cleared.
  *                 On too long input failure, old hostname is unchanged.
  */
 int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname );
diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
index 545468a..7d5eba0 100644
--- a/include/mbedtls/ssl_ciphersuites.h
+++ b/include/mbedtls/ssl_ciphersuites.h
@@ -169,6 +169,45 @@
 #define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256           0xC03A /**< Weak! No SSL3! */
 #define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384           0xC03B /**< Weak! No SSL3! */
 
+#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256         0xC03C /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384         0xC03D /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256     0xC044 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384     0xC045 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256  0xC04A /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384  0xC04B /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256   0xC04C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384   0xC04D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256    0xC04E /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384    0xC04F /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256         0xC050 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384         0xC051 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256     0xC052 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384     0xC053 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256  0xC05E /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384  0xC05F /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256   0xC060 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384   0xC061 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256    0xC062 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384    0xC063 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256         0xC064 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384         0xC065 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256     0xC066 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384     0xC067 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256     0xC068 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384     0xC069 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256         0xC06A /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384         0xC06B /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256     0xC06C /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384     0xC06D /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256     0xC06E /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384     0xC06F /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256   0xC070 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384   0xC071 /**< TLS 1.2 */
+
 #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */
 #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */
 #define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  0xC074 /**< Not in SSL3! */
@@ -267,7 +306,7 @@
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)      ||       \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     ||       \
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)    ||       \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) 
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
 #define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED
 #endif
 
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 60b431a..2b5a616 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -630,7 +630,13 @@
     volatile unsigned char diff = 0;
 
     for( i = 0; i < n; i++ )
-        diff |= A[i] ^ B[i];
+    {
+        /* Read volatile data in order before computing diff.
+         * This avoids IAR compiler warning:
+         * 'the order of volatile accesses is undefined ..' */
+        unsigned char x = A[i], y = B[i];
+        diff |= x ^ y;
+    }
 
     return( diff );
 }
diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h
index 2c497bf..bbcb906 100644
--- a/include/mbedtls/timing.h
+++ b/include/mbedtls/timing.h
@@ -30,16 +30,16 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#if !defined(MBEDTLS_TIMING_ALT)
-// Regular implementation
-//
-
 #include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_TIMING_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          timer structure
  */
@@ -58,6 +58,10 @@
     uint32_t                        fin_ms;
 } mbedtls_timing_delay_context;
 
+#else  /* MBEDTLS_TIMING_ALT */
+#include "timing_alt.h"
+#endif /* MBEDTLS_TIMING_ALT */
+
 extern volatile int mbedtls_timing_alarmed;
 
 /**
@@ -133,18 +137,6 @@
  */
 int mbedtls_timing_get_delay( void *data );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_TIMING_ALT */
-#include "timing_alt.h"
-#endif /* MBEDTLS_TIMING_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if defined(MBEDTLS_SELF_TEST)
 /**
  * \brief          Checkup routine
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index c3ee649..83e3c17 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -39,7 +39,7 @@
  * Major, Minor, Patchlevel
  */
 #define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  8
+#define MBEDTLS_VERSION_MINOR  10
 #define MBEDTLS_VERSION_PATCH  0
 
 /**
@@ -47,9 +47,9 @@
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02080000
-#define MBEDTLS_VERSION_STRING         "2.8.0"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.8.0"
+#define MBEDTLS_VERSION_NUMBER         0x020A0000
+#define MBEDTLS_VERSION_STRING         "2.10.0"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.10.0"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/include/mbedtls/xtea.h b/include/mbedtls/xtea.h
index 34ccee3..8df708a 100644
--- a/include/mbedtls/xtea.h
+++ b/include/mbedtls/xtea.h
@@ -39,14 +39,14 @@
 #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
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_XTEA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          XTEA context structure
  */
@@ -56,6 +56,10 @@
 }
 mbedtls_xtea_context;
 
+#else  /* MBEDTLS_XTEA_ALT */
+#include "xtea_alt.h"
+#endif /* MBEDTLS_XTEA_ALT */
+
 /**
  * \brief          Initialize XTEA context
  *
@@ -115,18 +119,6 @@
                     unsigned char *output);
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_XTEA_ALT */
-#include "xtea_alt.h"
-#endif /* MBEDTLS_XTEA_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * \brief          Checkup routine
  *
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 7742c22..60fa7f8 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -6,6 +6,7 @@
     aes.c
     aesni.c
     arc4.c
+    aria.c
     asn1parse.c
     asn1write.c
     base64.c
@@ -29,6 +30,7 @@
     error.c
     gcm.c
     havege.c
+    hkdf.c
     hmac_drbg.c
     md.c
     md2.c
@@ -46,6 +48,7 @@
     pkparse.c
     pkwrite.c
     platform.c
+    platform_util.c
     ripemd160.c
     rsa.c
     rsa_internal.c
@@ -141,15 +144,15 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.8.0 SOVERSION 1)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.10.0 SOVERSION 2)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.8.0 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.10.0 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.8.0 SOVERSION 10)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.10.0 SOVERSION 10)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/Makefile b/library/Makefile
index 0333815..86696b6 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -33,7 +33,7 @@
 
 SOEXT_TLS=so.10
 SOEXT_X509=so.0
-SOEXT_CRYPTO=so.1
+SOEXT_CRYPTO=so.2
 
 # Set DLEXT=dylib to compile as a shared library for Mac OS X
 DLEXT ?= so
@@ -50,22 +50,25 @@
 OBJS_CRYPTO=	aes.o		aesni.o		arc4.o		\
 		asn1parse.o	asn1write.o	base64.o	\
 		bignum.o	blowfish.o	camellia.o	\
+		aria.o						\
 		ccm.o		cipher.o	cipher_wrap.o	\
 		cmac.o		ctr_drbg.o	des.o		\
 		dhm.o		ecdh.o		ecdsa.o		\
 		ecjpake.o	ecp.o				\
 		ecp_curves.o	entropy.o	entropy_poll.o	\
 		error.o		gcm.o		havege.o	\
+		hkdf.o						\
 		hmac_drbg.o	md.o		md2.o		\
 		md4.o		md5.o		md_wrap.o	\
 		memory_buffer_alloc.o		oid.o		\
 		padlock.o	pem.o		pk.o		\
 		pk_wrap.o	pkcs12.o	pkcs5.o		\
 		pkparse.o	pkwrite.o	platform.o	\
-		ripemd160.o	rsa_internal.o	rsa.o  		\
-		sha1.o		sha256.o	sha512.o	\
-		threading.o	timing.o	version.o	\
-		version_features.o		xtea.o
+		platform_util.o	ripemd160.o	rsa_internal.o	\
+		rsa.o 		sha1.o		sha256.o	\
+		sha512.o	threading.o	timing.o	\
+		version.o	version_features.o		\
+		xtea.o
 
 OBJS_X509=	certs.o		pkcs11.o	x509.o		\
 		x509_create.o	x509_crl.o	x509_crt.o	\
diff --git a/library/aes.c b/library/aes.c
index da94b19..4f3351f 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -36,6 +36,7 @@
 #include <string.h>
 
 #include "mbedtls/aes.h"
+#include "mbedtls/platform_util.h"
 #if defined(MBEDTLS_PADLOCK_C)
 #include "mbedtls/padlock.h"
 #endif
@@ -54,11 +55,6 @@
 
 #if !defined(MBEDTLS_AES_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 /*
  * 32-bit integer manipulation macros (little endian)
  */
@@ -522,7 +518,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_aes_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
 }
 
 /*
@@ -1065,7 +1061,41 @@
 
     return( 0 );
 }
-#endif /*MBEDTLS_CIPHER_MODE_CFB */
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB (Output Feedback Mode) buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+                           size_t length,
+                           size_t *iv_off,
+                           unsigned char iv[16],
+                           const unsigned char *input,
+                           unsigned char *output )
+{
+    int ret = 0;
+    size_t n = *iv_off;
+
+    while( length-- )
+    {
+        if( n == 0 )
+        {
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            if( ret != 0 )
+                goto exit;
+        }
+        *output++ =  *input++ ^ iv[n];
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *iv_off = n;
+
+exit:
+    return( ret );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
 
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /*
@@ -1082,6 +1112,9 @@
     int c, i;
     size_t n = *nc_off;
 
+    if ( n > 0x0F )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
     while( length-- )
     {
         if( n == 0 ) {
@@ -1219,6 +1252,72 @@
 };
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB test vectors from:
+ *
+ * https://csrc.nist.gov/publications/detail/sp/800-38a/final
+ */
+static const unsigned char aes_test_ofb_key[3][32] =
+{
+    { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+      0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
+    { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
+      0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
+      0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
+    { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+      0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+      0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+      0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
+};
+
+static const unsigned char aes_test_ofb_iv[16] =
+{
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+static const unsigned char aes_test_ofb_pt[64] =
+{
+    0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+    0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+    0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+    0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+    0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+    0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+    0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+    0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const unsigned char aes_test_ofb_ct[3][64] =
+{
+    { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
+      0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
+      0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
+      0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
+      0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
+      0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
+      0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
+      0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
+    { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
+      0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
+      0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
+      0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
+      0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
+      0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
+      0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
+      0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
+    { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
+      0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
+      0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
+      0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
+      0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
+      0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
+      0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
+      0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /*
  * AES-CTR test vectors from:
@@ -1298,7 +1397,8 @@
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     unsigned char prv[16];
 #endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB)
+#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
+    defined(MBEDTLS_CIPHER_MODE_OFB)
     size_t offset;
 #endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
@@ -1510,6 +1610,69 @@
         mbedtls_printf( "\n" );
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    /*
+     * OFB mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  AES-OFB-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( iv,  aes_test_ofb_iv, 16 );
+        memcpy( key, aes_test_ofb_key[u], keybits / 8 );
+
+        offset = 0;
+        ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+        {
+            memcpy( buf, aes_test_ofb_ct[u], 64 );
+            aes_tests = aes_test_ofb_pt;
+        }
+        else
+        {
+            memcpy( buf, aes_test_ofb_pt, 64 );
+            aes_tests = aes_test_ofb_ct[u];
+        }
+
+        ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
+        if( ret != 0 )
+            goto exit;
+
+        if( memcmp( buf, aes_tests, 64 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     /*
      * CTR mode
diff --git a/library/aesni.c b/library/aesni.c
index 1ca3c3e..062708b 100644
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -32,6 +32,12 @@
 
 #if defined(MBEDTLS_AESNI_C)
 
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#warning "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code."
+#endif
+#endif
+
 #include "mbedtls/aesni.h"
 
 #include <string.h>
diff --git a/library/arc4.c b/library/arc4.c
index 05b33d3..b8998ac 100644
--- a/library/arc4.c
+++ b/library/arc4.c
@@ -33,6 +33,7 @@
 #if defined(MBEDTLS_ARC4_C)
 
 #include "mbedtls/arc4.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -47,11 +48,6 @@
 
 #if !defined(MBEDTLS_ARC4_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_arc4_context ) );
@@ -62,7 +58,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
 }
 
 /*
diff --git a/library/aria.c b/library/aria.c
new file mode 100644
index 0000000..e9bcd6d
--- /dev/null
+++ b/library/aria.c
@@ -0,0 +1,1028 @@
+/*
+ *  ARIA implementation
+ *
+ *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * This implementation is based on the following standards:
+ * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf
+ * [2] https://tools.ietf.org/html/rfc5794
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ARIA_C)
+
+#include "mbedtls/aria.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_ARIA_ALT)
+
+#include "mbedtls/platform_util.h"
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE( n, b, i )                \
+{                                               \
+    (n) = ( (uint32_t) (b)[(i)    ]       )     \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )     \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )     \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );    \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE( n, b, i )                                \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+/*
+ * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
+ *
+ * This is submatrix P1 in [1] Appendix B.1
+ *
+ * Common compilers fail to translate this to minimal number of instructions,
+ * so let's provide asm versions for common platforms with C fallback.
+ */
+#if defined(MBEDTLS_HAVE_ASM)
+#if defined(__arm__) /* rev16 available from v6 up */
+/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
+#if defined(__GNUC__) && \
+    ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \
+    __ARM_ARCH >= 6
+static inline uint32_t aria_p1( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev16 %0, %1" : "=l" (r) : "l" (x) );
+    return( r );
+}
+#define ARIA_P1 aria_p1
+#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
+    ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 )
+static inline uint32_t aria_p1( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev16 r, x" );
+    return( r );
+}
+#define ARIA_P1 aria_p1
+#endif
+#endif /* arm */
+#if defined(__GNUC__) && \
+    defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
+/* I couldn't find an Intel equivalent of rev16, so two instructions */
+#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) )
+#endif /* x86 gnuc */
+#endif /* MBEDTLS_HAVE_ASM && GNUC */
+#if !defined(ARIA_P1)
+#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
+#endif
+
+/*
+ * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
+ *
+ * This is submatrix P2 in [1] Appendix B.1
+ *
+ * Common compilers will translate this to a single instruction.
+ */
+#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
+
+/*
+ * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
+ *
+ * This is submatrix P3 in [1] Appendix B.1
+ *
+ * Some compilers fail to translate this to a single instruction,
+ * so let's provide asm versions for common platforms with C fallback.
+ */
+#if defined(MBEDTLS_HAVE_ASM)
+#if defined(__arm__) /* rev available from v6 up */
+/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
+#if defined(__GNUC__) && \
+    ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \
+    __ARM_ARCH >= 6
+static inline uint32_t aria_p3( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev %0, %1" : "=l" (r) : "l" (x) );
+    return( r );
+}
+#define ARIA_P3 aria_p3
+#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
+    ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 )
+static inline uint32_t aria_p3( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev r, x" );
+    return( r );
+}
+#define ARIA_P3 aria_p3
+#endif
+#endif /* arm */
+#if defined(__GNUC__) && \
+    defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
+static inline uint32_t aria_p3( uint32_t x )
+{
+    __asm( "bswap %0" : "=r" (x) : "0" (x) );
+    return( x );
+}
+#define ARIA_P3 aria_p3
+#endif /* x86 gnuc */
+#endif /* MBEDTLS_HAVE_ASM && GNUC */
+#if !defined(ARIA_P3)
+#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) )
+#endif
+
+/*
+ * ARIA Affine Transform
+ * (a, b, c, d) = state in/out
+ *
+ * If we denote the first byte of input by 0, ..., the last byte by f,
+ * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
+ *
+ * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple
+ * rearrangements on adjacent pairs, output is:
+ *
+ * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
+ *   = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
+ * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd
+ *   = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
+ * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe
+ *   = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
+ * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef
+ *   = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
+ *
+ * Note: another presentation of the A transform can be found as the first
+ * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
+ * The implementation below uses only P1 and P2 as they are sufficient.
+ */
+static inline void aria_a( uint32_t *a, uint32_t *b,
+                           uint32_t *c, uint32_t *d )
+{
+    uint32_t ta, tb, tc;
+    ta  =  *b;                      // 4567
+    *b  =  *a;                      // 0123
+    *a  =  ARIA_P2( ta );           // 6745
+    tb  =  ARIA_P2( *d );           // efcd
+    *d  =  ARIA_P1( *c );           // 98ba
+    *c  =  ARIA_P1( tb );           // fedc
+    ta  ^= *d;                      // 4567+98ba
+    tc  =  ARIA_P2( *b );           // 2301
+    ta  =  ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc
+    tb  ^= ARIA_P2( *d );           // ba98+efcd
+    tc  ^= ARIA_P1( *a );           // 2301+7654
+    *b  ^= ta ^ tb;                 // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
+    tb  =  ARIA_P2( tb ) ^ ta;      // 2301+5476+89ab+98ba+cdef+fedc
+    *a  ^= ARIA_P1( tb );           // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
+    ta  =  ARIA_P2( ta );           // 0123+7654+ab89+dcfe
+    *d  ^= ARIA_P1( ta ) ^ tc;      // 1032+2301+6745+7654+98ba+ba98+cdef OUT
+    tc  =  ARIA_P2( tc );           // 0123+5476
+    *c  ^= ARIA_P1( tc ) ^ ta;      // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
+}
+
+/*
+ * ARIA Substitution Layer SL1 / SL2
+ * (a, b, c, d) = state in/out
+ * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
+ *
+ * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
+ * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
+ */
+static inline void aria_sl( uint32_t *a, uint32_t *b,
+                            uint32_t *c, uint32_t *d,
+                            const uint8_t sa[256], const uint8_t sb[256],
+                            const uint8_t sc[256], const uint8_t sd[256] )
+{
+    *a = ( (uint32_t) sa[ *a        & 0xFF]       ) ^
+         (((uint32_t) sb[(*a >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *a >> 24        ]) << 24);
+    *b = ( (uint32_t) sa[ *b        & 0xFF]       ) ^
+         (((uint32_t) sb[(*b >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *b >> 24        ]) << 24);
+    *c = ( (uint32_t) sa[ *c        & 0xFF]       ) ^
+         (((uint32_t) sb[(*c >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *c >> 24        ]) << 24);
+    *d = ( (uint32_t) sa[ *d        & 0xFF]       ) ^
+         (((uint32_t) sb[(*d >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *d >> 24        ]) << 24);
+}
+
+/*
+ * S-Boxes
+ */
+static const uint8_t aria_sb1[256] =
+{
+    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
+    0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+    0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
+    0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+    0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
+    0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+    0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
+    0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+    0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
+    0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+    0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
+    0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+    0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
+    0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+    0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
+    0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+    0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
+    0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+    0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
+    0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+    0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
+    0xB0, 0x54, 0xBB, 0x16
+};
+
+static const uint8_t aria_sb2[256] =
+{
+    0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
+    0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
+    0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
+    0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
+    0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
+    0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
+    0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
+    0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
+    0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
+    0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
+    0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
+    0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
+    0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
+    0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
+    0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
+    0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
+    0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
+    0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
+    0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
+    0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
+    0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
+    0xAF, 0xBA, 0xB5, 0x81
+};
+
+static const uint8_t aria_is1[256] =
+{
+    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
+    0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+    0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
+    0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
+    0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
+    0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
+    0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+    0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
+    0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
+    0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+    0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
+    0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
+    0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+    0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
+    0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
+    0x55, 0x21, 0x0C, 0x7D
+};
+
+static const uint8_t aria_is2[256] =
+{
+    0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
+    0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
+    0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
+    0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
+    0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
+    0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
+    0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
+    0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
+    0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
+    0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
+    0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
+    0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
+    0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
+    0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
+    0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
+    0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
+    0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
+    0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
+    0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
+    0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
+    0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
+    0x03, 0xA2, 0xAC, 0x60
+};
+
+/*
+ * Helper for key schedule: r = FO( p, k ) ^ x
+ */
+static void aria_fo_xor( uint32_t r[4], const uint32_t p[4],
+                         const uint32_t k[4], const uint32_t x[4] )
+{
+    uint32_t a, b, c, d;
+
+    a = p[0] ^ k[0];
+    b = p[1] ^ k[1];
+    c = p[2] ^ k[2];
+    d = p[3] ^ k[3];
+
+    aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
+    aria_a( &a, &b, &c, &d );
+
+    r[0] = a ^ x[0];
+    r[1] = b ^ x[1];
+    r[2] = c ^ x[2];
+    r[3] = d ^ x[3];
+}
+
+/*
+ * Helper for key schedule: r = FE( p, k ) ^ x
+ */
+static void aria_fe_xor( uint32_t r[4], const uint32_t p[4],
+                         const uint32_t k[4], const uint32_t x[4] )
+{
+    uint32_t a, b, c, d;
+
+    a = p[0] ^ k[0];
+    b = p[1] ^ k[1];
+    c = p[2] ^ k[2];
+    d = p[3] ^ k[3];
+
+    aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
+    aria_a( &a, &b, &c, &d );
+
+    r[0] = a ^ x[0];
+    r[1] = b ^ x[1];
+    r[2] = c ^ x[2];
+    r[3] = d ^ x[3];
+}
+
+/*
+ * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
+ *
+ * We chose to store bytes into 32-bit words in little-endian format (see
+ * GET/PUT_UINT32_LE) so we need to reverse bytes here.
+ */
+static void aria_rot128( uint32_t r[4], const uint32_t a[4],
+                         const uint32_t b[4], uint8_t n )
+{
+    uint8_t i, j;
+    uint32_t t, u;
+
+    const uint8_t n1 = n % 32;              // bit offset
+    const uint8_t n2 = n1 ? 32 - n1 : 0;    // reverse bit offset
+
+    j = ( n / 32 ) % 4;                     // initial word offset
+    t = ARIA_P3( b[j] );                    // big endian
+    for( i = 0; i < 4; i++ )
+    {
+        j = ( j + 1 ) % 4;                  // get next word, big endian
+        u = ARIA_P3( b[j] );
+        t <<= n1;                           // rotate
+        t |= u >> n2;
+        t = ARIA_P3( t );                   // back to little endian
+        r[i] = a[i] ^ t;                    // store
+        t = u;                              // move to next word
+    }
+}
+
+/*
+ * Set encryption key
+ */
+int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
+                             const unsigned char *key, unsigned int keybits )
+{
+    /* round constant masks */
+    const uint32_t rc[3][4] =
+    {
+        {   0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA  },
+        {   0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF  },
+        {   0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804  }
+    };
+
+    int i;
+    uint32_t w[4][4], *w2;
+
+    if( keybits != 128 && keybits != 192 && keybits != 256 )
+        return( MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH );
+
+    /* Copy key to W0 (and potential remainder to W1) */
+    GET_UINT32_LE( w[0][0], key,  0 );
+    GET_UINT32_LE( w[0][1], key,  4 );
+    GET_UINT32_LE( w[0][2], key,  8 );
+    GET_UINT32_LE( w[0][3], key, 12 );
+
+    memset( w[1], 0, 16 );
+    if( keybits >= 192 )
+    {
+        GET_UINT32_LE( w[1][0], key, 16 );  // 192 bit key
+        GET_UINT32_LE( w[1][1], key, 20 );
+    }
+    if( keybits == 256 )
+    {
+        GET_UINT32_LE( w[1][2], key, 24 );  // 256 bit key
+        GET_UINT32_LE( w[1][3], key, 28 );
+    }
+
+    i = ( keybits - 128 ) >> 6;             // index: 0, 1, 2
+    ctx->nr = 12 + 2 * i;                   // no. rounds: 12, 14, 16
+
+    aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR
+    i = i < 2 ? i + 1 : 0;
+    aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0
+    i = i < 2 ? i + 1 : 0;
+    aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1
+
+    for( i = 0; i < 4; i++ )                // create round keys
+    {
+        w2 = w[(i + 1) & 3];
+        aria_rot128( ctx->rk[i     ], w[i], w2, 128 - 19 );
+        aria_rot128( ctx->rk[i +  4], w[i], w2, 128 - 31 );
+        aria_rot128( ctx->rk[i +  8], w[i], w2,       61 );
+        aria_rot128( ctx->rk[i + 12], w[i], w2,       31 );
+    }
+    aria_rot128( ctx->rk[16], w[0], w[1], 19 );
+
+    /* w holds enough info to reconstruct the round keys */
+    mbedtls_platform_zeroize( w, sizeof( w ) );
+
+    return( 0 );
+}
+
+/*
+ * Set decryption key
+ */
+int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
+                             const unsigned char *key, unsigned int keybits )
+{
+    int i, j, k, ret;
+
+    ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
+    if( ret != 0 )
+        return( ret );
+
+    /* flip the order of round keys */
+    for( i = 0, j = ctx->nr; i < j; i++, j-- )
+    {
+        for( k = 0; k < 4; k++ )
+        {
+            uint32_t t = ctx->rk[i][k];
+            ctx->rk[i][k] = ctx->rk[j][k];
+            ctx->rk[j][k] = t;
+        }
+    }
+
+    /* apply affine transform to middle keys */
+    for( i = 1; i < ctx->nr; i++ )
+    {
+        aria_a( &ctx->rk[i][0], &ctx->rk[i][1],
+                &ctx->rk[i][2], &ctx->rk[i][3] );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Encrypt a block
+ */
+int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
+                            const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] )
+{
+    int i;
+
+    uint32_t a, b, c, d;
+
+    GET_UINT32_LE( a, input,  0 );
+    GET_UINT32_LE( b, input,  4 );
+    GET_UINT32_LE( c, input,  8 );
+    GET_UINT32_LE( d, input, 12 );
+
+    i = 0;
+    while( 1 )
+    {
+        a ^= ctx->rk[i][0];
+        b ^= ctx->rk[i][1];
+        c ^= ctx->rk[i][2];
+        d ^= ctx->rk[i][3];
+        i++;
+
+        aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
+        aria_a( &a, &b, &c, &d );
+
+        a ^= ctx->rk[i][0];
+        b ^= ctx->rk[i][1];
+        c ^= ctx->rk[i][2];
+        d ^= ctx->rk[i][3];
+        i++;
+
+        aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
+        if( i >= ctx->nr )
+            break;
+        aria_a( &a, &b, &c, &d );
+    }
+
+    /* final key mixing */
+    a ^= ctx->rk[i][0];
+    b ^= ctx->rk[i][1];
+    c ^= ctx->rk[i][2];
+    d ^= ctx->rk[i][3];
+
+    PUT_UINT32_LE( a, output,  0 );
+    PUT_UINT32_LE( b, output,  4 );
+    PUT_UINT32_LE( c, output,  8 );
+    PUT_UINT32_LE( d, output, 12 );
+
+    return( 0 );
+}
+
+/* Initialize context */
+void mbedtls_aria_init( mbedtls_aria_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_aria_context ) );
+}
+
+/* Clear context */
+void mbedtls_aria_free( mbedtls_aria_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * ARIA-CBC buffer encryption/decryption
+ */
+int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
+                            int mode,
+                            size_t length,
+                            unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    int i;
+    unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
+
+    if( length % MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
+
+    if( mode == MBEDTLS_ARIA_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE );
+            mbedtls_aria_crypt_ecb( ctx, input, output );
+
+            for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE );
+
+            input  += MBEDTLS_ARIA_BLOCKSIZE;
+            output += MBEDTLS_ARIA_BLOCKSIZE;
+            length -= MBEDTLS_ARIA_BLOCKSIZE;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_aria_crypt_ecb( ctx, output, output );
+            memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE );
+
+            input  += MBEDTLS_ARIA_BLOCKSIZE;
+            output += MBEDTLS_ARIA_BLOCKSIZE;
+            length -= MBEDTLS_ARIA_BLOCKSIZE;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * ARIA-CFB128 buffer encryption/decryption
+ */
+int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
+                               int mode,
+                               size_t length,
+                               size_t *iv_off,
+                               unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                               const unsigned char *input,
+                               unsigned char *output )
+{
+    unsigned char c;
+    size_t n = *iv_off;
+
+    if( mode == MBEDTLS_ARIA_DECRYPT )
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aria_crypt_ecb( ctx, iv, iv );
+
+            c = *input++;
+            *output++ = c ^ iv[n];
+            iv[n] = c;
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+    else
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aria_crypt_ecb( ctx, iv, iv );
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+
+    *iv_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * ARIA-CTR buffer encryption/decryption
+ */
+int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
+                            size_t length,
+                            size_t *nc_off,
+                            unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    int c, i;
+    size_t n = *nc_off;
+
+    while( length-- )
+    {
+        if( n == 0 ) {
+            mbedtls_aria_crypt_ecb( ctx, nonce_counter,
+                                stream_block );
+
+            for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- )
+                if( ++nonce_counter[i - 1] != 0 )
+                    break;
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *nc_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#endif /* !MBEDTLS_ARIA_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * Basic ARIA ECB test vectors from RFC 5794
+ */
+static const uint8_t aria_test1_ecb_key[32] =           // test key
+{
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,     // 128 bit
+    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,     // 192 bit
+    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F      // 256 bit
+};
+
+static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] =            // plaintext
+{
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // same for all
+    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF      // key sizes
+};
+
+static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] =         // ciphertext
+{
+    { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73,   // 128 bit
+      0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
+    { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA,   // 192 bit
+      0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
+    { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F,   // 256 bit
+      0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
+};
+
+/*
+ * Mode tests from "Test Vectors for ARIA"  Version 1.0
+ * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
+ */
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
+    defined(MBEDTLS_CIPHER_MODE_CTR))
+static const uint8_t aria_test2_key[32] =
+{
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 128 bit
+    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 192 bit
+    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff      // 256 bit
+};
+
+static const uint8_t aria_test2_pt[48] =
+{
+    0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa,     // same for all
+    0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
+    0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
+    0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
+    0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
+    0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
+};
+#endif
+
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
+static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] =
+{
+    0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,     // same for CBC, CFB
+    0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0      // CTR has zero IV
+};
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const uint8_t aria_test2_cbc_ct[3][48] =         // CBC ciphertext
+{
+    { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10,   // 128-bit key
+      0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
+      0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
+      0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
+      0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
+      0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
+    { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c,   // 192-bit key
+      0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
+      0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
+      0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
+      0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
+      0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
+    { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1,   // 256-bit key
+      0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
+      0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
+      0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
+      0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
+      0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const uint8_t aria_test2_cfb_ct[3][48] =         // CFB ciphertext
+{
+    { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38,   // 128-bit key
+      0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
+      0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
+      0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
+      0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
+      0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
+    { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54,   // 192-bit key
+      0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
+      0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
+      0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
+      0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
+      0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
+    { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2,   // 256-bit key
+      0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
+      0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
+      0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
+      0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
+      0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const uint8_t aria_test2_ctr_ct[3][48] =         // CTR ciphertext
+{
+    { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c,   // 128-bit key
+      0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
+      0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
+      0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
+      0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
+      0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
+    { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19,   // 192-bit key
+      0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
+      0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
+      0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
+      0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
+      0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
+    { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17,   // 256-bit key
+      0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
+      0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
+      0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
+      0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
+      0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#define ARIA_SELF_TEST_IF_FAIL              \
+        {                                   \
+            if( verbose )                   \
+                printf( "failed\n" );       \
+            return( 1 );                    \
+        } else {                            \
+            if( verbose )                   \
+                printf( "passed\n" );       \
+        }
+
+/*
+ * Checkup routine
+ */
+int mbedtls_aria_self_test( int verbose )
+{
+    int i;
+    uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
+    mbedtls_aria_context ctx;
+
+#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
+    size_t j;
+#endif
+
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
+     defined(MBEDTLS_CIPHER_MODE_CFB) || \
+     defined(MBEDTLS_CIPHER_MODE_CTR))
+    uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
+#endif
+
+    /*
+     * Test set 1
+     */
+    for( i = 0; i < 3; i++ )
+    {
+        /* test ECB encryption */
+        if( verbose )
+            printf( "  ARIA-ECB-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
+        mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk );
+        if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* test ECB decryption */
+        if( verbose )
+            printf( "  ARIA-ECB-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
+        mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk );
+        if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        printf( "\n" );
+
+    /*
+     * Test set 2
+     */
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CBC encryption */
+        if( verbose )
+            printf( "  ARIA-CBC-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0x55, sizeof( buf ) );
+        mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
+            aria_test2_pt, buf );
+        if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* Test CBC decryption */
+        if( verbose )
+            printf( "  ARIA-CBC-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0xAA, sizeof( buf ) );
+        mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
+            aria_test2_cbc_ct[i], buf );
+        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        printf( "\n" );
+
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CFB encryption */
+        if( verbose )
+            printf( "  ARIA-CFB-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0x55, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
+            aria_test2_pt, buf );
+        if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* Test CFB decryption */
+        if( verbose )
+            printf( "  ARIA-CFB-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0xAA, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
+            iv, aria_test2_cfb_ct[i], buf );
+        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CTR encryption */
+        if( verbose )
+            printf( "  ARIA-CTR-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE );                    // IV = 0
+        memset( buf, 0x55, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
+            aria_test2_pt, buf );
+        if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* Test CTR decryption */
+        if( verbose )
+            printf( "  ARIA-CTR-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE );                    // IV = 0
+        memset( buf, 0xAA, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
+            aria_test2_ctr_ct[i], buf );
+        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_ARIA_C */
diff --git a/library/asn1parse.c b/library/asn1parse.c
index 4dd65c0..171c340 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -28,6 +28,7 @@
 #if defined(MBEDTLS_ASN1_PARSE_C)
 
 #include "mbedtls/asn1.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -43,11 +44,6 @@
 #define mbedtls_free       free
 #endif
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 /*
  * ASN.1 DER decoding routines
  */
@@ -313,7 +309,7 @@
 
     if( *p == end )
     {
-        mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) );
+        mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
         return( 0 );
     }
 
@@ -358,7 +354,7 @@
     mbedtls_free( cur->oid.p );
     mbedtls_free( cur->val.p );
 
-    mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
+    mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
 }
 
 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
diff --git a/library/asn1write.c b/library/asn1write.c
index 69b61b2..72acdf3 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -83,7 +83,9 @@
         return( 4 );
     }
 
+#if SIZE_MAX > 0xFFFFFFFF
     if( len <= 0xFFFFFFFF )
+#endif
     {
         if( *p - start < 5 )
             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@@ -96,7 +98,9 @@
         return( 5 );
     }
 
+#if SIZE_MAX > 0xFFFFFFFF
     return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+#endif
 }
 
 int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
@@ -232,10 +236,6 @@
     int ret;
     size_t len = 0;
 
-    // TODO negative values and values larger than 128
-    // DER format assumes 2s complement for numbers, so the leftmost bit
-    // should be 0 for positive numbers and 1 for negative numbers.
-    //
     if( *p - start < 1 )
         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
 
diff --git a/library/bignum.c b/library/bignum.c
index 47bf1ef..423e375 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -45,6 +45,7 @@
 
 #include "mbedtls/bignum.h"
 #include "mbedtls/bn_mul.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -58,16 +59,6 @@
 #define mbedtls_free       free
 #endif
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
-    volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
-}
-
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 #define ciL    (sizeof(mbedtls_mpi_uint))         /* chars in limb  */
 #define biL    (ciL << 3)               /* bits  in limb  */
 #define biH    (ciL << 2)               /* half limb size */
@@ -81,6 +72,12 @@
 #define BITS_TO_LIMBS(i)  ( (i) / biL + ( (i) % biL != 0 ) )
 #define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
 
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n )
+{
+    mbedtls_platform_zeroize( v, ciL * n );
+}
+
 /*
  * Initialize one MPI
  */
@@ -1897,7 +1894,7 @@
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
 
 cleanup:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
     return( ret );
 }
 
@@ -2194,12 +2191,23 @@
 
 /*
  * Prime number generation
+ *
+ * If dh_flag is 0 and nbits is at least 1024, then the procedure
+ * follows the RSA probably-prime generation method of FIPS 186-4.
+ * NB. FIPS 186-4 only allows the specific bit lengths of 1024 and 1536.
  */
 int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
                    int (*f_rng)(void *, unsigned char *, size_t),
                    void *p_rng )
 {
-    int ret;
+#ifdef MBEDTLS_HAVE_INT64
+// ceil(2^63.5)
+#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
+#else
+// ceil(2^31.5)
+#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
+#endif
+    int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
     size_t k, n;
     mbedtls_mpi_uint r;
     mbedtls_mpi Y;
@@ -2211,69 +2219,66 @@
 
     n = BITS_TO_LIMBS( nbits );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
-
-    k = mbedtls_mpi_bitlen( X );
-    if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) );
-
-    mbedtls_mpi_set_bit( X, nbits-1, 1 );
-
-    X->p[0] |= 1;
-
-    if( dh_flag == 0 )
+    while( 1 )
     {
-        while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
+        /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
+        if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
+
+        k = n * biL;
+        if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
+        X->p[0] |= 1;
+
+        if( dh_flag == 0 )
         {
+            ret = mbedtls_mpi_is_prime( X, f_rng, p_rng );
+
             if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
                 goto cleanup;
-
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) );
         }
-    }
-    else
-    {
-        /*
-         * An necessary condition for Y and X = 2Y + 1 to be prime
-         * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
-         * Make sure it is satisfied, while keeping X = 3 mod 4
-         */
-
-        X->p[0] |= 2;
-
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
-        if( r == 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
-        else if( r == 1 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
-
-        /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
-
-        while( 1 )
+        else
         {
             /*
-             * First, check small factors for X and Y
-             * before doing Miller-Rabin on any of them
+             * An necessary condition for Y and X = 2Y + 1 to be prime
+             * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
+             * Make sure it is satisfied, while keeping X = 3 mod 4
              */
-            if( ( ret = mpi_check_small_factors(  X         ) ) == 0 &&
-                ( ret = mpi_check_small_factors( &Y         ) ) == 0 &&
-                ( ret = mpi_miller_rabin(  X, f_rng, p_rng  ) ) == 0 &&
-                ( ret = mpi_miller_rabin( &Y, f_rng, p_rng  ) ) == 0 )
+
+            X->p[0] |= 2;
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
+            if( r == 0 )
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
+            else if( r == 1 )
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
+
+            /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
+            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
+
+            while( 1 )
             {
-                break;
+                /*
+                 * First, check small factors for X and Y
+                 * before doing Miller-Rabin on any of them
+                 */
+                if( ( ret = mpi_check_small_factors(  X         ) ) == 0 &&
+                    ( ret = mpi_check_small_factors( &Y         ) ) == 0 &&
+                    ( ret = mpi_miller_rabin(  X, f_rng, p_rng  ) ) == 0 &&
+                    ( ret = mpi_miller_rabin( &Y, f_rng, p_rng  ) ) == 0 )
+                    goto cleanup;
+
+                if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+                    goto cleanup;
+
+                /*
+                 * Next candidates. We want to preserve Y = (X-1) / 2 and
+                 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
+                 * so up Y by 6 and X by 12.
+                 */
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(  X,  X, 12 ) );
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6  ) );
             }
-
-            if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
-                goto cleanup;
-
-            /*
-             * Next candidates. We want to preserve Y = (X-1) / 2 and
-             * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
-             * so up Y by 6 and X by 12.
-             */
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(  X,  X, 12 ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6  ) );
         }
     }
 
diff --git a/library/blowfish.c b/library/blowfish.c
index 9003f0d..5b6bb98 100644
--- a/library/blowfish.c
+++ b/library/blowfish.c
@@ -34,16 +34,12 @@
 #if defined(MBEDTLS_BLOWFISH_C)
 
 #include "mbedtls/blowfish.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
 #if !defined(MBEDTLS_BLOWFISH_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -165,7 +161,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
 }
 
 /*
diff --git a/library/camellia.c b/library/camellia.c
index ac6f96a..41b7da0 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -34,6 +34,7 @@
 #if defined(MBEDTLS_CAMELLIA_C)
 
 #include "mbedtls/camellia.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -48,11 +49,6 @@
 
 #if !defined(MBEDTLS_CAMELLIA_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -333,7 +329,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
 }
 
 /*
diff --git a/library/ccm.c b/library/ccm.c
index 9101e5f..804eaf8 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -37,6 +37,7 @@
 #if defined(MBEDTLS_CCM_C)
 
 #include "mbedtls/ccm.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -51,11 +52,6 @@
 
 #if !defined(MBEDTLS_CCM_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 #define CCM_ENCRYPT 0
 #define CCM_DECRYPT 1
 
@@ -102,7 +98,7 @@
 void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
 {
     mbedtls_cipher_free( &ctx->cipher_ctx );
-    mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
 }
 
 /*
@@ -156,8 +152,10 @@
      * Check length requirements: SP800-38C A.1
      * Additional requirement: a < 2^16 - 2^8 to simplify the code.
      * 'length' checked later (when writing it to the first block)
+     *
+     * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
      */
-    if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
+    if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
 
     /* Also implies q is within bounds */
@@ -306,7 +304,7 @@
 /*
  * Authenticated encryption
  */
-int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
                          const unsigned char *iv, size_t iv_len,
                          const unsigned char *add, size_t add_len,
                          const unsigned char *input, unsigned char *output,
@@ -316,10 +314,23 @@
                             add, add_len, input, output, tag, tag_len ) );
 }
 
+int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *add, size_t add_len,
+                         const unsigned char *input, unsigned char *output,
+                         unsigned char *tag, size_t tag_len )
+{
+    if( tag_len == 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
+                add_len, input, output, tag, tag_len ) );
+}
+
 /*
  * Authenticated decryption
  */
-int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                       const unsigned char *iv, size_t iv_len,
                       const unsigned char *add, size_t add_len,
                       const unsigned char *input, unsigned char *output,
@@ -343,13 +354,25 @@
 
     if( diff != 0 )
     {
-        mbedtls_zeroize( output, length );
+        mbedtls_platform_zeroize( output, length );
         return( MBEDTLS_ERR_CCM_AUTH_FAILED );
     }
 
     return( 0 );
 }
 
+int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len )
+{
+    if( tag_len == 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add,
+                add_len, input, output, tag, tag_len ) );
+}
 #endif /* !MBEDTLS_CCM_ALT */
 
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
diff --git a/library/cipher.c b/library/cipher.c
index 7369f48..2c599e5 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -33,6 +33,7 @@
 
 #include "mbedtls/cipher.h"
 #include "mbedtls/cipher_internal.h"
+#include "mbedtls/platform_util.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -60,11 +61,6 @@
 #define MBEDTLS_CIPHER_MODE_STREAM
 #endif
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 static int supported_init = 0;
 
 const int *mbedtls_cipher_list( void )
@@ -141,7 +137,8 @@
 #if defined(MBEDTLS_CMAC_C)
     if( ctx->cmac_ctx )
     {
-       mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) );
+       mbedtls_platform_zeroize( ctx->cmac_ctx,
+                                 sizeof( mbedtls_cmac_context_t ) );
        mbedtls_free( ctx->cmac_ctx );
     }
 #endif
@@ -149,7 +146,7 @@
     if( ctx->cipher_ctx )
         ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
 
-    mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
+    mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
 }
 
 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
@@ -194,10 +191,11 @@
     ctx->operation = operation;
 
     /*
-     * For CFB and CTR mode always use the encryption key schedule
+     * For OFB, CFB and CTR mode always use the encryption key schedule
      */
     if( MBEDTLS_ENCRYPT == operation ||
         MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
         MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
     {
         return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
@@ -427,6 +425,21 @@
     }
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
+    {
+        if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
+                ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
+        {
+            return( ret );
+        }
+
+        *olen = ilen;
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
     {
@@ -642,6 +655,7 @@
     *olen = 0;
 
     if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
         MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
         MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
         MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index dc76af8..fd6e69c 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -45,6 +45,10 @@
 #include "mbedtls/camellia.h"
 #endif
 
+#if defined(MBEDTLS_ARIA_C)
+#include "mbedtls/aria.h"
+#endif
+
 #if defined(MBEDTLS_DES_C)
 #include "mbedtls/des.h"
 #endif
@@ -138,6 +142,15 @@
 }
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off,
+        unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off,
+                                    iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
         unsigned char *nonce_counter, unsigned char *stream_block,
@@ -187,6 +200,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     aes_crypt_cfb128_wrap,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    aes_crypt_ofb_wrap,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     aes_crypt_ctr_wrap,
 #endif
@@ -302,6 +318,41 @@
 };
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+static const mbedtls_cipher_info_t aes_128_ofb_info = {
+    MBEDTLS_CIPHER_AES_128_OFB,
+    MBEDTLS_MODE_OFB,
+    128,
+    "AES-128-OFB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ofb_info = {
+    MBEDTLS_CIPHER_AES_192_OFB,
+    MBEDTLS_MODE_OFB,
+    192,
+    "AES-192-OFB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ofb_info = {
+    MBEDTLS_CIPHER_AES_256_OFB,
+    MBEDTLS_MODE_OFB,
+    256,
+    "AES-256-OFB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 static const mbedtls_cipher_info_t aes_128_ctr_info = {
     MBEDTLS_CIPHER_AES_128_CTR,
@@ -354,6 +405,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -417,6 +471,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -544,6 +601,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     camellia_crypt_cfb128_wrap,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     camellia_crypt_ctr_wrap,
 #endif
@@ -711,6 +771,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -774,6 +837,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -822,6 +888,373 @@
 
 #endif /* MBEDTLS_CAMELLIA_C */
 
+#if defined(MBEDTLS_ARIA_C)
+
+static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    (void) operation;
+    return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input,
+                               output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv,
+                               input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, size_t *iv_off, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length,
+                                  iv_off, iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+        unsigned char *nonce_counter, unsigned char *stream_block,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off,
+                               nonce_counter, stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen );
+}
+
+static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen );
+}
+
+static void * aria_ctx_alloc( void )
+{
+    mbedtls_aria_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_aria_init( ctx );
+
+    return( ctx );
+}
+
+static void aria_ctx_free( void *ctx )
+{
+    mbedtls_aria_free( (mbedtls_aria_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t aria_info = {
+    MBEDTLS_CIPHER_ID_ARIA,
+    aria_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    aria_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    aria_crypt_cfb128_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    aria_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    aria_setkey_enc_wrap,
+    aria_setkey_dec_wrap,
+    aria_ctx_alloc,
+    aria_ctx_free
+};
+
+static const mbedtls_cipher_info_t aria_128_ecb_info = {
+    MBEDTLS_CIPHER_ARIA_128_ECB,
+    MBEDTLS_MODE_ECB,
+    128,
+    "ARIA-128-ECB",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ecb_info = {
+    MBEDTLS_CIPHER_ARIA_192_ECB,
+    MBEDTLS_MODE_ECB,
+    192,
+    "ARIA-192-ECB",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ecb_info = {
+    MBEDTLS_CIPHER_ARIA_256_ECB,
+    MBEDTLS_MODE_ECB,
+    256,
+    "ARIA-256-ECB",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t aria_128_cbc_info = {
+    MBEDTLS_CIPHER_ARIA_128_CBC,
+    MBEDTLS_MODE_CBC,
+    128,
+    "ARIA-128-CBC",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_cbc_info = {
+    MBEDTLS_CIPHER_ARIA_192_CBC,
+    MBEDTLS_MODE_CBC,
+    192,
+    "ARIA-192-CBC",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_cbc_info = {
+    MBEDTLS_CIPHER_ARIA_256_CBC,
+    MBEDTLS_MODE_CBC,
+    256,
+    "ARIA-256-CBC",
+    16,
+    0,
+    16,
+    &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t aria_128_cfb128_info = {
+    MBEDTLS_CIPHER_ARIA_128_CFB128,
+    MBEDTLS_MODE_CFB,
+    128,
+    "ARIA-128-CFB128",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_cfb128_info = {
+    MBEDTLS_CIPHER_ARIA_192_CFB128,
+    MBEDTLS_MODE_CFB,
+    192,
+    "ARIA-192-CFB128",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_cfb128_info = {
+    MBEDTLS_CIPHER_ARIA_256_CFB128,
+    MBEDTLS_MODE_CFB,
+    256,
+    "ARIA-256-CFB128",
+    16,
+    0,
+    16,
+    &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t aria_128_ctr_info = {
+    MBEDTLS_CIPHER_ARIA_128_CTR,
+    MBEDTLS_MODE_CTR,
+    128,
+    "ARIA-128-CTR",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ctr_info = {
+    MBEDTLS_CIPHER_ARIA_192_CTR,
+    MBEDTLS_MODE_CTR,
+    192,
+    "ARIA-192-CTR",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ctr_info = {
+    MBEDTLS_CIPHER_ARIA_256_CTR,
+    MBEDTLS_MODE_CTR,
+    256,
+    "ARIA-256-CTR",
+    16,
+    0,
+    16,
+    &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_GCM_C)
+static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t gcm_aria_info = {
+    MBEDTLS_CIPHER_ID_ARIA,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    gcm_aria_setkey_wrap,
+    gcm_aria_setkey_wrap,
+    gcm_ctx_alloc,
+    gcm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aria_128_gcm_info = {
+    MBEDTLS_CIPHER_ARIA_128_GCM,
+    MBEDTLS_MODE_GCM,
+    128,
+    "ARIA-128-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_gcm_info = {
+    MBEDTLS_CIPHER_ARIA_192_GCM,
+    MBEDTLS_MODE_GCM,
+    192,
+    "ARIA-192-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_gcm_info = {
+    MBEDTLS_CIPHER_ARIA_256_GCM,
+    MBEDTLS_MODE_GCM,
+    256,
+    "ARIA-256-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aria_info
+};
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t ccm_aria_info = {
+    MBEDTLS_CIPHER_ID_ARIA,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    ccm_aria_setkey_wrap,
+    ccm_aria_setkey_wrap,
+    ccm_ctx_alloc,
+    ccm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aria_128_ccm_info = {
+    MBEDTLS_CIPHER_ARIA_128_CCM,
+    MBEDTLS_MODE_CCM,
+    128,
+    "ARIA-128-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ccm_info = {
+    MBEDTLS_CIPHER_ARIA_192_CCM,
+    MBEDTLS_MODE_CCM,
+    192,
+    "ARIA-192-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ccm_info = {
+    MBEDTLS_CIPHER_ARIA_256_CCM,
+    MBEDTLS_MODE_CCM,
+    256,
+    "ARIA-256-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+#endif /* MBEDTLS_CCM_C */
+
+#endif /* MBEDTLS_ARIA_C */
+
 #if defined(MBEDTLS_DES_C)
 
 static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
@@ -950,6 +1383,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -995,6 +1431,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -1040,6 +1479,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -1149,6 +1591,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     blowfish_crypt_cfb64_wrap,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     blowfish_crypt_ctr_wrap,
 #endif
@@ -1259,6 +1704,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -1322,6 +1770,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     NULL,
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     NULL,
 #endif
@@ -1362,6 +1813,11 @@
     { MBEDTLS_CIPHER_AES_192_CFB128,       &aes_192_cfb128_info },
     { MBEDTLS_CIPHER_AES_256_CFB128,       &aes_256_cfb128_info },
 #endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    { MBEDTLS_CIPHER_AES_128_OFB,          &aes_128_ofb_info },
+    { MBEDTLS_CIPHER_AES_192_OFB,          &aes_192_ofb_info },
+    { MBEDTLS_CIPHER_AES_256_OFB,          &aes_256_ofb_info },
+#endif
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
     { MBEDTLS_CIPHER_AES_128_CTR,          &aes_128_ctr_info },
     { MBEDTLS_CIPHER_AES_192_CTR,          &aes_192_ctr_info },
@@ -1427,6 +1883,37 @@
 #endif
 #endif /* MBEDTLS_CAMELLIA_C */
 
+#if defined(MBEDTLS_ARIA_C)
+    { MBEDTLS_CIPHER_ARIA_128_ECB,     &aria_128_ecb_info },
+    { MBEDTLS_CIPHER_ARIA_192_ECB,     &aria_192_ecb_info },
+    { MBEDTLS_CIPHER_ARIA_256_ECB,     &aria_256_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_CIPHER_ARIA_128_CBC,     &aria_128_cbc_info },
+    { MBEDTLS_CIPHER_ARIA_192_CBC,     &aria_192_cbc_info },
+    { MBEDTLS_CIPHER_ARIA_256_CBC,     &aria_256_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    { MBEDTLS_CIPHER_ARIA_128_CFB128,  &aria_128_cfb128_info },
+    { MBEDTLS_CIPHER_ARIA_192_CFB128,  &aria_192_cfb128_info },
+    { MBEDTLS_CIPHER_ARIA_256_CFB128,  &aria_256_cfb128_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    { MBEDTLS_CIPHER_ARIA_128_CTR,     &aria_128_ctr_info },
+    { MBEDTLS_CIPHER_ARIA_192_CTR,     &aria_192_ctr_info },
+    { MBEDTLS_CIPHER_ARIA_256_CTR,     &aria_256_ctr_info },
+#endif
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_CIPHER_ARIA_128_GCM,     &aria_128_gcm_info },
+    { MBEDTLS_CIPHER_ARIA_192_GCM,     &aria_192_gcm_info },
+    { MBEDTLS_CIPHER_ARIA_256_GCM,     &aria_256_gcm_info },
+#endif
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_CIPHER_ARIA_128_CCM,     &aria_128_ccm_info },
+    { MBEDTLS_CIPHER_ARIA_192_CCM,     &aria_192_ccm_info },
+    { MBEDTLS_CIPHER_ARIA_256_CCM,     &aria_256_ccm_info },
+#endif
+#endif /* MBEDTLS_ARIA_C */
+
 #if defined(MBEDTLS_DES_C)
     { MBEDTLS_CIPHER_DES_ECB,              &des_ecb_info },
     { MBEDTLS_CIPHER_DES_EDE_ECB,          &des_ede_ecb_info },
diff --git a/library/cmac.c b/library/cmac.c
index a4a2106..4d7a1f1 100644
--- a/library/cmac.c
+++ b/library/cmac.c
@@ -49,6 +49,7 @@
 #if defined(MBEDTLS_CMAC_C)
 
 #include "mbedtls/cmac.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -67,11 +68,6 @@
 
 #if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 /*
  * Multiplication by u in the Galois field of GF(2^n)
  *
@@ -144,7 +140,7 @@
     unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
     size_t olen, block_size;
 
-    mbedtls_zeroize( L, sizeof( L ) );
+    mbedtls_platform_zeroize( L, sizeof( L ) );
 
     block_size = ctx->cipher_info->block_size;
 
@@ -162,7 +158,7 @@
         goto exit;
 
 exit:
-    mbedtls_zeroize( L, sizeof( L ) );
+    mbedtls_platform_zeroize( L, sizeof( L ) );
 
     return( ret );
 }
@@ -238,7 +234,7 @@
 
     ctx->cmac_ctx = cmac_ctx;
 
-    mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
+    mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
 
     return 0;
 }
@@ -330,8 +326,8 @@
     block_size = ctx->cipher_info->block_size;
     state = cmac_ctx->state;
 
-    mbedtls_zeroize( K1, sizeof( K1 ) );
-    mbedtls_zeroize( K2, sizeof( K2 ) );
+    mbedtls_platform_zeroize( K1, sizeof( K1 ) );
+    mbedtls_platform_zeroize( K2, sizeof( K2 ) );
     cmac_generate_subkeys( ctx, K1, K2 );
 
     last_block = cmac_ctx->unprocessed_block;
@@ -361,14 +357,14 @@
 exit:
     /* Wipe the generated keys on the stack, and any other transients to avoid
      * side channel leakage */
-    mbedtls_zeroize( K1, sizeof( K1 ) );
-    mbedtls_zeroize( K2, sizeof( K2 ) );
+    mbedtls_platform_zeroize( K1, sizeof( K1 ) );
+    mbedtls_platform_zeroize( K2, sizeof( K2 ) );
 
     cmac_ctx->unprocessed_len = 0;
-    mbedtls_zeroize( cmac_ctx->unprocessed_block,
-                     sizeof( cmac_ctx->unprocessed_block ) );
+    mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
+                              sizeof( cmac_ctx->unprocessed_block ) );
 
-    mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
+    mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
     return( ret );
 }
 
@@ -383,10 +379,10 @@
 
     /* Reset the internal state */
     cmac_ctx->unprocessed_len = 0;
-    mbedtls_zeroize( cmac_ctx->unprocessed_block,
-                     sizeof( cmac_ctx->unprocessed_block ) );
-    mbedtls_zeroize( cmac_ctx->state,
-                     sizeof( cmac_ctx->state ) );
+    mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
+                              sizeof( cmac_ctx->unprocessed_block ) );
+    mbedtls_platform_zeroize( cmac_ctx->state,
+                              sizeof( cmac_ctx->state ) );
 
     return( 0 );
 }
@@ -466,7 +462,7 @@
                                output );
 
 exit:
-    mbedtls_zeroize( int_key, sizeof( int_key ) );
+    mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
 
     return( ret );
 }
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index ff532a0..d0e5ba8 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -33,6 +33,7 @@
 #if defined(MBEDTLS_CTR_DRBG_C)
 
 #include "mbedtls/ctr_drbg.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -49,11 +50,6 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 /*
  * CTR_DRBG context initialization
  */
@@ -125,7 +121,7 @@
     mbedtls_mutex_free( &ctx->mutex );
 #endif
     mbedtls_aes_free( &ctx->aes_ctx );
-    mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
 }
 
 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
@@ -245,16 +241,16 @@
     /*
     * tidy up the stack
     */
-    mbedtls_zeroize( buf, sizeof( buf ) );
-    mbedtls_zeroize( tmp, sizeof( tmp ) );
-    mbedtls_zeroize( key, sizeof( key ) );
-    mbedtls_zeroize( chain, sizeof( chain ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( key, sizeof( key ) );
+    mbedtls_platform_zeroize( chain, sizeof( chain ) );
     if( 0 != ret )
     {
         /*
         * wipe partial seed from memory
         */
-        mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
+        mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
     }
 
     return( ret );
@@ -493,7 +489,7 @@
         ret = 0;
 
 exit:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     fclose( f );
     return( ret );
@@ -526,7 +522,7 @@
 
     fclose( f );
 
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     if( ret != 0 )
         return( ret );
diff --git a/library/des.c b/library/des.c
index 09f95cfc..ca9e071 100644
--- a/library/des.c
+++ b/library/des.c
@@ -34,6 +34,7 @@
 #if defined(MBEDTLS_DES_C)
 
 #include "mbedtls/des.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -48,11 +49,6 @@
 
 #if !defined(MBEDTLS_DES_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -316,7 +312,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_des_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
 }
 
 void mbedtls_des3_init( mbedtls_des3_context *ctx )
@@ -329,7 +325,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_des3_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
 }
 
 static const unsigned char odd_parity_table[128] = { 1,  2,  4,  7,  8,
@@ -553,7 +549,7 @@
     uint32_t sk[96];
 
     des3_set2key( ctx->sk, sk, key );
-    mbedtls_zeroize( sk,  sizeof( sk ) );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
@@ -567,7 +563,7 @@
     uint32_t sk[96];
 
     des3_set2key( sk, ctx->sk, key );
-    mbedtls_zeroize( sk,  sizeof( sk ) );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
@@ -604,7 +600,7 @@
     uint32_t sk[96];
 
     des3_set3key( ctx->sk, sk, key );
-    mbedtls_zeroize( sk,  sizeof( sk ) );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
@@ -618,7 +614,7 @@
     uint32_t sk[96];
 
     des3_set3key( sk, ctx->sk, key );
-    mbedtls_zeroize( sk,  sizeof( sk ) );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
diff --git a/library/dhm.c b/library/dhm.c
index 28ac310..82cbb0c 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -36,6 +36,7 @@
 #if defined(MBEDTLS_DHM_C)
 
 #include "mbedtls/dhm.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -58,10 +59,6 @@
 #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;
-}
 
 /*
  * helper to validate the mbedtls_mpi size and import it
@@ -437,7 +434,7 @@
     mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X  );
     mbedtls_mpi_free( &ctx->G  ); mbedtls_mpi_free( &ctx->P  );
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
 }
 
 #if defined(MBEDTLS_ASN1_PARSE_C)
@@ -575,7 +572,7 @@
     {
         fclose( f );
 
-        mbedtls_zeroize( *buf, *n + 1 );
+        mbedtls_platform_zeroize( *buf, *n + 1 );
         mbedtls_free( *buf );
 
         return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
@@ -605,7 +602,7 @@
 
     ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
 
-    mbedtls_zeroize( buf, n );
+    mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
 
     return( ret );
diff --git a/library/ecjpake.c b/library/ecjpake.c
index e8f4086..ec5a400 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -301,7 +301,7 @@
  */
 static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
                               const mbedtls_ecp_group *grp,
-                              const int pf, 
+                              const int pf,
                               const mbedtls_ecp_point *G,
                               const mbedtls_mpi *x,
                               const mbedtls_ecp_point *X,
diff --git a/library/ecp.c b/library/ecp.c
index 92a188b..41db3fb 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -51,6 +51,7 @@
 
 #include "mbedtls/ecp.h"
 #include "mbedtls/threading.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -73,11 +74,6 @@
 #define inline __inline
 #endif
 
-/* 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;
-}
-
 #if defined(MBEDTLS_SELF_TEST)
 /*
  * Counts of point addition and doubling, and field multiplications.
@@ -348,7 +344,7 @@
         mbedtls_free( grp->T );
     }
 
-    mbedtls_zeroize( grp, sizeof( mbedtls_ecp_group ) );
+    mbedtls_platform_zeroize( grp, sizeof( mbedtls_ecp_group ) );
 }
 
 /*
diff --git a/library/entropy.c b/library/entropy.c
index e17512e..f8db1a5 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -35,6 +35,7 @@
 
 #include "mbedtls/entropy.h"
 #include "mbedtls/entropy_poll.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -59,11 +60,6 @@
 #include "mbedtls/havege.h"
 #endif
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 #define ENTROPY_MAX_LOOP    256     /**< Maximum amount to loop before error */
 
 void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
@@ -140,7 +136,7 @@
     ctx->initial_entropy_run = 0;
 #endif
     ctx->source_count = 0;
-    mbedtls_zeroize( ctx->source, sizeof( ctx->source ) );
+    mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
     ctx->accumulator_started = 0;
 }
 
@@ -232,7 +228,7 @@
 #endif
 
 cleanup:
-    mbedtls_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
 
     return( ret );
 }
@@ -300,7 +296,7 @@
         ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
 
 cleanup:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     return( ret );
 }
@@ -433,7 +429,7 @@
     ret = 0;
 
 exit:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
 #if defined(MBEDTLS_THREADING_C)
     if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
@@ -486,7 +482,7 @@
     ret = 0;
 
 exit:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     fclose( f );
     return( ret );
@@ -516,7 +512,7 @@
 
     fclose( f );
 
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     if( ret != 0 )
         return( ret );
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 67900c4..fd96258 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -25,13 +25,14 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
+#include <string.h>
+
 #if defined(MBEDTLS_ENTROPY_C)
 
 #include "mbedtls/entropy.h"
 #include "mbedtls/entropy_poll.h"
 
 #if defined(MBEDTLS_TIMING_C)
-#include <string.h>
 #include "mbedtls/timing.h"
 #endif
 #if defined(MBEDTLS_HAVEGE_C)
diff --git a/library/error.c b/library/error.c
index 96ab203..5b57c7c 100644
--- a/library/error.c
+++ b/library/error.c
@@ -49,6 +49,10 @@
 #include "mbedtls/arc4.h"
 #endif
 
+#if defined(MBEDTLS_ARIA_C)
+#include "mbedtls/aria.h"
+#endif
+
 #if defined(MBEDTLS_BASE64_C)
 #include "mbedtls/base64.h"
 #endif
@@ -101,6 +105,10 @@
 #include "mbedtls/gcm.h"
 #endif
 
+#if defined(MBEDTLS_HKDF_C)
+#include "mbedtls/hkdf.h"
+#endif
+
 #if defined(MBEDTLS_HMAC_DRBG_C)
 #include "mbedtls/hmac_drbg.h"
 #endif
@@ -256,19 +264,19 @@
         if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
             mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
         if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
-            mbedtls_snprintf( buf, buflen, "ECP - Requested curve not available" );
+            mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" );
         if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
             mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
         if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
             mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
         if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
-            mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" );
+            mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" );
         if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
             mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
         if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
             mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
         if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
-            mbedtls_snprintf( buf, buflen, "ECP - ECP hardware accelerator failed" );
+            mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" );
 #endif /* MBEDTLS_ECP_C */
 
 #if defined(MBEDTLS_MD_C)
@@ -572,6 +580,8 @@
         mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
     if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
         mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "AES - Invalid input data" );
     if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
         mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
     if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
@@ -583,6 +593,17 @@
         mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
 #endif /* MBEDTLS_ARC4_C */
 
+#if defined(MBEDTLS_ARIA_C)
+    if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "ARIA - Invalid key length" );
+    if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) )
+        mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" );
+    if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" );
+#endif /* MBEDTLS_ARIA_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" );
@@ -698,6 +719,11 @@
         mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
 #endif /* MBEDTLS_GCM_C */
 
+#if defined(MBEDTLS_HKDF_C)
+    if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" );
+#endif /* MBEDTLS_HKDF_C */
+
 #if defined(MBEDTLS_HMAC_DRBG_C)
     if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
         mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
diff --git a/library/gcm.c b/library/gcm.c
index 294a86d..57b0279 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -38,6 +38,7 @@
 #if defined(MBEDTLS_GCM_C)
 
 #include "mbedtls/gcm.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -80,11 +81,6 @@
 }
 #endif
 
-/* 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;
-}
-
 /*
  * Initialize a context
  */
@@ -498,7 +494,7 @@
 
     if( diff != 0 )
     {
-        mbedtls_zeroize( output, length );
+        mbedtls_platform_zeroize( output, length );
         return( MBEDTLS_ERR_GCM_AUTH_FAILED );
     }
 
@@ -508,7 +504,7 @@
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
 {
     mbedtls_cipher_free( &ctx->cipher_ctx );
-    mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
 }
 
 #endif /* !MBEDTLS_GCM_ALT */
diff --git a/library/havege.c b/library/havege.c
index 2b75ef7..4dcac02 100644
--- a/library/havege.c
+++ b/library/havege.c
@@ -36,14 +36,10 @@
 
 #include "mbedtls/havege.h"
 #include "mbedtls/timing.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
-/* 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;
-}
-
 /* ------------------------------------------------------------------------
  * On average, one iteration accesses two 8-word blocks in the havege WALK
  * table, and generates 16 words in the RES array.
@@ -208,7 +204,7 @@
     if( hs == NULL )
         return;
 
-    mbedtls_zeroize( hs, sizeof( mbedtls_havege_state ) );
+    mbedtls_platform_zeroize( hs, sizeof( mbedtls_havege_state ) );
 }
 
 /*
diff --git a/library/hkdf.c b/library/hkdf.c
new file mode 100644
index 0000000..d2e55e8
--- /dev/null
+++ b/library/hkdf.c
@@ -0,0 +1,180 @@
+/*
+ *  HKDF implementation -- RFC 5869
+ *
+ *  Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_HKDF_C)
+
+#include <string.h>
+#include "mbedtls/hkdf.h"
+#include "mbedtls/platform_util.h"
+
+int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
+                  size_t salt_len, const unsigned char *ikm, size_t ikm_len,
+                  const unsigned char *info, size_t info_len,
+                  unsigned char *okm, size_t okm_len )
+{
+    int ret;
+    unsigned char prk[MBEDTLS_MD_MAX_SIZE];
+
+    ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
+
+    if( ret == 0 )
+    {
+        ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ),
+                                   info, info_len, okm, okm_len );
+    }
+
+    mbedtls_platform_zeroize( prk, sizeof( prk ) );
+
+    return( ret );
+}
+
+int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
+                          const unsigned char *salt, size_t salt_len,
+                          const unsigned char *ikm, size_t ikm_len,
+                          unsigned char *prk )
+{
+    unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
+
+    if( salt == NULL )
+    {
+        size_t hash_len;
+
+        hash_len = mbedtls_md_get_size( md );
+
+        if( hash_len == 0 )
+        {
+            return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
+        }
+
+        salt = null_salt;
+        salt_len = hash_len;
+    }
+
+    return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) );
+}
+
+int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
+                         size_t prk_len, const unsigned char *info,
+                         size_t info_len, unsigned char *okm, size_t okm_len )
+{
+    size_t hash_len;
+    size_t where = 0;
+    size_t n;
+    size_t t_len = 0;
+    size_t i;
+    int ret = 0;
+    mbedtls_md_context_t ctx;
+    unsigned char t[MBEDTLS_MD_MAX_SIZE];
+
+    if( okm == NULL )
+    {
+        return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+    }
+
+    hash_len = mbedtls_md_get_size( md );
+
+    if( prk_len < hash_len || hash_len == 0 )
+    {
+        return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+    }
+
+    if( info == NULL )
+    {
+        info = (const unsigned char *) "";
+        info_len = 0;
+    }
+
+    n = okm_len / hash_len;
+
+    if( (okm_len % hash_len) != 0 )
+    {
+        n++;
+    }
+
+    if( n > 255 )
+    {
+        return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+    }
+
+    mbedtls_md_init( &ctx );
+
+    if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
+    {
+        goto exit;
+    }
+
+    /* RFC 5869 Section 2.3. */
+    for( i = 1; i <= n; i++ )
+    {
+        size_t num_to_copy;
+        unsigned char c = i & 0xff;
+
+        ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        ret = mbedtls_md_hmac_update( &ctx, t, t_len );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        ret = mbedtls_md_hmac_update( &ctx, info, info_len );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        /* The constant concatenated to the end of each t(n) is a single octet.
+         * */
+        ret = mbedtls_md_hmac_update( &ctx, &c, 1 );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        ret = mbedtls_md_hmac_finish( &ctx, t );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        num_to_copy = i != n ? hash_len : okm_len - where;
+        memcpy( okm + where, t, num_to_copy );
+        where += hash_len;
+        t_len = hash_len;
+    }
+
+exit:
+    mbedtls_md_free( &ctx );
+    mbedtls_platform_zeroize( t, sizeof( t ) );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_HKDF_C */
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 24c609e..dad55ff 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -34,6 +34,7 @@
 #if defined(MBEDTLS_HMAC_DRBG_C)
 
 #include "mbedtls/hmac_drbg.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -50,11 +51,6 @@
 #endif /* MBEDTLS_SELF_TEST */
 #endif /* MBEDTLS_PLATFORM_C */
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 /*
  * HMAC_DRBG context initialization
  */
@@ -338,7 +334,7 @@
     mbedtls_mutex_free( &ctx->mutex );
 #endif
     mbedtls_md_free( &ctx->md_ctx );
-    mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
 }
 
 #if defined(MBEDTLS_FS_IO)
@@ -364,7 +360,7 @@
 
 exit:
     fclose( f );
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     return( ret );
 }
@@ -396,7 +392,7 @@
 
     fclose( f );
 
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     if( ret != 0 )
         return( ret );
diff --git a/library/md.c b/library/md.c
index 00249af..303cdcb 100644
--- a/library/md.c
+++ b/library/md.c
@@ -33,6 +33,7 @@
 
 #include "mbedtls/md.h"
 #include "mbedtls/md_internal.h"
+#include "mbedtls/platform_util.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -48,11 +49,6 @@
 #include <stdio.h>
 #endif
 
-/* 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;
-}
-
 /*
  * Reminder: update profiles in x509_crt.c when adding a new hash!
  */
@@ -193,11 +189,12 @@
 
     if( ctx->hmac_ctx != NULL )
     {
-        mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size );
+        mbedtls_platform_zeroize( ctx->hmac_ctx,
+                                  2 * ctx->md_info->block_size );
         mbedtls_free( ctx->hmac_ctx );
     }
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
 }
 
 int mbedtls_md_clone( mbedtls_md_context_t *dst,
@@ -311,7 +308,7 @@
         ret = md_info->finish_func( ctx.md_ctx, output );
 
 cleanup:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
     fclose( f );
     mbedtls_md_free( &ctx );
 
@@ -361,7 +358,7 @@
         goto cleanup;
 
 cleanup:
-    mbedtls_zeroize( sum, sizeof( sum ) );
+    mbedtls_platform_zeroize( sum, sizeof( sum ) );
 
     return( ret );
 }
diff --git a/library/md2.c b/library/md2.c
index b88aa40..1c0b3df 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -34,6 +34,7 @@
 #if defined(MBEDTLS_MD2_C)
 
 #include "mbedtls/md2.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -48,11 +49,6 @@
 
 #if !defined(MBEDTLS_MD2_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;
-}
-
 static const unsigned char PI_SUBST[256] =
 {
     0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
@@ -93,7 +89,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_md2_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md2_context ) );
 }
 
 void mbedtls_md2_clone( mbedtls_md2_context *dst,
diff --git a/library/md4.c b/library/md4.c
index ba704f5..3f8ddff 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -34,6 +34,7 @@
 #if defined(MBEDTLS_MD4_C)
 
 #include "mbedtls/md4.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -48,11 +49,6 @@
 
 #if !defined(MBEDTLS_MD4_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;
-}
-
 /*
  * 32-bit integer manipulation macros (little endian)
  */
@@ -86,7 +82,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
 }
 
 void mbedtls_md4_clone( mbedtls_md4_context *dst,
diff --git a/library/md5.c b/library/md5.c
index 8440ebf..8238c2b 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -33,6 +33,7 @@
 #if defined(MBEDTLS_MD5_C)
 
 #include "mbedtls/md5.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -47,11 +48,6 @@
 
 #if !defined(MBEDTLS_MD5_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;
-}
-
 /*
  * 32-bit integer manipulation macros (little endian)
  */
@@ -85,7 +81,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) );
 }
 
 void mbedtls_md5_clone( mbedtls_md5_context *dst,
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index 821ae2c..ceaeda1 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -31,6 +31,7 @@
 /* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
    is dependent upon MBEDTLS_PLATFORM_C */
 #include "mbedtls/platform.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -42,11 +43,6 @@
 #include "mbedtls/threading.h"
 #endif
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 #define MAGIC1       0xFF00AA55
 #define MAGIC2       0xEE119966
 #define MAX_BT 20
@@ -612,7 +608,7 @@
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_free( &heap.mutex );
 #endif
-    mbedtls_zeroize( &heap, sizeof(buffer_alloc_ctx) );
+    mbedtls_platform_zeroize( &heap, sizeof(buffer_alloc_ctx) );
 }
 
 #if defined(MBEDTLS_SELF_TEST)
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 62f5b68..202da01 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -460,11 +460,15 @@
     if( fd < 0 )
         return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 
-    /* Ensure that memory sanitizers consider
-     * read_fds and write_fds as initialized even
-     * if FD_ZERO is implemented in assembly. */
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+    /* Ensure that memory sanitizers consider read_fds and write_fds as
+     * initialized even on platforms such as Glibc/x86_64 where FD_ZERO
+     * is implemented in assembly. */
     memset( &read_fds, 0, sizeof( read_fds ) );
     memset( &write_fds, 0, sizeof( write_fds ) );
+#endif
+#endif
 
     FD_ZERO( &read_fds );
     if( rw & MBEDTLS_NET_POLL_READ )
diff --git a/library/pem.c b/library/pem.c
index 13f9208..6069a23 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -33,6 +33,7 @@
 #include "mbedtls/aes.h"
 #include "mbedtls/md5.h"
 #include "mbedtls/cipher.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -45,11 +46,6 @@
 #endif
 
 #if defined(MBEDTLS_PEM_PARSE_C)
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 void mbedtls_pem_init( mbedtls_pem_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_pem_context ) );
@@ -135,7 +131,7 @@
 
 exit:
     mbedtls_md5_free( &md5_ctx );
-    mbedtls_zeroize( md5sum, 16 );
+    mbedtls_platform_zeroize( md5sum, 16 );
 
     return( ret );
 }
@@ -164,7 +160,7 @@
 
 exit:
     mbedtls_des_free( &des_ctx );
-    mbedtls_zeroize( des_key, 8 );
+    mbedtls_platform_zeroize( des_key, 8 );
 
     return( ret );
 }
@@ -192,7 +188,7 @@
 
 exit:
     mbedtls_des3_free( &des3_ctx );
-    mbedtls_zeroize( des3_key, 24 );
+    mbedtls_platform_zeroize( des3_key, 24 );
 
     return( ret );
 }
@@ -222,7 +218,7 @@
 
 exit:
     mbedtls_aes_free( &aes_ctx );
-    mbedtls_zeroize( aes_key, keylen );
+    mbedtls_platform_zeroize( aes_key, keylen );
 
     return( ret );
 }
@@ -359,7 +355,7 @@
 
     if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
     {
-        mbedtls_zeroize( buf, len );
+        mbedtls_platform_zeroize( buf, len );
         mbedtls_free( buf );
         return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
     }
@@ -370,7 +366,7 @@
     ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
         if( pwd == NULL )
         {
-            mbedtls_zeroize( buf, len );
+            mbedtls_platform_zeroize( buf, len );
             mbedtls_free( buf );
             return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
         }
@@ -407,12 +403,12 @@
          */
         if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
         {
-            mbedtls_zeroize( buf, len );
+            mbedtls_platform_zeroize( buf, len );
             mbedtls_free( buf );
             return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
         }
 #else
-        mbedtls_zeroize( buf, len );
+        mbedtls_platform_zeroize( buf, len );
         mbedtls_free( buf );
         return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
 #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
@@ -428,11 +424,11 @@
 void mbedtls_pem_free( mbedtls_pem_context *ctx )
 {
     if( ctx->buf != NULL )
-        mbedtls_zeroize( ctx->buf, ctx->buflen );
+        mbedtls_platform_zeroize( ctx->buf, ctx->buflen );
     mbedtls_free( ctx->buf );
     mbedtls_free( ctx->info );
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_pem_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) );
 }
 #endif /* MBEDTLS_PEM_PARSE_C */
 
diff --git a/library/pk.c b/library/pk.c
index b52c73f..f05b139 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -29,6 +29,8 @@
 #include "mbedtls/pk.h"
 #include "mbedtls/pk_internal.h"
 
+#include "mbedtls/platform_util.h"
+
 #if defined(MBEDTLS_RSA_C)
 #include "mbedtls/rsa.h"
 #endif
@@ -42,11 +44,6 @@
 #include <limits.h>
 #include <stdint.h>
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 /*
  * Initialise a mbedtls_pk_context
  */
@@ -69,7 +66,7 @@
 
     ctx->pk_info->ctx_free_func( ctx->pk_ctx );
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_pk_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
 }
 
 /*
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 5446e23..2c7d2d7 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -41,6 +41,10 @@
 #include "mbedtls/ecdsa.h"
 #endif
 
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+#include "mbedtls/platform_util.h"
+#endif
+
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
@@ -52,13 +56,6 @@
 #include <limits.h>
 #include <stdint.h>
 
-#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-#endif
-
 #if defined(MBEDTLS_RSA_C)
 static int rsa_can_do( mbedtls_pk_type_t type )
 {
@@ -498,7 +495,7 @@
 
 static void rsa_alt_free_wrap( void *ctx )
 {
-    mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
     mbedtls_free( ctx );
 }
 
diff --git a/library/pkcs12.c b/library/pkcs12.c
index c603a13..16a15cb 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -36,6 +36,7 @@
 #include "mbedtls/pkcs12.h"
 #include "mbedtls/asn1.h"
 #include "mbedtls/cipher.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -47,11 +48,6 @@
 #include "mbedtls/des.h"
 #endif
 
-/* 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;
-}
-
 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
                                     mbedtls_asn1_buf *salt, int *iterations )
 {
@@ -166,7 +162,7 @@
         goto exit;
 
 exit:
-    mbedtls_zeroize( key, sizeof( key ) );
+    mbedtls_platform_zeroize( key, sizeof( key ) );
     mbedtls_arc4_free( &ctx );
 
     return( ret );
@@ -223,8 +219,8 @@
         ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
 
 exit:
-    mbedtls_zeroize( key, sizeof( key ) );
-    mbedtls_zeroize( iv,  sizeof( iv  ) );
+    mbedtls_platform_zeroize( key, sizeof( key ) );
+    mbedtls_platform_zeroize( iv,  sizeof( iv  ) );
     mbedtls_cipher_free( &cipher_ctx );
 
     return( ret );
@@ -352,10 +348,10 @@
     ret = 0;
 
 exit:
-    mbedtls_zeroize( salt_block, sizeof( salt_block ) );
-    mbedtls_zeroize( pwd_block, sizeof( pwd_block ) );
-    mbedtls_zeroize( hash_block, sizeof( hash_block ) );
-    mbedtls_zeroize( hash_output, sizeof( hash_output ) );
+    mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) );
+    mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) );
+    mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) );
+    mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) );
 
     mbedtls_md_free( &md_ctx );
 
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 440a174..f04f0ab 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -249,8 +249,10 @@
     memset( counter, 0, 4 );
     counter[3] = 1;
 
+#if UINT_MAX > 0xFFFFFFFF
     if( iteration_count > 0xFFFFFFFF )
         return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
+#endif
 
     while( key_length )
     {
diff --git a/library/pkparse.c b/library/pkparse.c
index 5ad5edf..ccb7f54 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -30,6 +30,7 @@
 #include "mbedtls/pk.h"
 #include "mbedtls/asn1.h"
 #include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -60,14 +61,6 @@
 #define mbedtls_free       free
 #endif
 
-#if defined(MBEDTLS_FS_IO) || \
-    defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-#endif
-
 #if defined(MBEDTLS_FS_IO)
 /*
  * Load all data from a file into a given buffer.
@@ -105,7 +98,7 @@
     {
         fclose( f );
 
-        mbedtls_zeroize( *buf, *n );
+        mbedtls_platform_zeroize( *buf, *n );
         mbedtls_free( *buf );
 
         return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
@@ -140,7 +133,7 @@
         ret = mbedtls_pk_parse_key( ctx, buf, n,
                 (const unsigned char *) pwd, strlen( pwd ) );
 
-    mbedtls_zeroize( buf, n );
+    mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
 
     return( ret );
@@ -160,7 +153,7 @@
 
     ret = mbedtls_pk_parse_public_key( ctx, buf, n );
 
-    mbedtls_zeroize( buf, n );
+    mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
 
     return( ret );
@@ -1295,7 +1288,7 @@
         ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
                                                 pwd, pwdlen );
 
-        mbedtls_zeroize( key_copy, keylen );
+        mbedtls_platform_zeroize( key_copy, keylen );
         mbedtls_free( key_copy );
     }
 
diff --git a/library/platform.c b/library/platform.c
index a295f9b..9e99287 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -28,14 +28,7 @@
 #if defined(MBEDTLS_PLATFORM_C)
 
 #include "mbedtls/platform.h"
-
-#if defined(MBEDTLS_ENTROPY_NV_SEED) && \
-    !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-#endif
+#include "mbedtls/platform_util.h"
 
 #if defined(MBEDTLS_PLATFORM_MEMORY)
 #if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
@@ -241,7 +234,7 @@
     if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
     {
         fclose( file );
-        mbedtls_zeroize( buf, buf_len );
+        mbedtls_platform_zeroize( buf, buf_len );
         return( -1 );
     }
 
diff --git a/library/platform_util.c b/library/platform_util.c
new file mode 100644
index 0000000..1a57de9
--- /dev/null
+++ b/library/platform_util.c
@@ -0,0 +1,67 @@
+/*
+ * Common and shared functions used by multiple modules in the Mbed TLS
+ * library.
+ *
+ *  Copyright (C) 2018, Arm Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/platform_util.h"
+
+#include <stddef.h>
+#include <string.h>
+
+#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
+/*
+ * This implementation should never be optimized out by the compiler
+ *
+ * This implementation for mbedtls_platform_zeroize() was inspired from Colin
+ * Percival's blog article at:
+ *
+ * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
+ *
+ * It uses a volatile function pointer to the standard memset(). Because the
+ * pointer is volatile the compiler expects it to change at
+ * any time and will not optimize out the call that could potentially perform
+ * other operations on the input buffer instead of just setting it to 0.
+ * Nevertheless, as pointed out by davidtgoldblatt on Hacker News
+ * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
+ * details), optimizations of the following form are still possible:
+ *
+ * if( memset_func != memset )
+ *     memset_func( buf, 0, len );
+ *
+ * Note that it is extremely difficult to guarantee that
+ * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers
+ * in a portable way. For this reason, Mbed TLS also provides the configuration
+ * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
+ * mbedtls_platform_zeroize() to use a suitable implementation for their
+ * platform and needs.
+ */
+static void * (* const volatile memset_func)( void *, int, size_t ) = memset;
+
+void mbedtls_platform_zeroize( void *buf, size_t len )
+{
+    memset_func( buf, 0, len );
+}
+#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
diff --git a/library/ripemd160.c b/library/ripemd160.c
index 2ba48b7..bd25ada 100644
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -34,6 +34,7 @@
 #if defined(MBEDTLS_RIPEMD160_C)
 
 #include "mbedtls/ripemd160.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -71,11 +72,6 @@
 }
 #endif
 
-/* 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;
-}
-
 void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
@@ -86,7 +82,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
 }
 
 void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
diff --git a/library/rsa.c b/library/rsa.c
index 2185040..88c1cf1 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -48,6 +48,7 @@
 #include "mbedtls/rsa.h"
 #include "mbedtls/rsa_internal.h"
 #include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -70,11 +71,6 @@
 
 #if !defined(MBEDTLS_RSA_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 #if defined(MBEDTLS_PKCS1_V15)
 /* constant-time buffer comparison */
 static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
@@ -495,6 +491,9 @@
 
 /*
  * Generate an RSA keypair
+ *
+ * This generation method follows the RSA key pair generation procedure of
+ * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
  */
 int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
                  int (*f_rng)(void *, unsigned char *, size_t),
@@ -502,7 +501,7 @@
                  unsigned int nbits, int exponent )
 {
     int ret;
-    mbedtls_mpi H, G;
+    mbedtls_mpi H, G, L;
 
     if( f_rng == NULL || nbits < 128 || exponent < 3 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -512,10 +511,13 @@
 
     mbedtls_mpi_init( &H );
     mbedtls_mpi_init( &G );
+    mbedtls_mpi_init( &L );
 
     /*
      * find primes P and Q with Q < P so that:
-     * GCD( E, (P-1)*(Q-1) ) == 1
+     * 1.  |P-Q| > 2^( nbits / 2 - 100 )
+     * 2.  GCD( E, (P-1)*(Q-1) ) == 1
+     * 3.  E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
      */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
 
@@ -527,40 +529,51 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
                                                 f_rng, p_rng ) );
 
-        if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
+        /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
+        if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
             continue;
 
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
-        if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
-            continue;
-
-        if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
+        /* not required by any standards, but some users rely on the fact that P > Q */
+        if( H.s < 0 )
             mbedtls_mpi_swap( &ctx->P, &ctx->Q );
 
         /* Temporarily replace P,Q by P-1, Q-1 */
         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
+
+        /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
         MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H  ) );
+        if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
+            continue;
+
+        /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
+
+        if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
+            continue;
+
+        break;
     }
-    while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
+    while( 1 );
 
     /* Restore P,Q */
     MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P,  &ctx->P, 1 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q,  &ctx->Q, 1 ) );
 
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
+
     ctx->len = mbedtls_mpi_size( &ctx->N );
 
+#if !defined(MBEDTLS_RSA_NO_CRT)
     /*
-     * D  = E^-1 mod ((P-1)*(Q-1))
      * DP = D mod (P - 1)
      * DQ = D mod (Q - 1)
      * QP = Q^-1 mod P
      */
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H  ) );
-
-#if !defined(MBEDTLS_RSA_NO_CRT)
     MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
                                              &ctx->DP, &ctx->DQ, &ctx->QP ) );
 #endif /* MBEDTLS_RSA_NO_CRT */
@@ -572,6 +585,7 @@
 
     mbedtls_mpi_free( &H );
     mbedtls_mpi_free( &G );
+    mbedtls_mpi_free( &L );
 
     if( ret != 0 )
     {
@@ -1042,7 +1056,7 @@
     }
 
 exit:
-    mbedtls_zeroize( mask, sizeof( mask ) );
+    mbedtls_platform_zeroize( mask, sizeof( mask ) );
 
     return( ret );
 }
@@ -1356,8 +1370,8 @@
     ret = 0;
 
 cleanup:
-    mbedtls_zeroize( buf, sizeof( buf ) );
-    mbedtls_zeroize( lhash, sizeof( lhash ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( lhash, sizeof( lhash ) );
 
     return( ret );
 }
@@ -1454,7 +1468,7 @@
     ret = 0;
 
 cleanup:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     return( ret );
 }
@@ -1585,7 +1599,7 @@
     p += hlen;
     *p++ = 0xBC;
 
-    mbedtls_zeroize( salt, sizeof( salt ) );
+    mbedtls_platform_zeroize( salt, sizeof( salt ) );
 
 exit:
     mbedtls_md_free( &md_ctx );
@@ -1727,7 +1741,7 @@
      * after the initial bounds check. */
     if( p != dst + dst_len )
     {
-        mbedtls_zeroize( dst, dst_len );
+        mbedtls_platform_zeroize( dst, dst_len );
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     }
 
@@ -2064,13 +2078,13 @@
 
     if( encoded != NULL )
     {
-        mbedtls_zeroize( encoded, sig_len );
+        mbedtls_platform_zeroize( encoded, sig_len );
         mbedtls_free( encoded );
     }
 
     if( encoded_expected != NULL )
     {
-        mbedtls_zeroize( encoded_expected, sig_len );
+        mbedtls_platform_zeroize( encoded_expected, sig_len );
         mbedtls_free( encoded_expected );
     }
 
diff --git a/library/sha1.c b/library/sha1.c
index 1f29a0f..1587de4 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -33,6 +33,7 @@
 #if defined(MBEDTLS_SHA1_C)
 
 #include "mbedtls/sha1.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -47,11 +48,6 @@
 
 #if !defined(MBEDTLS_SHA1_ALT)
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
-}
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -85,7 +81,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
 }
 
 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
diff --git a/library/sha256.c b/library/sha256.c
index f39bcba..695485d 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -33,6 +33,7 @@
 #if defined(MBEDTLS_SHA256_C)
 
 #include "mbedtls/sha256.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -50,11 +51,6 @@
 
 #if !defined(MBEDTLS_SHA256_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;
-}
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -88,7 +84,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
 }
 
 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
diff --git a/library/sha512.c b/library/sha512.c
index 97cee07..6de94e9 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -33,6 +33,7 @@
 #if defined(MBEDTLS_SHA512_C)
 
 #include "mbedtls/sha512.h"
+#include "mbedtls/platform_util.h"
 
 #if defined(_MSC_VER) || defined(__WATCOMC__)
   #define UL64(x) x##ui64
@@ -56,11 +57,6 @@
 
 #if !defined(MBEDTLS_SHA512_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;
-}
-
 /*
  * 64-bit integer manipulation macros (big endian)
  */
@@ -102,7 +98,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
 }
 
 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 95e6163..2e9a0fd 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -47,7 +47,7 @@
  * 1. By key exchange:
  *    Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
  * 2. By key length and cipher:
- *    AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES
+ *    AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 > 3DES
  * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8
  * 4. By hash function used when relevant
  * 5. By key exchange/auth again: EC > non-EC
@@ -81,6 +81,14 @@
     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
 
+    /* All ARIA-256 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
+
     /* All AES-128 ephemeral suites */
     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
@@ -105,6 +113,14 @@
     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
 
+    /* All ARIA-128 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
+
     /* All remaining >= 128-bit ephemeral suites */
     MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
     MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
@@ -121,6 +137,9 @@
     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
 
     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
@@ -132,6 +151,9 @@
     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
 
     MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
     MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
@@ -161,6 +183,14 @@
     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
 
+    /* All ARIA-256 suites */
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
+
     /* All AES-128 suites */
     MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
     MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
@@ -183,6 +213,14 @@
     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
 
+    /* All ARIA-128 suites */
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
+
     /* All remaining >= 128-bit suites */
     MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
     MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
@@ -194,12 +232,16 @@
     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
 
     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
 
     MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
 
@@ -211,6 +253,8 @@
     MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
     MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
     MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
+    MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
 
     MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
     MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
@@ -219,6 +263,8 @@
     MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
     MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
     MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
+    MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
 
     MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
 
@@ -1688,6 +1734,365 @@
 #endif /* MBEDTLS_DES_C */
 #endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */
 
+#if defined(MBEDTLS_ARIA_C)
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
+             "TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
+             "TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
+             "TLS-PSK-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384,MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
+             "TLS-PSK-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
+             "TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
+             "TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+
+#endif /* MBEDTLS_ARIA_C */
+
+
     { 0, "",
       MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE,
       0, 0, 0, 0, 0 }
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 738014e..7455e99 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -48,10 +48,7 @@
 #endif
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-/* 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;
-}
+#include "mbedtls/platform_util.h"
 #endif
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -355,7 +352,7 @@
 
     *olen = 6;
 }
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || 
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -717,6 +714,49 @@
     return( 0 );
 }
 
+/**
+ * \brief           Validate cipher suite against config in SSL context.
+ *
+ * \param suite_info    cipher suite to validate
+ * \param ssl           SSL context
+ * \param min_minor_ver Minimal minor version to accept a cipher suite
+ * \param max_minor_ver Maximal minor version to accept a cipher suite
+ *
+ * \return          0 if valid, else 1
+ */
+static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info,
+                                     const mbedtls_ssl_context * ssl,
+                                     int min_minor_ver, int max_minor_ver )
+{
+    (void) ssl;
+    if( suite_info == NULL )
+        return( 1 );
+
+    if( suite_info->min_minor_ver > max_minor_ver ||
+            suite_info->max_minor_ver < min_minor_ver )
+        return( 1 );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+            ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
+        return( 1 );
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+    if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
+            suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
+        return( 1 );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
+            mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
+        return( 1 );
+#endif
+
+    return( 0 );
+}
+
 static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
 {
     int ret;
@@ -869,31 +909,11 @@
     {
         ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
 
-        if( ciphersuite_info == NULL )
+        if( ssl_validate_ciphersuite( ciphersuite_info, ssl,
+                                      ssl->conf->min_minor_ver,
+                                      ssl->conf->max_minor_ver ) != 0 )
             continue;
 
-        if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
-            ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
-            continue;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-            ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
-            continue;
-#endif
-
-#if defined(MBEDTLS_ARC4_C)
-        if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
-            ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
-            continue;
-#endif
-
-#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
-            mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
-            continue;
-#endif
-
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
                                     ciphersuites[i] ) );
 
@@ -1261,7 +1281,7 @@
                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
     return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 }
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || 
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1690,22 +1710,9 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
 
-    suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
-    if( suite_info == NULL
-#if defined(MBEDTLS_ARC4_C)
-            || ( ssl->conf->arc4_disabled &&
-                suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
-#endif
-        )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
-    }
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
-
+    /*
+     * Perform cipher suite validation in same way as in ssl_write_client_hello.
+     */
     i = 0;
     while( 1 )
     {
@@ -1724,6 +1731,17 @@
         }
     }
 
+    suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
+    if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
+
     if( comp != MBEDTLS_SSL_COMPRESS_NULL
 #if defined(MBEDTLS_ZLIB_SUPPORT)
         && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
@@ -2673,10 +2691,27 @@
     buf = ssl->in_msg;
 
     /* certificate_types */
+    if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+    }
     cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
     n = cert_type_len;
 
-    if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
+    /*
+     * In the subsequent code there are two paths that read from buf:
+     *     * the length of the signature algorithms field (if minor version of
+     *       SSL is 3),
+     *     * distinguished name length otherwise.
+     * Both reach at most the index:
+     *    ...hdr_len + 2 + n,
+     * therefore the buffer length at this point must be greater than that
+     * regardless of the actual code path.
+     */
+    if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -2691,9 +2726,32 @@
         size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] <<  8 )
                              | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n]       ) );
 #if defined(MBEDTLS_DEBUG_C)
-        unsigned char* sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
+        unsigned char* sig_alg;
         size_t i;
+#endif
 
+        /*
+         * The furthest access in buf is in the loop few lines below:
+         *     sig_alg[i + 1],
+         * where:
+         *     sig_alg = buf + ...hdr_len + 3 + n,
+         *     max(i) = sig_alg_len - 1.
+         * Therefore the furthest access is:
+         *     buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1],
+         * which reduces to:
+         *     buf[...hdr_len + 3 + n + sig_alg_len],
+         * which is one less than we need the buf to be.
+         */
+        if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        }
+
+#if defined(MBEDTLS_DEBUG_C)
+        sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
         for( i = 0; i < sig_alg_len; i += 2 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d"
@@ -2702,14 +2760,6 @@
 #endif
 
         n += 2 + sig_alg_len;
-
-        if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
-        }
     }
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
@@ -3289,8 +3339,8 @@
     if( ticket_len == 0 )
         return( 0 );
 
-    mbedtls_zeroize( ssl->session_negotiate->ticket,
-                      ssl->session_negotiate->ticket_len );
+    mbedtls_platform_zeroize( ssl->session_negotiate->ticket,
+                              ssl->session_negotiate->ticket_len );
     mbedtls_free( ssl->session_negotiate->ticket );
     ssl->session_negotiate->ticket = NULL;
     ssl->session_negotiate->ticket_len = 0;
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index caf1199..56e9bdd 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -40,14 +40,10 @@
 
 #include "mbedtls/ssl_cookie.h"
 #include "mbedtls/ssl_internal.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
-/* 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;
-}
-
 /*
  * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
  * available. Try SHA-256 first, 512 wastes resources since we need to stay
@@ -101,7 +97,7 @@
     mbedtls_mutex_free( &ctx->mutex );
 #endif
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) );
 }
 
 int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
@@ -122,7 +118,7 @@
     if( ret != 0 )
         return( ret );
 
-    mbedtls_zeroize( key, sizeof( key ) );
+    mbedtls_platform_zeroize( key, sizeof( key ) );
 
     return( 0 );
 }
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 2c180f1..09b7a3f 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -38,6 +38,7 @@
 #include "mbedtls/debug.h"
 #include "mbedtls/ssl.h"
 #include "mbedtls/ssl_internal.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -49,13 +50,6 @@
 #include "mbedtls/platform_time.h"
 #endif
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-#endif
-
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
 int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl,
                                  const unsigned char *info,
@@ -553,7 +547,7 @@
     memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) );
 
     /* Zeroize instead of free as we copied the content */
-    mbedtls_zeroize( &session, sizeof( mbedtls_ssl_session ) );
+    mbedtls_platform_zeroize( &session, sizeof( mbedtls_ssl_session ) );
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) );
 
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 4d9116d..a2b3048 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -36,14 +36,10 @@
 #endif
 
 #include "mbedtls/ssl_ticket.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
-/* 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;
-}
-
 /*
  * Initialze context
  */
@@ -83,7 +79,7 @@
                                  mbedtls_cipher_get_key_bitlen( &key->ctx ),
                                  MBEDTLS_ENCRYPT );
 
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     return( ret );
 }
@@ -483,7 +479,7 @@
     mbedtls_mutex_free( &ctx->mutex );
 #endif
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) );
 }
 
 #endif /* MBEDTLS_SSL_TICKET_C */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index e8063d2..e8e0cd8 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -46,6 +46,7 @@
 #include "mbedtls/debug.h"
 #include "mbedtls/ssl.h"
 #include "mbedtls/ssl_internal.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -53,11 +54,6 @@
 #include "mbedtls/oid.h"
 #endif
 
-/* 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;
-}
-
 /* Length of the "epoch" field in the record header */
 static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
 {
@@ -269,8 +265,8 @@
     mbedtls_md5_free(  &md5  );
     mbedtls_sha1_free( &sha1 );
 
-    mbedtls_zeroize( padding, sizeof( padding ) );
-    mbedtls_zeroize( sha1sum, sizeof( sha1sum ) );
+    mbedtls_platform_zeroize( padding, sizeof( padding ) );
+    mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
 
     return( ret );
 }
@@ -367,8 +363,8 @@
 
     mbedtls_md_free( &md_ctx );
 
-    mbedtls_zeroize( tmp, sizeof( tmp ) );
-    mbedtls_zeroize( h_i, sizeof( h_i ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
 
     return( 0 );
 }
@@ -432,8 +428,8 @@
 
     mbedtls_md_free( &md_ctx );
 
-    mbedtls_zeroize( tmp, sizeof( tmp ) );
-    mbedtls_zeroize( h_i, sizeof( h_i ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
 
     return( 0 );
 }
@@ -642,7 +638,8 @@
             return( ret );
         }
 
-        mbedtls_zeroize( handshake->premaster, sizeof(handshake->premaster) );
+        mbedtls_platform_zeroize( handshake->premaster,
+                                  sizeof(handshake->premaster) );
     }
     else
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
@@ -653,7 +650,7 @@
     memcpy( tmp, handshake->randbytes, 64 );
     memcpy( handshake->randbytes, tmp + 32, 32 );
     memcpy( handshake->randbytes + 32, tmp, 32 );
-    mbedtls_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
 
     /*
      *  SSLv3:
@@ -681,7 +678,8 @@
     MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
     MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
 
-    mbedtls_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) );
+    mbedtls_platform_zeroize( handshake->randbytes,
+                              sizeof( handshake->randbytes ) );
 
     /*
      * Determine the appropriate key, IV and MAC length.
@@ -948,7 +946,7 @@
     }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
-    mbedtls_zeroize( keyblk, sizeof( keyblk ) );
+    mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
 
 #if defined(MBEDTLS_ZLIB_SUPPORT)
     // Initialize compression
@@ -1274,7 +1272,7 @@
 
 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) ||     \
     ( defined(MBEDTLS_CIPHER_MODE_CBC) &&                                  \
-      ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) )
+      ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C)) )
 #define SSL_SOME_MODES_USE_MAC
 #endif
 
@@ -1475,7 +1473,7 @@
     else
 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
 #if defined(MBEDTLS_CIPHER_MODE_CBC) &&                                    \
-    ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) )
+    ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
     if( mode == MBEDTLS_MODE_CBC )
     {
         int ret;
@@ -1591,7 +1589,7 @@
     }
     else
 #endif /* MBEDTLS_CIPHER_MODE_CBC &&
-          ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */
+          ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -1735,7 +1733,7 @@
     else
 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
 #if defined(MBEDTLS_CIPHER_MODE_CBC) &&                                    \
-    ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) )
+    ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
     if( mode == MBEDTLS_MODE_CBC )
     {
         /*
@@ -1947,7 +1945,7 @@
     }
     else
 #endif /* MBEDTLS_CIPHER_MODE_CBC &&
-          ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */
+          ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -2108,6 +2106,7 @@
 {
     int ret;
     unsigned char *msg_post = ssl->out_msg;
+    ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
     size_t len_pre = ssl->out_msglen;
     unsigned char *msg_pre = ssl->compress_buf;
 
@@ -2127,7 +2126,7 @@
     ssl->transform_out->ctx_deflate.next_in = msg_pre;
     ssl->transform_out->ctx_deflate.avail_in = len_pre;
     ssl->transform_out->ctx_deflate.next_out = msg_post;
-    ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN;
+    ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN - bytes_written;
 
     ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
     if( ret != Z_OK )
@@ -2137,7 +2136,7 @@
     }
 
     ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN -
-                      ssl->transform_out->ctx_deflate.avail_out;
+                      ssl->transform_out->ctx_deflate.avail_out - bytes_written;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
                    ssl->out_msglen ) );
@@ -2154,6 +2153,7 @@
 {
     int ret;
     unsigned char *msg_post = ssl->in_msg;
+    ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
     size_t len_pre = ssl->in_msglen;
     unsigned char *msg_pre = ssl->compress_buf;
 
@@ -2173,7 +2173,8 @@
     ssl->transform_in->ctx_inflate.next_in = msg_pre;
     ssl->transform_in->ctx_inflate.avail_in = len_pre;
     ssl->transform_in->ctx_inflate.next_out = msg_post;
-    ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_MAX_CONTENT_LEN;
+    ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_BUFFER_LEN -
+                                               header_bytes;
 
     ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
     if( ret != Z_OK )
@@ -2182,8 +2183,8 @@
         return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
     }
 
-    ssl->in_msglen = MBEDTLS_SSL_MAX_CONTENT_LEN -
-                     ssl->transform_in->ctx_inflate.avail_out;
+    ssl->in_msglen = MBEDTLS_SSL_BUFFER_LEN -
+                     ssl->transform_in->ctx_inflate.avail_out - header_bytes;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
                    ssl->in_msglen ) );
@@ -2444,8 +2445,8 @@
 
             if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
             {
-                MBEDTLS_SSL_DEBUG_MSG( 1, 
-                    ( "f_recv returned %d bytes but only %lu were requested", 
+                MBEDTLS_SSL_DEBUG_MSG( 1,
+                    ( "f_recv returned %d bytes but only %lu were requested",
                     ret, (unsigned long)len ) );
                 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
             }
@@ -2499,8 +2500,8 @@
 
         if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
         {
-            MBEDTLS_SSL_DEBUG_MSG( 1, 
-                ( "f_send returned %d bytes but only %lu bytes were sent", 
+            MBEDTLS_SSL_DEBUG_MSG( 1,
+                ( "f_send returned %d bytes but only %lu bytes were sent",
                 ret, (unsigned long)ssl->out_left ) );
             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
         }
@@ -5027,9 +5028,9 @@
     mbedtls_md5_free(  &md5  );
     mbedtls_sha1_free( &sha1 );
 
-    mbedtls_zeroize(  padbuf, sizeof(  padbuf ) );
-    mbedtls_zeroize(  md5sum, sizeof(  md5sum ) );
-    mbedtls_zeroize( sha1sum, sizeof( sha1sum ) );
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+    mbedtls_platform_zeroize(  md5sum, sizeof(  md5sum ) );
+    mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -5088,7 +5089,7 @@
     mbedtls_md5_free(  &md5  );
     mbedtls_sha1_free( &sha1 );
 
-    mbedtls_zeroize(  padbuf, sizeof(  padbuf ) );
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -5138,7 +5139,7 @@
 
     mbedtls_sha256_free( &sha256 );
 
-    mbedtls_zeroize(  padbuf, sizeof(  padbuf ) );
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -5187,7 +5188,7 @@
 
     mbedtls_sha512_free( &sha512 );
 
-    mbedtls_zeroize(  padbuf, sizeof( padbuf ) );
+    mbedtls_platform_zeroize(  padbuf, sizeof( padbuf ) );
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -6106,7 +6107,7 @@
 
     if( conf->psk != NULL )
     {
-        mbedtls_zeroize( conf->psk, conf->psk_len );
+        mbedtls_platform_zeroize( conf->psk, conf->psk_len );
 
         mbedtls_free( conf->psk );
         conf->psk = NULL;
@@ -6149,7 +6150,8 @@
 
     if( ssl->handshake->psk != NULL )
     {
-        mbedtls_zeroize( ssl->handshake->psk, ssl->handshake->psk_len );
+        mbedtls_platform_zeroize( ssl->handshake->psk,
+                                  ssl->handshake->psk_len );
         mbedtls_free( ssl->handshake->psk );
         ssl->handshake->psk_len = 0;
     }
@@ -6279,7 +6281,7 @@
 
     if( ssl->hostname != NULL )
     {
-        mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) );
+        mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) );
         mbedtls_free( ssl->hostname );
     }
 
@@ -6948,30 +6950,6 @@
         }
     }
 
-    /*
-     * The logic could be streamlined here. Instead of
-     * - Manually checking whether ssl->in_offt is NULL
-     * - Fetching a new record if yes
-     * - Setting ssl->in_offt if one finds an application record
-     * - Resetting keep_current_message after handling the application data
-     * one should
-     * - Adapt read_record to set ssl->in_offt automatically
-     *   when a new application data record is processed.
-     * - Always call mbedtls_ssl_read_record here.
-     * This way, the logic of ssl_read would be much clearer:
-     * (1) Always call record layer and see what kind of record is on
-     *     and have it ready for consumption (in particular, in_offt
-     *     properly set for application data records).
-     * (2) If it's application data (either freshly fetched
-     *     or something already being partially processed),
-     *     serve the read request from it.
-     * (3) If it's something different from application data,
-     *     handle it accordingly, e.g. potentially start a
-     *     renegotiation.
-     * This will also remove the need to manually reset
-     * ssl->keep_current_message = 0 below.
-     */
-
     /* Loop as long as no application data record is available */
     while( ssl->in_offt == NULL )
     {
@@ -7392,7 +7370,7 @@
     mbedtls_md_free( &transform->md_ctx_enc );
     mbedtls_md_free( &transform->md_ctx_dec );
 
-    mbedtls_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
+    mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
 }
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -7452,7 +7430,7 @@
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
     if( handshake->psk != NULL )
     {
-        mbedtls_zeroize( handshake->psk, handshake->psk_len );
+        mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
         mbedtls_free( handshake->psk );
     }
 #endif
@@ -7482,7 +7460,8 @@
     ssl_flight_free( handshake->flight );
 #endif
 
-    mbedtls_zeroize( handshake, sizeof( mbedtls_ssl_handshake_params ) );
+    mbedtls_platform_zeroize( handshake,
+                              sizeof( mbedtls_ssl_handshake_params ) );
 }
 
 void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
@@ -7502,7 +7481,7 @@
     mbedtls_free( session->ticket );
 #endif
 
-    mbedtls_zeroize( session, sizeof( mbedtls_ssl_session ) );
+    mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) );
 }
 
 /*
@@ -7517,20 +7496,20 @@
 
     if( ssl->out_buf != NULL )
     {
-        mbedtls_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN );
+        mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN );
         mbedtls_free( ssl->out_buf );
     }
 
     if( ssl->in_buf != NULL )
     {
-        mbedtls_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN );
+        mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN );
         mbedtls_free( ssl->in_buf );
     }
 
 #if defined(MBEDTLS_ZLIB_SUPPORT)
     if( ssl->compress_buf != NULL )
     {
-        mbedtls_zeroize( ssl->compress_buf, MBEDTLS_SSL_BUFFER_LEN );
+        mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_BUFFER_LEN );
         mbedtls_free( ssl->compress_buf );
     }
 #endif
@@ -7561,7 +7540,7 @@
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     if( ssl->hostname != NULL )
     {
-        mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) );
+        mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) );
         mbedtls_free( ssl->hostname );
     }
 #endif
@@ -7581,7 +7560,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );
 
     /* Actually clear after last debug message */
-    mbedtls_zeroize( ssl, sizeof( mbedtls_ssl_context ) );
+    mbedtls_platform_zeroize( ssl, sizeof( mbedtls_ssl_context ) );
 }
 
 /*
@@ -7808,7 +7787,7 @@
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
     if( conf->psk != NULL )
     {
-        mbedtls_zeroize( conf->psk, conf->psk_len );
+        mbedtls_platform_zeroize( conf->psk, conf->psk_len );
         mbedtls_free( conf->psk );
         conf->psk = NULL;
         conf->psk_len = 0;
@@ -7816,7 +7795,7 @@
 
     if( conf->psk_identity != NULL )
     {
-        mbedtls_zeroize( conf->psk_identity, conf->psk_identity_len );
+        mbedtls_platform_zeroize( conf->psk_identity, conf->psk_identity_len );
         mbedtls_free( conf->psk_identity );
         conf->psk_identity = NULL;
         conf->psk_identity_len = 0;
@@ -7827,7 +7806,7 @@
     ssl_key_cert_free( conf->key_cert );
 #endif
 
-    mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) );
+    mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) );
 }
 
 #if defined(MBEDTLS_PK_C) && \
diff --git a/library/version_features.c b/library/version_features.c
index a452caf..fa37119 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -90,6 +90,9 @@
 #if defined(MBEDTLS_ARC4_ALT)
     "MBEDTLS_ARC4_ALT",
 #endif /* MBEDTLS_ARC4_ALT */
+#if defined(MBEDTLS_ARIA_ALT)
+    "MBEDTLS_ARIA_ALT",
+#endif /* MBEDTLS_ARIA_ALT */
 #if defined(MBEDTLS_BLOWFISH_ALT)
     "MBEDTLS_BLOWFISH_ALT",
 #endif /* MBEDTLS_BLOWFISH_ALT */
@@ -246,6 +249,9 @@
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     "MBEDTLS_CIPHER_MODE_CBC",
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    "MBEDTLS_CIPHER_MODE_OFB",
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
     "MBEDTLS_CIPHER_MODE_CFB",
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
@@ -531,6 +537,9 @@
 #if defined(MBEDTLS_CAMELLIA_C)
     "MBEDTLS_CAMELLIA_C",
 #endif /* MBEDTLS_CAMELLIA_C */
+#if defined(MBEDTLS_ARIA_C)
+    "MBEDTLS_ARIA_C",
+#endif /* MBEDTLS_ARIA_C */
 #if defined(MBEDTLS_CCM_C)
     "MBEDTLS_CCM_C",
 #endif /* MBEDTLS_CCM_C */
@@ -579,6 +588,9 @@
 #if defined(MBEDTLS_HAVEGE_C)
     "MBEDTLS_HAVEGE_C",
 #endif /* MBEDTLS_HAVEGE_C */
+#if defined(MBEDTLS_HKDF_C)
+    "MBEDTLS_HKDF_C",
+#endif /* MBEDTLS_HKDF_C */
 #if defined(MBEDTLS_HMAC_DRBG_C)
     "MBEDTLS_HMAC_DRBG_C",
 #endif /* MBEDTLS_HMAC_DRBG_C */
diff --git a/library/x509_crl.c b/library/x509_crl.c
index b0f39d4..8450f87 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -39,6 +39,7 @@
 
 #include "mbedtls/x509_crl.h"
 #include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -66,11 +67,6 @@
 #include <stdio.h>
 #endif
 
-/* 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;
-}
-
 /*
  *  Version  ::=  INTEGER  {  v1(0), v2(1)  }
  */
@@ -616,7 +612,7 @@
 
     ret = mbedtls_x509_crl_parse( chain, buf, n );
 
-    mbedtls_zeroize( buf, n );
+    mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
 
     return( ret );
@@ -737,7 +733,7 @@
         {
             name_prv = name_cur;
             name_cur = name_cur->next;
-            mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
             mbedtls_free( name_prv );
         }
 
@@ -746,13 +742,14 @@
         {
             entry_prv = entry_cur;
             entry_cur = entry_cur->next;
-            mbedtls_zeroize( entry_prv, sizeof( mbedtls_x509_crl_entry ) );
+            mbedtls_platform_zeroize( entry_prv,
+                                      sizeof( mbedtls_x509_crl_entry ) );
             mbedtls_free( entry_prv );
         }
 
         if( crl_cur->raw.p != NULL )
         {
-            mbedtls_zeroize( crl_cur->raw.p, crl_cur->raw.len );
+            mbedtls_platform_zeroize( crl_cur->raw.p, crl_cur->raw.len );
             mbedtls_free( crl_cur->raw.p );
         }
 
@@ -766,7 +763,7 @@
         crl_prv = crl_cur;
         crl_cur = crl_cur->next;
 
-        mbedtls_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) );
+        mbedtls_platform_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) );
         if( crl_prv != crl )
             mbedtls_free( crl_prv );
     }
diff --git a/library/x509_crt.c b/library/x509_crt.c
index afff4e1..290c1eb 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -41,6 +41,7 @@
 
 #include "mbedtls/x509_crt.h"
 #include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -90,11 +91,6 @@
  */
 #define X509_MAX_VERIFY_CHAIN_SIZE    ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
 
-/* 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;
-}
-
 /*
  * Default profile
  */
@@ -733,7 +729,7 @@
 
     memcpy( p, buf, crt->raw.len );
 
-    // Direct pointers to the new buffer 
+    // Direct pointers to the new buffer
     p += crt->raw.len - len;
     end = crt_end = p + len;
 
@@ -1115,7 +1111,7 @@
 
     ret = mbedtls_x509_crt_parse( chain, buf, n );
 
-    mbedtls_zeroize( buf, n );
+    mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
 
     return( ret );
@@ -2426,7 +2422,7 @@
         {
             name_prv = name_cur;
             name_cur = name_cur->next;
-            mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
             mbedtls_free( name_prv );
         }
 
@@ -2435,7 +2431,7 @@
         {
             name_prv = name_cur;
             name_cur = name_cur->next;
-            mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
             mbedtls_free( name_prv );
         }
 
@@ -2444,7 +2440,8 @@
         {
             seq_prv = seq_cur;
             seq_cur = seq_cur->next;
-            mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
+            mbedtls_platform_zeroize( seq_prv,
+                                      sizeof( mbedtls_x509_sequence ) );
             mbedtls_free( seq_prv );
         }
 
@@ -2453,13 +2450,14 @@
         {
             seq_prv = seq_cur;
             seq_cur = seq_cur->next;
-            mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
+            mbedtls_platform_zeroize( seq_prv,
+                                      sizeof( mbedtls_x509_sequence ) );
             mbedtls_free( seq_prv );
         }
 
         if( cert_cur->raw.p != NULL )
         {
-            mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len );
+            mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
             mbedtls_free( cert_cur->raw.p );
         }
 
@@ -2473,7 +2471,7 @@
         cert_prv = cert_cur;
         cert_cur = cert_cur->next;
 
-        mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
+        mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
         if( cert_prv != crt )
             mbedtls_free( cert_prv );
     }
diff --git a/library/x509_csr.c b/library/x509_csr.c
index 26a06db..3e8e8fb 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -39,6 +39,7 @@
 
 #include "mbedtls/x509_csr.h"
 #include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -60,11 +61,6 @@
 #include <stdio.h>
 #endif
 
-/* 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;
-}
-
 /*
  *  Version  ::=  INTEGER  {  v1(0)  }
  */
@@ -325,7 +321,7 @@
 
     ret = mbedtls_x509_csr_parse( csr, buf, n );
 
-    mbedtls_zeroize( buf, n );
+    mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
 
     return( ret );
@@ -407,17 +403,17 @@
     {
         name_prv = name_cur;
         name_cur = name_cur->next;
-        mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+        mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
         mbedtls_free( name_prv );
     }
 
     if( csr->raw.p != NULL )
     {
-        mbedtls_zeroize( csr->raw.p, csr->raw.len );
+        mbedtls_platform_zeroize( csr->raw.p, csr->raw.len );
         mbedtls_free( csr->raw.p );
     }
 
-    mbedtls_zeroize( csr, sizeof( mbedtls_x509_csr ) );
+    mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) );
 }
 
 #endif /* MBEDTLS_X509_CSR_PARSE_C */
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 41dfe87..b1ef216 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -37,6 +37,7 @@
 #include "mbedtls/oid.h"
 #include "mbedtls/asn1write.h"
 #include "mbedtls/sha1.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -44,11 +45,6 @@
 #include "mbedtls/pem.h"
 #endif /* MBEDTLS_PEM_WRITE_C */
 
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
-
 void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_x509write_cert ) );
@@ -65,7 +61,7 @@
     mbedtls_asn1_free_named_data_list( &ctx->issuer );
     mbedtls_asn1_free_named_data_list( &ctx->extensions );
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_x509write_cert ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) );
 }
 
 void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version )
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index e800538..66cee56 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -35,6 +35,7 @@
 #include "mbedtls/x509_csr.h"
 #include "mbedtls/oid.h"
 #include "mbedtls/asn1write.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -43,11 +44,6 @@
 #include "mbedtls/pem.h"
 #endif
 
-/* 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;
-}
-
 void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
@@ -58,7 +54,7 @@
     mbedtls_asn1_free_named_data_list( &ctx->subject );
     mbedtls_asn1_free_named_data_list( &ctx->extensions );
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
 }
 
 void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
diff --git a/library/xtea.c b/library/xtea.c
index fe0a350..a33707b 100644
--- a/library/xtea.c
+++ b/library/xtea.c
@@ -28,6 +28,7 @@
 #if defined(MBEDTLS_XTEA_C)
 
 #include "mbedtls/xtea.h"
+#include "mbedtls/platform_util.h"
 
 #include <string.h>
 
@@ -42,11 +43,6 @@
 
 #if !defined(MBEDTLS_XTEA_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;
-}
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -80,7 +76,7 @@
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_xtea_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_xtea_context ) );
 }
 
 /*
diff --git a/programs/.gitignore b/programs/.gitignore
index 27055b8..ddfa1a4 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -47,6 +47,7 @@
 test/selftest
 test/ssl_cert_test
 test/udp_proxy
+test/zeroize
 util/pem2der
 util/strerror
 x509/cert_app
diff --git a/programs/Makefile b/programs/Makefile
index 25f184f..080e82d 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -67,6 +67,7 @@
 	random/gen_random_ctr_drbg$(EXEXT)				\
 	test/ssl_cert_test$(EXEXT)	test/benchmark$(EXEXT)		\
 	test/selftest$(EXEXT)		test/udp_proxy$(EXEXT)		\
+	test/zeroize$(EXEXT)						\
 	util/pem2der$(EXEXT)		util/strerror$(EXEXT)		\
 	x509/cert_app$(EXEXT)		x509/crl_app$(EXEXT)		\
 	x509/cert_req$(EXEXT)		x509/cert_write$(EXEXT)		\
@@ -249,6 +250,10 @@
 	echo "  CC    test/udp_proxy.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/udp_proxy.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+test/zeroize$(EXEXT): test/zeroize.c $(DEP)
+	echo "  CC    test/zeroize.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/zeroize.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 util/pem2der$(EXEXT): util/pem2der.c $(DEP)
 	echo "  CC    util/pem2der.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) util/pem2der.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index fa70431..01cee13 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -30,7 +30,7 @@
 #else
 #include <stdio.h>
 #include <stdlib.h>
-#define mbedtls_time       time 
+#define mbedtls_time       time
 #define mbedtls_time_t     time_t
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index b49ffb4..04b847a 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -31,7 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_time       time
-#define mbedtls_time_t     time_t 
+#define mbedtls_time_t     time_t
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #endif
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index fd54f17..dcdafbb 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -31,7 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #define mbedtls_time       time
-#define mbedtls_time_t     time_t 
+#define mbedtls_time_t     time_t
 #define mbedtls_fprintf    fprintf
 #define mbedtls_printf     printf
 #endif
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 0ed7145..0c5ce27 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -22,6 +22,9 @@
 add_executable(udp_proxy udp_proxy.c)
 target_link_libraries(udp_proxy ${libs})
 
+add_executable(zeroize zeroize.c)
+target_link_libraries(zeroize ${libs})
+
 install(TARGETS selftest benchmark ssl_cert_test udp_proxy
         DESTINATION "bin"
         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index cecf3e3..07298c1 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -54,21 +54,26 @@
 #include "mbedtls/sha1.h"
 #include "mbedtls/sha256.h"
 #include "mbedtls/sha512.h"
+
 #include "mbedtls/arc4.h"
 #include "mbedtls/des.h"
 #include "mbedtls/aes.h"
+#include "mbedtls/aria.h"
 #include "mbedtls/blowfish.h"
 #include "mbedtls/camellia.h"
 #include "mbedtls/gcm.h"
 #include "mbedtls/ccm.h"
 #include "mbedtls/cmac.h"
+
 #include "mbedtls/havege.h"
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/hmac_drbg.h"
+
 #include "mbedtls/rsa.h"
 #include "mbedtls/dhm.h"
 #include "mbedtls/ecdsa.h"
 #include "mbedtls/ecdh.h"
+
 #include "mbedtls/error.h"
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
@@ -229,7 +234,7 @@
     char md4, md5, ripemd160, sha1, sha256, sha512,
          arc4, des3, des,
          aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,
-         camellia, blowfish,
+         aria, camellia, blowfish,
          havege, ctr_drbg, hmac_drbg,
          rsa, dhm, ecdsa, ecdh;
 } todo_list;
@@ -282,6 +287,8 @@
                 todo.aes_cmac = 1;
             else if( strcmp( argv[i], "des3_cmac" ) == 0 )
                 todo.des3_cmac = 1;
+            else if( strcmp( argv[i], "aria" ) == 0 )
+                todo.aria = 1;
             else if( strcmp( argv[i], "camellia" ) == 0 )
                 todo.camellia = 1;
             else if( strcmp( argv[i], "blowfish" ) == 0 )
@@ -498,6 +505,28 @@
 #endif /* MBEDTLS_CMAC_C */
 #endif /* MBEDTLS_AES_C */
 
+#if defined(MBEDTLS_ARIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
+    if( todo.aria )
+    {
+        int keysize;
+        mbedtls_aria_context aria;
+        mbedtls_aria_init( &aria );
+        for( keysize = 128; keysize <= 256; keysize += 64 )
+        {
+            mbedtls_snprintf( title, sizeof( title ), "ARIA-CBC-%d", keysize );
+
+            memset( buf, 0, sizeof( buf ) );
+            memset( tmp, 0, sizeof( tmp ) );
+            mbedtls_aria_setkey_enc( &aria, tmp, keysize );
+
+            TIME_AND_TSC( title,
+                    mbedtls_aria_crypt_cbc( &aria, MBEDTLS_ARIA_ENCRYPT,
+                        BUFSIZE, tmp, buf, buf ) );
+        }
+        mbedtls_aria_free( &aria );
+    }
+#endif
+
 #if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
     if( todo.camellia )
     {
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 72a3734..019071b 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -44,6 +44,7 @@
 #include "mbedtls/des.h"
 #include "mbedtls/aes.h"
 #include "mbedtls/camellia.h"
+#include "mbedtls/aria.h"
 #include "mbedtls/base64.h"
 #include "mbedtls/bignum.h"
 #include "mbedtls/rsa.h"
@@ -225,6 +226,9 @@
 #if defined(MBEDTLS_CAMELLIA_C)
     {"camellia", mbedtls_camellia_self_test},
 #endif
+#if defined(MBEDTLS_ARIA_C)
+    {"aria", mbedtls_aria_self_test},
+#endif
 #if defined(MBEDTLS_CTR_DRBG_C)
     {"ctr_drbg", mbedtls_ctr_drbg_self_test},
 #endif
diff --git a/programs/test/zeroize.c b/programs/test/zeroize.c
new file mode 100644
index 0000000..29cc0ac
--- /dev/null
+++ b/programs/test/zeroize.c
@@ -0,0 +1,101 @@
+/*
+ * Zeroize application for debugger-driven testing
+ *
+ * This is a simple test application used for debugger-driven testing to check
+ * whether calls to mbedtls_platform_zeroize() are being eliminated by compiler
+ * optimizations. This application is used by the GDB script at
+ * tests/scripts/test_zeroize.gdb under the assumption that the code does not
+ * change often (as opposed to the library code) because the script sets a
+ * breakpoint at the last return statement in the main() function of this
+ * program. The debugger facilities are then used to manually inspect the
+ * memory and verify that the call to mbedtls_platform_zeroize() was not
+ * eliminated.
+ *
+ *  Copyright (C) 2018, Arm Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdio.h>
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_printf     printf
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
+#endif
+
+#include "mbedtls/platform_util.h"
+
+#define BUFFER_LEN 1024
+
+void usage( void )
+{
+    mbedtls_printf( "Zeroize is a simple program to assist with testing\n" );
+    mbedtls_printf( "the mbedtls_platform_zeroize() function by using the\n" );
+    mbedtls_printf( "debugger. This program takes a file as input and\n" );
+    mbedtls_printf( "prints the first %d characters. Usage:\n\n", BUFFER_LEN );
+    mbedtls_printf( "       zeroize <FILE>\n" );
+}
+
+int main( int argc, char** argv )
+{
+    int exit_code = MBEDTLS_EXIT_FAILURE;
+    FILE *fp;
+    char buf[BUFFER_LEN];
+    char *p = buf;
+    char *end = p + BUFFER_LEN;
+    int c;
+
+    if( argc != 2 )
+    {
+        mbedtls_printf( "This program takes exactly 1 agument\n" );
+        usage();
+        return( exit_code );
+    }
+
+    fp = fopen( argv[1], "r" );
+    if( fp == NULL )
+    {
+        mbedtls_printf( "Could not open file '%s'\n", argv[1] );
+        return( exit_code );
+    }
+
+    while( ( c = fgetc( fp ) ) != EOF && p < end - 1 )
+        *p++ = (char)c;
+    *p = '\0';
+
+    if( p - buf != 0 )
+    {
+        mbedtls_printf( "%s\n", buf );
+        exit_code = MBEDTLS_EXIT_SUCCESS;
+    }
+    else
+        mbedtls_printf( "The file is empty!\n" );
+
+    fclose( fp );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    return( exit_code );
+}
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 9cc582d..12baf72 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -607,11 +607,7 @@
     //
     if( strlen( opt.issuer_crt ) )
     {
-        if( !mbedtls_pk_can_do( &issuer_crt.pk, MBEDTLS_PK_RSA ) ||
-            mbedtls_mpi_cmp_mpi( &mbedtls_pk_rsa( issuer_crt.pk )->N,
-                         &mbedtls_pk_rsa( *issuer_key )->N ) != 0 ||
-            mbedtls_mpi_cmp_mpi( &mbedtls_pk_rsa( issuer_crt.pk )->E,
-                         &mbedtls_pk_rsa( *issuer_key )->E ) != 0 )
+        if( mbedtls_pk_check_pair( &issuer_crt.pk, issuer_key ) != 0 )
         {
             mbedtls_printf( " failed\n  !  issuer_key does not match "
                             "issuer certificate\n\n" );
diff --git a/scripts/abi_check.py b/scripts/abi_check.py
new file mode 100755
index 0000000..8f9cd0f
--- /dev/null
+++ b/scripts/abi_check.py
@@ -0,0 +1,241 @@
+#!/usr/bin/env python3
+"""
+This file is part of Mbed TLS (https://tls.mbed.org)
+
+Copyright (c) 2018, Arm Limited, All Rights Reserved
+
+Purpose
+
+This script is a small wrapper around the abi-compliance-checker and
+abi-dumper tools, applying them to compare the ABI and API of the library
+files from two different Git revisions within an Mbed TLS repository.
+The results of the comparison are formatted as HTML and stored at
+a configurable location. Returns 0 on success, 1 on ABI/API non-compliance,
+and 2 if there is an error while running the script.
+Note: must be run from Mbed TLS root.
+"""
+
+import os
+import sys
+import traceback
+import shutil
+import subprocess
+import argparse
+import logging
+import tempfile
+
+
+class AbiChecker(object):
+
+    def __init__(self, report_dir, old_rev, new_rev, keep_all_reports):
+        self.repo_path = "."
+        self.log = None
+        self.setup_logger()
+        self.report_dir = os.path.abspath(report_dir)
+        self.keep_all_reports = keep_all_reports
+        self.should_keep_report_dir = os.path.isdir(self.report_dir)
+        self.old_rev = old_rev
+        self.new_rev = new_rev
+        self.mbedtls_modules = ["libmbedcrypto", "libmbedtls", "libmbedx509"]
+        self.old_dumps = {}
+        self.new_dumps = {}
+        self.git_command = "git"
+        self.make_command = "make"
+
+    def check_repo_path(self):
+        current_dir = os.path.realpath('.')
+        root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+        if current_dir != root_dir:
+            raise Exception("Must be run from Mbed TLS root")
+
+    def setup_logger(self):
+        self.log = logging.getLogger()
+        self.log.setLevel(logging.INFO)
+        self.log.addHandler(logging.StreamHandler())
+
+    def check_abi_tools_are_installed(self):
+        for command in ["abi-dumper", "abi-compliance-checker"]:
+            if not shutil.which(command):
+                raise Exception("{} not installed, aborting".format(command))
+
+    def get_clean_worktree_for_git_revision(self, git_rev):
+        self.log.info(
+            "Checking out git worktree for revision {}".format(git_rev)
+        )
+        git_worktree_path = tempfile.mkdtemp()
+        worktree_process = subprocess.Popen(
+            [self.git_command, "worktree", "add", git_worktree_path, git_rev],
+            cwd=self.repo_path,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT
+        )
+        worktree_output, _ = worktree_process.communicate()
+        self.log.info(worktree_output.decode("utf-8"))
+        if worktree_process.returncode != 0:
+            raise Exception("Checking out worktree failed, aborting")
+        return git_worktree_path
+
+    def build_shared_libraries(self, git_worktree_path):
+        my_environment = os.environ.copy()
+        my_environment["CFLAGS"] = "-g -Og"
+        my_environment["SHARED"] = "1"
+        make_process = subprocess.Popen(
+            self.make_command,
+            env=my_environment,
+            cwd=git_worktree_path,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT
+        )
+        make_output, _ = make_process.communicate()
+        self.log.info(make_output.decode("utf-8"))
+        if make_process.returncode != 0:
+            raise Exception("make failed, aborting")
+
+    def get_abi_dumps_from_shared_libraries(self, git_ref, git_worktree_path):
+        abi_dumps = {}
+        for mbed_module in self.mbedtls_modules:
+            output_path = os.path.join(
+                self.report_dir, "{}-{}.dump".format(mbed_module, git_ref)
+            )
+            abi_dump_command = [
+                "abi-dumper",
+                os.path.join(
+                    git_worktree_path, "library", mbed_module + ".so"),
+                "-o", output_path,
+                "-lver", git_ref
+            ]
+            abi_dump_process = subprocess.Popen(
+                abi_dump_command,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT
+            )
+            abi_dump_output, _ = abi_dump_process.communicate()
+            self.log.info(abi_dump_output.decode("utf-8"))
+            if abi_dump_process.returncode != 0:
+                raise Exception("abi-dumper failed, aborting")
+            abi_dumps[mbed_module] = output_path
+        return abi_dumps
+
+    def cleanup_worktree(self, git_worktree_path):
+        shutil.rmtree(git_worktree_path)
+        worktree_process = subprocess.Popen(
+            [self.git_command, "worktree", "prune"],
+            cwd=self.repo_path,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT
+        )
+        worktree_output, _ = worktree_process.communicate()
+        self.log.info(worktree_output.decode("utf-8"))
+        if worktree_process.returncode != 0:
+            raise Exception("Worktree cleanup failed, aborting")
+
+    def get_abi_dump_for_ref(self, git_rev):
+        git_worktree_path = self.get_clean_worktree_for_git_revision(git_rev)
+        self.build_shared_libraries(git_worktree_path)
+        abi_dumps = self.get_abi_dumps_from_shared_libraries(
+            git_rev, git_worktree_path
+        )
+        self.cleanup_worktree(git_worktree_path)
+        return abi_dumps
+
+    def get_abi_compatibility_report(self):
+        compatibility_report = ""
+        compliance_return_code = 0
+        for mbed_module in self.mbedtls_modules:
+            output_path = os.path.join(
+                self.report_dir, "{}-{}-{}.html".format(
+                    mbed_module, self.old_rev, self.new_rev
+                )
+            )
+            abi_compliance_command = [
+                "abi-compliance-checker",
+                "-l", mbed_module,
+                "-old", self.old_dumps[mbed_module],
+                "-new", self.new_dumps[mbed_module],
+                "-strict",
+                "-report-path", output_path
+            ]
+            abi_compliance_process = subprocess.Popen(
+                abi_compliance_command,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT
+            )
+            abi_compliance_output, _ = abi_compliance_process.communicate()
+            self.log.info(abi_compliance_output.decode("utf-8"))
+            if abi_compliance_process.returncode == 0:
+                compatibility_report += (
+                    "No compatibility issues for {}\n".format(mbed_module)
+                )
+                if not self.keep_all_reports:
+                    os.remove(output_path)
+            elif abi_compliance_process.returncode == 1:
+                compliance_return_code = 1
+                self.should_keep_report_dir = True
+                compatibility_report += (
+                    "Compatibility issues found for {}, "
+                    "for details see {}\n".format(mbed_module, output_path)
+                )
+            else:
+                raise Exception(
+                    "abi-compliance-checker failed with a return code of {},"
+                    " aborting".format(abi_compliance_process.returncode)
+                )
+            os.remove(self.old_dumps[mbed_module])
+            os.remove(self.new_dumps[mbed_module])
+        if not self.should_keep_report_dir and not self.keep_all_reports:
+            os.rmdir(self.report_dir)
+        self.log.info(compatibility_report)
+        return compliance_return_code
+
+    def check_for_abi_changes(self):
+        self.check_repo_path()
+        self.check_abi_tools_are_installed()
+        self.old_dumps = self.get_abi_dump_for_ref(self.old_rev)
+        self.new_dumps = self.get_abi_dump_for_ref(self.new_rev)
+        return self.get_abi_compatibility_report()
+
+
+def run_main():
+    try:
+        parser = argparse.ArgumentParser(
+            description=(
+                """This script is a small wrapper around the
+                abi-compliance-checker and abi-dumper tools, applying them
+                to compare the ABI and API of the library files from two
+                different Git revisions within an Mbed TLS repository.
+                The results of the comparison are formatted as HTML and stored
+                at a configurable location. Returns 0 on success, 1 on ABI/API
+                non-compliance, and 2 if there is an error while running the
+                script. Note: must be run from Mbed TLS root."""
+            )
+        )
+        parser.add_argument(
+            "-r", "--report-dir", type=str, default="reports",
+            help="directory where reports are stored, default is reports",
+        )
+        parser.add_argument(
+            "-k", "--keep-all-reports", action="store_true",
+            help="keep all reports, even if there are no compatibility issues",
+        )
+        parser.add_argument(
+            "-o", "--old-rev", type=str, help="revision for old version",
+            required=True
+        )
+        parser.add_argument(
+            "-n", "--new-rev", type=str, help="revision for new version",
+            required=True
+        )
+        abi_args = parser.parse_args()
+        abi_check = AbiChecker(
+            abi_args.report_dir, abi_args.old_rev,
+            abi_args.new_rev, abi_args.keep_all_reports
+        )
+        return_code = abi_check.check_for_abi_changes()
+        sys.exit(return_code)
+    except Exception:
+        traceback.print_exc()
+        sys.exit(2)
+
+
+if __name__ == "__main__":
+    run_main()
diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl
index ac0fbff..60e5233 100755
--- a/scripts/generate_errors.pl
+++ b/scripts/generate_errors.pl
@@ -29,9 +29,9 @@
 
 my $error_format_file = $data_dir.'/error.fmt';
 
-my @low_level_modules = qw( AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH
+my @low_level_modules = qw( AES ARC4 ARIA ASN1 BASE64 BIGNUM BLOWFISH
                             CAMELLIA CCM CMAC CTR_DRBG DES
-                            ENTROPY GCM HMAC_DRBG MD2 MD4 MD5
+                            ENTROPY GCM HKDF HMAC_DRBG MD2 MD4 MD5
                             NET OID PADLOCK PBKDF2 RIPEMD160
                             SHA1 SHA256 SHA512 THREADING XTEA );
 my @high_level_modules = qw( CIPHER DHM ECP MD
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index 8d36653..e042a44 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -1,8 +1,7 @@
 #!/usr/bin/perl
 
-# Generate files for MS Visual Studio:
-# - for VS6: main project (library) file, individual app files, workspace
-# - for VS2010: main file, individual apps, solution file
+# Generate main file, individual apps and solution files for MS Visual Studio
+# 2010
 #
 # Must be run from mbedTLS root or scripts directory.
 # Takes no argument.
@@ -171,12 +170,22 @@
     content_to_file( $out, $vsx_sln_file );
 }
 
+sub del_vsx_files {
+    unlink glob "'$vsx_dir/*.$vsx_ext'";
+    unlink $vsx_main_file;
+    unlink $vsx_sln_file;
+}
+
 sub main {
     if( ! check_dirs() ) {
         chdir '..' or die;
         check_dirs or die "Must but run from mbedTLS root or scripts dir\n";
     }
 
+    # Remove old files to ensure that, for example, project files from deleted
+    # apps are not kept
+    del_vsx_files();
+
     my @app_list = get_app_list();
     my @headers = <$header_dir/*.h>;
     my @sources = <$source_dir/*.c>;
diff --git a/scripts/output_env.sh b/scripts/output_env.sh
index 1afaac3..c809d46 100755
--- a/scripts/output_env.sh
+++ b/scripts/output_env.sh
@@ -47,13 +47,15 @@
 print_version "uname" "-a" ""
 echo
 
-: ${ARMC5_CC:=armcc}
-print_version "$ARMC5_CC" "--vsn" "armcc not found!" "head -n 2"
-echo
+if [ "${RUN_ARMCC:-1}" -ne 0 ]; then
+    : "${ARMC5_CC:=armcc}"
+    print_version "$ARMC5_CC" "--vsn" "armcc not found!" "head -n 2"
+    echo
 
-: ${ARMC6_CC:=armclang}
-print_version "$ARMC6_CC" "--vsn" "armclang not found!" "head -n 2"
-echo
+    : "${ARMC6_CC:=armclang}"
+    print_version "$ARMC6_CC" "--vsn" "armclang not found!" "head -n 2"
+    echo
+fi
 
 print_version "arm-none-eabi-gcc" "--version" "gcc-arm not found!" "head -n 1"
 echo
@@ -81,6 +83,11 @@
     echo
 fi
 
+if [ -n "${OPENSSL_NEXT+set}" ]; then
+    print_version "$OPENSSL_NEXT" "version" "openssl next version not found!"
+    echo
+fi
+
 : ${GNUTLS_CLI:=gnutls-cli}
 print_version "$GNUTLS_CLI" "--version" "gnuTLS client not found!" "head -n 1"
 echo
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 16e19a9..653687b 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -49,6 +49,7 @@
 add_test_suite(aes aes.cfb)
 add_test_suite(aes aes.rest)
 add_test_suite(arc4)
+add_test_suite(aria)
 add_test_suite(asn1write)
 add_test_suite(base64)
 add_test_suite(blowfish)
@@ -81,6 +82,7 @@
 add_test_suite(gcm gcm.aes192_de)
 add_test_suite(gcm gcm.aes256_de)
 add_test_suite(gcm gcm.camellia)
+add_test_suite(hkdf)
 add_test_suite(hmac_drbg hmac_drbg.misc)
 add_test_suite(hmac_drbg hmac_drbg.no_reseed)
 add_test_suite(hmac_drbg hmac_drbg.nopr)
@@ -105,26 +107,11 @@
 add_test_suite(x509parse)
 add_test_suite(x509write)
 
-# Make data_files available in an out-of-source build
+# Make scripts and data files needed for testing available in an
+# out-of-source build.
 if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
-    # Get OS dependent path to use in `execute_process`
-    file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/data_files" link)
-    file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/data_files" target)
-
-    if (NOT EXISTS ${link})
-        if (CMAKE_HOST_UNIX)
-            set(command ln -s ${target} ${link})
-        else()
-            set(command cmd.exe /c mklink /j ${link} ${target})
-        endif()
-
-        execute_process(COMMAND ${command}
-                        RESULT_VARIABLE result
-                        ERROR_VARIABLE output)
-
-        if (NOT ${result} EQUAL 0)
-            message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
-        endif()
-    endif()
+    link_to_source(compat.sh)
+    link_to_source(data_files)
+    link_to_source(scripts)
+    link_to_source(ssl-opt.sh)
 endif()
-
diff --git a/tests/Makefile b/tests/Makefile
index d85617f..caacb12 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -46,10 +46,12 @@
 endif
 
 APPS =	test_suite_aes.ecb$(EXEXT)	test_suite_aes.cbc$(EXEXT)	\
-	test_suite_aes.cfb$(EXEXT)	test_suite_aes.rest$(EXEXT)	\
+	test_suite_aes.cfb$(EXEXT)	test_suite_aes.ofb$(EXEXT)	\
+	test_suite_aes.rest$(EXEXT)	\
 	test_suite_arc4$(EXEXT)		test_suite_asn1write$(EXEXT)	\
 	test_suite_base64$(EXEXT)	test_suite_blowfish$(EXEXT)	\
 	test_suite_camellia$(EXEXT)	test_suite_ccm$(EXEXT)		\
+	test_suite_aria$(EXEXT)						\
 	test_suite_cmac$(EXEXT)						\
 	test_suite_cipher.aes$(EXEXT)					\
 	test_suite_cipher.arc4$(EXEXT)	test_suite_cipher.ccm$(EXEXT)	\
@@ -70,6 +72,7 @@
 	test_suite_gcm.aes192_en$(EXEXT)				\
 	test_suite_gcm.aes256_en$(EXEXT)				\
 	test_suite_gcm.camellia$(EXEXT)					\
+	test_suite_hkdf$(EXEXT)						\
 	test_suite_hmac_drbg.misc$(EXEXT)				\
 	test_suite_hmac_drbg.no_reseed$(EXEXT)				\
 	test_suite_hmac_drbg.nopr$(EXEXT)				\
@@ -109,6 +112,10 @@
 	echo "  Gen   $@"
 	perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.cfb
 
+test_suite_aes.ofb.c : suites/test_suite_aes.function suites/test_suite_aes.ofb.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+	echo "  Gen   $@"
+	perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.ofb
+
 test_suite_aes.rest.c : suites/test_suite_aes.function suites/test_suite_aes.rest.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
 	echo "  Gen   $@"
 	perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.rest
@@ -177,6 +184,10 @@
 	echo "  Gen   $@"
 	perl scripts/generate_code.pl suites test_suite_gcm test_suite_gcm.camellia
 
+test_suite_hkdf.c : suites/test_suite_hkdf.function suites/test_suite_hkdf.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+	echo "  Gen   $@"
+	perl scripts/generate_code.pl suites test_suite_hkdf test_suite_hkdf
+
 test_suite_hmac_drbg.misc.c : suites/test_suite_hmac_drbg.function suites/test_suite_hmac_drbg.misc.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
 	echo "  Gen   $@"
 	perl scripts/generate_code.pl suites test_suite_hmac_drbg test_suite_hmac_drbg.misc
@@ -209,6 +220,10 @@
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+test_suite_aes.ofb$(EXEXT): test_suite_aes.ofb.c $(DEP)
+	echo "  CC    $<"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 test_suite_aes.rest$(EXEXT): test_suite_aes.rest.c $(DEP)
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -341,6 +356,10 @@
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+test_suite_hkdf$(EXEXT): test_suite_hkdf.c $(DEP)
+	echo "  CC    $<"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 test_suite_hmac_drbg.misc$(EXEXT): test_suite_hmac_drbg.misc.c $(DEP)
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -437,6 +456,10 @@
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+test_suite_aria$(EXEXT): test_suite_aria.c $(DEP)
+	echo "  CC    $<"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 clean:
 ifndef WINDOWS
 	rm -f $(APPS) *.c
diff --git a/tests/compat.sh b/tests/compat.sh
index 34e38f1..d383cb4 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -53,7 +53,12 @@
 VERIFIES="NO YES"
 TYPES="ECDSA RSA PSK"
 FILTER=""
-EXCLUDE='NULL\|DES-CBC-\|RC4\|ARCFOUR' # avoid plain DES but keep 3DES-EDE-CBC (mbedTLS), DES-CBC3 (OpenSSL)
+# exclude:
+# - NULL: excluded from our default config
+# - RC4, single-DES: requires legacy OpenSSL/GnuTLS versions
+#   avoid plain DES but keep 3DES-EDE-CBC (mbedTLS), DES-CBC3 (OpenSSL)
+# - ARIA: not in default config.h + requires OpenSSL >= 1.1.1
+EXCLUDE='NULL\|DES-CBC-\|RC4\|ARCFOUR\|ARIA'
 VERBOSE=""
 MEMCHECK=0
 PEERS="OpenSSL$PEER_GNUTLS mbedTLS"
@@ -226,6 +231,9 @@
     G_CIPHERS=""
 }
 
+# Ciphersuites that can be used with all peers.
+# Since we currently have three possible peers, each ciphersuite should appear
+# three times: in each peer's list (with the name that this peer uses).
 add_common_ciphersuites()
 {
     case $TYPE in
@@ -422,6 +430,13 @@
     esac
 }
 
+# Ciphersuites usable only with Mbed TLS and OpenSSL
+# Each ciphersuite should appear two times, once with its OpenSSL name, once
+# with its Mbed TLS name.
+#
+# NOTE: for some reason RSA-PSK doesn't work with OpenSSL,
+# so RSA-PSK ciphersuites need to go in other sections, see
+# https://github.com/ARMmbed/mbedtls/issues/1419
 add_openssl_ciphersuites()
 {
     case $TYPE in
@@ -451,12 +466,16 @@
                     TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384          \
                     TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256          \
                     TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384          \
+                    TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384        \
+                    TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256        \
                     "
                 O_CIPHERS="$O_CIPHERS               \
                     ECDH-ECDSA-AES128-SHA256        \
                     ECDH-ECDSA-AES256-SHA384        \
                     ECDH-ECDSA-AES128-GCM-SHA256    \
                     ECDH-ECDSA-AES256-GCM-SHA384    \
+                    ECDHE-ECDSA-ARIA256-GCM-SHA384  \
+                    ECDHE-ECDSA-ARIA128-GCM-SHA256  \
                     "
             fi
             ;;
@@ -470,13 +489,50 @@
                 DES-CBC-SHA                     \
                 EDH-RSA-DES-CBC-SHA             \
                 "
+            if [ `minor_ver "$MODE"` -ge 3 ]
+            then
+                M_CIPHERS="$M_CIPHERS                               \
+                    TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384          \
+                    TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384            \
+                    TLS-RSA-WITH-ARIA-256-GCM-SHA384                \
+                    TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256          \
+                    TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256            \
+                    TLS-RSA-WITH-ARIA-128-GCM-SHA256                \
+                    "
+                O_CIPHERS="$O_CIPHERS               \
+                    ECDHE-ARIA256-GCM-SHA384        \
+                    DHE-RSA-ARIA256-GCM-SHA384      \
+                    ARIA256-GCM-SHA384              \
+                    ECDHE-ARIA128-GCM-SHA256        \
+                    DHE-RSA-ARIA128-GCM-SHA256      \
+                    ARIA128-GCM-SHA256              \
+                    "
+            fi
             ;;
 
         "PSK")
+            if [ `minor_ver "$MODE"` -ge 3 ]
+            then
+                M_CIPHERS="$M_CIPHERS                               \
+                    TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384            \
+                    TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256            \
+                    TLS-PSK-WITH-ARIA-256-GCM-SHA384                \
+                    TLS-PSK-WITH-ARIA-128-GCM-SHA256                \
+                    "
+                O_CIPHERS="$O_CIPHERS               \
+                    DHE-PSK-ARIA256-GCM-SHA384      \
+                    DHE-PSK-ARIA128-GCM-SHA256      \
+                    PSK-ARIA256-GCM-SHA384          \
+                    PSK-ARIA128-GCM-SHA256          \
+                    "
+            fi
             ;;
     esac
 }
 
+# Ciphersuites usable only with Mbed TLS and GnuTLS
+# Each ciphersuite should appear two times, once with its GnuTLS name, once
+# with its Mbed TLS name.
 add_gnutls_ciphersuites()
 {
     case $TYPE in
@@ -661,6 +717,9 @@
     esac
 }
 
+# Ciphersuites usable only with Mbed TLS (not currently supported by another
+# peer usable in this script). This provide only very rudimentaty testing, as
+# this is not interop testing, but it's better than nothing.
 add_mbedtls_ciphersuites()
 {
     case $TYPE in
@@ -682,12 +741,18 @@
                     TLS-ECDHE-ECDSA-WITH-AES-256-CCM                \
                     TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8              \
                     TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8              \
+                    TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384        \
+                    TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256        \
+                    TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384         \
+                    TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256         \
+                    TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384         \
+                    TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256         \
                     "
             fi
             ;;
 
         "RSA")
-            if [ "$MODE" = "tls1_2" ];
+            if [ `minor_ver "$MODE"` -ge 3 ]
             then
                 M_CIPHERS="$M_CIPHERS                               \
                     TLS-RSA-WITH-AES-128-CCM                        \
@@ -698,6 +763,12 @@
                     TLS-RSA-WITH-AES-256-CCM-8                      \
                     TLS-DHE-RSA-WITH-AES-128-CCM-8                  \
                     TLS-DHE-RSA-WITH-AES-256-CCM-8                  \
+                    TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384          \
+                    TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384            \
+                    TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256          \
+                    TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256            \
+                    TLS-RSA-WITH-ARIA-256-CBC-SHA384                \
+                    TLS-RSA-WITH-ARIA-128-CBC-SHA256                \
                     "
             fi
             ;;
@@ -715,7 +786,7 @@
                     TLS-RSA-PSK-WITH-NULL-SHA            \
                     "
             fi
-            if [ "$MODE" = "tls1_2" ];
+            if [ `minor_ver "$MODE"` -ge 3 ]
             then
                 M_CIPHERS="$M_CIPHERS                               \
                     TLS-PSK-WITH-AES-128-CCM                        \
@@ -726,6 +797,16 @@
                     TLS-PSK-WITH-AES-256-CCM-8                      \
                     TLS-DHE-PSK-WITH-AES-128-CCM-8                  \
                     TLS-DHE-PSK-WITH-AES-256-CCM-8                  \
+                    TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384            \
+                    TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256            \
+                    TLS-PSK-WITH-ARIA-256-CBC-SHA384                \
+                    TLS-PSK-WITH-ARIA-128-CBC-SHA256                \
+                    TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384            \
+                    TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256            \
+                    TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384          \
+                    TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256          \
+                    TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384            \
+                    TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256            \
                     "
             fi
             ;;
@@ -998,7 +1079,7 @@
             if [ $EXIT -eq 0 ]; then
                 RESULT=0
             else
-                # If the cipher isn't supported... 
+                # If the cipher isn't supported...
                 if grep 'Cipher is (NONE)' $CLI_OUT >/dev/null; then
                     RESULT=1
                 else
diff --git a/tests/git-scripts/pre-push.sh b/tests/git-scripts/pre-push.sh
index ee54a6c..7407f44 100755
--- a/tests/git-scripts/pre-push.sh
+++ b/tests/git-scripts/pre-push.sh
@@ -45,3 +45,4 @@
 run_test ./tests/scripts/check-doxy-blocks.pl
 run_test ./tests/scripts/check-names.sh
 run_test ./tests/scripts/check-generated-files.sh
+run_test ./tests/scripts/check-files.py
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 497a261..4894ad9 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -94,13 +94,13 @@
 MEMORY=0
 FORCE=0
 KEEP_GOING=0
-RELEASE=0
 RUN_ARMCC=1
 YOTTA=1
 
 # Default commands, can be overriden by the environment
 : ${OPENSSL:="openssl"}
 : ${OPENSSL_LEGACY:="$OPENSSL"}
+: ${OPENSSL_NEXT:="$OPENSSL"}
 : ${GNUTLS_CLI:="gnutls-cli"}
 : ${GNUTLS_SERV:="gnutls-serv"}
 : ${GNUTLS_LEGACY_CLI:="$GNUTLS_CLI"}
@@ -126,8 +126,12 @@
   -m|--memory           Additional optional memory tests.
      --armcc            Run ARM Compiler builds (on by default).
      --no-armcc         Skip ARM Compiler builds.
+     --no-force         Refuse to overwrite modified files (default).
+     --no-keep-going    Stop at the first error (default).
+     --no-memory        No additional memory tests (default).
      --no-yotta         Skip yotta module build.
      --out-of-source-dir=<path>  Directory used for CMake out-of-source build tests.
+     --random-seed      Use a random seed value for randomized tests (default).
   -r|--release-test     Run this script in release mode. This fixes the seed value to 1.
   -s|--seed             Integer seed value to use for this test run.
      --yotta            Build yotta module (on by default).
@@ -141,15 +145,26 @@
      --gnutls-legacy-serv=<GnuTLS_serv_path>    GnuTLS server executable to use for legacy tests.
      --openssl=<OpenSSL_path>                   OpenSSL executable to use for most tests.
      --openssl-legacy=<OpenSSL_path>            OpenSSL executable to use for legacy tests e.g. SSLv3.
+     --openssl-next=<OpenSSL_path>              OpenSSL executable to use for recent things like ARIA
 EOF
 }
 
 # remove built files as well as the cmake cache/config
 cleanup()
 {
+    if [ -n "${MBEDTLS_ROOT_DIR+set}" ]; then
+        cd "$MBEDTLS_ROOT_DIR"
+    fi
+
     command make clean
 
-    find . -name yotta -prune -o -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} \+
+    # Remove CMake artefacts
+    find . -name .git -prune -o -name yotta -prune -o \
+           -iname CMakeFiles -exec rm -rf {} \+ -o \
+           \( -iname cmake_install.cmake -o \
+              -iname CTestTestfile.cmake -o \
+              -iname CMakeCache.txt \) -exec rm {} \+
+    # Recover files overwritten by in-tree CMake builds
     rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile
     git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile
     git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile
@@ -214,74 +229,30 @@
 
 while [ $# -gt 0 ]; do
     case "$1" in
-        --armcc)
-            RUN_ARMCC=1
-            ;;
-        --armc5-bin-dir)
-            shift
-            ARMC5_BIN_DIR="$1"
-            ;;
-        --armc6-bin-dir)
-            shift
-            ARMC6_BIN_DIR="$1"
-            ;;
-        --force|-f)
-            FORCE=1
-            ;;
-        --gnutls-cli)
-            shift
-            GNUTLS_CLI="$1"
-            ;;
-        --gnutls-legacy-cli)
-            shift
-            GNUTLS_LEGACY_CLI="$1"
-            ;;
-        --gnutls-legacy-serv)
-            shift
-            GNUTLS_LEGACY_SERV="$1"
-            ;;
-        --gnutls-serv)
-            shift
-            GNUTLS_SERV="$1"
-            ;;
-        --help|-h)
-            usage
-            exit
-            ;;
-        --keep-going|-k)
-            KEEP_GOING=1
-            ;;
-        --memory|-m)
-            MEMORY=1
-            ;;
-        --no-armcc)
-            RUN_ARMCC=0
-            ;;
-        --no-yotta)
-            YOTTA=0
-            ;;
-        --openssl)
-            shift
-            OPENSSL="$1"
-            ;;
-        --openssl-legacy)
-            shift
-            OPENSSL_LEGACY="$1"
-            ;;
-        --out-of-source-dir)
-            shift
-            OUT_OF_SOURCE_DIR="$1"
-            ;;
-        --release-test|-r)
-            RELEASE=1
-            ;;
-        --seed|-s)
-            shift
-            SEED="$1"
-            ;;
-        --yotta)
-            YOTTA=1
-            ;;
+        --armcc) RUN_ARMCC=1;;
+        --armc5-bin-dir) shift; ARMC5_BIN_DIR="$1";;
+        --armc6-bin-dir) shift; ARMC6_BIN_DIR="$1";;
+        --force|-f) FORCE=1;;
+        --gnutls-cli) shift; GNUTLS_CLI="$1";;
+        --gnutls-legacy-cli) shift; GNUTLS_LEGACY_CLI="$1";;
+        --gnutls-legacy-serv) shift; GNUTLS_LEGACY_SERV="$1";;
+        --gnutls-serv) shift; GNUTLS_SERV="$1";;
+        --help|-h) usage; exit;;
+        --keep-going|-k) KEEP_GOING=1;;
+        --memory|-m) MEMORY=1;;
+        --no-armcc) RUN_ARMCC=0;;
+        --no-force) FORCE=0;;
+        --no-keep-going) KEEP_GOING=0;;
+        --no-memory) MEMORY=0;;
+        --no-yotta) YOTTA=0;;
+        --openssl) shift; OPENSSL="$1";;
+        --openssl-legacy) shift; OPENSSL_LEGACY="$1";;
+        --openssl-next) shift; OPENSSL_NEXT="$1";;
+        --out-of-source-dir) shift; OUT_OF_SOURCE_DIR="$1";;
+        --random-seed) unset SEED;;
+        --release-test|-r) SEED=1;;
+        --seed|-s) shift; SEED="$1";;
+        --yotta) YOTTA=1;;
         *)
             echo >&2 "Unknown option: $1"
             echo >&2 "Run $0 --help for usage."
@@ -386,17 +357,13 @@
     fi
 }
 
-if [ $RELEASE -eq 1 ]; then
-    # Fix the seed value to 1 to ensure that the tests are deterministic.
-    SEED=1
-fi
-
 msg "info: $0 configuration"
 echo "MEMORY: $MEMORY"
 echo "FORCE: $FORCE"
 echo "SEED: ${SEED-"UNSET"}"
 echo "OPENSSL: $OPENSSL"
 echo "OPENSSL_LEGACY: $OPENSSL_LEGACY"
+echo "OPENSSL_NEXT: $OPENSSL_NEXT"
 echo "GNUTLS_CLI: $GNUTLS_CLI"
 echo "GNUTLS_SERV: $GNUTLS_SERV"
 echo "GNUTLS_LEGACY_CLI: $GNUTLS_LEGACY_CLI"
@@ -416,12 +383,15 @@
 export GNUTLS_SERV="$GNUTLS_SERV"
 
 # Avoid passing --seed flag in every call to ssl-opt.sh
-[ ! -z ${SEED+set} ] && export SEED
+if [ -n "${SEED-}" ]; then
+  export SEED
+fi
 
 # Make sure the tools we need are available.
-check_tools "$OPENSSL" "$OPENSSL_LEGACY" "$GNUTLS_CLI" "$GNUTLS_SERV" \
+check_tools "$OPENSSL" "$OPENSSL_LEGACY" "$OPENSSL_NEXT" \
+            "$GNUTLS_CLI" "$GNUTLS_SERV" \
             "$GNUTLS_LEGACY_CLI" "$GNUTLS_LEGACY_SERV" "doxygen" "dot" \
-            "arm-none-eabi-gcc" "i686-w64-mingw32-gcc"
+            "arm-none-eabi-gcc" "i686-w64-mingw32-gcc" "gdb"
 if [ $RUN_ARMCC -ne 0 ]; then
     check_tools "$ARMC5_CC" "$ARMC5_AR" "$ARMC6_CC" "$ARMC6_AR"
 fi
@@ -447,7 +417,7 @@
 OPENSSL="$OPENSSL" OPENSSL_LEGACY="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_CLI" \
     GNUTLS_SERV="$GNUTLS_SERV" GNUTLS_LEGACY_CLI="$GNUTLS_LEGACY_CLI" \
     GNUTLS_LEGACY_SERV="$GNUTLS_LEGACY_SERV" ARMC5_CC="$ARMC5_CC" \
-    ARMC6_CC="$ARMC6_CC" scripts/output_env.sh
+    ARMC6_CC="$ARMC6_CC" RUN_ARMCC="$RUN_ARMCC" scripts/output_env.sh
 
 msg "test: recursion.pl" # < 1s
 tests/scripts/recursion.pl library/*.c
@@ -458,6 +428,10 @@
 msg "test: doxygen markup outside doxygen blocks" # < 1s
 tests/scripts/check-doxy-blocks.pl
 
+msg "test: check-files.py" # < 1s
+cleanup
+tests/scripts/check-files.py
+
 msg "test/build: declared and exported names" # < 3s
 cleanup
 tests/scripts/check-names.sh
@@ -563,6 +537,9 @@
 msg "test: compat.sh RC4, DES & NULL (full config)" # ~ 2 min
 if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR'
 
+msg "test: compat.sh ARIA"
+if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA'
+
 msg "test/build: curves.pl (gcc)" # ~ 4 min
 cleanup
 record_status tests/scripts/curves.pl
@@ -904,8 +881,29 @@
 
 msg "test: cmake 'out-of-source' build"
 make test
+# Test an SSL option that requires an auxiliary script in test/scripts/.
+# Also ensure that there are no error messages such as
+# "No such file or directory", which would indicate that some required
+# file is missing (ssl-opt.sh tolerates the absence of some files so
+# may exit with status 0 but emit errors).
+if_build_succeeded ./tests/ssl-opt.sh -f 'Fallback SCSV: beginning of list' 2>ssl-opt.err
+if [ -s ssl-opt.err ]; then
+  cat ssl-opt.err >&2
+  record_status [ ! -s ssl-opt.err ]
+  rm ssl-opt.err
+fi
 cd "$MBEDTLS_ROOT_DIR"
 rm -rf "$OUT_OF_SOURCE_DIR"
+unset MBEDTLS_ROOT_DIR
+
+for optimization_flag in -O2 -O3 -Ofast -Os; do
+    for compiler in clang gcc; do
+        msg "test: $compiler $optimization_flag, mbedtls_platform_zeroize()"
+        cleanup
+        CC="$compiler" DEBUG=1 CFLAGS="$optimization_flag" make programs
+        gdb -x tests/scripts/test_zeroize.gdb -nw -batch -nx
+    done
+done
 
 
 
diff --git a/tests/scripts/check-files.py b/tests/scripts/check-files.py
new file mode 100755
index 0000000..f560d03
--- /dev/null
+++ b/tests/scripts/check-files.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python3
+"""
+This file is part of Mbed TLS (https://tls.mbed.org)
+
+Copyright (c) 2018, Arm Limited, All Rights Reserved
+
+Purpose
+
+This script checks the current state of the source code for minor issues,
+including incorrect file permissions, presence of tabs, non-Unix line endings,
+trailing whitespace, presence of UTF-8 BOM, and TODO comments.
+Note: requires python 3, must be run from Mbed TLS root.
+"""
+
+import os
+import argparse
+import logging
+import codecs
+import sys
+
+
+class IssueTracker(object):
+    """Base class for issue tracking. Issues should inherit from this and
+    overwrite either issue_with_line if they check the file line by line, or
+    overwrite check_file_for_issue if they check the file as a whole."""
+
+    def __init__(self):
+        self.heading = ""
+        self.files_exemptions = []
+        self.files_with_issues = {}
+
+    def should_check_file(self, filepath):
+        for files_exemption in self.files_exemptions:
+            if filepath.endswith(files_exemption):
+                return False
+        return True
+
+    def issue_with_line(self, line):
+        raise NotImplementedError
+
+    def check_file_for_issue(self, filepath):
+        with open(filepath, "rb") as f:
+            for i, line in enumerate(iter(f.readline, b"")):
+                self.check_file_line(filepath, line, i + 1)
+
+    def check_file_line(self, filepath, line, line_number):
+        if self.issue_with_line(line):
+            if filepath not in self.files_with_issues.keys():
+                self.files_with_issues[filepath] = []
+            self.files_with_issues[filepath].append(line_number)
+
+    def output_file_issues(self, logger):
+        if self.files_with_issues.values():
+            logger.info(self.heading)
+            for filename, lines in sorted(self.files_with_issues.items()):
+                if lines:
+                    logger.info("{}: {}".format(
+                        filename, ", ".join(str(x) for x in lines)
+                    ))
+                else:
+                    logger.info(filename)
+            logger.info("")
+
+
+class PermissionIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "Incorrect permissions:"
+
+    def check_file_for_issue(self, filepath):
+        if not (os.access(filepath, os.X_OK) ==
+                filepath.endswith((".sh", ".pl", ".py"))):
+            self.files_with_issues[filepath] = None
+
+
+class EndOfFileNewlineIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "Missing newline at end of file:"
+
+    def check_file_for_issue(self, filepath):
+        with open(filepath, "rb") as f:
+            if not f.read().endswith(b"\n"):
+                self.files_with_issues[filepath] = None
+
+
+class Utf8BomIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "UTF-8 BOM present:"
+
+    def check_file_for_issue(self, filepath):
+        with open(filepath, "rb") as f:
+            if f.read().startswith(codecs.BOM_UTF8):
+                self.files_with_issues[filepath] = None
+
+
+class LineEndingIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "Non Unix line endings:"
+
+    def issue_with_line(self, line):
+        return b"\r" in line
+
+
+class TrailingWhitespaceIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "Trailing whitespace:"
+        self.files_exemptions = [".md"]
+
+    def issue_with_line(self, line):
+        return line.rstrip(b"\r\n") != line.rstrip()
+
+
+class TabIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "Tabs present:"
+        self.files_exemptions = [
+            "Makefile", "generate_visualc_files.pl"
+        ]
+
+    def issue_with_line(self, line):
+        return b"\t" in line
+
+
+class TodoIssueTracker(IssueTracker):
+
+    def __init__(self):
+        super().__init__()
+        self.heading = "TODO present:"
+        self.files_exemptions = [
+            __file__, "benchmark.c", "pull_request_template.md"
+        ]
+
+    def issue_with_line(self, line):
+        return b"todo" in line.lower()
+
+
+class IntegrityChecker(object):
+
+    def __init__(self, log_file):
+        self.check_repo_path()
+        self.logger = None
+        self.setup_logger(log_file)
+        self.files_to_check = (
+            ".c", ".h", ".sh", ".pl", ".py", ".md", ".function", ".data",
+            "Makefile", "CMakeLists.txt", "ChangeLog"
+        )
+        self.issues_to_check = [
+            PermissionIssueTracker(),
+            EndOfFileNewlineIssueTracker(),
+            Utf8BomIssueTracker(),
+            LineEndingIssueTracker(),
+            TrailingWhitespaceIssueTracker(),
+            TabIssueTracker(),
+            TodoIssueTracker(),
+        ]
+
+    def check_repo_path(self):
+        if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
+            raise Exception("Must be run from Mbed TLS root")
+
+    def setup_logger(self, log_file, level=logging.INFO):
+        self.logger = logging.getLogger()
+        self.logger.setLevel(level)
+        if log_file:
+            handler = logging.FileHandler(log_file)
+            self.logger.addHandler(handler)
+        else:
+            console = logging.StreamHandler()
+            self.logger.addHandler(console)
+
+    def check_files(self):
+        for root, dirs, files in sorted(os.walk(".")):
+            for filename in sorted(files):
+                filepath = os.path.join(root, filename)
+                if (os.path.join("yotta", "module") in filepath or
+                        not filepath.endswith(self.files_to_check)):
+                    continue
+                for issue_to_check in self.issues_to_check:
+                    if issue_to_check.should_check_file(filepath):
+                        issue_to_check.check_file_for_issue(filepath)
+
+    def output_issues(self):
+        integrity_return_code = 0
+        for issue_to_check in self.issues_to_check:
+            if issue_to_check.files_with_issues:
+                integrity_return_code = 1
+            issue_to_check.output_file_issues(self.logger)
+        return integrity_return_code
+
+
+def run_main():
+    parser = argparse.ArgumentParser(
+        description=(
+            "This script checks the current state of the source code for "
+            "minor issues, including incorrect file permissions, "
+            "presence of tabs, non-Unix line endings, trailing whitespace, "
+            "presence of UTF-8 BOM, and TODO comments. "
+            "Note: requires python 3, must be run from Mbed TLS root."
+        )
+    )
+    parser.add_argument(
+        "-l", "--log_file", type=str, help="path to optional output log",
+    )
+    check_args = parser.parse_args()
+    integrity_check = IntegrityChecker(check_args.log_file)
+    integrity_check.check_files()
+    return_code = integrity_check.output_issues()
+    sys.exit(return_code)
+
+
+if __name__ == "__main__":
+    run_main()
diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh
index 0400bc7..4976bac 100755
--- a/tests/scripts/check-generated-files.sh
+++ b/tests/scripts/check-generated-files.sh
@@ -1,6 +1,12 @@
-#!/bin/sh
+#! /usr/bin/env sh
 
-# check if generated files are up-to-date
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2018, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Check if generated files are up-to-date.
 
 set -eu
 
@@ -11,14 +17,53 @@
 
 check()
 {
-    FILE=$1
-    SCRIPT=$2
+    SCRIPT=$1
+    TO_CHECK=$2
+    PATTERN=""
+    FILES=""
 
-    cp $FILE $FILE.bak
+    if [ -d $TO_CHECK ]; then
+        for FILE in $TO_CHECK/*; do
+            FILES="$FILE $FILES"
+        done
+    else
+        FILES=$TO_CHECK
+    fi
+
+    for FILE in $FILES; do
+        cp $FILE $FILE.bak
+    done
+
     $SCRIPT
-    diff $FILE $FILE.bak
-    mv $FILE.bak $FILE
+
+    # Compare the script output to the old files and remove backups
+    for FILE in $FILES; do
+        if ! diff $FILE $FILE.bak >/dev/null 2>&1; then
+            echo "'$FILE' was either modified or deleted by '$SCRIPT'"
+            exit 1
+        fi
+        mv $FILE.bak $FILE
+
+        if [ -d $TO_CHECK ]; then
+            # Create a grep regular expression that we can check against the
+            # directory contents to test whether new files have been created
+            if [ -z $PATTERN ]; then
+                PATTERN="$(basename $FILE)"
+            else
+                PATTERN="$PATTERN\|$(basename $FILE)"
+            fi
+        fi
+    done
+
+    if [ -d $TO_CHECK ]; then
+        # Check if there are any new files
+        if ls -1 $TO_CHECK | grep -v "$PATTERN" >/dev/null 2>&1; then
+            echo "Files were created by '$SCRIPT'"
+            exit 1
+        fi
+    fi
 }
 
-check library/error.c scripts/generate_errors.pl
-check library/version_features.c scripts/generate_features.pl
+check scripts/generate_errors.pl library/error.c
+check scripts/generate_features.pl library/version_features.c
+check scripts/generate_visualc_files.pl visualc/VS2010
diff --git a/tests/scripts/gen_ctr_drbg.pl b/tests/scripts/gen_ctr_drbg.pl
index 66d9b3a..ee13024 100755
--- a/tests/scripts/gen_ctr_drbg.pl
+++ b/tests/scripts/gen_ctr_drbg.pl
@@ -64,7 +64,7 @@
         my $AdditionalInput2 = get_val("AdditionalInput");
         my $EntropyInputPR2 = get_val("EntropyInputPR") if ($PredictionResistance == 1);
         my $ReturnedBits = get_val("ReturnedBits");
-    
+
         if ($PredictionResistance == 1)
         {
             print("CTR_DRBG NIST Validation (AES-256 use df,$PredictionResistanceStr,$EntropyInputLen,$NonceLen,$PersonalizationStringLen,$AdditionalInputLen) #$Count\n");
diff --git a/tests/scripts/gen_pkcs1_v21_sign_verify.pl b/tests/scripts/gen_pkcs1_v21_sign_verify.pl
index 0d7fc7d..678e2f9 100755
--- a/tests/scripts/gen_pkcs1_v21_sign_verify.pl
+++ b/tests/scripts/gen_pkcs1_v21_sign_verify.pl
@@ -18,10 +18,10 @@
         next if($line !~ /^# $str/);
         last;
     }
-        
+
     while(my $line = <TEST_DATA>)
     {
-        last if($line eq "\r\n"); 
+        last if($line eq "\r\n");
         $val .= $line;
     }
 
@@ -66,7 +66,7 @@
         print(":\"$val_salt\"");
         print(":\"$val_sig\":0");
         print("\n\n");
-    } 
+    }
     $cnt++;
 }
 close(TEST_DATA);
diff --git a/tests/scripts/test_zeroize.gdb b/tests/scripts/test_zeroize.gdb
new file mode 100644
index 0000000..617ab55
--- /dev/null
+++ b/tests/scripts/test_zeroize.gdb
@@ -0,0 +1,70 @@
+# test_zeroize.gdb
+#
+# This file is part of Mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2018, Arm Limited, All Rights Reserved
+#
+# Purpose
+#
+# Run a test using the debugger to check that the mbedtls_platform_zeroize()
+# function in platform_util.h is not being optimized out by the compiler. To do
+# so, the script loads the test program at programs/test/zeroize.c and sets a
+# breakpoint at the last return statement in main(). When the breakpoint is
+# hit, the debugger manually checks the contents to be zeroized and checks that
+# it is actually cleared.
+#
+# The mbedtls_platform_zeroize() test is debugger driven because there does not
+# seem to be a mechanism to reliably check whether the zeroize calls are being
+# eliminated by compiler optimizations from within the compiled program. The
+# problem is that a compiler would typically remove what it considers to be
+# "unecessary" assignments as part of redundant code elimination. To identify
+# such code, the compilar will create some form dependency graph between
+# reads and writes to variables (among other situations). It will then use this
+# data structure to remove redundant code that does not have an impact on the
+# program's observable behavior. In the case of mbedtls_platform_zeroize(), an
+# intelligent compiler could determine that this function clears a block of
+# memory that is not accessed later in the program, so removing the call to
+# mbedtls_platform_zeroize() does not have an observable behavior. However,
+# inserting a test after a call to mbedtls_platform_zeroize() to check whether
+# the block of memory was correctly zeroed would force the compiler to not
+# eliminate the mbedtls_platform_zeroize() call. If this does not occur, then
+# the compiler potentially has a bug.
+#
+# Note: This test requires that the test program is compiled with -g3.
+#
+# WARNING: There does not seem to be a mechanism in GDB scripts to set a
+# breakpoint at the end of a function (probably because there are a lot of
+# complications as function can have multiple exit points, etc). Therefore, it
+# was necessary to hard-code the line number of the breakpoint in the zeroize.c
+# test app. The assumption is that zeroize.c is a simple test app that does not
+# change often (as opposed to the actual library code), so the breakpoint line
+# number does not need to be updated often.
+
+set confirm off
+file ./programs/test/zeroize
+break zeroize.c:100
+
+set args ./programs/test/zeroize.c
+run
+
+set $i = 0
+set $len = sizeof(buf)
+set $buf = buf
+
+while $i < $len
+    if $buf[$i++] != 0
+        echo The buffer at was not zeroized\n
+        quit 1
+    end
+end
+
+echo The buffer was correctly zeroized\n
+
+continue
+
+if $_exitcode != 0
+    echo The program did not terminate correctly\n
+    quit 1
+end
+
+quit 0
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index eef41c7..f82694a 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -109,6 +109,9 @@
 }
 test_info;
 
+#if defined(MBEDTLS_PLATFORM_C)
+mbedtls_platform_context platform_ctx;
+#endif
 
 /*----------------------------------------------------------------------------*/
 /* Helper flags for complex dependencies */
@@ -127,6 +130,21 @@
 
 /*----------------------------------------------------------------------------*/
 /* Helper Functions */
+static int platform_setup()
+{
+    int ret = 0;
+#if defined(MBEDTLS_PLATFORM_C)
+    ret = mbedtls_platform_setup( &platform_ctx );
+#endif /* MBEDTLS_PLATFORM_C */
+    return( ret );
+}
+
+static void platform_teardown()
+{
+#if defined(MBEDTLS_PLATFORM_C)
+    mbedtls_platform_teardown( &platform_ctx );
+#endif /* MBEDTLS_PLATFORM_C */
+}
 
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 static int redirect_output( FILE** out_stream, const char* path )
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 042085f..b6e3104 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -226,12 +226,23 @@
     return( cnt );
 }
 
+#if defined(__GNUC__)
+/* At high optimization levels (e.g. gcc -O3), this function may be
+ * inlined in run_test_snprintf. This can trigger a spurious warning about
+ * potential misuse of snprintf from gcc -Wformat-truncation (observed with
+ * gcc 7.2). This warning makes tests in run_test_snprintf redundant on gcc
+ * only. They are still valid for other compilers. Avoid this warning by
+ * forbidding inlining of this function by gcc. */
+__attribute__((__noinline__))
+#endif
 static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
 {
     int ret;
     char buf[10] = "xxxxxxxxx";
     const char ref[10] = "xxxxxxxxx";
 
+    if( n >= sizeof( buf ) )
+        return( -1 );
     ret = mbedtls_snprintf( buf, n, "%s", "123" );
     if( ret < 0 || (size_t) ret >= n )
         ret = -1;
@@ -281,6 +292,18 @@
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
     !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
     unsigned char alloc_buf[1000000];
+#endif
+    /* Platform setup should be called in the beginning */
+    ret = platform_setup();
+    if( ret != 0 )
+    {
+        mbedtls_fprintf( stderr,
+                         "FATAL: Failed to initialize platform - error %d\n",
+                         ret );
+        return( -1 );
+    }
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
+    !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
 #endif
 
@@ -293,6 +316,7 @@
     if( pointer != NULL )
     {
         mbedtls_fprintf( stderr, "all-bits-zero is not a NULL pointer\n" );
+        platform_teardown();
         return( 1 );
     }
 
@@ -302,7 +326,8 @@
     if( run_test_snprintf() != 0 )
     {
         mbedtls_fprintf( stderr, "the snprintf implementation is broken\n" );
-        return( 0 );
+        platform_teardown();
+        return( 1 );
     }
 
     while( arg_index < argc)
@@ -318,6 +343,7 @@
                  strcmp(next_arg, "-h" ) == 0 )
         {
             mbedtls_fprintf( stdout, USAGE );
+            platform_teardown();
             mbedtls_exit( EXIT_SUCCESS );
         }
         else
@@ -357,6 +383,7 @@
         {
             mbedtls_fprintf( stderr, "Failed to open test file: %s\n",
                              test_filename );
+            platform_teardown();
             return( 1 );
         }
 
@@ -366,6 +393,7 @@
             {
                 mbedtls_fprintf( stderr,
                     "FATAL: Dep count larger than zero at start of loop\n" );
+                platform_teardown();
                 mbedtls_exit( MBEDTLS_EXIT_FAILURE );
             }
             unmet_dep_count = 0;
@@ -402,6 +430,7 @@
                         if(  unmet_dependencies[ unmet_dep_count ] == NULL )
                         {
                             mbedtls_fprintf( stderr, "FATAL: Out of memory\n" );
+                            platform_teardown();
                             mbedtls_exit( MBEDTLS_EXIT_FAILURE );
                         }
                         unmet_dep_count++;
@@ -427,6 +456,7 @@
                     stdout_fd = redirect_output( &stdout, "/dev/null" );
                     if( stdout_fd == -1 )
                     {
+                        platform_teardown();
                         /* Redirection has failed with no stdout so exit */
                         exit( 1 );
                     }
@@ -439,6 +469,7 @@
                 if( !option_verbose && restore_output( &stdout, stdout_fd ) )
                 {
                         /* Redirection has failed with no stdout so exit */
+                        platform_teardown();
                         exit( 1 );
                 }
 #endif /* __unix__ || __APPLE__ __MACH__ */
@@ -490,6 +521,7 @@
             {
                 mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
                 fclose( file );
+                platform_teardown();
                 mbedtls_exit( 2 );
             }
             else
@@ -501,6 +533,7 @@
             {
                 mbedtls_fprintf( stderr, "Should be empty %d\n",
                                  (int) strlen( buf ) );
+                platform_teardown();
                 return( 1 );
             }
         }
@@ -533,5 +566,6 @@
         close_output( stdout );
 #endif /* __unix__ || __APPLE__ __MACH__ */
 
+    platform_teardown();
     return( total_errors != 0 );
 }
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index c5f0eaa..f1e9033 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -289,6 +289,63 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_OFB */
+void aes_encrypt_ofb( int fragment_size, char *hex_key_string,
+                      char *hex_iv_string, char *hex_src_string,
+                      char *hex_dst_string )
+{
+    unsigned char key_str[32];
+    unsigned char iv_str[16];
+    unsigned char src_str[64];
+    unsigned char dst_str[64];
+    unsigned char output[32];
+    mbedtls_aes_context ctx;
+    size_t iv_offset = 0;
+    int in_buffer_len;
+    unsigned char* src_str_next;
+    int key_len;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( iv_str, 0x00, sizeof( iv_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aes_init( &ctx );
+
+    TEST_ASSERT( strlen( hex_key_string ) <= ( 32 * 2 ) );
+    TEST_ASSERT( strlen( hex_iv_string ) <= ( 16 * 2 ) );
+    TEST_ASSERT( strlen( hex_src_string ) <= ( 64 * 2 ) );
+    TEST_ASSERT( strlen( hex_dst_string ) <= ( 64 * 2 ) );
+
+    key_len = unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    in_buffer_len = unhexify( src_str, hex_src_string );
+
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str, key_len * 8 ) == 0 );
+    src_str_next = src_str;
+
+    while( in_buffer_len > 0 )
+    {
+        TEST_ASSERT( mbedtls_aes_crypt_ofb( &ctx, fragment_size, &iv_offset,
+                                            iv_str, src_str_next, output ) == 0 );
+
+        hexify( dst_str, output, fragment_size );
+        TEST_ASSERT( strncmp( (char *) dst_str, hex_dst_string,
+                              ( 2 * fragment_size ) ) == 0 );
+
+        in_buffer_len -= fragment_size;
+        hex_dst_string += ( fragment_size * 2 );
+        src_str_next += fragment_size;
+
+        if( in_buffer_len < fragment_size )
+            fragment_size = in_buffer_len;
+    }
+
+exit:
+    mbedtls_aes_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void aes_selftest()
 {
diff --git a/tests/suites/test_suite_aes.ofb.data b/tests/suites/test_suite_aes.ofb.data
new file mode 100644
index 0000000..4b9d80e
--- /dev/null
+++ b/tests/suites/test_suite_aes.ofb.data
@@ -0,0 +1,35 @@
+# NIST Special Publication 800-38A
+# Recommendation for Block Cipher Modes of Operation
+# Test Vectors - Appendix F, Section F.4
+OFB-AES128.Encrypt - Single block
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172a":"3b3fd92eb72dad20333449f8e83cfb4a"
+
+OFB-AES128.Encrypt - Partial blocks - 7 bytes
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:5:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e"
+
+OFB-AES128.Encrypt - Test NIST SP800-38A - F.4.1
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e"
+
+OFB-AES128.Decrypt - Test NIST SP800-38A - F.4.2
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090a0b0c0d0e0f":"3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
+
+OFB-AES192.Encrypt - Test NIST SP800-38A - F.4.3
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a"
+
+OFB-AES192.Decrypt - Test NIST SP800-38A - F.4.4
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"000102030405060708090a0b0c0d0e0f":"cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
+
+OFB-AES256.Encrypt - Test NIST SP800-38A - F.4.5
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484"
+
+OFB-AES256.Decrypt - Test NIST SP800-38A - F.4.6
+depends_on:MBEDTLS_CIPHER_MODE_OFB
+aes_encrypt_ofb:16:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"000102030405060708090a0b0c0d0e0f":"dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
+
diff --git a/tests/suites/test_suite_aria.data b/tests/suites/test_suite_aria.data
new file mode 100644
index 0000000..46c6ecc
--- /dev/null
+++ b/tests/suites/test_suite_aria.data
@@ -0,0 +1,95 @@
+ARIA-128-ECB Encrypt - RFC 5794
+aria_encrypt_ecb:"000102030405060708090a0b0c0d0e0f":"00112233445566778899aabbccddeeff":"d718fbd6ab644c739da95f3be6451778":0
+
+ARIA-128-ECB Decrypt - RFC 5794
+aria_decrypt_ecb:"000102030405060708090a0b0c0d0e0f":"d718fbd6ab644c739da95f3be6451778":"00112233445566778899aabbccddeeff":0
+
+ARIA-192-ECB Encrypt - RFC 5794
+aria_encrypt_ecb:"000102030405060708090a0b0c0d0e0f1011121314151617":"00112233445566778899aabbccddeeff":"26449c1805dbe7aa25a468ce263a9e79":0
+
+ARIA-192-ECB Decrypt - RFC 5794
+aria_decrypt_ecb:"000102030405060708090a0b0c0d0e0f1011121314151617":"26449c1805dbe7aa25a468ce263a9e79":"00112233445566778899aabbccddeeff":0
+
+ARIA-256-ECB_Encrypt - RFC 5794
+aria_encrypt_ecb:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"00112233445566778899aabbccddeeff":"f92bd7c79fb72e2f2b8f80c1972d24fc":0
+
+ARIA-256-ECB_Decrypt - RFC 5794
+aria_decrypt_ecb:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"f92bd7c79fb72e2f2b8f80c1972d24fc":"00112233445566778899aabbccddeeff":0
+
+ARIA-128-ECB Decrypt - RFC 5794
+aria_decrypt_ecb:"000102030405060708090a0b0c0d0e0f":"d718fbd6ab644c739da95f3be6451778":"00112233445566778899aabbccddeeff":0
+
+ARIA-192-ECB Decrypt - RFC 5794
+aria_decrypt_ecb:"000102030405060708090a0b0c0d0e0f1011121314151617":"26449c1805dbe7aa25a468ce263a9e79":"00112233445566778899aabbccddeeff":0
+
+ARIA-256-ECB Decrypt - RFC 5794
+aria_decrypt_ecb:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"f92bd7c79fb72e2f2b8f80c1972d24fc":"00112233445566778899aabbccddeeff":0
+
+ARIA-128-ECB Encrypt - Official Test Vectors 1.0
+aria_encrypt_ecb:"00112233445566778899aabbccddeeff":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"c6ecd08e22c30abdb215cf74e2075e6e29ccaac63448708d331b2f816c51b17d9e133d1528dbf0af5787c7f3a3f5c2bf6b6f345907a3055612ce072ff54de7d788424da6e8ccfe8172b391be499354165665ba7864917000a6eeb2ecb4a698edfc7887e7f556377614ab0a282293e6d884dbb84206cdb16ed1754e77a1f243fd086953f752cc1e46c7c794ae85537dcaec8dd721f55c93b6edfe2adea43873e8":0
+
+ARIA-128-ECB Decrypt - Official Test Vectors 1.0
+aria_decrypt_ecb:"00112233445566778899aabbccddeeff":"c6ecd08e22c30abdb215cf74e2075e6e29ccaac63448708d331b2f816c51b17d9e133d1528dbf0af5787c7f3a3f5c2bf6b6f345907a3055612ce072ff54de7d788424da6e8ccfe8172b391be499354165665ba7864917000a6eeb2ecb4a698edfc7887e7f556377614ab0a282293e6d884dbb84206cdb16ed1754e77a1f243fd086953f752cc1e46c7c794ae85537dcaec8dd721f55c93b6edfe2adea43873e8":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-192-ECB Encrypt - Official Test Vectors 1.0
+aria_encrypt_ecb:"00112233445566778899aabbccddeeff0011223344556677":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"8d1470625f59ebacb0e55b534b3e462b5f23d33bff78f46c3c15911f4a21809aaccad80b4bda915aa9dae6bcebe06a6c83f77fd5391acfe61de2f646b5d447edbfd5bb49b12fbb9145b227895a757b2af1f7188734863d7b8b6ede5a5b2f06a0a233c8523d2db778fb31b0e311f32700152f33861e9d040c83b5eb40cd88ea49975709dc629365a189f78a3ec40345fc6a5a307a8f9a4413091e007eca5645a0":0
+
+ARIA-192-ECB Decrypt - Official Test Vectors 1.0
+aria_decrypt_ecb:"00112233445566778899aabbccddeeff0011223344556677":"8d1470625f59ebacb0e55b534b3e462b5f23d33bff78f46c3c15911f4a21809aaccad80b4bda915aa9dae6bcebe06a6c83f77fd5391acfe61de2f646b5d447edbfd5bb49b12fbb9145b227895a757b2af1f7188734863d7b8b6ede5a5b2f06a0a233c8523d2db778fb31b0e311f32700152f33861e9d040c83b5eb40cd88ea49975709dc629365a189f78a3ec40345fc6a5a307a8f9a4413091e007eca5645a0":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-256-ECB Encrypt - Official Test Vectors 1.0
+aria_encrypt_ecb:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"58a875e6044ad7fffa4f58420f7f442d8e191016f28e79aefc01e204773280d7018e5f7a938ec30711719953bae86542cd7ebc752474c1a5f6eaaace2a7e29462ee7dfa5afdb84177ead95ccd4b4bb6e1ed17b9534cff0a5fc2941429cfee2ee49c7adbeb7e9d1b0d2a8531d942079596a27ed79f5b1dd13ecd604b07a48885a3afa0627a0e4e60a3c703af292f1baa77b702f16c54aa74bc727ea95c7468b00":0
+
+ARIA-256-ECB Decrypt - Official Test Vectors 1.0
+aria_decrypt_ecb:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"58a875e6044ad7fffa4f58420f7f442d8e191016f28e79aefc01e204773280d7018e5f7a938ec30711719953bae86542cd7ebc752474c1a5f6eaaace2a7e29462ee7dfa5afdb84177ead95ccd4b4bb6e1ed17b9534cff0a5fc2941429cfee2ee49c7adbeb7e9d1b0d2a8531d942079596a27ed79f5b1dd13ecd604b07a48885a3afa0627a0e4e60a3c703af292f1baa77b702f16c54aa74bc727ea95c7468b00":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-128-CBC Encrypt - Official Test Vectors 1.0
+aria_encrypt_cbc:"00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"49d61860b14909109cef0d22a9268134fadf9fb23151e9645fba75018bdb1538b53334634bbf7d4cd4b5377033060c155fe3948ca75de1031e1d85619e0ad61eb419a866b3c2dbfd10a4ed18b22149f75897f0b8668b0c1c542c687778835fb7cd46e45f85eaa7072437dd9fa6793d6f8d4ccefc4eb1ac641ac1bd30b18c6d64c49bca137eb21c2e04da62712ca2b4f540c57112c38791852cfac7a5d19ed83a":0
+
+ARIA-128-CBC Decrypt - Official Test Vectors 1.0
+aria_decrypt_cbc:"00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"49d61860b14909109cef0d22a9268134fadf9fb23151e9645fba75018bdb1538b53334634bbf7d4cd4b5377033060c155fe3948ca75de1031e1d85619e0ad61eb419a866b3c2dbfd10a4ed18b22149f75897f0b8668b0c1c542c687778835fb7cd46e45f85eaa7072437dd9fa6793d6f8d4ccefc4eb1ac641ac1bd30b18c6d64c49bca137eb21c2e04da62712ca2b4f540c57112c38791852cfac7a5d19ed83a":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-192-CBC Encrypt - Official Test Vectors 1.0
+aria_encrypt_cbc:"00112233445566778899aabbccddeeff0011223344556677":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"afe6cf23974b533c672a826264ea785f4e4f7f780dc7f3f1e0962b80902386d514e9c3e77259de92dd1102ffab086c1ea52a71260db5920a83295c25320e421147ca45d532f327b856ea947cd2196ae2e040826548b4c891b0ed0ca6e714dbc4631998d548110d666b3d54c2a091955c6f05beb4f62309368696c9791fc4c551564a2637f194346ec45fbca6c72a5b4612e208d531d6c34cc5c64eac6bd0cf8c":0
+
+ARIA-192-CBC Decrypt - Official Test Vectors 1.0
+aria_decrypt_cbc:"00112233445566778899aabbccddeeff0011223344556677":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"afe6cf23974b533c672a826264ea785f4e4f7f780dc7f3f1e0962b80902386d514e9c3e77259de92dd1102ffab086c1ea52a71260db5920a83295c25320e421147ca45d532f327b856ea947cd2196ae2e040826548b4c891b0ed0ca6e714dbc4631998d548110d666b3d54c2a091955c6f05beb4f62309368696c9791fc4c551564a2637f194346ec45fbca6c72a5b4612e208d531d6c34cc5c64eac6bd0cf8c":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-256-CBC Encrypt - Official Test Vectors 1.0
+aria_encrypt_cbc:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"523a8a806ae621f155fdd28dbc34e1ab7b9b42432ad8b2efb96e23b13f0a6e52f36185d50ad002c5f601bee5493f118b243ee2e313642bffc3902e7b2efd9a12fa682edd2d23c8b9c5f043c18b17c1ec4b5867918270fbec1027c19ed6af833da5d620994668ca22f599791d292dd6273b2959082aafb7a996167cce1eec5f0cfd15f610d87e2dda9ba68ce1260ca54b222491418374294e7909b1e8551cd8de":0
+
+ARIA-256-CBC Decrypt - Official Test Vectors 1.0
+aria_decrypt_cbc:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"523a8a806ae621f155fdd28dbc34e1ab7b9b42432ad8b2efb96e23b13f0a6e52f36185d50ad002c5f601bee5493f118b243ee2e313642bffc3902e7b2efd9a12fa682edd2d23c8b9c5f043c18b17c1ec4b5867918270fbec1027c19ed6af833da5d620994668ca22f599791d292dd6273b2959082aafb7a996167cce1eec5f0cfd15f610d87e2dda9ba68ce1260ca54b222491418374294e7909b1e8551cd8de":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-128-CTR Encrypt - Official Test Vectors 1.0
+aria_encrypt_ctr:"00112233445566778899aabbccddeeff":"00000000000000000000000000000000":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"ac5d7de805a0bf1c57c854501af60fa11497e2a34519dea1569e91e5b5ccae2ff3bfa1bf975f4571f48be191613546c3911163c085f871f0e7ae5f2a085b81851c2a3ddf20ecb8fa51901aec8ee4ba32a35dab67bb72cd9140ad188a967ac0fbbdfa94ea6cce47dcf8525ab5a814cfeb2bb60ee2b126e2d9d847c1a9e96f9019e3e6a7fe40d3829afb73db1cc245646addb62d9b907baaafbe46a73dbc131d3d":0
+
+ARIA-192-CTR Encrypt - Official Test Vectors 1.0
+aria_encrypt_ctr:"00112233445566778899aabbccddeeff0011223344556677":"00000000000000000000000000000000":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"08625ca8fe569c19ba7af3760a6ed1cef4d199263e999dde14082dbba7560b79a4c6b456b8707dce751f9854f18893dfdb3f4e5afa539733e6f1e70b98ba37891f8f81e95df8efc26c7ce043504cb18958b865e4e316cd2aa1c97f31bf23dc046ef326b95a692a191ba0f2a41c5fe9ae070f236ff7078e703b42666caafbdd20bad74ac4c20c0f46c7ca24c151716575c947da16c90cfe1bf217a41cfebe7531":0
+
+ARIA-192-CTR Decrypt - Official Test Vectors 1.0
+aria_decrypt_ctr:"00112233445566778899aabbccddeeff0011223344556677":"00000000000000000000000000000000":"08625ca8fe569c19ba7af3760a6ed1cef4d199263e999dde14082dbba7560b79a4c6b456b8707dce751f9854f18893dfdb3f4e5afa539733e6f1e70b98ba37891f8f81e95df8efc26c7ce043504cb18958b865e4e316cd2aa1c97f31bf23dc046ef326b95a692a191ba0f2a41c5fe9ae070f236ff7078e703b42666caafbdd20bad74ac4c20c0f46c7ca24c151716575c947da16c90cfe1bf217a41cfebe7531":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-256-CTR Encrypt - Official Test Vectors 1.0
+aria_encrypt_ctr:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"00000000000000000000000000000000":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"30026c329666141721178b99c0a1f1b2f06940253f7b3089e2a30ea86aa3c88f5940f05ad7ee41d71347bb7261e348f18360473fdf7d4e7723bffb4411cc13f6cdd89f3bc7b9c768145022c7a74f14d7c305cd012a10f16050c23f1ae5c23f45998d13fbaa041e51619577e0772764896a5d4516d8ffceb3bf7e05f613edd9a60cdcedaff9cfcaf4e00d445a54334f73ab2cad944e51d266548e61c6eb0aa1cd":0
+
+ARIA-256-CTR Decrypt - Official Test Vectors 1.0
+aria_decrypt_ctr:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"00000000000000000000000000000000":"30026c329666141721178b99c0a1f1b2f06940253f7b3089e2a30ea86aa3c88f5940f05ad7ee41d71347bb7261e348f18360473fdf7d4e7723bffb4411cc13f6cdd89f3bc7b9c768145022c7a74f14d7c305cd012a10f16050c23f1ae5c23f45998d13fbaa041e51619577e0772764896a5d4516d8ffceb3bf7e05f613edd9a60cdcedaff9cfcaf4e00d445a54334f73ab2cad944e51d266548e61c6eb0aa1cd":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-128-CFB128 Encrypt - Official Test Vectors 1.0
+aria_encrypt_cfb128:"00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"3720e53ba7d615383406b09f0a05a200c07c21e6370f413a5d132500a68285017c61b434c7b7ca9685a51071861e4d4bb873b599b479e2d573dddeafba89f812ac6a9e44d554078eb3be94839db4b33da3f59c063123a7ef6f20e10579fa4fd239100ca73b52d4fcafeadee73f139f78f9b7614c2b3b9dbe010f87db06a89a9435f79ce8121431371f4e87b984e0230c22a6dacb32fc42dcc6accef33285bf11":0
+
+ARIA-128-CFB128 Decrypt - Official Test Vectors 1.0
+aria_decrypt_cfb128:"00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"3720e53ba7d615383406b09f0a05a200c07c21e6370f413a5d132500a68285017c61b434c7b7ca9685a51071861e4d4bb873b599b479e2d573dddeafba89f812ac6a9e44d554078eb3be94839db4b33da3f59c063123a7ef6f20e10579fa4fd239100ca73b52d4fcafeadee73f139f78f9b7614c2b3b9dbe010f87db06a89a9435f79ce8121431371f4e87b984e0230c22a6dacb32fc42dcc6accef33285bf11":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-192-CFB128 Encrypt - Official Test Vectors 1.0
+aria_encrypt_cfb128:"00112233445566778899aabbccddeeff0011223344556677":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"4171f7192bf4495494d2736129640f5c4d87a9a213664c9448477c6ecc2013598d9766952dd8c3868f17e36ef66fd84bfa45d1593d2d6ee3ea2115047d710d4fb66187caa3a315b3c8ea2d313962edcfe5a3e2028d5ba9a09fd5c65c19d3440e477f0cab0628ec6902c73ee02f1afee9f80115be7b9df82d1e28228e28581a20560e195cbb9e2b327bf56fd2d0ae5502e42c13e9b4015d4da42dc859252e7da4":0
+
+ARIA-192-CFB128 Decrypt - Official Test Vectors 1.0
+aria_decrypt_cfb128:"00112233445566778899aabbccddeeff0011223344556677":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"4171f7192bf4495494d2736129640f5c4d87a9a213664c9448477c6ecc2013598d9766952dd8c3868f17e36ef66fd84bfa45d1593d2d6ee3ea2115047d710d4fb66187caa3a315b3c8ea2d313962edcfe5a3e2028d5ba9a09fd5c65c19d3440e477f0cab0628ec6902c73ee02f1afee9f80115be7b9df82d1e28228e28581a20560e195cbb9e2b327bf56fd2d0ae5502e42c13e9b4015d4da42dc859252e7da4":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
+
+ARIA-256-CFB128 Encrypt - Official Test Vectors 1.0
+aria_encrypt_cfb128:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":"26834705b0f2c0e2588d4a7f09009635f28bb93d8c31f870ec1e0bdb082b66fa402dd9c202be300c4517d196b14d4ce11dce97f7aaba54341b0d872cc9b63753a3e8556a14be6f7b3e27e3cfc39caf80f2a355aa50dc83c09c7b11828694f8e4aa726c528976b53f2c877f4991a3a8d28adb63bd751846ffb2350265e179d4990753ae8485ff9b4133ddad5875b84a90cbcfa62a045d726df71b6bda0eeca0be":0
+
+ARIA-256-CFB128 Decrypt - Official Test Vectors 1.0
+aria_decrypt_cfb128:"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff":"0f1e2d3c4b5a69788796a5b4c3d2e1f0":"26834705b0f2c0e2588d4a7f09009635f28bb93d8c31f870ec1e0bdb082b66fa402dd9c202be300c4517d196b14d4ce11dce97f7aaba54341b0d872cc9b63753a3e8556a14be6f7b3e27e3cfc39caf80f2a355aa50dc83c09c7b11828694f8e4aa726c528976b53f2c877f4991a3a8d28adb63bd751846ffb2350265e179d4990753ae8485ff9b4133ddad5875b84a90cbcfa62a045d726df71b6bda0eeca0be":"11111111aaaaaaaa11111111bbbbbbbb11111111cccccccc11111111dddddddd22222222aaaaaaaa22222222bbbbbbbb22222222cccccccc22222222dddddddd33333333aaaaaaaa33333333bbbbbbbb33333333cccccccc33333333dddddddd44444444aaaaaaaa44444444bbbbbbbb44444444cccccccc44444444dddddddd55555555aaaaaaaa55555555bbbbbbbb55555555cccccccc55555555dddddddd":0
diff --git a/tests/suites/test_suite_aria.function b/tests/suites/test_suite_aria.function
new file mode 100644
index 0000000..4e39078
--- /dev/null
+++ b/tests/suites/test_suite_aria.function
@@ -0,0 +1,338 @@
+/* BEGIN_HEADER */
+#include "mbedtls/aria.h"
+
+/* Maxium size of data used by test vectors
+ * WARNING: to be adapted if and when adding larger test cases */
+#define ARIA_MAX_DATASIZE  160
+
+/* Maximum sizes of hexified things */
+#define ARIA_MAX_KEY_STR    ( 2 * MBEDTLS_ARIA_MAX_KEYSIZE + 1 )
+#define ARIA_BLOCK_STR      ( 2 * MBEDTLS_ARIA_BLOCKSIZE + 1 )
+#define ARIA_MAX_DATA_STR   ( 2 * ARIA_MAX_DATASIZE + 1 )
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_ARIA_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void aria_encrypt_ecb( char *hex_key_string, char *hex_src_string,
+                       char *hex_dst_string, int setkey_result )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    mbedtls_aria_context ctx;
+    int key_len, data_len, i;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    TEST_ASSERT( mbedtls_aria_setkey_enc( &ctx, key_str, key_len * 8 )
+                 == setkey_result );
+    if( setkey_result == 0 )
+    {
+        for( i = 0; i < data_len; i += MBEDTLS_ARIA_BLOCKSIZE )
+        {
+            TEST_ASSERT( mbedtls_aria_crypt_ecb( &ctx, src_str + i, output + i )
+                                                 == 0 );
+        }
+        hexify( dst_str, output, data_len );
+
+        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    }
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aria_decrypt_ecb( char *hex_key_string, char *hex_src_string,
+                       char *hex_dst_string, int setkey_result )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    mbedtls_aria_context ctx;
+    int key_len, data_len, i;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    TEST_ASSERT( mbedtls_aria_setkey_dec( &ctx, key_str, key_len * 8 )
+                 == setkey_result );
+    if( setkey_result == 0 )
+    {
+        for( i = 0; i < data_len; i += MBEDTLS_ARIA_BLOCKSIZE )
+        {
+            TEST_ASSERT( mbedtls_aria_crypt_ecb( &ctx, src_str + i, output + i )
+                         == 0 );
+        }
+        hexify( dst_str, output, data_len );
+
+        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    }
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
+void aria_encrypt_cbc( char *hex_key_string, char *hex_iv_string,
+                       char *hex_src_string, char *hex_dst_string,
+                       int cbc_result )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char iv_str[ARIA_BLOCK_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    mbedtls_aria_context ctx;
+    int key_len, data_len;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( iv_str, 0x00, sizeof( iv_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    mbedtls_aria_setkey_enc( &ctx, key_str, key_len * 8 );
+    TEST_ASSERT( mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, data_len,
+                                         iv_str, src_str, output )
+                 == cbc_result );
+    if( cbc_result == 0 )
+    {
+        hexify( dst_str, output, data_len );
+
+        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    }
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
+void aria_decrypt_cbc( char *hex_key_string, char *hex_iv_string,
+                       char *hex_src_string, char *hex_dst_string,
+                       int cbc_result )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char iv_str[ARIA_BLOCK_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    mbedtls_aria_context ctx;
+    int key_len, data_len;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( iv_str, 0x00, sizeof( iv_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    mbedtls_aria_setkey_dec( &ctx, key_str, key_len * 8 );
+    TEST_ASSERT( mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, data_len,
+                                         iv_str, src_str, output )
+                 == cbc_result );
+    if( cbc_result == 0 )
+    {
+        hexify( dst_str, output, data_len );
+
+        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    }
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
+void aria_encrypt_cfb128( char *hex_key_string, char *hex_iv_string,
+                          char *hex_src_string, char *hex_dst_string,
+                          int result )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char iv_str[ARIA_BLOCK_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    mbedtls_aria_context ctx;
+    size_t iv_offset = 0;
+    int key_len, data_len;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( iv_str, 0x00, sizeof( iv_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    mbedtls_aria_setkey_enc( &ctx, key_str, key_len * 8 );
+    TEST_ASSERT( mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT,
+                                            data_len, &iv_offset, iv_str,
+                                            src_str, output )
+                 == result );
+    hexify( dst_str, output, data_len );
+
+    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
+void aria_decrypt_cfb128( char *hex_key_string, char *hex_iv_string,
+                          char *hex_src_string, char *hex_dst_string,
+                          int result  )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char iv_str[ARIA_BLOCK_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    mbedtls_aria_context ctx;
+    size_t iv_offset = 0;
+    int key_len, data_len;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( iv_str, 0x00, sizeof( iv_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    mbedtls_aria_setkey_enc( &ctx, key_str, key_len * 8 );
+    TEST_ASSERT( mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT,
+                                            data_len, &iv_offset, iv_str,
+                                            src_str, output )
+                 == result );
+    hexify( dst_str, output, data_len );
+
+    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
+void aria_encrypt_ctr( char *hex_key_string, char *hex_iv_string,
+                       char *hex_src_string, char *hex_dst_string,
+                       int result )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char iv_str[ARIA_BLOCK_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    unsigned char blk[MBEDTLS_ARIA_BLOCKSIZE];
+    mbedtls_aria_context ctx;
+    size_t iv_offset = 0;
+    int key_len, data_len;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( iv_str, 0x00, sizeof( iv_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    mbedtls_aria_setkey_enc( &ctx, key_str, key_len * 8 );
+    TEST_ASSERT( mbedtls_aria_crypt_ctr( &ctx, data_len, &iv_offset, iv_str,
+                                         blk, src_str, output )
+                 == result );
+    hexify( dst_str, output, data_len );
+
+    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
+void aria_decrypt_ctr( char *hex_key_string, char *hex_iv_string,
+                       char *hex_src_string, char *hex_dst_string,
+                       int result )
+{
+    unsigned char key_str[ARIA_MAX_KEY_STR];
+    unsigned char iv_str[ARIA_BLOCK_STR];
+    unsigned char src_str[ARIA_MAX_DATA_STR];
+    unsigned char dst_str[ARIA_MAX_DATA_STR];
+    unsigned char output[ARIA_MAX_DATASIZE];
+    unsigned char blk[MBEDTLS_ARIA_BLOCKSIZE];
+    mbedtls_aria_context ctx;
+    size_t iv_offset = 0;
+    int key_len, data_len;
+
+    memset( key_str, 0x00, sizeof( key_str ) );
+    memset( iv_str, 0x00, sizeof( iv_str ) );
+    memset( src_str, 0x00, sizeof( src_str ) );
+    memset( dst_str, 0x00, sizeof( dst_str ) );
+    memset( output, 0x00, sizeof( output ) );
+    mbedtls_aria_init( &ctx );
+
+    key_len = unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    data_len = unhexify( src_str, hex_src_string );
+
+    mbedtls_aria_setkey_enc( &ctx, key_str, key_len * 8 );
+    TEST_ASSERT( mbedtls_aria_crypt_ctr( &ctx, data_len, &iv_offset, iv_str,
+                                         blk, src_str, output )
+                 == result );
+    hexify( dst_str, output, data_len );
+
+    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+
+exit:
+    mbedtls_aria_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
+void aria_selftest()
+{
+    TEST_ASSERT( mbedtls_aria_self_test( 1 ) == 0 );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data
index 90ba42d..cad40d5 100644
--- a/tests/suites/test_suite_ccm.data
+++ b/tests/suites/test_suite_ccm.data
@@ -41,6 +41,39 @@
 CCM lengths #8 msg too long for this IV length (2^16, q = 2)
 ccm_lengths:65536:13:5:8:MBEDTLS_ERR_CCM_BAD_INPUT
 
+CCM lengths #9 tag length 0
+ccm_lengths:5:10:5:0:MBEDTLS_ERR_CCM_BAD_INPUT
+
+CCM* fixed tag lengths #1 all OK
+ccm_star_lengths:5:10:5:8:0
+
+CCM* fixed tag lengths #2 all OK - tag length 0
+ccm_star_lengths:5:10:5:0:0
+
+CCM* encrypt and tag #1
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"":"ACDE480000000001":"00000005":2:"08D0842143010000000048DEAC020500000055CF000051525354":"223BC1EC841AB553":0
+
+CCM* encrypt and tag #2
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"61626364":"ACDE480000000001":"00000005":4:"69DC842143020000000048DEAC010000000048DEAC0405000000":"D43E022B":0
+
+CCM* encrypt and tag #3
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"CE":"ACDE480000000001":"00000005":6:"2BDC842143020000000048DEACFFFF010000000048DEAC060500000001":"D84FDE529061F9C6F1":0
+
+CCM* auth decrypt tag #1
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"223BC1EC841AB553":"ACDE480000000001":"00000005":2:"08D0842143010000000048DEAC020500000055CF000051525354":"":0
+
+CCM* auth decrypt tag #2
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"D43E022B":"ACDE480000000001":"00000005":4:"69DC842143020000000048DEAC010000000048DEAC0405000000":"61626364":0
+
+CCM* auth decrypt tag #3
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_auth_decrypt:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"D84FDE529061F9C6F1":"ACDE480000000001":"00000005":6:"2BDC842143020000000048DEACFFFF010000000048DEAC060500000001":"CE":0
+
 CCM encrypt and tag RFC 3610 #1
 depends_on:MBEDTLS_AES_C
 mbedtls_ccm_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"00000003020100A0A1A2A3A4A5":"0001020304050607":"588C979A61C663D2F066D0C2C0F989806D5F6B61DAC38417E8D12CFDF926E0"
diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function
index 2f5c77c..58c8569 100644
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -74,6 +74,47 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
+void ccm_star_lengths( int msg_len, int iv_len, int add_len, int tag_len,
+                       int res )
+{
+    mbedtls_ccm_context ctx;
+    unsigned char key[16];
+    unsigned char msg[10];
+    unsigned char iv[14];
+    unsigned char add[10];
+    unsigned char out[10];
+    unsigned char tag[18];
+    int decrypt_ret;
+
+    mbedtls_ccm_init( &ctx );
+
+    memset( key, 0, sizeof( key ) );
+    memset( msg, 0, sizeof( msg ) );
+    memset( iv, 0, sizeof( iv ) );
+    memset( add, 0, sizeof( add ) );
+    memset( out, 0, sizeof( out ) );
+    memset( tag, 0, sizeof( tag ) );
+
+    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
+                                 key, 8 * sizeof( key ) ) == 0 );
+
+    TEST_ASSERT( mbedtls_ccm_star_encrypt_and_tag( &ctx, msg_len, iv, iv_len,
+                 add, add_len, msg, out, tag, tag_len ) == res );
+
+    decrypt_ret = mbedtls_ccm_star_auth_decrypt( &ctx, msg_len, iv, iv_len, add,
+                  add_len, msg, out, tag, tag_len );
+
+    if( res == 0 && tag_len != 0 )
+        TEST_ASSERT( decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED );
+    else
+        TEST_ASSERT( decrypt_ret == res );
+
+exit:
+    mbedtls_ccm_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void mbedtls_ccm_encrypt_and_tag( int cipher_id,
                           char *key_hex, char *msg_hex,
@@ -187,3 +228,140 @@
     mbedtls_ccm_free( &ctx );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_ccm_star_encrypt_and_tag( int cipher_id,
+                            char *key_hex, char *msg_hex,
+                            char *source_address_hex, char *frame_counter_hex,
+                            int sec_level, char *add_hex,
+                            char *result_hex, int output_ret )
+{
+    unsigned char key[32];
+    unsigned char msg[50];
+    unsigned char iv[13];
+    unsigned char add[32];
+    unsigned char result[50];
+    unsigned char source_address[8];
+    unsigned char frame_counter[4];
+    mbedtls_ccm_context ctx;
+    size_t i, key_len, msg_len, iv_len, add_len, result_len, source_address_len, frame_counter_len, tag_len;
+    int ret;
+
+    mbedtls_ccm_init( &ctx );
+
+    memset( key, 0x00, sizeof( key ) );
+    memset( msg, 0x00, sizeof( msg ) );
+    memset( iv, 0x00, sizeof( iv ) );
+    memset( add, 0x00, sizeof( add ) );
+    memset( result, 0x00, sizeof( result ) );
+    memset( source_address, 0x00, sizeof( source_address ) );
+    memset( frame_counter, 0x00, sizeof( frame_counter ) );
+
+    key_len = unhexify( key, key_hex );
+    msg_len = unhexify( msg, msg_hex );
+    add_len = unhexify( add, add_hex );
+    result_len = unhexify( result, result_hex );
+    source_address_len = unhexify( source_address, source_address_hex );
+    frame_counter_len = unhexify( frame_counter, frame_counter_hex );
+
+    if( sec_level % 4 == 0)
+        tag_len = 0;
+    else
+        tag_len = 1 << ( sec_level % 4 + 1);
+
+    for( i = 0; i < source_address_len; i++ )
+        iv[i] = source_address[i];
+
+    for( i = 0; i < frame_counter_len; i++ )
+        iv[source_address_len + i] = frame_counter[i];
+
+    iv[source_address_len + frame_counter_len] = sec_level;
+    iv_len = sizeof( iv );
+
+    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );
+
+    ret = mbedtls_ccm_star_encrypt_and_tag( &ctx, msg_len, iv, iv_len,
+                 add, add_len, msg, msg, msg + msg_len, tag_len );
+
+    TEST_ASSERT( ret == output_ret );
+
+    TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );
+
+    /* Check we didn't write past the end */
+    TEST_ASSERT( msg[result_len] == 0 && msg[result_len + 1] == 0 );
+
+exit:
+    mbedtls_ccm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_ccm_star_auth_decrypt( int cipher_id,
+                            char *key_hex, char *msg_hex,
+                            char *source_address_hex, char *frame_counter_hex,
+                            int sec_level, char *add_hex,
+                            char *result_hex, int output_ret )
+{
+    unsigned char key[32];
+    unsigned char msg[50];
+    unsigned char iv[13];
+    unsigned char add[32];
+    unsigned char tag[16];
+    unsigned char result[50];
+    unsigned char source_address[8];
+    unsigned char frame_counter[4];
+    mbedtls_ccm_context ctx;
+    size_t i, key_len, msg_len, iv_len, add_len, tag_len, result_len, source_address_len, frame_counter_len;
+    int ret;
+
+    mbedtls_ccm_init( &ctx );
+
+    memset( key, 0x00, sizeof( key ) );
+    memset( msg, 0x00, sizeof( msg ) );
+    memset( iv, 0x00, sizeof( iv ) );
+    memset( add, 0x00, sizeof( add ) );
+    memset( result, 0x00, sizeof( result ) );
+    memset( source_address, 0x00, sizeof( source_address ) );
+    memset( frame_counter, 0x00, sizeof( frame_counter ) );
+    memset( tag, 0x00, sizeof( tag ) );
+
+    key_len = unhexify( key, key_hex );
+    msg_len = unhexify( msg, msg_hex );
+    add_len = unhexify( add, add_hex );
+    result_len = unhexify( result, result_hex );
+    source_address_len = unhexify( source_address, source_address_hex );
+    frame_counter_len = unhexify( frame_counter, frame_counter_hex );
+
+    if( sec_level % 4 == 0)
+        tag_len = 0;
+    else
+        tag_len = 1 << ( sec_level % 4 + 1);
+
+    for( i = 0; i < source_address_len; i++ )
+        iv[i] = source_address[i];
+
+    for( i = 0; i < frame_counter_len; i++ )
+        iv[source_address_len + i] = frame_counter[i];
+
+    iv[source_address_len + frame_counter_len] = sec_level;
+    iv_len = sizeof( iv );
+
+    msg_len -= tag_len;
+    memcpy( tag, msg + msg_len, tag_len );
+
+    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );
+
+    ret = mbedtls_ccm_star_auth_decrypt( &ctx, msg_len, iv, iv_len,
+                 add, add_len, msg, msg, msg + msg_len, tag_len );
+
+    TEST_ASSERT( ret == output_ret );
+
+    TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );
+
+    /* Check we didn't write past the end (where the original tag is) */
+    TEST_ASSERT( memcmp( msg + msg_len, tag, tag_len ) == 0 );
+
+exit:
+    mbedtls_ccm_free( &ctx );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index e8e9a15..475c91e 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -474,6 +474,318 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB
 enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CFB128:128:16:16:-1:16:16:16:16
 
+AES-128 OFB - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:0:-1
+
+AES-128 OFB - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:1:-1
+
+AES-128 OFB - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:2:-1
+
+AES-128 OFB - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:7:-1
+
+AES-128 OFB - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:8:-1
+
+AES-128 OFB - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:9:-1
+
+AES-128 OFB - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:15:-1
+
+AES-128 OFB - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:16:-1
+
+AES-128 OFB - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:17:-1
+
+AES-128 OFB - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:31:-1
+
+AES-128 OFB - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:32:-1
+
+AES-128 OFB - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:33:-1
+
+AES-128 OFB - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:47:-1
+
+AES-128 OFB - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:48:-1
+
+AES-128 OFB - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_OFB:"AES-128-OFB":128:49:-1
+
+AES-128 OFB - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:0:0:-1:0:0:0:0
+
+AES-128 OFB - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:1:0:-1:1:0:1:0
+
+AES-128 OFB - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:0:1:-1:0:1:0:1
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:16:0:-1:16:0:16:0
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:0:16:-1:0:16:0:16
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:1:15:-1:1:15:1:15
+
+AES-128 OFB - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:15:1:-1:15:1:15:1
+
+AES-128 OFB - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:15:7:-1:15:7:15:7
+
+AES-128 OFB - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:16:6:-1:16:6:16:6
+
+AES-128 OFB - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:17:6:-1:17:6:17:6
+
+AES-128 OFB - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_OFB:128:16:16:-1:16:16:16:16
+
+AES-192 OFB - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:0:-1
+
+AES-192 OFB - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:1:-1
+
+AES-192 OFB - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:2:-1
+
+AES-192 OFB - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:7:-1
+
+AES-192 OFB - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:8:-1
+
+AES-192 OFB - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:9:-1
+
+AES-192 OFB - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:15:-1
+
+AES-192 OFB - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:16:-1
+
+AES-192 OFB - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:17:-1
+
+AES-192 OFB - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:31:-1
+
+AES-192 OFB - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:32:-1
+
+AES-192 OFB - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:33:-1
+
+AES-192 OFB - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:47:-1
+
+AES-192 OFB - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:48:-1
+
+AES-192 OFB - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_OFB:"AES-192-OFB":192:49:-1
+
+AES-192 OFB - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:0:0:-1:0:0:0:0
+
+AES-192 OFB - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:1:0:-1:1:0:1:0
+
+AES-192 OFB - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:0:1:-1:0:1:0:1
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:16:0:-1:16:0:16:0
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:0:16:-1:0:16:0:16
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:1:15:-1:1:15:1:15
+
+AES-192 OFB - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:15:1:-1:15:1:15:1
+
+AES-192 OFB - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:15:7:-1:15:7:15:7
+
+AES-192 OFB - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:16:6:-1:16:6:16:6
+
+AES-192 OFB - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:17:6:-1:17:6:17:6
+
+AES-192 OFB - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_OFB:192:16:16:-1:16:16:16:16
+
+AES-256 OFB - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:0:-1
+
+AES-256 OFB - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:1:-1
+
+AES-256 OFB - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:2:-1
+
+AES-256 OFB - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:7:-1
+
+AES-256 OFB - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:8:-1
+
+AES-256 OFB - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:9:-1
+
+AES-256 OFB - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:15:-1
+
+AES-256 OFB - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:16:-1
+
+AES-256 OFB - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:17:-1
+
+AES-256 OFB - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:31:-1
+
+AES-256 OFB - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:32:-1
+
+AES-256 OFB - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:33:-1
+
+AES-256 OFB - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:47:-1
+
+AES-256 OFB - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:48:-1
+
+AES-256 OFB - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_OFB:"AES-256-OFB":256:49:-1
+
+AES-256 OFB - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:0:0:-1:0:0:0:0
+
+AES-256 OFB - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:1:0:-1:1:0:1:0
+
+AES-256 OFB - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:0:1:-1:0:1:0:1
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:16:0:-1:16:0:16:0
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:0:16:-1:0:16:0:16
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:1:15:-1:1:15:1:15
+
+AES-256 OFB - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:15:1:-1:15:1:15:1
+
+AES-256 OFB - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:15:7:-1:15:7:15:7
+
+AES-256 OFB - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:16:6:-1:16:6:16:6
+
+AES-256 OFB - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:17:6:-1:17:6:17:6
+
+AES-256 OFB - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:16:16:-1:16:16:16:16
+
 AES-128 CTR - Encrypt and decrypt 0 bytes
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
 enc_dec_buf:MBEDTLS_CIPHER_AES_128_CTR:"AES-128-CTR":128:0:-1
@@ -814,6 +1126,18 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB
 decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CFB128:-1:"ffffffffff800000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"be66cfea2fecd6bf0ec7b4352c99bcaa":"00000000000000000000000000000000":"":"":0:0
 
+AES Decrypt test vector #7
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+decrypt_test_vec:MBEDTLS_CIPHER_AES_128_OFB:-1:"2B7E151628AED2A6ABF7158809CF4F3C":"000102030405060708090A0B0C0D0E0F":"3B3FD92EB72DAD20333449F8E83CFB4A7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
+
+AES Decrypt test vector #8
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+decrypt_test_vec:MBEDTLS_CIPHER_AES_192_OFB:-1:"8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B":"000102030405060708090A0B0C0D0E0F":"CDC80D6FDDF18CAB34C25909C99A4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
+
+AES Decrypt test vector #9
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
+decrypt_test_vec:MBEDTLS_CIPHER_AES_256_OFB:-1:"603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4":"000102030405060708090A0B0C0D0E0F":"DC7E84BFDA79164B7ECD8486985D38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
+
 AES-128-ECB Encrypt NIST KAT #1
 depends_on:MBEDTLS_AES_C
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index 308e14b..3d0830e 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -35,7 +35,7 @@
     memset( tag_str, 0x00, sizeof( tag_str ) );
     memset( output, 0x00, sizeof( output ) );
     memset( tag_output, 0x00, sizeof( tag_output ) );
-    
+
     key_len = unhexify( key_str, hex_key_string );
     pt_len = unhexify( src_str, hex_src_string );
     iv_len = unhexify( iv_str, hex_iv_string );
diff --git a/tests/suites/test_suite_hkdf.data b/tests/suites/test_suite_hkdf.data
new file mode 100644
index 0000000..1583736
--- /dev/null
+++ b/tests/suites/test_suite_hkdf.data
@@ -0,0 +1,98 @@
+HKDF extract fails with hash_len of 0
+test_hkdf_extract_ret:0:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with NULL okm
+test_hkdf_expand_ret:32:32:0:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with hash_len of 0
+test_hkdf_expand_ret:0:32:32:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with prk_len < hash_len
+test_hkdf_expand_ret:32:16:32:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF expand fails with okm_len / hash_len > 255
+test_hkdf_expand_ret:32:32:8192:MBEDTLS_ERR_HKDF_BAD_INPUT_DATA
+
+HKDF RFC5869 Test Vector #1
+depends_on:MBEDTLS_SHA256_C
+test_hkdf:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+HKDF RFC5869 Test Vector #2
+depends_on:MBEDTLS_SHA256_C
+test_hkdf:6:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87"
+
+HKDF RFC5869 Test Vector #3
+depends_on:MBEDTLS_SHA256_C
+test_hkdf:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"
+
+HKDF RFC5869 Test Vector #4
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896"
+
+HKDF RFC5869 Test Vector #5
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4"
+
+HKDF RFC5869 Test Vector #6
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918"
+
+HKDF RFC5869 Test Vector #7
+depends_on:MBEDTLS_SHA1_C
+test_hkdf:4:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48"
+
+HKDF RFC5869 Test Vector #1 Extract
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_extract:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"
+
+HKDF RFC5869 Test Vector #2 Extract
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_extract:6:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244"
+
+HKDF RFC5869 Test Vector #3 Extract
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_extract:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04"
+
+HKDF RFC5869 Test Vector #4 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243"
+
+HKDF RFC5869 Test Vector #5 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"8adae09a2a307059478d309b26c4115a224cfaf6"
+
+HKDF RFC5869 Test Vector #6 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"da8c8a73c7fa77288ec6f5e7c297786aa0d32d01"
+
+HKDF RFC5869 Test Vector #7 Extract
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_extract:4:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"2adccada18779e7c2077ad2eb19d3f3e731385dd"
+
+HKDF RFC5869 Test Vector #1 Expand
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_expand:6:"f0f1f2f3f4f5f6f7f8f9":"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+HKDF RFC5869 Test Vector #2 Expand
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_expand:6:"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244":"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87"
+
+HKDF RFC5869 Test Vector #3 Expand
+depends_on:MBEDTLS_SHA256_C
+test_hkdf_expand:6:"":"19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04":"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"
+
+HKDF RFC5869 Test Vector #4 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"f0f1f2f3f4f5f6f7f8f9":"9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243":"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896"
+
+HKDF RFC5869 Test Vector #5 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"8adae09a2a307059478d309b26c4115a224cfaf6":"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4"
+
+HKDF RFC5869 Test Vector #6 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"":"da8c8a73c7fa77288ec6f5e7c297786aa0d32d01":"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918"
+
+HKDF RFC5869 Test Vector #7 Expand
+depends_on:MBEDTLS_SHA1_C
+test_hkdf_expand:4:"":"2adccada18779e7c2077ad2eb19d3f3e731385dd":"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48"
diff --git a/tests/suites/test_suite_hkdf.function b/tests/suites/test_suite_hkdf.function
new file mode 100644
index 0000000..c85a51a
--- /dev/null
+++ b/tests/suites/test_suite_hkdf.function
@@ -0,0 +1,170 @@
+/* BEGIN_HEADER */
+#include "mbedtls/hkdf.h"
+#include "mbedtls/md_internal.h"
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_HKDF_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void test_hkdf( int md_alg, char *hex_ikm_string, char *hex_salt_string,
+                char *hex_info_string, char *hex_okm_string )
+{
+    int ret;
+    size_t ikm_len, salt_len, info_len, okm_len;
+    unsigned char ikm[1024] = { '\0' };
+    unsigned char salt[1024] = { '\0' };
+    unsigned char info[1024] = { '\0' };
+    unsigned char expected_okm[1024] = { '\0' };
+    unsigned char okm[1024] = { '\0' };
+    unsigned char okm_string[1000] = { '\0' };
+
+    const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
+    TEST_ASSERT( md != NULL );
+
+    ikm_len = unhexify( ikm, hex_ikm_string );
+    salt_len = unhexify( salt, hex_salt_string );
+    info_len = unhexify( info, hex_info_string );
+    okm_len = unhexify( expected_okm, hex_okm_string );
+
+    ret = mbedtls_hkdf( md, salt, salt_len, ikm, ikm_len, info, info_len, okm,
+                        okm_len);
+    TEST_ASSERT( ret == 0 );
+
+    // Run hexify on it so that it looks nicer if the assertion fails
+    hexify( okm_string, okm, okm_len );
+    TEST_ASSERT( !strcmp( (char *)okm_string, hex_okm_string ) );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_extract( int md_alg, char *hex_ikm_string,
+                        char *hex_salt_string, char *hex_prk_string )
+{
+    int ret;
+    unsigned char *ikm = NULL;
+    unsigned char *salt = NULL;
+    unsigned char *prk = NULL;
+    unsigned char *output_prk = NULL;
+    size_t ikm_len, salt_len, prk_len, output_prk_len;
+
+    const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
+    TEST_ASSERT( md != NULL );
+
+    output_prk_len = mbedtls_md_get_size( md );
+    output_prk = mbedtls_calloc( 1, output_prk_len );
+
+    ikm = unhexify_alloc( hex_ikm_string, &ikm_len );
+    salt = unhexify_alloc( hex_salt_string, &salt_len );
+    prk = unhexify_alloc( hex_prk_string, &prk_len );
+    TEST_ASSERT( prk_len == output_prk_len );
+
+    ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, output_prk );
+    TEST_ASSERT( ret == 0 );
+
+    TEST_ASSERT( !memcmp( output_prk, prk, prk_len ) );
+
+exit:
+    mbedtls_free(ikm);
+    mbedtls_free(salt);
+    mbedtls_free(prk);
+    mbedtls_free(output_prk);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_expand( int md_alg, char *hex_info_string,
+                       char *hex_prk_string, char *hex_okm_string )
+{
+    enum { OKM_LEN  = 1024 };
+    int ret;
+    unsigned char *info = NULL;
+    unsigned char *prk = NULL;
+    unsigned char *okm = NULL;
+    unsigned char *output_okm = NULL;
+    size_t info_len, prk_len, okm_len;
+
+    const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
+    TEST_ASSERT( md != NULL );
+
+    output_okm = mbedtls_calloc( OKM_LEN, 1 );
+
+    prk = unhexify_alloc( hex_prk_string, &prk_len );
+    info = unhexify_alloc( hex_info_string, &info_len );
+    okm = unhexify_alloc( hex_okm_string, &okm_len );
+    TEST_ASSERT( prk_len == mbedtls_md_get_size( md ) );
+    TEST_ASSERT( okm_len < OKM_LEN );
+
+    ret = mbedtls_hkdf_expand( md, prk, prk_len, info, info_len,
+                               output_okm, OKM_LEN );
+    TEST_ASSERT( ret == 0 );
+    TEST_ASSERT( !memcmp( output_okm, okm, okm_len ) );
+
+exit:
+    mbedtls_free(info);
+    mbedtls_free(prk);
+    mbedtls_free(okm);
+    mbedtls_free(output_okm);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_extract_ret( int hash_len, int ret )
+{
+    int output_ret;
+    unsigned char *salt = NULL;
+    unsigned char *ikm = NULL;
+    unsigned char *prk = NULL;
+    size_t salt_len, ikm_len;
+    struct mbedtls_md_info_t fake_md_info;
+
+    memset( &fake_md_info, 0, sizeof( fake_md_info ) );
+    fake_md_info.type = MBEDTLS_MD_NONE;
+    fake_md_info.size = hash_len;
+
+    prk = mbedtls_calloc( MBEDTLS_MD_MAX_SIZE, 1 );
+    salt_len = 0;
+    ikm_len = 0;
+
+    output_ret = mbedtls_hkdf_extract( &fake_md_info, salt, salt_len,
+                                       ikm, ikm_len, prk );
+    TEST_ASSERT( output_ret == ret );
+
+exit:
+    mbedtls_free(prk);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void test_hkdf_expand_ret( int hash_len, int prk_len, int okm_len, int ret )
+{
+    int output_ret;
+    unsigned char *info = NULL;
+    unsigned char *prk = NULL;
+    unsigned char *okm = NULL;
+    size_t info_len;
+    struct mbedtls_md_info_t fake_md_info;
+
+    memset( &fake_md_info, 0, sizeof( fake_md_info ) );
+    fake_md_info.type = MBEDTLS_MD_NONE;
+    fake_md_info.size = hash_len;
+
+    info_len = 0;
+
+    if (prk_len > 0)
+        prk = mbedtls_calloc( prk_len, 1 );
+
+    if (okm_len > 0)
+        okm = mbedtls_calloc( okm_len, 1 );
+
+    output_ret = mbedtls_hkdf_expand( &fake_md_info, prk, prk_len,
+                                      info, info_len, okm, okm_len );
+    TEST_ASSERT( output_ret == ret );
+
+exit:
+    mbedtls_free(prk);
+    mbedtls_free(okm);
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 17cf350..c450088 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -301,10 +301,10 @@
 Base test mbedtls_mpi_add_mpi inplace #1
 mbedtls_mpi_add_mpi_inplace:10:"12345678":10:"24691356"
 
-Test mbedtls_mpi_add_mpi inplace #2 
+Test mbedtls_mpi_add_mpi inplace #2
 mbedtls_mpi_add_mpi_inplace:10:"643808006803554439230129854961492699151386107534013432918073439524138264842370630061369715394739134090922937332590384720397133335969549256322620979036686633213903952966175107096769180017646161851573147596390153":10:"1287616013607108878460259709922985398302772215068026865836146879048276529684741260122739430789478268181845874665180769440794266671939098512645241958073373266427807905932350214193538360035292323703146295192780306"
 
-Test mbedtls_mpi_add_mpi inplace #3 
+Test mbedtls_mpi_add_mpi inplace #3
 mbedtls_mpi_add_mpi_inplace:16:"ffffffffffffffffffffffffffffffff":16:"01fffffffffffffffffffffffffffffffe"
 
 Test mbedtls_mpi_add_int #1
@@ -688,6 +688,18 @@
 depends_on:MBEDTLS_GENPRIME
 mbedtls_mpi_gen_prime:3:0:0
 
+Test mbedtls_mpi_gen_prime (corner case limb size -1 bits)
+depends_on:MBEDTLS_GENPRIME
+mbedtls_mpi_gen_prime:63:0:0
+
+Test mbedtls_mpi_gen_prime (corner case limb size)
+depends_on:MBEDTLS_GENPRIME
+mbedtls_mpi_gen_prime:64:0:0
+
+Test mbedtls_mpi_gen_prime (corner case limb size +1 bits)
+depends_on:MBEDTLS_GENPRIME
+mbedtls_mpi_gen_prime:65:0:0
+
 Test mbedtls_mpi_gen_prime (Larger)
 depends_on:MBEDTLS_GENPRIME
 mbedtls_mpi_gen_prime:128:0:0
diff --git a/tests/suites/test_suite_pkcs1_v15.data b/tests/suites/test_suite_pkcs1_v15.data
index db7a4cd..0309400 100644
--- a/tests/suites/test_suite_pkcs1_v15.data
+++ b/tests/suites/test_suite_pkcs1_v15.data
@@ -13,19 +13,19 @@
 RSAES-V15 Encryption Test Vector Data too long 1
 pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"b84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"05abded6751d620a95177abdba915027b58dd6eecf4ebe71f71c400b115e1d9e12465ace4db3cc03eb57fcbbfe017770f438cf84c10bad505919aefebfa0752087f6376b055beabf0e089fbb90e10f99c795d2d5676eea196db7f94a8fd34aedaba39fb230281bb9917cc91793eb37f84dedb2421e9680c39cfda34d4a012134":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
 
-RSAES-V15 Decryption Test Vector Padding too short 7 
+RSAES-V15 Decryption Test Vector Padding too short 7
 pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"b84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"05abded6751d620a95177abdba915027b58dd6eecf4ebe71f71c400b115e1d9e12465ace4db3cc03eb57fcbbfe017770f438cf84c10bad505919aefebfa0752087f6376b055beabf0e089fbb90e10f99c795d2d5676eea196db7f94a8fd34aedaba39fb230281bb9917cc91793eb37f84dedb2421e9680c39cfda34d4a012134":MBEDTLS_ERR_RSA_INVALID_PADDING
 
 RSAES-V15 Encryption Test Vector Data too long 3
 pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"aa1ab84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"10d60b8040d57d8701bacb55f2f283d54601ec24d465601ac7f7d5a2f75cac380ba78ca4ab6f3c159f3a9fd6839f5adde0333852ebf876c585664c1a58a1e6885231982f2027be6d7f08ff1807d3ceda8e41ad1f02ddf97a7458832fd13a1f431de6a4ab79e3d4b88bb1df2c5c77fcde9e7b5aa1e7bb29112eae58763127752a":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
 
-RSAES-V15 Decryption Test Vector Padding too short 5 
+RSAES-V15 Decryption Test Vector Padding too short 5
 pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"aa1ab84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"10d60b8040d57d8701bacb55f2f283d54601ec24d465601ac7f7d5a2f75cac380ba78ca4ab6f3c159f3a9fd6839f5adde0333852ebf876c585664c1a58a1e6885231982f2027be6d7f08ff1807d3ceda8e41ad1f02ddf97a7458832fd13a1f431de6a4ab79e3d4b88bb1df2c5c77fcde9e7b5aa1e7bb29112eae58763127752a":MBEDTLS_ERR_RSA_INVALID_PADDING
 
 RSAES-V15 Encryption Test Vector Data too long 8
 pkcs1_rsaes_v15_encrypt:1024:16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"a5a384ef64a6acb84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"72f98d12ddc230484179ec3022d11b3719222daaa0dc016fc3dbd6771a3f2c9fdd0560f86d616dd50ef1fa5b8c7e1fc40b5abf7b845d7795b3a6af02457b97f783360575cde7497bdf9c104650d4e9a8f4034406de1af95ace39bef2b9e979b74d9a2c0a741d8a21221d9afc98992776cad52d73151613dbc10da9bd8038751a":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
 
-RSAES-V15 Decryption Test Vector Padding too short 0 
+RSAES-V15 Decryption Test Vector Padding too short 0
 pkcs1_rsaes_v15_decrypt:1024:16:"eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599":16:"c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503":16:"bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb":16:"11":MBEDTLS_MD_SHA1:"a5a384ef64a6acb84293cecc8095232ae595b84c15ec26f35cf5fde88ae7a9aaa717bcb1ecc4de498da81db97425000770817b5dde5eed01ca3745ff5ab894d0fc0921e5a10b081490129d8ccbaa154ad3dd461397af8ec964ef99402d60a7591ee44b8ce1c16ef88fcb2717076c730d88223893bdd8000b23d87d38ab":"aafd12f659cae63489b479e5076ddec2f06cb58f":"72f98d12ddc230484179ec3022d11b3719222daaa0dc016fc3dbd6771a3f2c9fdd0560f86d616dd50ef1fa5b8c7e1fc40b5abf7b845d7795b3a6af02457b97f783360575cde7497bdf9c104650d4e9a8f4034406de1af95ace39bef2b9e979b74d9a2c0a741d8a21221d9afc98992776cad52d73151613dbc10da9bd8038751a":MBEDTLS_ERR_RSA_INVALID_PADDING
 
 RSASSA-V15 Signing Test Vector Int
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 60683af..5cc32ab 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -52,4 +52,4 @@
 
     mbedtls_ssl_free( &ssl );
 }
-/* END_CASE */
\ No newline at end of file
+/* END_CASE */
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index 79cc751..999a933 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.8.0"
+check_compiletime_version:"2.10.0"
 
 Check runtime library version
-check_runtime_version:"2.8.0"
+check_runtime_version:"2.10.0"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/visualc/VS2010/mbedTLS.sln b/visualc/VS2010/mbedTLS.sln
index 686091c..66b96c3 100644
--- a/visualc/VS2010/mbedTLS.sln
+++ b/visualc/VS2010/mbedTLS.sln
@@ -203,6 +203,11 @@
 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

 	EndProjectSection

 EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zeroize", "zeroize.vcxproj", "{10C01E94-4926-063E-9F56-C84ED190D349}"

+	ProjectSection(ProjectDependencies) = postProject

+		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

+	EndProjectSection

+EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pem2der", "pem2der.vcxproj", "{D3C6FBD6-D78E-7180-8345-5E09B492DBEC}"

 	ProjectSection(ProjectDependencies) = postProject

 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

@@ -574,6 +579,14 @@
 		{7E2C80FE-3CC3-82B4-0CAD-65DC233DE13A}.Release|Win32.Build.0 = Release|Win32

 		{7E2C80FE-3CC3-82B4-0CAD-65DC233DE13A}.Release|x64.ActiveCfg = Release|x64

 		{7E2C80FE-3CC3-82B4-0CAD-65DC233DE13A}.Release|x64.Build.0 = Release|x64

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Debug|Win32.ActiveCfg = Debug|Win32

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Debug|Win32.Build.0 = Debug|Win32

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Debug|x64.ActiveCfg = Debug|x64

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Debug|x64.Build.0 = Debug|x64

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Release|Win32.ActiveCfg = Release|Win32

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Release|Win32.Build.0 = Release|Win32

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Release|x64.ActiveCfg = Release|x64

+		{10C01E94-4926-063E-9F56-C84ED190D349}.Release|x64.Build.0 = Release|x64

 		{D3C6FBD6-D78E-7180-8345-5E09B492DBEC}.Debug|Win32.ActiveCfg = Debug|Win32

 		{D3C6FBD6-D78E-7180-8345-5E09B492DBEC}.Debug|Win32.Build.0 = Debug|Win32

 		{D3C6FBD6-D78E-7180-8345-5E09B492DBEC}.Debug|x64.ActiveCfg = Debug|x64

diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index f13f83c..737556a 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -149,6 +149,7 @@
     <ClInclude Include="..\..\include\mbedtls\aes.h" />

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

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

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

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

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

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

@@ -178,6 +179,7 @@
     <ClInclude Include="..\..\include\mbedtls\error.h" />

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

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

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

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

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

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

@@ -197,6 +199,7 @@
     <ClInclude Include="..\..\include\mbedtls\pkcs5.h" />

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

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

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

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

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

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

@@ -222,6 +225,7 @@
     <ClCompile Include="..\..\library\aes.c" />

     <ClCompile Include="..\..\library\aesni.c" />

     <ClCompile Include="..\..\library\arc4.c" />

+    <ClCompile Include="..\..\library\aria.c" />

     <ClCompile Include="..\..\library\asn1parse.c" />

     <ClCompile Include="..\..\library\asn1write.c" />

     <ClCompile Include="..\..\library\base64.c" />

@@ -247,6 +251,7 @@
     <ClCompile Include="..\..\library\error.c" />

     <ClCompile Include="..\..\library\gcm.c" />

     <ClCompile Include="..\..\library\havege.c" />

+    <ClCompile Include="..\..\library\hkdf.c" />

     <ClCompile Include="..\..\library\hmac_drbg.c" />

     <ClCompile Include="..\..\library\md.c" />

     <ClCompile Include="..\..\library\md2.c" />

@@ -266,6 +271,7 @@
     <ClCompile Include="..\..\library\pkparse.c" />

     <ClCompile Include="..\..\library\pkwrite.c" />

     <ClCompile Include="..\..\library\platform.c" />

+    <ClCompile Include="..\..\library\platform_util.c" />

     <ClCompile Include="..\..\library\ripemd160.c" />

     <ClCompile Include="..\..\library\rsa.c" />

     <ClCompile Include="..\..\library\rsa_internal.c" />

diff --git a/visualc/VS2010/md5sum.vcxproj b/visualc/VS2010/md5sum.vcxproj
deleted file mode 100644
index 6f20e57..0000000
--- a/visualc/VS2010/md5sum.vcxproj
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|Win32">

-      <Configuration>Release</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|x64">

-      <Configuration>Release</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\programs\hash\md5sum.c" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="mbedTLS.vcxproj">
-      <Project>{46cf2d25-6a36-4189-b59c-e4815388e554}</Project>

-      <LinkLibraryDependencies>true</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <ProjectGuid>{80FE1ECF-6992-A275-7973-E2976718D128}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-    <RootNamespace>md5sum</RootNamespace>

-  </PropertyGroup>

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

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

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

-  </PropertyGroup>

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

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <LinkIncremental>true</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <LinkIncremental>true</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <LinkIncremental>false</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <LinkIncremental>false</LinkIncremental>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

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

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>

diff --git a/visualc/VS2010/sha2sum.vcxproj b/visualc/VS2010/sha2sum.vcxproj
deleted file mode 100644
index b1afb67..0000000
--- a/visualc/VS2010/sha2sum.vcxproj
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|Win32">

-      <Configuration>Release</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|x64">

-      <Configuration>Release</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\programs\hash\sha2sum.c" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="mbedTLS.vcxproj">
-      <Project>{46cf2d25-6a36-4189-b59c-e4815388e554}</Project>

-      <LinkLibraryDependencies>true</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <ProjectGuid>{8C5CF095-A0A4-54FB-0D48-8DF2B7FE4CA5}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-    <RootNamespace>sha2sum</RootNamespace>

-  </PropertyGroup>

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

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

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

-  </PropertyGroup>

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

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <LinkIncremental>true</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <LinkIncremental>true</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <LinkIncremental>false</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <LinkIncremental>false</LinkIncremental>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

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

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>

diff --git a/visualc/VS2010/sha1sum.vcxproj b/visualc/VS2010/zeroize.vcxproj
similarity index 95%
rename from visualc/VS2010/sha1sum.vcxproj
rename to visualc/VS2010/zeroize.vcxproj
index 2c3674b..9d311c7 100644
--- a/visualc/VS2010/sha1sum.vcxproj
+++ b/visualc/VS2010/zeroize.vcxproj
@@ -19,7 +19,7 @@
     </ProjectConfiguration>

   </ItemGroup>

   <ItemGroup>

-    <ClCompile Include="..\..\programs\hash\sha1sum.c" />

+    <ClCompile Include="..\..\programs\test\zeroize.c" />

   </ItemGroup>

   <ItemGroup>

     <ProjectReference Include="mbedTLS.vcxproj">
@@ -28,9 +28,9 @@
     </ProjectReference>

   </ItemGroup>

   <PropertyGroup Label="Globals">

-    <ProjectGuid>{E91D12D7-01C0-357F-CAB1-8478B096743C}</ProjectGuid>

+    <ProjectGuid>{10C01E94-4926-063E-9F56-C84ED190D349}</ProjectGuid>

     <Keyword>Win32Proj</Keyword>

-    <RootNamespace>sha1sum</RootNamespace>

+    <RootNamespace>zeroize</RootNamespace>

   </PropertyGroup>

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

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

@@ -72,18 +72,22 @@
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

   </ImportGroup>

   <PropertyGroup Label="UserMacros" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <LinkIncremental>true</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <LinkIncremental>true</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <LinkIncremental>false</LinkIncremental>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <LinkIncremental>false</LinkIncremental>

-  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

     <ClCompile>

       <PrecompiledHeader>

diff --git a/yotta/data/example-authcrypt/README.md b/yotta/data/example-authcrypt/README.md
index ae4b1ef..4498b9d 100644
--- a/yotta/data/example-authcrypt/README.md
+++ b/yotta/data/example-authcrypt/README.md
@@ -38,11 +38,11 @@
 
 6. Start the serial terminal emulator and connect to the virtual serial port presented by FRDM-K64F. 
 
-	Use the following settings:
+   Use the following settings:
 
-	* 115200 baud (not 9600).
-	* 8N1.
-	* No flow control. 
+    * 115200 baud (not 9600).
+    * 8N1.
+    * No flow control.
 
 7. Press the Reset button on the board.
 
diff --git a/yotta/data/example-benchmark/README.md b/yotta/data/example-benchmark/README.md
index 3b66916..715abee 100644
--- a/yotta/data/example-benchmark/README.md
+++ b/yotta/data/example-benchmark/README.md
@@ -38,11 +38,11 @@
 
 6. Start the serial terminal emulator and connect to the virtual serial port presented by FRDM-K64F. 
 
-	Use the following settings:
+   Use the following settings:
 
-	* 115200 baud (not 9600).
-	* 8N1.
-	* No flow control. 
+    * 115200 baud (not 9600).
+    * 8N1.
+    * No flow control.
 
 7. Press the Reset button on the board.
 
diff --git a/yotta/data/example-hashing/README.md b/yotta/data/example-hashing/README.md
index 553c3a6..6f0f969 100644
--- a/yotta/data/example-hashing/README.md
+++ b/yotta/data/example-hashing/README.md
@@ -38,11 +38,11 @@
 
 6. Start the serial terminal emulator and connect to the virtual serial port presented by FRDM-K64F. 
 
-	Use the following settings:
+   Use the following settings:
 
-	* 115200 baud (not 9600).
-	* 8N1.
-	* No flow control. 
+    * 115200 baud (not 9600).
+    * 8N1.
+    * No flow control.
 
 7. Press the Reset button on the board.
 
diff --git a/yotta/data/example-selftest/README.md b/yotta/data/example-selftest/README.md
index 5bc22a6..b8e9cd4 100644
--- a/yotta/data/example-selftest/README.md
+++ b/yotta/data/example-selftest/README.md
@@ -38,11 +38,11 @@
 
 6. Start the serial terminal emulator and connect to the virtual serial port presented by FRDM-K64F. 
 
-	Use the following settings:
+   Use the following settings:
 
-	* 115200 baud (not 9600).
-	* 8N1.
-	* No flow control. 
+    * 115200 baud (not 9600).
+    * 8N1.
+    * No flow control.
 
 7. Press the Reset button on the board.