Merge remote-tracking branch 'ptahpeteh/patch-1' into mbedtls-1.3

* ptahpeteh/patch-1:
  Serious bug fix in entropy.c
diff --git a/.travis.yml b/.travis.yml
index 0a51e7e..24c7667 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,14 +13,14 @@
 - tests/scripts/test-ref-configs.pl
 env:
   global:
-    secure: LidFb8vsR72MKTVpaZ8IYHR1xeVnff47/+ckEge5F9gcwf7QmfSI3+gBLZZciNdyrWzOFhlQ5Q2z/pqVeRtEkKrlcporoMMcHRIbyIA+lfRE1HnYHw7jITScfN9ZmK4msU1ElRlAk6U7ND6MPTH8QfWwchNafDk9d3AoHL4/RrQ=
+    secure: "barHldniAfXyoWOD/vcO+E6/Xm4fmcaUoC9BeKW+LwsHqlDMLvugaJnmLXkSpkbYhVL61Hzf3bo0KPJn88AFc5Rkf8oYHPjH4adMnVXkf3B9ghHCgznqHsAH3choo6tnPxaFgOwOYmLGb382nQxfE5lUdvnM/W/psQjWt66A1+k="
 
 addons:
   coverity_scan:
     project:
-      name: "polarssl/polarssl"
+      name: "ARMmbed/mbedtls"
       description: "mbed TLS Open Source SSL Library"
     notification_email: p.j.bakker@polarssl.org
     build_command_prepend:
     build_command: make
-    branch_pattern: development
+    branch_pattern: coverity_scan
diff --git a/ChangeLog b/ChangeLog
index a8758f6..160c0fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,8 +3,18 @@
 = mbed TLS 1.3 branch
 
 Security
+   * With authmode set to SSL_VERIFY_OPTIONAL, verification of keyUsage and
+     extendedKeyUsage on the leaf certificate was lost (results not accessible
+     via ssl_get_verify_results()).
+   * Add countermeasure against "Lucky 13 strikes back" cache-based attack,
+     https://dl.acm.org/citation.cfm?id=2714625
 
 Features
+   * Improve ECC performance by using more efficient doubling formulas
+     (contributed by Peter Dettman).
+   * Add x509_crt_verify_info() to display certificate verification results.
+   * Add support for reading DH parameters with privateValueLength included
+     (contributed by Daniel Kahn Gillmor).
    * Add support for bit strings in X.509 names (request by Fredrik Axelsson).
    * Add support for id-at-uniqueIdentifier in X.509 names.
    * Add support for overriding snprintf() (except on Windows) and exit() in
@@ -19,12 +29,28 @@
      speed and RAM (heap only for now) usage.
    * New script memory.sh helps measuring the ROM and RAM requirements of two
      reduced configurations (PSK-CCM and NSA suite B).
-   * Add config flags POLARSSL_DEPRECATED_WARNING (off by default) to produce
+   * Add config flag POLARSSL_DEPRECATED_WARNING (off by default) to produce
      warnings on use of deprecated functions (with GCC and Clang only).
-   * Add config flags POLARSSL_DEPRECATED_REMOVED (off by default) to produce
+   * Add config flag POLARSSL_DEPRECATED_REMOVED (off by default) to produce
      errors on use of deprecated functions.
 
 Bugfix
+   * Fix memory leak when gcm_setkey() and ccm_setkey() are used more than
+     once on the same context.
+   * Fix bug in ssl_mail_client when password is longer that username (found
+     by Bruno Pape).
+   * Fix undefined behaviour (memcmp( NULL, NULL, 0 );) in X.509 modules
+     (detected by Clang's 3.6 UBSan).
+   * mpi_size() and mpi_msb() would segfault when called on an mpi that is
+     initialized but not set (found by pravic).
+   * Fix detection of support for getrandom() on Linux (reported by syzzer) by
+     doing it at runtime (using uname) rather that compile time.
+   * Fix handling of symlinks by "make install" (found by Gaël PORTAY).
+   * Fix potential NULL pointer dereference (not trigerrable remotely) when
+     ssl_write() is called before the handshake is finished (introduced in
+     1.3.10) (first reported by Martin Blumenstingl).
+   * Fix bug in pk_parse_key() that caused some valid private EC keys to be
+     rejected.
    * Fix bug in Via Padlock support (found by Nikos Mavrogiannopoulos).
    * Fix thread safety bug in RSA operations (found by Fredrik Axelsson).
    * Fix hardclock() (only used in the benchmarking program) with some
@@ -39,12 +65,20 @@
    * Add missing extern "C" guard in aesni.h (reported by amir zamani).
    * Add missing dependency on SHA-256 in some x509 programs (reported by
      Gergely Budai).
+   * Fix bug related to ssl_set_curves(): the client didn't check that the
+     curve picked by the server was actually allowed.
 
 Changes
-   * Adjusting/overriding CFLAGS and LDFLAGS with the make build syste is now
+   * Remove bias in mpi_gen_prime (contributed by Pascal Junod).
+   * Remove potential sources of timing variations (some contributed by Pascal
+     Junod).
+   * Options POLARSSL_HAVE_INT8 and POLARSSL_HAVE_INT16 are deprecated.
+   * Enabling POLARSSL_NET_C without POLARSSL_HAVE_IPV6 is deprecated.
+   * compat-1.2.h and openssl.h are deprecated.
+   * Adjusting/overriding CFLAGS and LDFLAGS with the make build system is now
      more flexible (warning: OFLAGS is not used any more) (see the README)
      (contributed by Alon Bar-Lev).
-   * ssl_set_own_cert() now longers calls pk_check_pair() since the
+   * ssl_set_own_cert() no longer calls pk_check_pair() since the
      performance impact was bad for some users (this was introduced in 1.3.10).
    * Move from SHA-1 to SHA-256 in example programs using signatures
      (suggested by Thorsten Mühlfelder).
@@ -83,7 +117,7 @@
      length of an X.509 verification chain.
    * Support for renegotiation can now be disabled at compile-time
    * Support for 1/n-1 record splitting, a countermeasure against BEAST.
-   * Certificate selection based on signature hash, prefering SHA-1 over SHA-2
+   * Certificate selection based on signature hash, preferring SHA-1 over SHA-2
      for pre-1.2 clients when multiple certificates are available.
    * Add support for getrandom() syscall on recent Linux kernels with Glibc or
      a compatible enough libc (eg uClibc).
@@ -558,6 +592,67 @@
    * RSA blinding on CRT operations to counter timing attacks
      (found by Cyril Arnaud and Pierre-Alain Fouque)
 
+
+= Version 1.2.14 released 2015-05-??
+
+Security
+   * Fix potential invalid memory read in the server, that allows a client to
+     crash it remotely (found by Caj Larsson).
+   * Fix potential invalid memory read in certificate parsing, that allows a
+     client to crash the server remotely if client authentication is enabled
+     (found using Codenomicon Defensics).
+   * Add countermeasure against "Lucky 13 strikes back" cache-based attack,
+     https://dl.acm.org/citation.cfm?id=2714625
+
+Bugfix
+   * Fix bug in Via Padlock support (found by Nikos Mavrogiannopoulos).
+   * Fix hardclock() (only used in the benchmarking program) with some
+     versions of mingw64 (found by kxjhlele).
+   * Fix warnings from mingw64 in timing.c (found by kxjklele).
+   * Fix potential unintended sign extension in asn1_get_len() on 64-bit
+     platforms (found with Coverity Scan).
+
+= Version 1.2.13 released 2015-02-16
+Note: Although PolarSSL has been renamed to mbed TLS, no changes reflecting
+      this will be made in the 1.2 branch at this point.
+
+Security
+   * Fix remotely-triggerable uninitialised pointer dereference caused by
+     crafted X.509 certificate (TLS server is not affected if it doesn't ask
+     for a client certificate) (found using Codenomicon Defensics).
+   * Fix remotely-triggerable memory leak caused by crafted X.509 certificates
+     (TLS server is not affected if it doesn't ask for a client certificate)
+     (found using Codenomicon Defensics).
+   * Fix potential stack overflow while parsing crafted X.509 certificates
+     (TLS server is not affected if it doesn't ask for a client certificate)
+     found using Codenomicon Defensics).
+   * Fix buffer overread of size 1 when parsing crafted X.509 certificates
+     (TLS server is not affected if it doesn't ask for a client certificate).
+
+Bugfix
+   * Fix potential undefined behaviour in Camellia.
+   * Fix memory leaks in PKCS#5 and PKCS#12.
+   * Stack buffer overflow if ctr_drbg_update() is called with too large
+     add_len (found by Jean-Philippe Aumasson) (not triggerable remotely).
+   * Fix bug in MPI/bignum on s390/s390x (reported by Dan Horák) (introduced
+     in 1.2.12).
+   * Fix unchecked return code in x509_crt_parse_path() on Windows (found by
+     Peter Vaskovic).
+   * Fix assembly selection for MIPS64 (thanks to James Cowgill).
+   * ssl_get_verify_result() now works even if the handshake was aborted due
+     to a failed verification (found by Fredrik Axelsson).
+   * Skip writing and parsing signature_algorithm extension if none of the
+     key exchanges enabled needs certificates. This fixes a possible interop
+     issue with some servers when a zero-length extension was sent. (Reported
+     by Peter Dettman.)
+   * On a 0-length input, base64_encode() did not correctly set output length
+     (found by Hendrik van den Boogaard).
+
+Changes
+   * Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined.
+   * Forbid repeated extensions in X.509 certificates.
+   * Add compile-time option POLARSSL_X509_MAX_INTERMEDIATE_CA to limit the
+     length of an X.509 verification chain (default = 8).
 = Version 1.2.12 released 2014-10-24
 
 Security
diff --git a/Makefile b/Makefile
index f9a4ce2..441d1f9 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@
 	cp -r include/polarssl $(DESTDIR)/include
 	
 	mkdir -p $(DESTDIR)/lib
-	cp library/libpolarssl.* library/libmbedtls.* $(DESTDIR)/lib
+	cp -RP library/libpolarssl.* library/libmbedtls.* $(DESTDIR)/lib
 	
 	mkdir -p $(DESTDIR)/bin
 	for p in programs/*/* ; do              \
diff --git a/README.rst b/README.rst
index ae335f8..59ca2c6 100644
--- a/README.rst
+++ b/README.rst
@@ -68,7 +68,7 @@
 - ASanDbg.
   Same as ASan but slower, with debug information and better stack traces.
 - MemSan.
-  This intruments the code with MemorySanitizer to check for uninitialised
+  This instruments the code with MemorySanitizer to check for uninitialised
   memory reads. Experimental, needs recent clang on Linux/x86_64.
 - MemSanDbg.
   Same as ASan but slower, with debug information, better stack traces and
diff --git a/configs/config-ccm-psk-tls1_2.h b/configs/config-ccm-psk-tls1_2.h
index 776179d..4a3ebb1 100644
--- a/configs/config-ccm-psk-tls1_2.h
+++ b/configs/config-ccm-psk-tls1_2.h
@@ -12,7 +12,7 @@
 #define POLARSSL_CONFIG_H
 
 /* System support */
-//#define POLARSSL_HAVE_IPV6 /* Optional */
+#define POLARSSL_HAVE_IPV6 /* Now mandatory for NET_C */
 //#define POLARSSL_HAVE_TIME /* Optionally used in Hello messages */
 /* Other POLARSSL_HAVE_XXX flags irrelevant for this configuration */
 
diff --git a/configs/config-psk-rc4-tls1_0.h b/configs/config-psk-rc4-tls1_0.h
index b8113ea..2f557c1 100644
--- a/configs/config-psk-rc4-tls1_0.h
+++ b/configs/config-psk-rc4-tls1_0.h
@@ -12,7 +12,7 @@
 #define POLARSSL_CONFIG_H
 
 /* System support */
-//#define POLARSSL_HAVE_IPV6 /* Optional */
+#define POLARSSL_HAVE_IPV6 /* Now mandatory for NET_C */
 //#define POLARSSL_HAVE_TIME /* Optionnaly used in Hello messages */
 /* Other POLARSSL_HAVE_XXX flags irrelevant for this configuration */
 
diff --git a/include/polarssl/bignum.h b/include/polarssl/bignum.h
index df25bd1..8e1687b 100644
--- a/include/polarssl/bignum.h
+++ b/include/polarssl/bignum.h
@@ -188,7 +188,9 @@
 mpi;
 
 /**
- * \brief           Initialize one MPI
+ * \brief           Initialize one MPI (make internal references valid)
+ *                  This just makes it ready to be set or freed,
+ *                  but does not define a value for the MPI.
  *
  * \param X         One MPI to initialize.
  */
diff --git a/include/polarssl/check_config.h b/include/polarssl/check_config.h
index a255874..f0d83c8 100644
--- a/include/polarssl/check_config.h
+++ b/include/polarssl/check_config.h
@@ -35,6 +35,15 @@
 #error "POLARSSL_DEPRECATED_WARNING only works with GCC and Clang"
 #endif
 
+#if defined(POLARSSL_NET_C) && !defined(POLARSSL_HAVE_IPV6)
+#if defined(POLARSSL_DEPRECATED_WARNING)
+#warning "Using POLARSSL_NET_C without POLARSSL_HAVE_IPV6 is deprecated"
+#endif
+#if defined(POLARSSL_DEPRECATED_REMOVED)
+#define POLARSSL_HAVE_IPV6
+#endif
+#endif /* POLARSSL_NET_C && !POLARSSL_HAVE_IPV6 */
+
 #if defined(POLARSSL_AESNI_C) && !defined(POLARSSL_HAVE_ASM)
 #error "POLARSSL_AESNI_C defined, but not all prerequisites"
 #endif
diff --git a/include/polarssl/compat-1.2.h b/include/polarssl/compat-1.2.h
index ca9a8e0..d694015 100644
--- a/include/polarssl/compat-1.2.h
+++ b/include/polarssl/compat-1.2.h
@@ -23,6 +23,12 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+#if ! defined(POLARSSL_DEPRECATED_REMOVED)
+
+#if defined(POLARSSL_DEPRECATED_WARNING)
+#warning "Including compat-1.2.h is deprecated"
+#endif
+
 #ifndef POLARSSL_COMPAT_1_2_H
 #define POLARSSL_COMPAT_1_2_H
 
@@ -386,3 +392,4 @@
 }
 #endif /* POLARSSL_PK_WRITE_C && POLARSSL_RSA_C */
 #endif /* compat-1.2.h */
+#endif /* POLARSSL_DEPRECATED_REMOVED */
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 63db5ee..6bfa705 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -44,6 +44,10 @@
  *
  * The system uses 8-bit wide native integers.
  *
+ * \deprecated The compiler should be able to generate code for 32-bit
+ * arithmetic (required by C89). This code is likely to be at least as
+ * efficient as ours.
+ *
  * Uncomment if native integers are 8-bit wide.
  */
 //#define POLARSSL_HAVE_INT8
@@ -53,6 +57,10 @@
  *
  * The system uses 16-bit wide native integers.
  *
+ * \deprecated The compiler should be able to generate code for 32-bit
+ * arithmetic (required by C89). This code is likely to be at least as
+ * efficient as ours.
+ *
  * Uncomment if native integers are 16-bit wide.
  */
 //#define POLARSSL_HAVE_INT16
@@ -107,6 +115,9 @@
  *
  * Note: on Windows/MingW, XP or higher is required.
  *
+ * \warning As of 1.3.11, *not* using this flag when POLARSSL_NET_C is
+ * defined, is deprecated. The alternative legacy code will be removed in 2.0.
+ *
  * Comment if your system does not support the IPv6 socket interface
  */
 #define POLARSSL_HAVE_IPV6
@@ -266,11 +277,19 @@
  * Store the AES tables in ROM.
  *
  * Uncomment this macro to store the AES tables in ROM.
- *
  */
 //#define POLARSSL_AES_ROM_TABLES
 
 /**
+ * \def POLARSSL_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define POLARSSL_CAMELLIA_SMALL_MEMORY
+
+/**
  * \def POLARSSL_CIPHER_MODE_CBC
  *
  * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
@@ -1749,6 +1768,9 @@
  *
  * Enable the TCP/IP networking routines.
  *
+ * \warning As of 1.3.11, it is deprecated to enable this module without
+ * POLARSSL_HAVE_IPV6. The alternative legacy code will be removed in 2.0.
+ *
  * Module:  library/net.c
  *
  * This module provides TCP/IP networking routines.
diff --git a/include/polarssl/ecdsa.h b/include/polarssl/ecdsa.h
index 9a04ee6..5eb83d9 100644
--- a/include/polarssl/ecdsa.h
+++ b/include/polarssl/ecdsa.h
@@ -25,10 +25,7 @@
 #define POLARSSL_ECDSA_H
 
 #include "ecp.h"
-
-#if defined(POLARSSL_ECDSA_DETERMINISTIC)
 #include "md.h"
-#endif
 
 /**
  * \brief           ECDSA context structure
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index eef445f..094a840 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -412,7 +412,7 @@
  *
  * \note            buf is updated to point right after the ECPoint on exit
  *
- * \return          O if successful,
+ * \return          0 if successful,
  *                  POLARSSL_ERR_MPI_XXX if initialization failed
  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
  */
@@ -462,7 +462,7 @@
  * \param grp       Destination group
  * \param index     Index in the list of well-known domain parameters
  *
- * \return          O if successful,
+ * \return          0 if successful,
  *                  POLARSSL_ERR_MPI_XXX if initialization failed
  *                  POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
  *
@@ -480,7 +480,7 @@
  *
  * \note            buf is updated to point right after ECParameters on exit
  *
- * \return          O if successful,
+ * \return          0 if successful,
  *                  POLARSSL_ERR_MPI_XXX if initialization failed
  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
  */
@@ -642,7 +642,7 @@
  * \param pub       Keypair structure holding a public key
  * \param prv       Keypair structure holding a private (plus public) key
  *
- * \return          0 if successfull (keys are valid and match), or
+ * \return          0 if successful (keys are valid and match), or
  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA, or
  *                  a POLARSSL_ERR_ECP_XXX or POLARSSL_ERR_MPI_XXX code.
  */
diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h
index 31a7d2b..11330f2 100644
--- a/include/polarssl/oid.h
+++ b/include/polarssl/oid.h
@@ -396,7 +396,7 @@
  * \param oid       OID to translate
  *
  * \return          Length of the string written (excluding final NULL) or
- *                  POLARSSL_ERR_OID_BUF_TO_SMALL in case of error
+ *                  POLARSSL_ERR_OID_BUF_TOO_SMALL in case of error
  */
 int oid_get_numeric_string( char *buf, size_t size, const asn1_buf *oid );
 
diff --git a/include/polarssl/openssl.h b/include/polarssl/openssl.h
index dc0eba4..233a093 100644
--- a/include/polarssl/openssl.h
+++ b/include/polarssl/openssl.h
@@ -23,9 +23,17 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+
 /*
  * OpenSSL wrapper contributed by David Barett
  */
+
+#if ! defined(POLARSSL_DEPRECATED_REMOVED)
+
+#if defined(POLARSSL_DEPRECATED_WARNING)
+#warning "Including openssl.h is deprecated"
+#endif
+
 #ifndef POLARSSL_OPENSSL_H
 #define POLARSSL_OPENSSL_H
 
@@ -137,3 +145,4 @@
 #endif
 
 #endif /* openssl.h */
+#endif /* POLARSSL_DEPRECATED_REMOVED */
diff --git a/include/polarssl/platform.h b/include/polarssl/platform.h
index 32d1c9f..9095203 100644
--- a/include/polarssl/platform.h
+++ b/include/polarssl/platform.h
@@ -30,7 +30,7 @@
 #include POLARSSL_CONFIG_FILE
 #endif
 
-/* Temporary compability hack for to keep MEMORY_C working */
+/* Temporary compatibility hack for to keep MEMORY_C working */
 #if defined(POLARSSL_MEMORY_C) && !defined(POLARSSL_PLATFORM_MEMORY)
 #define POLARSSL_PLATFORM_MEMORY
 #endif
diff --git a/include/polarssl/rsa.h b/include/polarssl/rsa.h
index 21109ed..b1354d1 100644
--- a/include/polarssl/rsa.h
+++ b/include/polarssl/rsa.h
@@ -43,7 +43,7 @@
 #define POLARSSL_ERR_RSA_BAD_INPUT_DATA                    -0x4080  /**< Bad input parameters to function. */
 #define POLARSSL_ERR_RSA_INVALID_PADDING                   -0x4100  /**< Input data contains invalid padding and is rejected. */
 #define POLARSSL_ERR_RSA_KEY_GEN_FAILED                    -0x4180  /**< Something failed during generation of a key. */
-#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED                  -0x4200  /**< Key failed to pass the libraries validity check. */
+#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED                  -0x4200  /**< Key failed to pass the library's validity check. */
 #define POLARSSL_ERR_RSA_PUBLIC_FAILED                     -0x4280  /**< The public key operation failed. */
 #define POLARSSL_ERR_RSA_PRIVATE_FAILED                    -0x4300  /**< The private key operation failed. */
 #define POLARSSL_ERR_RSA_VERIFY_FAILED                     -0x4380  /**< The PKCS#1 verification failed. */
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index cd9f770..730594a 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1154,6 +1154,9 @@
  *                      order. First in the list has the highest preference.
  *                      (Overrides all version specific lists)
  *
+ *                      The ciphersuites array is not copied, and must remain
+ *                      valid for the lifetime of the ssl_context.
+ *
  *                      Note: The server uses its own preferences
  *                      over the preference of the client unless
  *                      POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined!
@@ -1540,7 +1543,7 @@
  *                 SSL_MAX_FRAG_LEN_512,  SSL_MAX_FRAG_LEN_1024,
  *                 SSL_MAX_FRAG_LEN_2048, SSL_MAX_FRAG_LEN_4096)
  *
- * \return         O if successful or POLARSSL_ERR_SSL_BAD_INPUT_DATA
+ * \return         0 if successful or POLARSSL_ERR_SSL_BAD_INPUT_DATA
  */
 int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code );
 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
@@ -1589,7 +1592,7 @@
  * \param use_tickets   Enable or disable (SSL_SESSION_TICKETS_ENABLED or
  *                                         SSL_SESSION_TICKETS_DISABLED)
  *
- * \return         O if successful,
+ * \return         0 if successful,
  *                 or a specific error code (server only).
  */
 int ssl_set_session_tickets( ssl_context *ssl, int use_tickets );
@@ -1980,7 +1983,8 @@
  */
 int ssl_check_cert_usage( const x509_crt *cert,
                           const ssl_ciphersuite_t *ciphersuite,
-                          int cert_endpoint );
+                          int cert_endpoint,
+                          int *flags );
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
 /* constant-time buffer comparison */
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index 0dece06..cd01539 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -82,17 +82,21 @@
  * \name X509 Verify codes
  * \{
  */
+/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */
 #define BADCERT_EXPIRED             0x01  /**< The certificate validity has expired. */
 #define BADCERT_REVOKED             0x02  /**< The certificate has been revoked (is on a CRL). */
 #define BADCERT_CN_MISMATCH         0x04  /**< The certificate Common Name (CN) does not match with the expected CN. */
 #define BADCERT_NOT_TRUSTED         0x08  /**< The certificate is not correctly signed by the trusted CA. */
-#define BADCRL_NOT_TRUSTED          0x10  /**< CRL is not correctly signed by the trusted CA. */
-#define BADCRL_EXPIRED              0x20  /**< CRL is expired. */
+#define BADCRL_NOT_TRUSTED          0x10  /**< The CRL is not correctly signed by the trusted CA. */
+#define BADCRL_EXPIRED              0x20  /**< The CRL is expired. */
 #define BADCERT_MISSING             0x40  /**< Certificate was missing. */
 #define BADCERT_SKIP_VERIFY         0x80  /**< Certificate verification was skipped. */
 #define BADCERT_OTHER             0x0100  /**< Other reason (can be used by verify callback) */
 #define BADCERT_FUTURE            0x0200  /**< The certificate validity starts in the future. */
 #define BADCRL_FUTURE             0x0400  /**< The CRL is from the future */
+#define BADCERT_KEY_USAGE         0x0800  /**< Usage does not match the keyUsage extension. */
+#define BADCERT_EXT_KEY_USAGE     0x1000  /**< Usage does not match the extendedKeyUsage extension. */
+#define BADCERT_NS_CERT_TYPE      0x2000  /**< Usage does not match the nsCertType extension. */
 /* \} name */
 /* \} addtogroup x509_module */
 
diff --git a/include/polarssl/x509_crt.h b/include/polarssl/x509_crt.h
index fe27007..24f7c7a 100644
--- a/include/polarssl/x509_crt.h
+++ b/include/polarssl/x509_crt.h
@@ -203,6 +203,21 @@
                    const x509_crt *crt );
 
 /**
+ * \brief          Returns an informational string about the
+ *                 verification status of a certificate.
+ *
+ * \param buf      Buffer to write to
+ * \param size     Maximum size of buffer
+ * \param prefix   A line prefix
+ * \param flags    Verification flags created by x509_crt_verify()
+ *
+ * \return         The amount of data written to the buffer, or -1 in
+ *                 case of an error.
+ */
+int x509_crt_verify_info( char *buf, size_t size, const char *prefix,
+                          int flags );
+
+/**
  * \brief          Verify the certificate signature
  *
  *                 The verify callback is a user-supplied callback that
@@ -219,6 +234,9 @@
  *                 are also returned to the application. The function should
  *                 return 0 for anything but a fatal error.
  *
+ * \note           In case verification failed, the results can be displayed
+ *                 using \c x509_crt_verify_info()
+ *
  * \param crt      a certificate to be verified
  * \param trust_ca the trusted CA chain
  * \param ca_crl   the CRL chain for trusted CA's
@@ -229,12 +247,8 @@
  * \param p_vrfy   verification parameter
  *
  * \return         0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
- *                 in which case *flags will have one or more of
- *                 the following values set:
- *                      BADCERT_EXPIRED --
- *                      BADCERT_REVOKED --
- *                      BADCERT_CN_MISMATCH --
- *                      BADCERT_NOT_TRUSTED
+ *                 in which case *flags will have one or more BADCERT_XXX or
+ *                 BADCRL_XXX flags set,
  *                 or another error in case of a fatal error encountered
  *                 during the verification process.
  */
diff --git a/library/bignum.c b/library/bignum.c
index da70ae0..f479bc9 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -223,8 +223,8 @@
     int ret = 0;
     size_t i;
 
-    /* make sure assign is 0 or 1 */
-    assign = ( assign != 0 );
+    /* make sure assign is 0 or 1 in a time-constant manner */
+    assign = (assign | (unsigned char)-assign) >> 7;
 
     MPI_CHK( mpi_grow( X, Y->n ) );
 
@@ -255,8 +255,8 @@
     if( X == Y )
         return( 0 );
 
-    /* make sure swap is 0 or 1 */
-    swap = ( swap != 0 );
+    /* make sure swap is 0 or 1 in a time-constant manner */
+    swap = (swap | (unsigned char)-swap) >> 7;
 
     MPI_CHK( mpi_grow( X, Y->n ) );
     MPI_CHK( mpi_grow( Y, X->n ) );
@@ -356,6 +356,9 @@
 {
     size_t i, j;
 
+    if( X->n == 0 )
+        return( 0 );
+
     for( i = X->n - 1; i > 0; i-- )
         if( X->p[i] != 0 )
             break;
@@ -1958,8 +1961,8 @@
                              int (*f_rng)(void *, unsigned char *, size_t),
                              void *p_rng )
 {
-    int ret;
-    size_t i, j, n, s;
+    int ret, count;
+    size_t i, j, k, n, s;
     mpi W, R, T, A, RR;
 
     mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
@@ -1987,14 +1990,23 @@
         /*
          * pick a random A, 1 < A < |X| - 1
          */
-        MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
 
-        if( mpi_cmp_mpi( &A, &W ) >= 0 )
-        {
-            j = mpi_msb( &A ) - mpi_msb( &W );
-            MPI_CHK( mpi_shift_r( &A, j + 1 ) );
-        }
-        A.p[0] |= 3;
+        count = 0;
+        do {
+            MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
+
+            j = mpi_msb( &A );
+            k = mpi_msb( &W );
+            if (j > k) {
+                MPI_CHK( mpi_shift_r( &A, j - k ) );
+            }
+
+            if (count++ > 30) {
+                return POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
+            }
+
+        } while ( (mpi_cmp_mpi( &A, &W ) >= 0) ||
+                  (mpi_cmp_int( &A, 1 )  <= 0)    );
 
         /*
          * A = A^R mod |X|
@@ -2092,10 +2104,11 @@
     MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
 
     k = mpi_msb( X );
-    if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
-    if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
+    if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits + 1 ) );
 
-    X->p[0] |= 3;
+    mpi_set_bit( X, nbits-1, 1 );
+
+    X->p[0] |= 1;
 
     if( dh_flag == 0 )
     {
@@ -2114,6 +2127,9 @@
          * 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;
+
         MPI_CHK( mpi_mod_int( &r, X, 3 ) );
         if( r == 0 )
             MPI_CHK( mpi_add_int( X, X, 8 ) );
diff --git a/library/ccm.c b/library/ccm.c
index 87f1886..e397e0a 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -78,6 +78,8 @@
     if( cipher_info->block_size != 16 )
         return( POLARSSL_ERR_CCM_BAD_INPUT );
 
+    cipher_free( &ctx->cipher_ctx );
+
     if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
         return( ret );
 
diff --git a/library/dhm.c b/library/dhm.c
index 9fb7a21..0a4f820 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -444,8 +444,9 @@
 
     /*
      *  DHParams ::= SEQUENCE {
-     *      prime            INTEGER,  -- P
-     *      generator        INTEGER,  -- g
+     *      prime              INTEGER,  -- P
+     *      generator          INTEGER,  -- g
+     *      privateValueLength INTEGER OPTIONAL
      *  }
      */
     if( ( ret = asn1_get_tag( &p, end, &len,
@@ -466,9 +467,23 @@
 
     if( p != end )
     {
-        ret = POLARSSL_ERR_DHM_INVALID_FORMAT +
-              POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
-        goto exit;
+        /* this might be the optional privateValueLength; If so, we
+         can cleanly discard it; */
+        mpi rec;
+        mpi_init( &rec );
+        ret = asn1_get_mpi( &p, end, &rec );
+        mpi_free( &rec );
+        if ( ret != 0 )
+        {
+            ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret;
+            goto exit;
+        }
+        if ( p != end )
+        {
+            ret = POLARSSL_ERR_DHM_INVALID_FORMAT +
+                POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
+            goto exit;
+        }
     }
 
     ret = 0;
diff --git a/library/ecp.c b/library/ecp.c
index be6b0d5..adef09e 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -911,70 +911,86 @@
 /*
  * Point doubling R = 2 P, Jacobian coordinates
  *
- * http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian/doubling/dbl-2007-bl.op3
- * with heavy variable renaming, some reordering and one minor modification
- * (a = 2 * b, c = d - 2a replaced with c = d, c = c - b, c = c - b)
- * in order to use a lot less intermediate variables (6 vs 25).
+ * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 .
  *
- * Cost: 1D := 2M + 8S
+ * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR
+ * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
+ *
+ * Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
+ *
+ * Cost: 1D := 3M + 4S          (A ==  0)
+ *             4M + 4S          (A == -3)
+ *             3M + 6S + 1a     otherwise
  */
 static int ecp_double_jac( const ecp_group *grp, ecp_point *R,
                            const ecp_point *P )
 {
     int ret;
-    mpi T1, T2, T3, X3, Y3, Z3;
+    mpi M, S, T, U;
 
 #if defined(POLARSSL_SELF_TEST)
     dbl_count++;
 #endif
 
-    mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 );
-    mpi_init( &X3 ); mpi_init( &Y3 ); mpi_init( &Z3 );
-
-    MPI_CHK( mpi_mul_mpi( &T3,  &P->X,  &P->X   ) ); MOD_MUL( T3 );
-    MPI_CHK( mpi_mul_mpi( &T2,  &P->Y,  &P->Y   ) ); MOD_MUL( T2 );
-    MPI_CHK( mpi_mul_mpi( &Y3,  &T2,    &T2     ) ); MOD_MUL( Y3 );
-    MPI_CHK( mpi_add_mpi( &X3,  &P->X,  &T2     ) ); MOD_ADD( X3 );
-    MPI_CHK( mpi_mul_mpi( &X3,  &X3,    &X3     ) ); MOD_MUL( X3 );
-    MPI_CHK( mpi_sub_mpi( &X3,  &X3,    &Y3     ) ); MOD_SUB( X3 );
-    MPI_CHK( mpi_sub_mpi( &X3,  &X3,    &T3     ) ); MOD_SUB( X3 );
-    MPI_CHK( mpi_mul_int( &T1,  &X3,    2       ) ); MOD_ADD( T1 );
-    MPI_CHK( mpi_mul_mpi( &Z3,  &P->Z,  &P->Z   ) ); MOD_MUL( Z3 );
-    MPI_CHK( mpi_mul_mpi( &X3,  &Z3,    &Z3     ) ); MOD_MUL( X3 );
-    MPI_CHK( mpi_mul_int( &T3,  &T3,    3       ) ); MOD_ADD( T3 );
+    mpi_init( &M ); mpi_init( &S ); mpi_init( &T ); mpi_init( &U );
 
     /* Special case for A = -3 */
     if( grp->A.p == NULL )
     {
-        MPI_CHK( mpi_mul_int( &X3, &X3, 3 ) );
-        X3.s = -1; /* mpi_mul_int doesn't handle negative numbers */
-        MOD_SUB( X3 );
+        /* M = 3(X + Z^2)(X - Z^2) */
+        MPI_CHK( mpi_mul_mpi( &S,  &P->Z,  &P->Z   ) ); MOD_MUL( S );
+        MPI_CHK( mpi_add_mpi( &T,  &P->X,  &S      ) ); MOD_ADD( T );
+        MPI_CHK( mpi_sub_mpi( &U,  &P->X,  &S      ) ); MOD_SUB( U );
+        MPI_CHK( mpi_mul_mpi( &S,  &T,     &U      ) ); MOD_MUL( S );
+        MPI_CHK( mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
     }
     else
     {
-        MPI_CHK( mpi_mul_mpi( &X3,  &X3,    &grp->A ) ); MOD_MUL( X3 );
+        /* M = 3.X^2 */
+        MPI_CHK( mpi_mul_mpi( &S,  &P->X,  &P->X   ) ); MOD_MUL( S );
+        MPI_CHK( mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
+
+        /* Optimize away for "koblitz" curves with A = 0 */
+        if( mpi_cmp_int( &grp->A, 0 ) != 0 )
+        {
+            /* M += A.Z^4 */
+            MPI_CHK( mpi_mul_mpi( &S,  &P->Z,  &P->Z   ) ); MOD_MUL( S );
+            MPI_CHK( mpi_mul_mpi( &T,  &S,     &S      ) ); MOD_MUL( T );
+            MPI_CHK( mpi_mul_mpi( &S,  &T,     &grp->A ) ); MOD_MUL( S );
+            MPI_CHK( mpi_add_mpi( &M,  &M,     &S      ) ); MOD_ADD( M );
+        }
     }
 
-    MPI_CHK( mpi_add_mpi( &T3,  &T3,    &X3     ) ); MOD_ADD( T3 );
-    MPI_CHK( mpi_mul_mpi( &X3,  &T3,    &T3     ) ); MOD_MUL( X3 );
-    MPI_CHK( mpi_sub_mpi( &X3,  &X3,    &T1     ) ); MOD_SUB( X3 );
-    MPI_CHK( mpi_sub_mpi( &X3,  &X3,    &T1     ) ); MOD_SUB( X3 );
-    MPI_CHK( mpi_sub_mpi( &T1,  &T1,    &X3     ) ); MOD_SUB( T1 );
-    MPI_CHK( mpi_mul_mpi( &T1,  &T3,    &T1     ) ); MOD_MUL( T1 );
-    MPI_CHK( mpi_mul_int( &T3,  &Y3,    8       ) ); MOD_ADD( T3 );
-    MPI_CHK( mpi_sub_mpi( &Y3,  &T1,    &T3     ) ); MOD_SUB( Y3 );
-    MPI_CHK( mpi_add_mpi( &T1,  &P->Y,  &P->Z   ) ); MOD_ADD( T1 );
-    MPI_CHK( mpi_mul_mpi( &T1,  &T1,    &T1     ) ); MOD_MUL( T1 );
-    MPI_CHK( mpi_sub_mpi( &T1,  &T1,    &T2     ) ); MOD_SUB( T1 );
-    MPI_CHK( mpi_sub_mpi( &Z3,  &T1,    &Z3     ) ); MOD_SUB( Z3 );
+    /* S = 4.X.Y^2 */
+    MPI_CHK( mpi_mul_mpi( &T,  &P->Y,  &P->Y   ) ); MOD_MUL( T );
+    MPI_CHK( mpi_shift_l( &T,  1               ) ); MOD_ADD( T );
+    MPI_CHK( mpi_mul_mpi( &S,  &P->X,  &T      ) ); MOD_MUL( S );
+    MPI_CHK( mpi_shift_l( &S,  1               ) ); MOD_ADD( S );
 
-    MPI_CHK( mpi_copy( &R->X, &X3 ) );
-    MPI_CHK( mpi_copy( &R->Y, &Y3 ) );
-    MPI_CHK( mpi_copy( &R->Z, &Z3 ) );
+    /* U = 8.Y^4 */
+    MPI_CHK( mpi_mul_mpi( &U,  &T,     &T      ) ); MOD_MUL( U );
+    MPI_CHK( mpi_shift_l( &U,  1               ) ); MOD_ADD( U );
+
+    /* T = M^2 - 2.S */
+    MPI_CHK( mpi_mul_mpi( &T,  &M,     &M      ) ); MOD_MUL( T );
+    MPI_CHK( mpi_sub_mpi( &T,  &T,     &S      ) ); MOD_SUB( T );
+    MPI_CHK( mpi_sub_mpi( &T,  &T,     &S      ) ); MOD_SUB( T );
+
+    /* S = M(S - T) - U */
+    MPI_CHK( mpi_sub_mpi( &S,  &S,     &T      ) ); MOD_SUB( S );
+    MPI_CHK( mpi_mul_mpi( &S,  &S,     &M      ) ); MOD_MUL( S );
+    MPI_CHK( mpi_sub_mpi( &S,  &S,     &U      ) ); MOD_SUB( S );
+
+    /* U = 2.Y.Z */
+    MPI_CHK( mpi_mul_mpi( &U,  &P->Y,  &P->Z   ) ); MOD_MUL( U );
+    MPI_CHK( mpi_shift_l( &U,  1               ) ); MOD_ADD( U );
+
+    MPI_CHK( mpi_copy( &R->X, &T ) );
+    MPI_CHK( mpi_copy( &R->Y, &S ) );
+    MPI_CHK( mpi_copy( &R->Z, &U ) );
 
 cleanup:
-    mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 );
-    mpi_free( &X3 ); mpi_free( &Y3 ); mpi_free( &Z3 );
+    mpi_free( &M ); mpi_free( &S ); mpi_free( &T ); mpi_free( &U );
 
     return( ret );
 }
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 61eb3e7..e0f9ae2 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -86,27 +86,46 @@
 {
     return( syscall( SYS_getrandom, buf, buflen, flags ) );
 }
-#endif /* SYS_getrandom */
-#endif /* __linux__ */
 
-#if defined(HAVE_GETRANDOM)
-
-#include <errno.h>
-
-int platform_entropy_poll( void *data,
-                           unsigned char *output, size_t len, size_t *olen )
+#include <sys/utsname.h>
+/* Check if version is at least 3.17.0 */
+static int check_version_3_17_plus( void )
 {
-    int ret;
-    ((void) data);
+    int minor;
+    struct utsname un;
+    const char *ver;
 
-    if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
-        return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
+    /* Get version information */
+    uname(&un);
+    ver = un.release;
 
-    *olen = ret;
+    /* Check major version; assume a single digit */
+    if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
+        return( -1 );
+
+    if( ver[0] - '0' > 3 )
+        return( 0 );
+
+    /* Ok, so now we know major == 3, check minor.
+     * Assume 1 or 2 digits. */
+    if( ver[2] < '0' || ver[2] > '9' )
+        return( -1 );
+
+    minor = ver[2] - '0';
+
+    if( ver[3] >= '0' && ver[3] <= '9' )
+        minor = 10 * minor + ver[3] - '0';
+    else if( ver [3] != '.' )
+        return( -1 );
+
+    if( minor < 17 )
+        return( -1 );
+
     return( 0 );
 }
-
-#else /* HAVE_GETRANDOM */
+static int has_getrandom = -1;
+#endif /* SYS_getrandom */
+#endif /* __linux__ */
 
 #include <stdio.h>
 
@@ -117,6 +136,22 @@
     size_t ret;
     ((void) data);
 
+#if defined(HAVE_GETRANDOM)
+    if( has_getrandom == -1 )
+        has_getrandom = ( check_version_3_17_plus() == 0 );
+
+    if( has_getrandom )
+    {
+        int ret;
+
+        if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
+            return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
+
+        *olen = ret;
+        return( 0 );
+    }
+#endif /* HAVE_GETRANDOM */
+
     *olen = 0;
 
     file = fopen( "/dev/urandom", "rb" );
@@ -135,7 +170,6 @@
 
     return( 0 );
 }
-#endif /* HAVE_GETRANDOM */
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 #endif /* !POLARSSL_NO_PLATFORM_ENTROPY */
 
diff --git a/library/error.c b/library/error.c
index 4d7b81c..98fba5c 100644
--- a/library/error.c
+++ b/library/error.c
@@ -356,7 +356,7 @@
         if( use_ret == -(POLARSSL_ERR_RSA_KEY_GEN_FAILED) )
             polarssl_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
         if( use_ret == -(POLARSSL_ERR_RSA_KEY_CHECK_FAILED) )
-            polarssl_snprintf( buf, buflen, "RSA - Key failed to pass the libraries validity check" );
+            polarssl_snprintf( buf, buflen, "RSA - Key failed to pass the library's validity check" );
         if( use_ret == -(POLARSSL_ERR_RSA_PUBLIC_FAILED) )
             polarssl_snprintf( buf, buflen, "RSA - The public key operation failed" );
         if( use_ret == -(POLARSSL_ERR_RSA_PRIVATE_FAILED) )
diff --git a/library/gcm.c b/library/gcm.c
index f4f735b..b537b02 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -168,6 +168,8 @@
     if( cipher_info->block_size != 16 )
         return( POLARSSL_ERR_GCM_BAD_INPUT );
 
+    cipher_free( &ctx->cipher_ctx );
+
     if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
         return( ret );
 
diff --git a/library/pkparse.c b/library/pkparse.c
index 06fb292..39c51f6 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -761,58 +761,61 @@
 
     p += len;
 
-    /*
-     * Is 'parameters' present?
-     */
-    if( ( ret = asn1_get_tag( &p, end, &len,
-                    ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
+    pubkey_done = 0;
+    if( p != end )
     {
-        if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
-            ( ret = pk_use_ecparams( &params, &eck->grp )  ) != 0 )
+        /*
+         * Is 'parameters' present?
+         */
+        if( ( ret = asn1_get_tag( &p, end, &len,
+                        ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
+        {
+            if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
+                ( ret = pk_use_ecparams( &params, &eck->grp )  ) != 0 )
+            {
+                ecp_keypair_free( eck );
+                return( ret );
+            }
+        }
+        else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
         {
             ecp_keypair_free( eck );
-            return( ret );
-        }
-    }
-    else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
-    {
-        ecp_keypair_free( eck );
-        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
-    }
-
-    /*
-     * Is 'publickey' present? If not, or if we can't read it (eg because it
-     * is compressed), create it from the private key.
-     */
-    pubkey_done = 0;
-    if( ( ret = asn1_get_tag( &p, end, &len,
-                    ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
-    {
-        end2 = p + len;
-
-        if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
             return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
-
-        if( p + len != end2 )
-            return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
-                    POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
-
-        if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
-            pubkey_done = 1;
-        else
-        {
-            /*
-             * The only acceptable failure mode of pk_get_ecpubkey() above
-             * is if the point format is not recognized.
-             */
-            if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE )
-                return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
         }
-    }
-    else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
-    {
-        ecp_keypair_free( eck );
-        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+        /*
+         * Is 'publickey' present? If not, or if we can't read it (eg because it
+         * is compressed), create it from the private key.
+         */
+        if( ( ret = asn1_get_tag( &p, end, &len,
+                        ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
+        {
+            end2 = p + len;
+
+            if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
+                return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+            if( p + len != end2 )
+                return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
+                        POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+
+            if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
+                pubkey_done = 1;
+            else
+            {
+                /*
+                 * The only acceptable failure mode of pk_get_ecpubkey() above
+                 * is if the point format is not recognized.
+                 */
+                if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE )
+                    return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
+            }
+        }
+        else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
+        {
+            ecp_keypair_free( eck );
+            return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
+        }
     }
 
     if( ! pubkey_done &&
diff --git a/library/platform.c b/library/platform.c
index a161bc3..4afe8b7 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -141,7 +141,7 @@
 #endif /* POLARSSL_PLATFORM_FPRINTF_ALT */
 
 #if defined(POLARSSL_PLATFORM_EXIT_ALT)
-#if !defined(POLARSSL_STD_EXIT)
+#if !defined(POLARSSL_PLATFORM_STD_EXIT)
 /*
  * Make dummy function to prevent NULL pointer dereferences
  */
@@ -151,10 +151,10 @@
     return( 0 );
 }
 
-#define POLARSSL_STD_EXIT   platform_exit_uninit
-#endif /* !POLARSSL_STD_EXIT */
+#define POLARSSL_PLATFORM_STD_EXIT   platform_exit_uninit
+#endif /* !POLARSSL_PLATFORM_STD_EXIT */
 
-int (*polarssl_exit)( int status ) = POLARSSL_STD_EXIT;
+int (*polarssl_exit)( int status ) = POLARSSL_PLATFORM_STD_EXIT;
 
 int platform_set_exit( void (*exit_func)( int status ) )
 {
diff --git a/library/rsa.c b/library/rsa.c
index f45b234..8ffb341 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -773,7 +773,7 @@
     for( i = 0; i < ilen - 2 * hlen - 2; i++ )
     {
         pad_done |= p[i];
-        pad_len += ( pad_done == 0 );
+        pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
     }
 
     p += pad_len;
@@ -847,8 +847,8 @@
          * (minus one, for the 00 byte) */
         for( i = 0; i < ilen - 3; i++ )
         {
-            pad_done |= ( p[i] == 0 );
-            pad_count += ( pad_done == 0 );
+            pad_done  |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
+            pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
         }
 
         p += pad_count;
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 37853bc..caeb6f3 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1479,7 +1479,7 @@
 
     SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
 
-#if defined(POLARSSL_SSL_ECP_SET_CURVES)
+#if defined(POLARSSL_SSL_SET_CURVES)
     if( ! ssl_curve_is_acceptable( ssl, ssl->handshake->ecdh_ctx.grp.id ) )
 #else
     if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 2ac0902..5f01a01 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -829,6 +829,7 @@
 {
     ssl_key_cert *cur, *list, *fallback = NULL;
     pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
+    int flags;
 
 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
     if( ssl->handshake->sni_key_cert != NULL )
@@ -862,7 +863,7 @@
          * and decrypting with the same RSA key.
          */
         if( ssl_check_cert_usage( cur->cert, ciphersuite_info,
-                                  SSL_IS_SERVER ) != 0 )
+                                  SSL_IS_SERVER, &flags ) != 0 )
         {
             SSL_DEBUG_MSG( 3, ( "certificate mismatch: "
                                 "(extended) key usage extension" ) );
@@ -2887,7 +2888,7 @@
     unsigned char *pms = ssl->handshake->premaster + pms_offset;
     unsigned char fake_pms[48], peer_pms[48];
     unsigned char mask;
-    size_t i;
+    size_t i, diff, peer_pmslen;
 
     if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_RSA ) )
     {
@@ -2929,16 +2930,17 @@
         return( ret );
 
     ret = pk_decrypt( ssl_own_key( ssl ), p, len,
-                      peer_pms, &ssl->handshake->pmslen,
+                      peer_pms, &peer_pmslen,
                       sizeof( peer_pms ),
                       ssl->f_rng, ssl->p_rng );
 
-    ret |= ssl->handshake->pmslen - 48;
-    ret |= peer_pms[0] - ssl->handshake->max_major_ver;
-    ret |= peer_pms[1] - ssl->handshake->max_minor_ver;
+    diff  = (size_t) ret;
+    diff |= peer_pmslen ^ 48;
+    diff |= peer_pms[0] ^ ssl->handshake->max_major_ver;
+    diff |= peer_pms[1] ^ ssl->handshake->max_minor_ver;
 
 #if defined(POLARSSL_SSL_DEBUG_ALL)
-    if( ret != 0 )
+    if( diff != 0 )
         SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
 #endif
 
@@ -2950,7 +2952,8 @@
     }
     ssl->handshake->pmslen = 48;
 
-    mask = (unsigned char)( - ( ret != 0 ) ); /* ret ? 0xff : 0x00 */
+    mask = ( diff | - diff ) >> ( sizeof( size_t ) * 8 - 1 );
+    mask = (unsigned char)( - ( ret != 0 ) ); /* mask = diff ? 0xff : 0x00 */
     for( i = 0; i < ssl->handshake->pmslen; i++ )
         pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] );
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 515b903..f079adc 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1825,7 +1825,8 @@
                              ssl->in_msglen );
             md_hmac_finish( &ssl->transform_in->md_ctx_dec,
                              ssl->in_msg + ssl->in_msglen );
-            for( j = 0; j < extra_run; j++ )
+            /* Call md_process at least once due to cache attacks */
+            for( j = 0; j < extra_run + 1; j++ )
                 md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
 
             md_hmac_reset( &ssl->transform_in->md_ctx_dec );
@@ -2859,7 +2860,8 @@
 
         if( ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
                                   ciphersuite_info,
-                                  ! ssl->endpoint ) != 0 )
+                                  ! ssl->endpoint,
+                                 &ssl->session_negotiate->verify_result ) != 0 )
         {
             SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
             if( ret == 0 )
@@ -4754,37 +4756,16 @@
 }
 
 /*
- * Send application data to be encrypted by the SSL layer
+ * Send application data to be encrypted by the SSL layer,
+ * taking care of max fragment length and buffer size
  */
-#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
-static int ssl_write_real( ssl_context *ssl, const unsigned char *buf, size_t len )
-#else
-int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
-#endif
+static int ssl_write_real( ssl_context *ssl,
+                           const unsigned char *buf, size_t len )
 {
     int ret;
     size_t n;
     unsigned int max_len = SSL_MAX_CONTENT_LEN;
 
-    SSL_DEBUG_MSG( 2, ( "=> write" ) );
-
-#if defined(POLARSSL_SSL_RENEGOTIATION)
-    if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
-    {
-        SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
-        return( ret );
-    }
-#endif
-
-    if( ssl->state != SSL_HANDSHAKE_OVER )
-    {
-        if( ( ret = ssl_handshake( ssl ) ) != 0 )
-        {
-            SSL_DEBUG_RET( 1, "ssl_handshake", ret );
-            return( ret );
-        }
-    }
-
 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
     /*
      * Assume mfl_code is correct since it was checked when set
@@ -4824,8 +4805,6 @@
         }
     }
 
-    SSL_DEBUG_MSG( 2, ( "<= write" ) );
-
     return( (int) n );
 }
 
@@ -4837,7 +4816,8 @@
  * remember wether we already did the split or not.
  */
 #if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
-int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
+static int ssl_write_split( ssl_context *ssl,
+                            const unsigned char *buf, size_t len )
 {
     int ret;
 
@@ -4866,6 +4846,43 @@
 #endif /* POLARSSL_SSL_CBC_RECORD_SPLITTING */
 
 /*
+ * Write application data (public-facing wrapper)
+ */
+int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
+{
+    int ret;
+
+    SSL_DEBUG_MSG( 2, ( "=> write" ) );
+
+#if defined(POLARSSL_SSL_RENEGOTIATION)
+    if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+        return( ret );
+    }
+#endif
+
+    if( ssl->state != SSL_HANDSHAKE_OVER )
+    {
+        if( ( ret = ssl_handshake( ssl ) ) != 0 )
+        {
+            SSL_DEBUG_RET( 1, "ssl_handshake", ret );
+            return( ret );
+        }
+    }
+
+#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
+    ret = ssl_write_split( ssl, buf, len );
+#else
+    ret = ssl_write_real( ssl, buf, len );
+#endif
+
+    SSL_DEBUG_MSG( 2, ( "<= write" ) );
+
+    return( ret );
+}
+
+/*
  * Notify the peer that the connection is being closed
  */
 int ssl_close_notify( ssl_context *ssl )
@@ -5184,8 +5201,10 @@
 #if defined(POLARSSL_X509_CRT_PARSE_C)
 int ssl_check_cert_usage( const x509_crt *cert,
                           const ssl_ciphersuite_t *ciphersuite,
-                          int cert_endpoint )
+                          int cert_endpoint,
+                          int *flags )
 {
+    int ret = 0;
 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
     int usage = 0;
 #endif
@@ -5198,6 +5217,7 @@
     !defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
     ((void) cert);
     ((void) cert_endpoint);
+    ((void) flags);
 #endif
 
 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
@@ -5237,7 +5257,10 @@
     }
 
     if( x509_crt_check_key_usage( cert, usage ) != 0 )
-        return( -1 );
+    {
+        *flags |= BADCERT_KEY_USAGE;
+        ret = -1;
+    }
 #else
     ((void) ciphersuite);
 #endif /* POLARSSL_X509_CHECK_KEY_USAGE */
@@ -5255,10 +5278,13 @@
     }
 
     if( x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
-        return( -1 );
+    {
+        *flags |= BADCERT_EXT_KEY_USAGE;
+        ret = -1;
+    }
 #endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */
 
-    return( 0 );
+    return( ret );
 }
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
diff --git a/library/version_features.c b/library/version_features.c
index aa30da5..b8b3a4a 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -129,6 +129,9 @@
 #if defined(POLARSSL_AES_ROM_TABLES)
     "POLARSSL_AES_ROM_TABLES",
 #endif /* POLARSSL_AES_ROM_TABLES */
+#if defined(POLARSSL_CAMELLIA_SMALL_MEMORY)
+    "POLARSSL_CAMELLIA_SMALL_MEMORY",
+#endif /* POLARSSL_CAMELLIA_SMALL_MEMORY */
 #if defined(POLARSSL_CIPHER_MODE_CBC)
     "POLARSSL_CIPHER_MODE_CBC",
 #endif /* POLARSSL_CIPHER_MODE_CBC */
diff --git a/library/x509.c b/library/x509.c
index 857b8a3..ab105d8 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -449,7 +449,7 @@
             if( *p == end_set )
                 break;
 
-            /* Mark this item as being only one in a set */
+            /* Mark this item as being not the only one in a set */
             cur->next_merged = 1;
 
             cur->next = polarssl_malloc( sizeof( x509_name ) );
diff --git a/library/x509_crl.c b/library/x509_crl.c
index e2076a6..de2079f 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -462,7 +462,8 @@
     if( crl->sig_oid1.len != crl->sig_oid2.len ||
         memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 ||
         sig_params1.len != sig_params2.len ||
-        memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 )
+        ( sig_params1.len != 0 &&
+          memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
     {
         x509_crl_free( crl );
         return( POLARSSL_ERR_X509_SIG_MISMATCH );
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 77008ed..b94f213 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -760,7 +760,8 @@
     if( crt->sig_oid1.len != crt->sig_oid2.len ||
         memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 ||
         sig_params1.len != sig_params2.len ||
-        memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 )
+        ( sig_params1.len != 0 &&
+          memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
     {
         x509_crt_free( crt );
         return( POLARSSL_ERR_X509_SIG_MISMATCH );
@@ -1382,6 +1383,57 @@
     return( (int) ( size - n ) );
 }
 
+struct x509_crt_verify_string {
+    int code;
+    const char *string;
+};
+
+static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
+    { BADCERT_EXPIRED,       "The certificate validity has expired" },
+    { BADCERT_REVOKED,       "The certificate has been revoked (is on a CRL)" },
+    { BADCERT_CN_MISMATCH,   "The certificate Common Name (CN) does not match with the expected CN" },
+    { BADCERT_NOT_TRUSTED,   "The certificate is not correctly signed by the trusted CA" },
+    { BADCRL_NOT_TRUSTED,    "The CRL is not correctly signed by the trusted CA" },
+    { BADCRL_EXPIRED,        "The CRL is expired" },
+    { BADCERT_MISSING,       "Certificate was missing" },
+    { BADCERT_SKIP_VERIFY,   "Certificate verification was skipped" },
+    { BADCERT_OTHER,         "Other reason (can be used by verify callback)" },
+    { BADCERT_FUTURE,        "The certificate validity starts in the future" },
+    { BADCRL_FUTURE,         "The CRL is from the future" },
+    { BADCERT_KEY_USAGE,     "Usage does not match the keyUsage extension" },
+    { BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
+    { BADCERT_NS_CERT_TYPE,  "Usage does not match the nsCertType extension" },
+    { 0, NULL }
+};
+
+int x509_crt_verify_info( char *buf, size_t size, const char *prefix,
+                          int flags )
+{
+    int ret;
+    const struct x509_crt_verify_string *cur;
+    char *p = buf;
+    size_t n = size;
+
+    for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
+    {
+        if( ( flags & cur->code ) == 0 )
+            continue;
+
+        ret = polarssl_snprintf( p, n, "%s%s\n", prefix, cur->string );
+        SAFE_SNPRINTF();
+        flags ^= cur->code;
+    }
+
+    if( flags != 0 )
+    {
+        ret = polarssl_snprintf( p, n, "%sUnknown reason "
+                                       "(this should not happen)\n", prefix );
+        SAFE_SNPRINTF();
+    }
+
+    return( (int) ( size - n ) );
+}
+
 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
 int x509_crt_check_key_usage( const x509_crt *crt, int usage )
 {
@@ -1719,7 +1771,7 @@
                 void *p_vrfy )
 {
     int ret;
-    int ca_flags = 0, check_path_cnt = path_cnt + 1;
+    int ca_flags = 0, check_path_cnt;
     unsigned char hash[POLARSSL_MD_MAX_SIZE];
     const md_info_t *md_info;
 
@@ -1750,8 +1802,10 @@
         if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
             continue;
 
+        check_path_cnt = path_cnt + 1;
+
         /*
-         * Reduce path_len to check against if top of the chain is
+         * Reduce check_path_cnt to check against if top of the chain is
          * the same as the trusted CA
          */
         if( child->subject_raw.len == trust_ca->subject_raw.len &&
diff --git a/programs/pkey/mpi_demo.c b/programs/pkey/mpi_demo.c
index c94fb97..95267fc 100644
--- a/programs/pkey/mpi_demo.c
+++ b/programs/pkey/mpi_demo.c
@@ -96,7 +96,7 @@
 
     if( ret != 0 )
     {
-        polarssl_printf( "\nAn error occured.\n" );
+        polarssl_printf( "\nAn error occurred.\n" );
         ret = 1;
     }
 
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index 57104ca..057b842 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -203,24 +203,16 @@
      */
     polarssl_printf( "  . Verifying peer X.509 certificate..." );
 
-    /* In real life, we may want to bail out when ret != 0 */
+    /* In real life, we probably want to bail out when ret != 0 */
     if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
     {
+        char vrfy_buf[512];
+
         polarssl_printf( " failed\n" );
 
-        if( ( ret & BADCERT_EXPIRED ) != 0 )
-            polarssl_printf( "  ! server certificate has expired\n" );
+        x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", ret );
 
-        if( ( ret & BADCERT_REVOKED ) != 0 )
-            polarssl_printf( "  ! server certificate has been revoked\n" );
-
-        if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
-            polarssl_printf( "  ! CN mismatch (expected CN=%s)\n", "PolarSSL Server 1" );
-
-        if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
-            polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );
-
-        polarssl_printf( "\n" );
+        polarssl_printf( "%s\n", vrfy_buf );
     }
     else
         polarssl_printf( " ok\n" );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index da3dba7..cdadf59 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -350,29 +350,13 @@
     x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
     polarssl_printf( "%s", buf );
 
-    if( ( (*flags) & BADCERT_EXPIRED ) != 0 )
-        polarssl_printf( "  ! server certificate has expired\n" );
-
-    if( ( (*flags) & BADCERT_REVOKED ) != 0 )
-        polarssl_printf( "  ! server certificate has been revoked\n" );
-
-    if( ( (*flags) & BADCERT_CN_MISMATCH ) != 0 )
-        polarssl_printf( "  ! CN mismatch\n" );
-
-    if( ( (*flags) & BADCERT_NOT_TRUSTED ) != 0 )
-        polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );
-
-    if( ( (*flags) & BADCRL_NOT_TRUSTED ) != 0 )
-        polarssl_printf( "  ! CRL not trusted\n" );
-
-    if( ( (*flags) & BADCRL_EXPIRED ) != 0 )
-        polarssl_printf( "  ! CRL expired\n" );
-
-    if( ( (*flags) & BADCERT_OTHER ) != 0 )
-        polarssl_printf( "  ! other (unknown) flag\n" );
-
     if ( ( *flags ) == 0 )
         polarssl_printf( "  This certificate has no flags\n" );
+    else
+    {
+        x509_crt_verify_info( buf, sizeof( buf ), "  ! ", *flags );
+        polarssl_printf( "%s\n", buf );
+    }
 
     return( 0 );
 }
@@ -1142,21 +1126,13 @@
 
     if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
     {
+        char vrfy_buf[512];
+
         polarssl_printf( " failed\n" );
 
-        if( ( ret & BADCERT_EXPIRED ) != 0 )
-            polarssl_printf( "  ! server certificate has expired\n" );
+        x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", ret );
 
-        if( ( ret & BADCERT_REVOKED ) != 0 )
-            polarssl_printf( "  ! server certificate has been revoked\n" );
-
-        if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
-            polarssl_printf( "  ! CN mismatch (expected CN=%s)\n", opt.server_name );
-
-        if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
-            polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );
-
-        polarssl_printf( "\n" );
+        polarssl_printf( "%s\n", vrfy_buf );
     }
     else
         polarssl_printf( " ok\n" );
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 2b2d493..27c57a1 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -169,7 +169,7 @@
     }
 }
 
-static int do_handshake( ssl_context *ssl, struct options *opt )
+static int do_handshake( ssl_context *ssl )
 {
     int ret;
     unsigned char buf[1024];
@@ -201,24 +201,16 @@
      */
     polarssl_printf( "  . Verifying peer X.509 certificate..." );
 
-    /* In real life, we may want to bail out when ret != 0 */
+    /* In real life, we probably want to bail out when ret != 0 */
     if( ( ret = ssl_get_verify_result( ssl ) ) != 0 )
     {
+        char vrfy_buf[512];
+
         polarssl_printf( " failed\n" );
 
-        if( ( ret & BADCERT_EXPIRED ) != 0 )
-            polarssl_printf( "  ! server certificate has expired\n" );
+        x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", ret );
 
-        if( ( ret & BADCERT_REVOKED ) != 0 )
-            polarssl_printf( "  ! server certificate has been revoked\n" );
-
-        if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
-            polarssl_printf( "  ! CN mismatch (expected CN=%s)\n", opt->server_name );
-
-        if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
-            polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );
-
-        polarssl_printf( "\n" );
+        polarssl_printf( "%s\n", vrfy_buf );
     }
     else
         polarssl_printf( " ok\n" );
@@ -638,7 +630,7 @@
 
     if( opt.mode == MODE_SSL_TLS )
     {
-        if( do_handshake( &ssl, &opt ) != 0 )
+        if( do_handshake( &ssl ) != 0 )
             goto exit;
 
         polarssl_printf( "  > Get header from server:" );
@@ -707,7 +699,7 @@
 
         polarssl_printf(" ok\n" );
 
-        if( do_handshake( &ssl, &opt ) != 0 )
+        if( do_handshake( &ssl ) != 0 )
             goto exit;
     }
 
@@ -730,7 +722,7 @@
         polarssl_printf( "  > Write username to server: %s", opt.user_name );
         fflush( stdout );
 
-        n = sizeof( buf );
+        n = sizeof( base );
         ret = base64_encode( base, &n, (const unsigned char *) opt.user_name,
                              strlen( opt.user_name ) );
 
@@ -751,6 +743,7 @@
         polarssl_printf( "  > Write password to server: %s", opt.user_pwd );
         fflush( stdout );
 
+        n = sizeof( base );
         ret = base64_encode( base, &n, (const unsigned char *) opt.user_pwd,
                              strlen( opt.user_pwd ) );
 
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index d1bc36e..095fabd 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1626,21 +1626,13 @@
 
     if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
     {
+        char vrfy_buf[512];
+
         polarssl_printf( " failed\n" );
 
-        if( !ssl_get_peer_cert( &ssl ) )
-            polarssl_printf( "  ! no client certificate sent\n" );
+        x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", ret );
 
-        if( ( ret & BADCERT_EXPIRED ) != 0 )
-            polarssl_printf( "  ! client certificate has expired\n" );
-
-        if( ( ret & BADCERT_REVOKED ) != 0 )
-            polarssl_printf( "  ! client certificate has been revoked\n" );
-
-        if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
-            polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );
-
-        polarssl_printf( "\n" );
+        polarssl_printf( "%s\n", vrfy_buf );
     }
     else
         polarssl_printf( " ok\n" );
diff --git a/programs/test/o_p_test.c b/programs/test/o_p_test.c
index d949d51..f0ade14 100644
--- a/programs/test/o_p_test.c
+++ b/programs/test/o_p_test.c
@@ -52,8 +52,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
 #endif
 
 #if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_RSA_C) ||         \
diff --git a/programs/test/ssl_cert_test.c b/programs/test/ssl_cert_test.c
index d823964..aade251 100644
--- a/programs/test/ssl_cert_test.c
+++ b/programs/test/ssl_cert_test.c
@@ -173,19 +173,14 @@
         {
             if( ret == POLARSSL_ERR_X509_CERT_VERIFY_FAILED )
             {
-                if( flags & BADCERT_CN_MISMATCH )
-                    polarssl_printf( " CN_MISMATCH " );
-                if( flags & BADCERT_EXPIRED )
-                    polarssl_printf( " EXPIRED " );
-                if( flags & BADCERT_REVOKED )
-                    polarssl_printf( " REVOKED " );
-                if( flags & BADCERT_NOT_TRUSTED )
-                    polarssl_printf( " NOT_TRUSTED " );
-                if( flags & BADCRL_NOT_TRUSTED )
-                    polarssl_printf( " CRL_NOT_TRUSTED " );
-                if( flags & BADCRL_EXPIRED )
-                    polarssl_printf( " CRL_EXPIRED " );
-            } else {
+                char vrfy_buf[512];
+
+                polarssl_printf( " failed\n" );
+                x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
+                polarssl_printf( "%s\n", vrfy_buf );
+            }
+            else
+            {
                 polarssl_printf( " failed\n  !  x509_crt_verify returned %d\n\n", ret );
                 goto exit;
             }
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 72f69ba..51d71ae 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -128,29 +128,13 @@
     x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
     polarssl_printf( "%s", buf );
 
-    if( ( (*flags) & BADCERT_EXPIRED ) != 0 )
-        polarssl_printf( "  ! server certificate has expired\n" );
-
-    if( ( (*flags) & BADCERT_REVOKED ) != 0 )
-        polarssl_printf( "  ! server certificate has been revoked\n" );
-
-    if( ( (*flags) & BADCERT_CN_MISMATCH ) != 0 )
-        polarssl_printf( "  ! CN mismatch\n" );
-
-    if( ( (*flags) & BADCERT_NOT_TRUSTED ) != 0 )
-        polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );
-
-    if( ( (*flags) & BADCRL_NOT_TRUSTED ) != 0 )
-        polarssl_printf( "  ! CRL not trusted\n" );
-
-    if( ( (*flags) & BADCRL_EXPIRED ) != 0 )
-        polarssl_printf( "  ! CRL expired\n" );
-
-    if( ( (*flags) & BADCERT_OTHER ) != 0 )
-        polarssl_printf( "  ! other (unknown) flag\n" );
-
     if ( ( *flags ) == 0 )
         polarssl_printf( "  This certificate has no flags\n" );
+    else
+    {
+        x509_crt_verify_info( buf, sizeof( buf ), "  ! ", *flags );
+        polarssl_printf( "%s\n", buf );
+    }
 
     return( 0 );
 }
@@ -358,21 +342,13 @@
             if( ( ret = x509_crt_verify( &crt, &cacert, &cacrl, NULL, &flags,
                                          my_verify, NULL ) ) != 0 )
             {
+                char vrfy_buf[512];
+
                 polarssl_printf( " failed\n" );
 
-                if( ( ret & BADCERT_EXPIRED ) != 0 )
-                    polarssl_printf( "  ! server certificate has expired\n" );
+                x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
 
-                if( ( ret & BADCERT_REVOKED ) != 0 )
-                    polarssl_printf( "  ! server certificate has been revoked\n" );
-
-                if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
-                    polarssl_printf( "  ! CN mismatch (expected CN=%s)\n", opt.server_name );
-
-                if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
-                    polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );
-
-                polarssl_printf( "\n" );
+                polarssl_printf( "%s\n", vrfy_buf );
             }
             else
                 polarssl_printf( " ok\n" );
diff --git a/scripts/ecc-heap.sh b/scripts/ecc-heap.sh
index 4f88a44..8c53f09 100755
--- a/scripts/ecc-heap.sh
+++ b/scripts/ecc-heap.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Measure heap usage (and perfomance) of ECC operations with various values of
+# Measure heap usage (and performance) of ECC operations with various values of
 # the relevant tunable compile-time parameters.
 #
 # Usage (preferably on a 32-bit platform):
diff --git a/tests/compat.sh b/tests/compat.sh
index 554adef..5a3c222 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -679,7 +679,7 @@
     P_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE arc4=1"
     O_SERVER_ARGS="-accept $PORT -www -cipher NULL,ALL -$MODE"
     G_SERVER_ARGS="-p $PORT --http"
-    G_SERVER_PRIO="EXPORT:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
+    G_SERVER_PRIO="NORMAL:+ARCFOUR-128:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
 
     P_CLIENT_ARGS="server_port=$PORT force_version=$MODE"
     O_CLIENT_ARGS="-connect localhost:$PORT -$MODE"
diff --git a/tests/data_files/Readme-x509.txt b/tests/data_files/Readme-x509.txt
index 3022aae..2077f3a 100644
--- a/tests/data_files/Readme-x509.txt
+++ b/tests/data_files/Readme-x509.txt
@@ -73,7 +73,7 @@
 Signing CA in parentheses (same meaning as certificates).
 
 - crl-ec-sha*: (2) server6.crt
-- crl-future.pem: (2) server6.crt + unkown
+- crl-future.pem: (2) server6.crt + unknown
 - crl-rsa-pss-*.pem: (1) server9{,badsign,with-ca}.crt + cert_sha384.crt + unknown
 - crl.pem, crl_expired.pem: (1) server1{,.cert_type,.key_usage,.v1}.crt + unknown
 - crl_md*.pem: crl_sha*.pem: (1) same as crl.pem
diff --git a/tests/data_files/dh.optlen.pem b/tests/data_files/dh.optlen.pem
new file mode 100644
index 0000000..ee1e29b
--- /dev/null
+++ b/tests/data_files/dh.optlen.pem
@@ -0,0 +1,58 @@
+
+Recommended key length: 256 bits
+
+generator:
+	80:0a:bf:e7:dc:66:7a:a1:7b:cd:7c:04:61:4b:c2:
+	21:a6:54:82:cc:c0:4b:60:46:02:b0:e1:31:90:8a:
+	93:8e:a1:1b:48:dc:51:5d:ab:7a:bc:bb:1e:0c:7f:
+	d6:65:11:ed:c0:d8:65:51:b7:63:24:96:e0:3d:f9:
+	43:57:e1:c4:ea:07:a7:ce:1e:38:1a:2f:ca:fd:ff:
+	5f:5b:f0:0d:f8:28:80:60:20:e8:75:c0:09:26:e4:
+	d0:11:f8:84:77:a1:b0:19:27:d7:38:13:ca:d4:84:
+	7c:63:96:b9:24:46:21:be:2b:00:b6:3c:65:92:53:
+	31:84:13:44:3c:d2:44:21:5c:d7:fd:4c:be:79:6e:
+	82:c6:cf:70:f8:9c:c0:c5:28:fb:8e:34:48:09:b3:
+	18:76:e7:ef:73:9d:51:60:d0:95:c9:68:41:88:b0:
+	c8:75:5c:7a:46:8d:47:f5:6d:6d:b9:ea:01:29:24:
+	ec:b0:55:6f:b7:13:12:a8:d7:c9:3b:b2:89:8e:a0:
+	8e:e5:4e:eb:59:45:48:28:5f:06:a9:73:cb:be:2a:
+	0c:b0:2e:90:f3:23:fe:04:55:21:f3:4c:68:35:4a:
+	6d:3e:95:db:ff:f1:eb:64:69:2e:dc:0a:44:f3:d3:
+	e4:08:d0:e4:79:a5:41:e7:79:a6:05:42:59:e2:d8:
+	54:
+
+prime:
+	b3:12:6a:ea:f4:71:53:c7:d6:7f:40:30:30:b2:92:
+	b5:bd:5a:6c:9e:ae:1c:13:7a:f3:40:87:fc:e2:a3:
+	6a:57:8d:70:c5:c5:60:ad:2b:db:92:4c:4a:4d:be:
+	e2:0a:16:71:be:71:03:ce:87:de:fa:76:90:89:36:
+	80:3d:be:ca:60:c3:3e:12:89:c1:a0:3a:c2:c6:c4:
+	e4:94:05:e5:90:2f:a0:59:6a:1c:ba:a8:95:cc:40:
+	2d:52:13:ed:4a:5f:1f:5b:a8:b5:e1:ed:3d:a9:51:
+	a4:c4:75:af:eb:0c:a6:60:b7:36:8c:38:c8:e8:09:
+	f3:82:d9:6a:e1:9e:60:dc:98:4e:61:cb:42:b5:df:
+	d7:23:32:2a:cf:32:7f:9e:41:3c:da:64:00:c1:5c:
+	5b:2e:a1:fa:34:40:5d:83:98:2f:ba:40:e6:d8:52:
+	da:3d:91:01:9b:f2:35:11:31:42:54:dc:21:1a:90:
+	83:3e:5b:17:98:ee:52:a7:81:98:c5:55:64:47:29:
+	ad:92:f0:60:36:7c:74:de:d3:77:04:ad:fc:27:3a:
+	4a:33:fe:c8:21:bd:2e:bd:3b:c0:51:73:0e:97:a4:
+	dd:14:d2:b7:66:06:25:92:f5:ee:c0:9d:16:bb:50:
+	ef:eb:f2:cc:00:dd:3e:0e:34:18:e6:0e:c8:48:70:
+	f7:
+
+
+-----BEGIN DH PARAMETERS-----
+MIICDgKCAQEAsxJq6vRxU8fWf0AwMLKStb1abJ6uHBN680CH/OKjaleNcMXFYK0r
+25JMSk2+4goWcb5xA86H3vp2kIk2gD2+ymDDPhKJwaA6wsbE5JQF5ZAvoFlqHLqo
+lcxALVIT7UpfH1uoteHtPalRpMR1r+sMpmC3Now4yOgJ84LZauGeYNyYTmHLQrXf
+1yMyKs8yf55BPNpkAMFcWy6h+jRAXYOYL7pA5thS2j2RAZvyNRExQlTcIRqQgz5b
+F5juUqeBmMVVZEcprZLwYDZ8dN7TdwSt/Cc6SjP+yCG9Lr07wFFzDpek3RTSt2YG
+JZL17sCdFrtQ7+vyzADdPg40GOYOyEhw9wKCAQEAgAq/59xmeqF7zXwEYUvCIaZU
+gszAS2BGArDhMZCKk46hG0jcUV2rery7Hgx/1mUR7cDYZVG3YySW4D35Q1fhxOoH
+p84eOBovyv3/X1vwDfgogGAg6HXACSbk0BH4hHehsBkn1zgTytSEfGOWuSRGIb4r
+ALY8ZZJTMYQTRDzSRCFc1/1MvnlugsbPcPicwMUo+440SAmzGHbn73OdUWDQlclo
+QYiwyHVcekaNR/VtbbnqASkk7LBVb7cTEqjXyTuyiY6gjuVO61lFSChfBqlzy74q
+DLAukPMj/gRVIfNMaDVKbT6V2//x62RpLtwKRPPT5AjQ5HmlQed5pgVCWeLYVAIC
+AQA=
+-----END DH PARAMETERS-----
diff --git a/tests/data_files/ec_prv.noopt.der b/tests/data_files/ec_prv.noopt.der
new file mode 100644
index 0000000..fde16a1
--- /dev/null
+++ b/tests/data_files/ec_prv.noopt.der
Binary files differ
diff --git a/tests/scripts/generate_code.pl b/tests/scripts/generate_code.pl
index 81c454c..078e82d 100755
--- a/tests/scripts/generate_code.pl
+++ b/tests/scripts/generate_code.pl
@@ -139,7 +139,7 @@
             $param_defs .= "    char *param$i = params[$i];\n";
             $param_checks .= "    if( verify_string( &param$i ) != 0 ) return( 2 );\n";
             push @dispatch_params, "param$i";
-            $mapping_regex .= ":[^:]+";
+            $mapping_regex .= ":[^:\n]+";
         }
         else
         {
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 63c0a23..5cf4ff6 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1338,7 +1338,7 @@
             "$P_CLI debug_level=1 auth_mode=required" \
             1 \
             -c "x509_verify_cert() returned" \
-            -c "! self-signed or not signed by a trusted CA" \
+            -c "! The certificate is not correctly signed by the trusted CA" \
             -c "! ssl_handshake returned" \
             -c "X509 - Certificate verification failed"
 
@@ -1348,7 +1348,7 @@
             "$P_CLI debug_level=1 auth_mode=optional" \
             0 \
             -c "x509_verify_cert() returned" \
-            -c "! self-signed or not signed by a trusted CA" \
+            -c "! The certificate is not correctly signed by the trusted CA" \
             -C "! ssl_handshake returned" \
             -C "X509 - Certificate verification failed"
 
@@ -1358,7 +1358,7 @@
             "$P_CLI debug_level=1 auth_mode=none" \
             0 \
             -C "x509_verify_cert() returned" \
-            -C "! self-signed or not signed by a trusted CA" \
+            -C "! The certificate is not correctly signed by the trusted CA" \
             -C "! ssl_handshake returned" \
             -C "X509 - Certificate verification failed"
 
@@ -1374,7 +1374,7 @@
             -C "skip write certificate verify" \
             -S "skip parse certificate verify" \
             -s "x509_verify_cert() returned" \
-            -S "! self-signed or not signed by a trusted CA" \
+            -S "! The certificate is not correctly signed by the trusted CA" \
             -s "! ssl_handshake returned" \
             -c "! ssl_handshake returned" \
             -s "X509 - Certificate verification failed"
@@ -1391,7 +1391,7 @@
             -C "skip write certificate verify" \
             -S "skip parse certificate verify" \
             -s "x509_verify_cert() returned" \
-            -s "! self-signed or not signed by a trusted CA" \
+            -s "! The certificate is not correctly signed by the trusted CA" \
             -S "! ssl_handshake returned" \
             -C "! ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
@@ -1408,7 +1408,7 @@
             -c "skip write certificate verify" \
             -s "skip parse certificate verify" \
             -S "x509_verify_cert() returned" \
-            -S "! self-signed or not signed by a trusted CA" \
+            -S "! The certificate is not correctly signed by the trusted CA" \
             -S "! ssl_handshake returned" \
             -C "! ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
@@ -1425,7 +1425,7 @@
             -S "SSLv3 client has no certificate" \
             -c "skip write certificate verify" \
             -s "skip parse certificate verify" \
-            -s "! no client certificate sent" \
+            -s "! Certificate was missing" \
             -S "! ssl_handshake returned" \
             -C "! ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
@@ -1436,7 +1436,7 @@
             0 \
             -S "skip write certificate request" \
             -s "skip parse certificate verify" \
-            -s "! no client certificate sent" \
+            -s "! Certificate was missing" \
             -S "! ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
 
@@ -1462,7 +1462,7 @@
             -c "got no certificate to send" \
             -s "SSLv3 client has no certificate" \
             -s "skip parse certificate verify" \
-            -s "! no client certificate sent" \
+            -s "! Certificate was missing" \
             -S "! ssl_handshake returned" \
             -C "! ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
@@ -1878,6 +1878,17 @@
             -c "Processing of the Certificate handshake message failed" \
             -C "Ciphersuite is TLS-"
 
+run_test    "keyUsage cli: KeyEncipherment, DHE-RSA: fail, soft" \
+            "$O_SRV -key data_files/server2.key \
+             -cert data_files/server2.ku-ke.crt" \
+            "$P_CLI debug_level=1 auth_mode=optional \
+             force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA" \
+            0 \
+            -c "bad certificate (usage extensions)" \
+            -C "Processing of the Certificate handshake message failed" \
+            -c "Ciphersuite is TLS-" \
+            -c "! Usage does not match the keyUsage extension"
+
 run_test    "keyUsage cli: DigitalSignature, DHE-RSA: OK" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ds.crt" \
@@ -1898,6 +1909,17 @@
             -c "Processing of the Certificate handshake message failed" \
             -C "Ciphersuite is TLS-"
 
+run_test    "keyUsage cli: DigitalSignature, RSA: fail, soft" \
+            "$O_SRV -key data_files/server2.key \
+             -cert data_files/server2.ku-ds.crt" \
+            "$P_CLI debug_level=1 auth_mode=optional \
+             force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+            0 \
+            -c "bad certificate (usage extensions)" \
+            -C "Processing of the Certificate handshake message failed" \
+            -c "Ciphersuite is TLS-" \
+            -c "! Usage does not match the keyUsage extension"
+
 # Tests for keyUsage in leaf certificates, part 3:
 # server-side checking of client cert
 
diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data
index 57db3db..f2cdeff 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -10,5 +10,8 @@
 Diffie-Hallman load parameters from file
 dhm_file:"data_files/dhparams.pem":"9e35f430443a09904f3a39a979797d070df53378e79c2438bef4e761f3c714553328589b041c809be1d6c6b5f1fc9f47d3a25443188253a992a56818b37ba9de5a40d362e56eff0be5417474c125c199272c8fe41dea733df6f662c92ae76556e755d10c64e6a50968f67fc6ea73d0dca8569be2ba204e23580d8bca2f4975b3":"02":128
 
+Diffie-Hallman load parameters from file
+dhm_file:"data_files/dh.optlen.pem":"b3126aeaf47153c7d67f403030b292b5bd5a6c9eae1c137af34087fce2a36a578d70c5c560ad2bdb924c4a4dbee20a1671be7103ce87defa76908936803dbeca60c33e1289c1a03ac2c6c4e49405e5902fa0596a1cbaa895cc402d5213ed4a5f1f5ba8b5e1ed3da951a4c475afeb0ca660b7368c38c8e809f382d96ae19e60dc984e61cb42b5dfd723322acf327f9e413cda6400c15c5b2ea1fa34405d83982fba40e6d852da3d91019bf23511314254dc211a90833e5b1798ee52a78198c555644729ad92f060367c74ded37704adfc273a4a33fec821bd2ebd3bc051730e97a4dd14d2b766062592f5eec09d16bb50efebf2cc00dd3e0e3418e60ec84870f7":"800abfe7dc667aa17bcd7c04614bc221a65482ccc04b604602b0e131908a938ea11b48dc515dab7abcbb1e0c7fd66511edc0d86551b7632496e03df94357e1c4ea07a7ce1e381a2fcafdff5f5bf00df828806020e875c00926e4d011f88477a1b01927d73813cad4847c6396b9244621be2b00b63c659253318413443cd244215cd7fd4cbe796e82c6cf70f89cc0c528fb8e344809b31876e7ef739d5160d095c9684188b0c8755c7a468d47f56d6db9ea012924ecb0556fb71312a8d7c93bb2898ea08ee54eeb594548285f06a973cbbe2a0cb02e90f323fe045521f34c68354a6d3e95dbfff1eb64692edc0a44f3d3e408d0e479a541e779a6054259e2d854":256
+
 Diffie-Hellman selftest
 dhm_selftest:
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 7908f91..56817cc 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -1,3 +1,6 @@
+Arguments with no value
+mpi_null:
+
 Base test mpi_read_write_string #1
 mpi_read_write_string:10:"128":10:"128":100:0:0
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index ce1a072..023cab4 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -8,6 +8,25 @@
  */
 
 /* BEGIN_CASE */
+void mpi_null( )
+{
+    mpi X, Y, Z;
+
+    mpi_init( &X );
+    mpi_init( &Y );
+    mpi_init( &Z );
+
+    TEST_ASSERT( mpi_get_bit( &X, 42 ) == 0 );
+    TEST_ASSERT( mpi_lsb( &X ) == 0 );
+    TEST_ASSERT( mpi_msb( &X ) == 0 );
+    TEST_ASSERT( mpi_size( &X ) == 0 );
+
+exit:
+    mpi_free( &X );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mpi_read_write_string( int radix_X, char *input_X, int radix_A,
                             char *input_A, int output_size, int result_read,
                             int result_write )
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index b502017..aab568d 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -146,6 +146,10 @@
 depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.sec1.der":"NULL":0
 
+Parse EC Key #1a (SEC1 DER, no optional part)
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
+pk_parse_keyfile_ec:"data_files/ec_prv.noopt.der":"NULL":0
+
 Parse EC Key #2 (SEC1 PEM)
 depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.sec1.pem":"NULL":0
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 491f14e..47eef41 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -262,6 +262,27 @@
 depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_X509_RSASSA_PSS_SUPPORT:POLARSSL_SHA512_C
 x509_csr_info:"data_files/server9.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA512, MGF1-SHA512, 0x3E)\nRSA key size  \: 1024 bits\n"
 
+X509 Verify Information: empty
+x509_verify_info:0:"":""
+
+X509 Verify Information: one issue
+x509_verify_info:BADCERT_MISSING:"":"Certificate was missing\n"
+
+X509 Verify Information: two issues
+x509_verify_info:BADCERT_EXPIRED | BADCRL_EXPIRED:"":"The certificate validity has expired\nThe CRL is expired\n"
+
+X509 Verify Information: two issues, one unknown
+x509_verify_info:BADCERT_OTHER | 0x8000:"":"Other reason (can be used by verify callback)\nUnknown reason (this should not happen)\n"
+
+X509 Verify Information: empty, with prefix
+x509_verify_info:0:"  ! ":""
+
+X509 Verify Information: one issue, with prefix
+x509_verify_info:BADCERT_MISSING:"  ! ":"  ! Certificate was missing\n"
+
+X509 Verify Information: two issues, with prefix
+x509_verify_info:BADCERT_EXPIRED | BADCRL_EXPIRED:"  ! ":"  ! The certificate validity has expired\n  ! The CRL is expired\n"
+
 X509 Get Distinguished Name #1
 depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_RSA_C
 x509_dn_gets:"data_files/server1.crt":"subject":"C=NL, O=PolarSSL, CN=PolarSSL Server 1"
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 6959484..ab397e5 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -102,6 +102,22 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:POLARSSL_X509_CRT_PARSE_C */
+void x509_verify_info( int flags, char *prefix, char *result_str )
+{
+    char buf[2000];
+    int res;
+
+    memset( buf, 0, sizeof( buf ) );
+
+    res = x509_crt_verify_info( buf, sizeof( buf ), prefix, flags );
+
+    TEST_ASSERT( res >= 0 );
+
+    TEST_ASSERT( strcmp( buf, result_str ) == 0 );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_FS_IO:POLARSSL_X509_CRT_PARSE_C:POLARSSL_X509_CRL_PARSE_C */
 void x509_verify( char *crt_file, char *ca_file, char *crl_file,
                   char *cn_name_str, int result, int flags_result,