Browse Source

SSL rampage (#2938)

* Remove stale putative MD2 support

This hasn't worked in a while, presumably since one of our upstream
merges.  Don't bother making it work, since MD2 is generally considered
insecure.

* Land mbedtls 2.16.3-77-gf02988e57

* TLS: remove some dead code from espconn_mbedtls

There was some... frankly kind of scary buffer and data shuffling if
ESP8266_PLATFORM was defined.  Since we don't, in fact, define that
preprocessor symbol, just drop the code lest anyone (possibly future-me)
be scared.

* TLS: espconn_mbedtls: run through astyle

No functional changes

* TLS: espconn_mbedtls: put the file_params on the stack

There's no need to malloc a structure that's used only locally.

* TLS: Further minor tidying of mbedtls glue

What an absolute shitshow this is.  mbedtls should absolutely not
be mentioned inside sys/socket.h and app/mbedtls/app/lwIPSocket.c is not
so much glue as it as a complete copy of a random subset of lwIP; it
should go, but we aren't there yet.

Get rid of the mysterious "mbedlts_record" struct, which housed merely a
length of bytes sent solely for gating the "record sent" callback.

Remove spurious __attribute__((weak)) from symbols not otherwise
defined and rename them to emphasize that they are not actually part of
mbedtls proper.

* TLS: Rampage esp mbedtls glue and delete unused code

This at least makes the shitshow smaller

* TLS: lwip: fix some memp definitions

I presume these also need the new arguments

* TLS: Remove more non-NodeMCU code from our mbedtls

* TLS: drop support for 1.1

Depending on who you ask it's either EOL already or EOL soon, so
we may as well get rid of it now.
Nathaniel Wesley Filardo 4 years ago
parent
commit
863dfb59ed
100 changed files with 15785 additions and 4503 deletions
  1. 0 7
      app/crypto/digests.c
  2. 7 7
      app/include/lwip/memp_std.h
  3. 291 34
      app/include/mbedtls/aes.h
  4. 39 13
      app/include/mbedtls/aesni.h
  5. 13 16
      app/include/mbedtls/arc4.h
  6. 370 0
      app/include/mbedtls/aria.h
  7. 203 114
      app/include/mbedtls/asn1write.h
  8. 9 0
      app/include/mbedtls/base64.h
  9. 509 311
      app/include/mbedtls/bignum.h
  10. 141 59
      app/include/mbedtls/blowfish.h
  11. 20 3
      app/include/mbedtls/bn_mul.h
  12. 171 82
      app/include/mbedtls/camellia.h
  13. 181 47
      app/include/mbedtls/ccm.h
  14. 196 44
      app/include/mbedtls/certs.h
  15. 226 0
      app/include/mbedtls/chacha20.h
  16. 358 0
      app/include/mbedtls/chachapoly.h
  17. 34 4
      app/include/mbedtls/check_config.h
  18. 357 237
      app/include/mbedtls/cipher.h
  19. 15 0
      app/include/mbedtls/cipher_internal.h
  20. 33 28
      app/include/mbedtls/cmac.h
  21. 8 1
      app/include/mbedtls/compat-1.3.h
  22. 536 34
      app/include/mbedtls/config.h
  23. 248 87
      app/include/mbedtls/ctr_drbg.h
  24. 36 0
      app/include/mbedtls/debug.h
  25. 15 16
      app/include/mbedtls/des.h
  26. 141 106
      app/include/mbedtls/dhm.h
  27. 266 103
      app/include/mbedtls/ecdh.h
  28. 385 115
      app/include/mbedtls/ecdsa.h
  29. 96 74
      app/include/mbedtls/ecjpake.h
  30. 820 370
      app/include/mbedtls/ecp.h
  31. 6 0
      app/include/mbedtls/ecp_internal.h
  32. 3 3
      app/include/mbedtls/entropy.h
  33. 21 9
      app/include/mbedtls/error.h
  34. 104 67
      app/include/mbedtls/gcm.h
  35. 7 1
      app/include/mbedtls/havege.h
  36. 141 0
      app/include/mbedtls/hkdf.h
  37. 215 126
      app/include/mbedtls/hmac_drbg.h
  38. 63 48
      app/include/mbedtls/md.h
  39. 14 17
      app/include/mbedtls/md2.h
  40. 14 17
      app/include/mbedtls/md4.h
  41. 14 17
      app/include/mbedtls/md5.h
  42. 5 0
      app/include/mbedtls/net.h
  43. 46 2
      app/include/mbedtls/net_sockets.h
  44. 184 0
      app/include/mbedtls/nist_kw.h
  45. 21 5
      app/include/mbedtls/oid.h
  46. 30 12
      app/include/mbedtls/padlock.h
  47. 7 1
      app/include/mbedtls/pem.h
  48. 183 46
      app/include/mbedtls/pk.h
  49. 23 0
      app/include/mbedtls/pk_internal.h
  50. 2 1
      app/include/mbedtls/pkcs11.h
  51. 4 0
      app/include/mbedtls/pkcs5.h
  52. 49 30
      app/include/mbedtls/platform.h
  53. 196 0
      app/include/mbedtls/platform_util.h
  54. 192 0
      app/include/mbedtls/poly1305.h
  55. 15 17
      app/include/mbedtls/ripemd160.h
  56. 379 303
      app/include/mbedtls/rsa.h
  57. 113 83
      app/include/mbedtls/sha1.h
  58. 78 59
      app/include/mbedtls/sha256.h
  59. 81 61
      app/include/mbedtls/sha512.h
  60. 692 83
      app/include/mbedtls/ssl.h
  61. 6 0
      app/include/mbedtls/ssl_cache.h
  62. 54 0
      app/include/mbedtls/ssl_ciphersuites.h
  63. 7 1
      app/include/mbedtls/ssl_cookie.h
  64. 141 24
      app/include/mbedtls/ssl_internal.h
  65. 10 4
      app/include/mbedtls/ssl_ticket.h
  66. 14 3
      app/include/mbedtls/threading.h
  67. 9 17
      app/include/mbedtls/timing.h
  68. 5 5
      app/include/mbedtls/version.h
  69. 7 3
      app/include/mbedtls/x509.h
  70. 2 2
      app/include/mbedtls/x509_crl.h
  71. 102 2
      app/include/mbedtls/x509_crt.h
  72. 8 0
      app/include/mbedtls/x509_csr.h
  73. 14 16
      app/include/mbedtls/xtea.h
  74. 0 33
      app/include/sys/Espconn_mem.h
  75. 1 14
      app/include/sys/espconn_mbedtls.h
  76. 2 12
      app/include/sys/socket.h
  77. 0 1
      app/include/user_config.h
  78. 2 2
      app/include/user_mbedtls.h
  79. 0 73
      app/mbedtls/app/Espconn_mem.c
  80. 232 342
      app/mbedtls/app/espconn_mbedtls.c
  81. 6 234
      app/mbedtls/app/lwIPSocket.c
  82. 691 79
      app/mbedtls/library/aes.c
  83. 6 0
      app/mbedtls/library/aesni.c
  84. 2 6
      app/mbedtls/library/arc4.c
  85. 1079 0
      app/mbedtls/library/aria.c
  86. 3 7
      app/mbedtls/library/asn1parse.c
  87. 34 28
      app/mbedtls/library/asn1write.c
  88. 377 112
      app/mbedtls/library/bignum.c
  89. 52 12
      app/mbedtls/library/blowfish.c
  90. 59 17
      app/mbedtls/library/camellia.c
  91. 80 14
      app/mbedtls/library/ccm.c
  92. 1638 305
      app/mbedtls/library/certs.c
  93. 570 0
      app/mbedtls/library/chacha20.c
  94. 540 0
      app/mbedtls/library/chachapoly.c
  95. 289 54
      app/mbedtls/library/cipher.c
  96. 813 0
      app/mbedtls/library/cipher_wrap.c
  97. 16 20
      app/mbedtls/library/cmac.c
  98. 150 88
      app/mbedtls/library/ctr_drbg.c
  99. 88 6
      app/mbedtls/library/debug.c
  100. 50 47
      app/mbedtls/library/des.c

+ 0 - 7
app/crypto/digests.c

@@ -37,10 +37,6 @@
 #include <strings.h>
 #include <errno.h>
 
-#ifdef MD2_ENABLE
-#include "ssl/ssl_crypto.h"
-#endif
-
 #ifdef SHA2_ENABLE
 #include "sha2.h"
 #endif
@@ -60,9 +56,6 @@ typedef char ensure_int_and_size_t_same[(sizeof(int)==sizeof(size_t)) ? 0 : -1];
 
 static const digest_mech_info_t hash_mechs[] ICACHE_RODATA_ATTR =
 {
-#ifdef MD2_ENABLE
-   MECH(MD2, _ , MD2_SIZE,  16),
-#endif
    MECH(MD5,   , MD5_DIGEST_LENGTH,  64)
   ,MECH(SHA1,  , SHA1_DIGEST_LENGTH, 64)
 #ifdef SHA2_ENABLE

+ 7 - 7
app/include/lwip/memp_std.h

@@ -52,14 +52,14 @@ LWIP_MEMPOOL(FRAG_PBUF,      MEMP_NUM_FRAG_PBUF,       sizeof(struct pbuf_custom
 #endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */
 
 #if LWIP_NETCONN
-LWIP_MEMPOOL(NETBUF,         MEMP_NUM_NETBUF,          sizeof(struct netbuf),         "NETBUF")
-LWIP_MEMPOOL(NETCONN,        MEMP_NUM_NETCONN,         sizeof(struct netconn),        "NETCONN")
+LWIP_MEMPOOL(NETBUF,         MEMP_NUM_NETBUF,          sizeof(struct netbuf),         "NETBUF", DMEM_ATTR)
+LWIP_MEMPOOL(NETCONN,        MEMP_NUM_NETCONN,         sizeof(struct netconn),        "NETCONN", DMEM_ATTR)
 #endif /* LWIP_NETCONN */
 
 #if NO_SYS==0
-LWIP_MEMPOOL(TCPIP_MSG_API,  MEMP_NUM_TCPIP_MSG_API,   sizeof(struct tcpip_msg),      "TCPIP_MSG_API")
+LWIP_MEMPOOL(TCPIP_MSG_API,  MEMP_NUM_TCPIP_MSG_API,   sizeof(struct tcpip_msg),      "TCPIP_MSG_API", DMEM_ATTR)
 #if !LWIP_TCPIP_CORE_LOCKING_INPUT
-LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg),      "TCPIP_MSG_INPKT")
+LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg),      "TCPIP_MSG_INPKT", DMEM_ATTR)
 #endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
 #endif /* NO_SYS==0 */
 
@@ -82,13 +82,13 @@ LWIP_MEMPOOL(SNMP_VARBIND,   MEMP_NUM_SNMP_VARBIND,    sizeof(struct snmp_varbin
 LWIP_MEMPOOL(SNMP_VALUE,     MEMP_NUM_SNMP_VALUE,      SNMP_MAX_VALUE_SIZE,              "SNMP_VALUE")
 #endif /* LWIP_SNMP */
 #if LWIP_DNS && LWIP_SOCKET
-LWIP_MEMPOOL(NETDB,          MEMP_NUM_NETDB,           NETDB_ELEM_SIZE,               "NETDB")
+LWIP_MEMPOOL(NETDB,          MEMP_NUM_NETDB,           NETDB_ELEM_SIZE,               "NETDB", DMEM_ATTR)
 #endif /* LWIP_DNS && LWIP_SOCKET */
 #if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC
-LWIP_MEMPOOL(LOCALHOSTLIST,  MEMP_NUM_LOCALHOSTLIST,   LOCALHOSTLIST_ELEM_SIZE,       "LOCALHOSTLIST")
+LWIP_MEMPOOL(LOCALHOSTLIST,  MEMP_NUM_LOCALHOSTLIST,   LOCALHOSTLIST_ELEM_SIZE,       "LOCALHOSTLIST", DMEM_ATTR)
 #endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
 #if PPP_SUPPORT && PPPOE_SUPPORT
-LWIP_MEMPOOL(PPPOE_IF,      MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc),    "PPPOE_IF")
+LWIP_MEMPOOL(PPPOE_IF,      MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc),    "PPPOE_IF", DMEM_ATTR)
 #endif /* PPP_SUPPORT && PPPOE_SUPPORT */
 
 /*

+ 291 - 34
app/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.
  *
@@ -11,7 +13,13 @@
  *          <em>ISO/IEC 18033-2:2006: Information technology -- Security
  *          techniques -- Encryption algorithms -- Part 2: Asymmetric
  *          ciphers</em>.
+ *
+ *          The AES-XTS block mode is standardized by NIST SP 800-38E
+ *          <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
+ *          and described in detail by IEEE P1619
+ *          <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
  */
+
 /*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
  *  SPDX-License-Identifier: Apache-2.0
  *
@@ -50,8 +58,13 @@
 #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. */
+
+/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
 #define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023  /**< Feature not available. For example, an unsupported AES key size. */
+
+/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_AES_HW_ACCEL_FAILED                   -0x0025  /**< AES hardware accelerator failed. */
 
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
@@ -59,18 +72,18 @@
 #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.
  */
-typedef struct
+typedef struct mbedtls_aes_context
 {
     int nr;                     /*!< The number of rounds. */
     uint32_t *rk;               /*!< AES round keys. */
@@ -85,13 +98,30 @@ typedef struct
 }
 mbedtls_aes_context;
 
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief The AES XTS context-type definition.
+ */
+typedef struct mbedtls_aes_xts_context
+{
+    mbedtls_aes_context crypt; /*!< The AES context to use for AES block
+                                        encryption or decryption. */
+    mbedtls_aes_context tweak; /*!< The AES context used for tweak
+                                        computation. */
+} mbedtls_aes_xts_context;
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#else  /* MBEDTLS_AES_ALT */
+#include "aes_alt.h"
+#endif /* MBEDTLS_AES_ALT */
+
 /**
  * \brief          This function initializes the specified AES context.
  *
  *                 It must be the first API called before using
  *                 the context.
  *
- * \param ctx      The AES context to initialize.
+ * \param ctx      The AES context to initialize. This must not be \c NULL.
  */
 void mbedtls_aes_init( mbedtls_aes_context *ctx );
 
@@ -99,21 +129,46 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx );
  * \brief          This function releases and clears the specified AES context.
  *
  * \param ctx      The AES context to clear.
+ *                 If this is \c NULL, this function does nothing.
+ *                 Otherwise, the context must have been at least initialized.
  */
 void mbedtls_aes_free( mbedtls_aes_context *ctx );
 
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief          This function initializes the specified AES XTS context.
+ *
+ *                 It must be the first API called before using
+ *                 the context.
+ *
+ * \param ctx      The AES XTS context to initialize. This must not be \c NULL.
+ */
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
+
+/**
+ * \brief          This function releases and clears the specified AES XTS context.
+ *
+ * \param ctx      The AES XTS context to clear.
+ *                 If this is \c NULL, this function does nothing.
+ *                 Otherwise, the context must have been at least initialized.
+ */
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
 /**
  * \brief          This function sets the encryption key.
  *
  * \param ctx      The AES context to which the key should be bound.
+ *                 It must be initialized.
  * \param key      The encryption key.
+ *                 This must be a readable buffer of size \p keybits bits.
  * \param keybits  The size of data passed in bits. Valid options are:
  *                 <ul><li>128 bits</li>
  *                 <li>192 bits</li>
  *                 <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 );
@@ -122,17 +177,62 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
  * \brief          This function sets the decryption key.
  *
  * \param ctx      The AES context to which the key should be bound.
+ *                 It must be initialized.
  * \param key      The decryption key.
+ *                 This must be a readable buffer of size \p keybits bits.
  * \param keybits  The size of data passed. Valid options are:
  *                 <ul><li>128 bits</li>
  *                 <li>192 bits</li>
  *                 <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 );
 
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief          This function prepares an XTS context for encryption and
+ *                 sets the encryption key.
+ *
+ * \param ctx      The AES XTS context to which the key should be bound.
+ *                 It must be initialized.
+ * \param key      The encryption key. This is comprised of the XTS key1
+ *                 concatenated with the XTS key2.
+ *                 This must be a readable buffer of size \p keybits bits.
+ * \param keybits  The size of \p key passed in bits. Valid options are:
+ *                 <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
+ *                 <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits );
+
+/**
+ * \brief          This function prepares an XTS context for decryption and
+ *                 sets the decryption key.
+ *
+ * \param ctx      The AES XTS context to which the key should be bound.
+ *                 It must be initialized.
+ * \param key      The decryption key. This is comprised of the XTS key1
+ *                 concatenated with the XTS key2.
+ *                 This must be a readable buffer of size \p keybits bits.
+ * \param keybits  The size of \p key passed in bits. Valid options are:
+ *                 <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
+ *                 <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
 /**
  * \brief          This function performs an AES single-block encryption or
  *                 decryption operation.
@@ -146,10 +246,13 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
  *                 call to this API with the same context.
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT.
- * \param input    The 16-Byte buffer holding the input data.
- * \param output   The 16-Byte buffer holding the output data.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and at least \c 16 Bytes long.
+ * \param output   The buffer where the output data will be written.
+ *                 It must be writeable and at least \c 16 Bytes long.
 
  * \return         \c 0 on success.
  */
@@ -172,8 +275,8 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
  *         mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
  *         before the first call to this API with the same context.
  *
- * \note   This function operates on aligned blocks, that is, the input size
- *         must be a multiple of the AES block size of 16 Bytes.
+ * \note   This function operates on full blocks, that is, the input size
+ *         must be a multiple of the AES block size of \c 16 Bytes.
  *
  * \note   Upon exit, the content of the IV is updated so that you can
  *         call the same function again on the next
@@ -184,15 +287,20 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
  *
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT.
  * \param length   The length of the input data in Bytes. This must be a
- *                 multiple of the block size (16 Bytes).
+ *                 multiple of the block size (\c 16 Bytes).
  * \param iv       Initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
  * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
  * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
  *
- * \return         \c 0 on success, 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,
@@ -203,6 +311,50 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
                     unsigned char *output );
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief      This function performs an AES-XTS encryption or decryption
+ *             operation for an entire XTS data unit.
+ *
+ *             AES-XTS encrypts or decrypts blocks based on their location as
+ *             defined by a data unit number. The data unit number must be
+ *             provided by \p data_unit.
+ *
+ *             NIST SP 800-38E limits the maximum size of a data unit to 2^20
+ *             AES blocks. If the data unit is larger than this, this function
+ *             returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
+ *
+ * \param ctx          The AES XTS context to use for AES XTS operations.
+ *                     It must be initialized and bound to a key.
+ * \param mode         The AES operation: #MBEDTLS_AES_ENCRYPT or
+ *                     #MBEDTLS_AES_DECRYPT.
+ * \param length       The length of a data unit in Bytes. This can be any
+ *                     length between 16 bytes and 2^24 bytes inclusive
+ *                     (between 1 and 2^20 block cipher blocks).
+ * \param data_unit    The address of the data unit encoded as an array of 16
+ *                     bytes in little-endian format. For disk encryption, this
+ *                     is typically the index of the block device sector that
+ *                     contains the data.
+ * \param input        The buffer holding the input data (which is an entire
+ *                     data unit). This function reads \p length Bytes from \p
+ *                     input.
+ * \param output       The buffer holding the output data (which is an entire
+ *                     data unit). This function writes \p length Bytes to \p
+ *                     output.
+ *
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
+ *                     smaller than an AES block in size (16 Bytes) or if \p
+ *                     length is larger than 2^20 blocks (16 MiB).
+ */
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+                           int mode,
+                           size_t length,
+                           const unsigned char data_unit[16],
+                           const unsigned char *input,
+                           unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
 /**
  * \brief This function performs an AES-CFB128 encryption or decryption
@@ -228,13 +380,18 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
  *
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT.
- * \param length   The length of the input data.
+ * \param length   The length of the input data in Bytes.
  * \param iv_off   The offset in IV (updated after use).
+ *                 It must point to a valid \c size_t.
  * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
  * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
  * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
  *
  * \return         \c 0 on success.
  */
@@ -269,12 +426,16 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
  *
  *
  * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
  * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
  *                 #MBEDTLS_AES_DECRYPT
  * \param length   The length of the input data.
  * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
  * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
  * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
  *
  * \return         \c 0 on success.
  */
@@ -286,6 +447,61 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
                     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.
+ *                 It must be initialized and bound to a key.
+ * \param length   The length of the input data.
+ * \param iv_off   The offset in IV (updated after use).
+ *                 It must point to a valid \c size_t.
+ * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
+ * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ */
+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,20 +516,68 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
  *             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.
+ *                         It must be initialized and bound to a key.
  * \param length           The length of the input data.
  * \param nc_off           The offset in the current \p stream_block, for
  *                         resuming within the current cipher stream. The
  *                         offset pointer should be 0 at the start of a stream.
+ *                         It must point to a valid \c size_t.
  * \param nonce_counter    The 128-bit nonce and counter.
+ *                         It must be a readable-writeable buffer of \c 16 Bytes.
  * \param stream_block     The saved stream block for resuming. This is
  *                         overwritten by the function.
+ *                         It must be a readable-writeable buffer of \c 16 Bytes.
  * \param input            The buffer holding the input data.
+ *                         It must be readable and of size \p length Bytes.
  * \param output           The buffer holding the output data.
+ *                         It must be writeable and of size \p length Bytes.
  *
- * \return     \c 0 on success.
+ * \return                 \c 0 on success.
  */
 int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
                        size_t length,
@@ -364,7 +628,7 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
  * \brief           Deprecated internal AES block encryption function
  *                  without return value.
  *
- * \deprecated      Superseded by mbedtls_aes_encrypt_ext() in 2.5.0.
+ * \deprecated      Superseded by mbedtls_internal_aes_encrypt()
  *
  * \param ctx       The AES context to use for encryption.
  * \param input     Plaintext block.
@@ -378,7 +642,7 @@ MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
  * \brief           Deprecated internal AES block decryption function
  *                  without return value.
  *
- * \deprecated      Superseded by mbedtls_aes_decrypt_ext() in 2.5.0.
+ * \deprecated      Superseded by mbedtls_internal_aes_decrypt()
  *
  * \param ctx       The AES context to use for decryption.
  * \param input     Ciphertext block.
@@ -391,25 +655,18 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_AES_ALT */
-#include "aes_alt.h"
-#endif /* MBEDTLS_AES_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
 
+#if defined(MBEDTLS_SELF_TEST)
 /**
  * \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 );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 39 - 13
app/include/mbedtls/aesni.h

@@ -2,6 +2,9 @@
  * \file aesni.h
  *
  * \brief AES-NI for hardware AES acceleration on some Intel processors
+ *
+ * \warning These functions are only for internal use by other library
+ *          functions; you must not call them directly.
  */
 /*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@@ -24,6 +27,12 @@
 #ifndef MBEDTLS_AESNI_H
 #define MBEDTLS_AESNI_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "aes.h"
 
 #define MBEDTLS_AESNI_AES      0x02000000u
@@ -42,7 +51,10 @@ extern "C" {
 #endif
 
 /**
- * \brief          AES-NI features detection routine
+ * \brief          Internal function to detect the AES-NI feature in CPUs.
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param what     The feature to detect
  *                 (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)
@@ -52,7 +64,10 @@ extern "C" {
 int mbedtls_aesni_has_support( unsigned int what );
 
 /**
- * \brief          AES-NI AES-ECB block en(de)cryption
+ * \brief          Internal AES-NI AES-ECB block encryption and decryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param ctx      AES context
  * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@@ -62,12 +77,15 @@ int mbedtls_aesni_has_support( unsigned int what );
  * \return         0 on success (cannot fail)
  */
 int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
-                     int mode,
-                     const unsigned char input[16],
-                     unsigned char output[16] );
+                             int mode,
+                             const unsigned char input[16],
+                             unsigned char output[16] );
 
 /**
- * \brief          GCM multiplication: c = a * b in GF(2^128)
+ * \brief          Internal GCM multiplication: c = a * b in GF(2^128)
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param c        Result
  * \param a        First operand
@@ -77,21 +95,29 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
  *                 elements of GF(2^128) as per the GCM spec.
  */
 void mbedtls_aesni_gcm_mult( unsigned char c[16],
-                     const unsigned char a[16],
-                     const unsigned char b[16] );
+                             const unsigned char a[16],
+                             const unsigned char b[16] );
 
 /**
- * \brief           Compute decryption round keys from encryption round keys
+ * \brief           Internal round key inversion. This function computes
+ *                  decryption round keys from the encryption round keys.
+ *
+ * \note            This function is only for internal use by other library
+ *                  functions; you must not call it directly.
  *
  * \param invkey    Round keys for the equivalent inverse cipher
  * \param fwdkey    Original round keys (for encryption)
  * \param nr        Number of rounds (that is, number of round keys minus one)
  */
 void mbedtls_aesni_inverse_key( unsigned char *invkey,
-                        const unsigned char *fwdkey, int nr );
+                                const unsigned char *fwdkey,
+                                int nr );
 
 /**
- * \brief           Perform key expansion (for encryption)
+ * \brief           Internal key expansion for encryption
+ *
+ * \note            This function is only for internal use by other library
+ *                  functions; you must not call it directly.
  *
  * \param rk        Destination buffer where the round keys are written
  * \param key       Encryption key
@@ -100,8 +126,8 @@ void mbedtls_aesni_inverse_key( unsigned char *invkey,
  * \return          0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
  */
 int mbedtls_aesni_setkey_enc( unsigned char *rk,
-                      const unsigned char *key,
-                      size_t bits );
+                              const unsigned char *key,
+                              size_t bits );
 
 #ifdef __cplusplus
 }

+ 13 - 16
app/include/mbedtls/arc4.h

@@ -36,16 +36,17 @@
 
 #include <stddef.h>
 
+/* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */
 #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
  *
@@ -53,7 +54,7 @@ extern "C" {
  *            security risk. We recommend considering stronger ciphers instead.
  *
  */
-typedef struct
+typedef struct mbedtls_arc4_context
 {
     int x;                      /*!< permutation index */
     int y;                      /*!< permutation index */
@@ -61,6 +62,10 @@ typedef struct
 }
 mbedtls_arc4_context;
 
+#else  /* MBEDTLS_ARC4_ALT */
+#include "arc4_alt.h"
+#endif /* MBEDTLS_ARC4_ALT */
+
 /**
  * \brief          Initialize ARC4 context
  *
@@ -118,17 +123,7 @@ void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
 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
+#if defined(MBEDTLS_SELF_TEST)
 
 /**
  * \brief          Checkup routine
@@ -142,6 +137,8 @@ extern "C" {
  */
 int mbedtls_arc4_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 370 - 0
app/include/mbedtls/aria.h

@@ -0,0 +1,370 @@
+/**
+ * \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>
+
+#include "platform_util.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. */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */
+
+#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */
+
+/* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE  -0x005A  /**< Feature not available. For example, an unsupported ARIA key size. */
+
+/* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */
+#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 mbedtls_aria_context
+{
+    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. This must not be \c NULL.
+ */
+void mbedtls_aria_init( mbedtls_aria_context *ctx );
+
+/**
+ * \brief          This function releases and clears the specified ARIA context.
+ *
+ * \param ctx      The ARIA context to clear. This may be \c NULL, in which
+ *                 case this function returns immediately. If it is not \c NULL,
+ *                 it must point to an initialized ARIA context.
+ */
+void mbedtls_aria_free( mbedtls_aria_context *ctx );
+
+/**
+ * \brief          This function sets the encryption key.
+ *
+ * \param ctx      The ARIA context to which the key should be bound.
+ *                 This must be initialized.
+ * \param key      The encryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The size of \p key in Bits. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code 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.
+ *                 This must be initialized.
+ * \param key      The decryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The size of data passed. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code 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.
+ *                 This must be initialized and bound to a key.
+ * \param input    The 16-Byte buffer holding the input data.
+ * \param output   The 16-Byte buffer holding the output data.
+
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
+                            const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
+                            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.
+ *                 This must be initialized and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_ARIA_ENCRYPT for encryption, or
+ *                 #MBEDTLS_ARIA_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes. This must be a
+ *                 multiple of the block size (16 Bytes).
+ * \param iv       Initialization vector (updated after use).
+ *                 This must be a readable buffer of size 16 Bytes.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must
+ *                 be a writable buffer of length \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_crypt_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.
+ *                 This must be initialized and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_ARIA_ENCRYPT for encryption, or
+ *                 #MBEDTLS_ARIA_DECRYPT for decryption.
+ * \param length   The length of the input data \p input in Bytes.
+ * \param iv_off   The offset in IV (updated after use).
+ *                 This must not be larger than 15.
+ * \param iv       The initialization vector (updated after use).
+ *                 This must be a readable buffer of size 16 Bytes.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must
+ *                 be a writable buffer of length \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
+                               int mode,
+                               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.
+ *                         This must be initialized and bound to a key.
+ * \param length           The length of the input data \p input in Bytes.
+ * \param nc_off           The offset in Bytes in the current \p stream_block,
+ *                         for resuming within the current cipher stream. The
+ *                         offset pointer should be \c 0 at the start of a
+ *                         stream. This must not be larger than \c 15 Bytes.
+ * \param nonce_counter    The 128-bit nonce and counter. This must point to
+ *                         a read/write buffer of length \c 16 bytes.
+ * \param stream_block     The saved stream block for resuming. This must
+ *                         point to a read/write buffer of length \c 16 bytes.
+ *                         This is overwritten by the function.
+ * \param input            The buffer holding the input data. This must
+ *                         be a readable buffer of length \p length Bytes.
+ * \param output           The buffer holding the output data. This must
+ *                         be a writable buffer of length \p length Bytes.
+ *
+ * \return                 \c 0 on success.
+ * \return                 A negative error code on failure.
+ */
+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 */

+ 203 - 114
app/include/mbedtls/asn1write.h

@@ -24,193 +24,281 @@
 #ifndef MBEDTLS_ASN1_WRITE_H
 #define MBEDTLS_ASN1_WRITE_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "asn1.h"
 
-#define MBEDTLS_ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else   \
-                                g += ret; } while( 0 )
+#define MBEDTLS_ASN1_CHK_ADD(g, f)                      \
+    do                                                  \
+    {                                                   \
+        if( ( ret = (f) ) < 0 )                         \
+            return( ret );                              \
+        else                                            \
+            (g) += ret;                                 \
+    } while( 0 )
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * \brief           Write a length field in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write a length field in ASN.1 format.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param len       the length to write
+ * \note            This function works backwards in data buffer.
  *
- * \return          the length written or a negative error code
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param len       The length value to write.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
-int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
-
+int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start,
+                            size_t len );
 /**
- * \brief           Write a ASN.1 tag in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write an ASN.1 tag in ASN.1 format.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param tag       the tag to write
+ * \note            This function works backwards in data buffer.
  *
- * \return          the length written or a negative error code
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param tag       The tag to write.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
 int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start,
-                    unsigned char tag );
+                            unsigned char tag );
 
 /**
- * \brief           Write raw buffer data
- *                  Note: function works backwards in data buffer
+ * \brief           Write raw buffer data.
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param buf       data buffer to write
- * \param size      length of the data buffer
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param buf       The data buffer to write.
+ * \param size      The length of the data buffer.
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
 int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
-                           const unsigned char *buf, size_t size );
+                                   const unsigned char *buf, size_t size );
 
 #if defined(MBEDTLS_BIGNUM_C)
 /**
- * \brief           Write a big number (MBEDTLS_ASN1_INTEGER) in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param X         the MPI to write
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param X         The MPI to write.
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
-int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X );
+int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start,
+                            const mbedtls_mpi *X );
 #endif /* MBEDTLS_BIGNUM_C */
 
 /**
- * \brief           Write a NULL tag (MBEDTLS_ASN1_NULL) with zero data in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data
+ *                  in ASN.1 format.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
+ * \note            This function works backwards in data buffer.
  *
- * \return          the length written or a negative error code
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
 int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start );
 
 /**
- * \brief           Write an OID tag (MBEDTLS_ASN1_OID) and data in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write an OID tag (#MBEDTLS_ASN1_OID) and data
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param oid       the OID to write
- * \param oid_len   length of the OID
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param oid       The OID to write.
+ * \param oid_len   The length of the OID.
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
 int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
-                    const char *oid, size_t oid_len );
+                            const char *oid, size_t oid_len );
 
 /**
- * \brief           Write an AlgorithmIdentifier sequence in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write an AlgorithmIdentifier sequence in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param oid       the OID of the algorithm
- * \param oid_len   length of the OID
- * \param par_len   length of parameters, which must be already written.
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param oid       The OID of the algorithm to write.
+ * \param oid_len   The length of the algorithm's OID.
+ * \param par_len   The length of the parameters, which must be already written.
  *                  If 0, NULL parameters are added
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
-int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
-                                     const char *oid, size_t oid_len,
-                                     size_t par_len );
+int mbedtls_asn1_write_algorithm_identifier( unsigned char **p,
+                                             unsigned char *start,
+                                             const char *oid, size_t oid_len,
+                                             size_t par_len );
 
 /**
- * \brief           Write a boolean tag (MBEDTLS_ASN1_BOOLEAN) and value in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
+ *                  in ASN.1 format.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param boolean   0 or 1
+ * \note            This function works backwards in data buffer.
  *
- * \return          the length written or a negative error code
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param boolean   The boolean value to write, either \c 0 or \c 1.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
-int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean );
+int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
+                             int boolean );
 
 /**
- * \brief           Write an int tag (MBEDTLS_ASN1_INTEGER) and value in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write an int tag (#MBEDTLS_ASN1_INTEGER) and value
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param val       the integer value
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param val       The integer value to write.
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
 int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
 
 /**
- * \brief           Write a printable string tag (MBEDTLS_ASN1_PRINTABLE_STRING) and
- *                  value in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write a string in ASN.1 format using a specific
+ *                  string encoding tag.
+
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param tag       The string encoding tag to write, e.g.
+ *                  #MBEDTLS_ASN1_UTF8_STRING.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start,
+                                      int tag, const char *text,
+                                      size_t text_len );
+
+/**
+ * \brief           Write a string in ASN.1 format using the PrintableString
+ *                  string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param text      the text to write
- * \param text_len  length of the text
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
  */
-int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
-                                 const char *text, size_t text_len );
+int mbedtls_asn1_write_printable_string( unsigned char **p,
+                                         unsigned char *start,
+                                         const char *text, size_t text_len );
 
 /**
- * \brief           Write an IA5 string tag (MBEDTLS_ASN1_IA5_STRING) and
- *                  value in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write a UTF8 string in ASN.1 format using the UTF8String
+ *                  string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param text      the text to write
- * \param text_len  length of the text
+ * \note            This function works backwards in data buffer.
  *
- * \return          the length written or a negative error code
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
+                                    const char *text, size_t text_len );
+
+/**
+ * \brief           Write a string in ASN.1 format using the IA5String
+ *                  string encoding tag (#MBEDTLS_ASN1_IA5_STRING).
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
  */
 int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
-                           const char *text, size_t text_len );
+                                   const char *text, size_t text_len );
 
 /**
- * \brief           Write a bitstring tag (MBEDTLS_ASN1_BIT_STRING) and
- *                  value in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
+ *                  value in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param buf       the bitstring
- * \param bits      the total number of bits in the bitstring
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param buf       The bitstring to write.
+ * \param bits      The total number of bits in the bitstring.
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
  */
 int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
-                          const unsigned char *buf, size_t bits );
+                                  const unsigned char *buf, size_t bits );
 
 /**
- * \brief           Write an octet string tag (MBEDTLS_ASN1_OCTET_STRING) and
- *                  value in ASN.1 format
- *                  Note: function works backwards in data buffer
+ * \brief           Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
+ *                  and value in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
  *
- * \param p         reference to current position pointer
- * \param start     start of the buffer (for bounds-checking)
- * \param buf       data buffer to write
- * \param size      length of the data buffer
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param buf       The buffer holding the data to write.
+ * \param size      The length of the data buffer \p buf.
  *
- * \return          the length written or a negative error code
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
  */
 int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
-                             const unsigned char *buf, size_t size );
+                                     const unsigned char *buf, size_t size );
 
 /**
  * \brief           Create or find a specific named_data entry for writing in a
@@ -218,15 +306,16 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
  *                  a new entry is added to the head of the list.
  *                  Warning: Destructive behaviour for the val data!
  *
- * \param list      Pointer to the location of the head of the list to seek
- *                  through (will be updated in case of a new entry)
- * \param oid       The OID to look for
- * \param oid_len   Size of the OID
- * \param val       Data to store (can be NULL if you want to fill it by hand)
- * \param val_len   Minimum length of the data buffer needed
+ * \param list      The pointer to the location of the head of the list to seek
+ *                  through (will be updated in case of a new entry).
+ * \param oid       The OID to look for.
+ * \param oid_len   The size of the OID.
+ * \param val       The data to store (can be \c NULL if you want to fill
+ *                  it by hand).
+ * \param val_len   The minimum length of the data buffer needed.
  *
- * \return      NULL if if there was a memory allocation error, or a pointer
- *              to the new / existing entry.
+ * \return          A pointer to the new / existing entry on success.
+ * \return          \c NULL if if there was a memory allocation error.
  */
 mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list,
                                         const char *oid, size_t oid_len,

+ 9 - 0
app/include/mbedtls/base64.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_BASE64_H
 #define MBEDTLS_BASE64_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include <stddef.h>
 
 #define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL               -0x002A  /**< Output buffer too small. */
@@ -75,6 +81,7 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
 int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen );
 
+#if defined(MBEDTLS_SELF_TEST)
 /**
  * \brief          Checkup routine
  *
@@ -82,6 +89,8 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
  */
 int mbedtls_base64_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

File diff suppressed because it is too large
+ 509 - 311
app/include/mbedtls/bignum.h


+ 141 - 59
app/include/mbedtls/blowfish.h

@@ -33,6 +33,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "platform_util.h"
+
 #define MBEDTLS_BLOWFISH_ENCRYPT     1
 #define MBEDTLS_BLOWFISH_DECRYPT     0
 #define MBEDTLS_BLOWFISH_MAX_KEY_BITS     448
@@ -40,63 +42,87 @@
 #define MBEDTLS_BLOWFISH_ROUNDS      16         /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
 #define MBEDTLS_BLOWFISH_BLOCKSIZE   8          /* Blowfish uses 64 bit blocks */
 
-#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH                -0x0016  /**< Invalid key length. */
-#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_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */
 
-#if !defined(MBEDTLS_BLOWFISH_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
+
+/* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED                   -0x0017  /**< Blowfish hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_BLOWFISH_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          Blowfish context structure
  */
-typedef struct
+typedef struct mbedtls_blowfish_context
 {
     uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2];    /*!<  Blowfish round keys    */
     uint32_t S[4][256];                 /*!<  key dependent S-boxes  */
 }
 mbedtls_blowfish_context;
 
+#else  /* MBEDTLS_BLOWFISH_ALT */
+#include "blowfish_alt.h"
+#endif /* MBEDTLS_BLOWFISH_ALT */
+
 /**
- * \brief          Initialize Blowfish context
+ * \brief          Initialize a Blowfish context.
  *
- * \param ctx      Blowfish context to be initialized
+ * \param ctx      The Blowfish context to be initialized.
+ *                 This must not be \c NULL.
  */
 void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx );
 
 /**
- * \brief          Clear Blowfish context
+ * \brief          Clear a Blowfish context.
  *
- * \param ctx      Blowfish context to be cleared
+ * \param ctx      The Blowfish context to be cleared.
+ *                 This may be \c NULL, in which case this function
+ *                 returns immediately. If it is not \c NULL, it must
+ *                 point to an initialized Blowfish context.
  */
 void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx );
 
 /**
- * \brief          Blowfish key schedule
+ * \brief          Perform a Blowfish key schedule operation.
  *
- * \param ctx      Blowfish context to be initialized
- * \param key      encryption key
- * \param keybits  must be between 32 and 448 bits
+ * \param ctx      The Blowfish context to perform the key schedule on.
+ * \param key      The encryption key. This must be a readable buffer of
+ *                 length \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be between
+ *                 \c 32 and \c 448 and a multiple of \c 8.
  *
- * \return         0 if successful, or MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
                      unsigned int keybits );
 
 /**
- * \brief          Blowfish-ECB block encryption/decryption
+ * \brief          Perform a Blowfish-ECB block encryption/decryption operation.
  *
- * \param ctx      Blowfish context
- * \param mode     MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
- * \param input    8-byte input block
- * \param output   8-byte output block
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param input    The input block. This must be a readable buffer
+ *                 of size \c 8 Bytes.
+ * \param output   The output block. This must be a writable buffer
+ *                 of size \c 8 Bytes.
  *
- * \return         0 if successful
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
                         int mode,
@@ -105,9 +131,7 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
 /**
- * \brief          Blowfish-CBC buffer encryption/decryption
- *                 Length should be a multiple of the block
- *                 size (8 bytes)
+ * \brief          Perform a Blowfish-CBC buffer encryption/decryption operation.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -117,15 +141,22 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      Blowfish context
- * \param mode     MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
- * \param length   length of the input data
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes. This must be
+ *                 multiple of \c 8.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 8 Bytes. It is updated by this function.
+ * \param input    The input data. This must be a readable buffer of length
+ *                 \p length Bytes.
+ * \param output   The output data. This must be a writable buffer of length
+ *                 \p length Bytes.
  *
- * \return         0 if successful, or
- *                 MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
                         int mode,
@@ -137,7 +168,7 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
 /**
- * \brief          Blowfish CFB buffer encryption/decryption.
+ * \brief          Perform a Blowfish CFB buffer encryption/decryption operation.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -147,15 +178,25 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      Blowfish context
- * \param mode     MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
- * \param length   length of the input data
- * \param iv_off   offset in IV (updated after use)
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes.
+ * \param iv_off   The offset in the initialiation vector.
+ *                 The value pointed to must be smaller than \c 8 Bytes.
+ *                 It is updated by this function to support the aforementioned
+ *                 streaming usage.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of size \c 8 Bytes. It is updated after use.
+ * \param input    The input data. This must be a readable buffer of length
+ *                 \p length Bytes.
+ * \param output   The output data. This must be a writable buffer of length
+ *                 \p length Bytes.
  *
- * \return         0 if successful
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
                           int mode,
@@ -168,22 +209,67 @@ int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /**
- * \brief               Blowfish-CTR buffer encryption/decryption
+ * \brief      Perform a Blowfish-CTR buffer encryption/decryption operation.
+ *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             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.
  *
- * Warning: You have to keep the maximum use of your counter in mind!
+ *             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.
  *
- * \param ctx           Blowfish context
- * \param length        The length of the data
+ *             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           The Blowfish context to use. This must be initialized
+ *                      and bound to a key.
+ * \param length        The length of the input data in Bytes.
  * \param nc_off        The offset in the current stream_block (for resuming
- *                      within current cipher stream). The offset pointer to
- *                      should be 0 at the start of a stream.
- * \param nonce_counter The 64-bit nonce and counter.
- * \param stream_block  The saved stream-block for resuming. Is overwritten
- *                      by the function.
- * \param input         The input data stream
- * \param output        The output data stream
- *
- * \return         0 if successful
+ *                      within current cipher stream). The offset pointer
+ *                      should be \c 0 at the start of a stream and must be
+ *                      smaller than \c 8. It is updated by this function.
+ * \param nonce_counter The 64-bit nonce and counter. This must point to a
+ *                      read/write buffer of length \c 8 Bytes.
+ * \param stream_block  The saved stream-block for resuming. This must point to
+ *                      a read/write buffer of length \c 8 Bytes.
+ * \param input         The input data. This must be a readable buffer of
+ *                      length \p length Bytes.
+ * \param output        The output data. This must be a writable buffer of
+ *                      length \p length Bytes.
+ *
+ * \return              \c 0 if successful.
+ * \return              A negative error code on failure.
  */
 int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
                         size_t length,
@@ -198,8 +284,4 @@ int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
 }
 #endif
 
-#else  /* MBEDTLS_BLOWFISH_ALT */
-#include "blowfish_alt.h"
-#endif /* MBEDTLS_BLOWFISH_ALT */
-
 #endif /* blowfish.h */

+ 20 - 3
app/include/mbedtls/bn_mul.h

@@ -571,9 +571,8 @@
 #endif /* TriCore */
 
 /*
- * gcc -O0 by default uses r7 for the frame pointer, so it complains about our
- * use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately,
- * passing that option is not easy when building with yotta.
+ * Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about
+ * our use of r7 below, unless -fomit-frame-pointer is passed.
  *
  * On the other hand, -fomit-frame-pointer is implied by any -Ox options with
  * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
@@ -643,6 +642,24 @@
            "r6", "r7", "r8", "r9", "cc"         \
          );
 
+#elif (__ARM_ARCH >= 6) && \
+    defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
+
+#define MULADDC_INIT                            \
+    asm(
+
+#define MULADDC_CORE                            \
+            "ldr    r0, [%0], #4        \n\t"   \
+            "ldr    r1, [%1]            \n\t"   \
+            "umaal  r1, %2, %3, r0      \n\t"   \
+            "str    r1, [%1], #4        \n\t"
+
+#define MULADDC_STOP                            \
+         : "=r" (s),  "=r" (d), "=r" (c)        \
+         : "r" (b), "0" (s), "1" (d), "2" (c)   \
+         : "r0", "r1", "memory"                 \
+         );
+
 #else
 
 #define MULADDC_INIT                                    \

+ 171 - 82
app/include/mbedtls/camellia.h

@@ -33,78 +33,107 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "platform_util.h"
+
 #define MBEDTLS_CAMELLIA_ENCRYPT     1
 #define MBEDTLS_CAMELLIA_DECRYPT     0
 
-#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH           -0x0024  /**< Invalid key length. */
-#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH         -0x0026  /**< Invalid data input length. */
-#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED              -0x0027  /**< Camellia hardware accelerator failed. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */
 
-#if !defined(MBEDTLS_CAMELLIA_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
+
+/* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED              -0x0027  /**< Camellia hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_CAMELLIA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          CAMELLIA context structure
  */
-typedef struct
+typedef struct mbedtls_camellia_context
 {
     int nr;                     /*!<  number of rounds  */
     uint32_t rk[68];            /*!<  CAMELLIA round keys    */
 }
 mbedtls_camellia_context;
 
+#else  /* MBEDTLS_CAMELLIA_ALT */
+#include "camellia_alt.h"
+#endif /* MBEDTLS_CAMELLIA_ALT */
+
 /**
- * \brief          Initialize CAMELLIA context
+ * \brief          Initialize a CAMELLIA context.
  *
- * \param ctx      CAMELLIA context to be initialized
+ * \param ctx      The CAMELLIA context to be initialized.
+ *                 This must not be \c NULL.
  */
 void mbedtls_camellia_init( mbedtls_camellia_context *ctx );
 
 /**
- * \brief          Clear CAMELLIA context
+ * \brief          Clear a CAMELLIA context.
  *
- * \param ctx      CAMELLIA context to be cleared
+ * \param ctx      The CAMELLIA context to be cleared. This may be \c NULL,
+ *                 in which case this function returns immediately. If it is not
+ *                 \c NULL, it must be initialized.
  */
 void mbedtls_camellia_free( mbedtls_camellia_context *ctx );
 
 /**
- * \brief          CAMELLIA key schedule (encryption)
+ * \brief          Perform a CAMELLIA key schedule operation for encryption.
  *
- * \param ctx      CAMELLIA context to be initialized
- * \param key      encryption key
- * \param keybits  must be 128, 192 or 256
+ * \param ctx      The CAMELLIA context to use. This must be initialized.
+ * \param key      The encryption key to use. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be either \c 128,
+ *                 \c 192 or \c 256.
  *
- * \return         0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
-int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits );
+int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits );
 
 /**
- * \brief          CAMELLIA key schedule (decryption)
+ * \brief          Perform a CAMELLIA key schedule operation for decryption.
  *
- * \param ctx      CAMELLIA context to be initialized
- * \param key      decryption key
- * \param keybits  must be 128, 192 or 256
+ * \param ctx      The CAMELLIA context to use. This must be initialized.
+ * \param key      The decryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be either \c 128,
+ *                 \c 192 or \c 256.
  *
- * \return         0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
-int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits );
+int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits );
 
 /**
- * \brief          CAMELLIA-ECB block encryption/decryption
+ * \brief          Perform a CAMELLIA-ECB block encryption/decryption operation.
  *
- * \param ctx      CAMELLIA context
- * \param mode     MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
- * \param input    16-byte input block
- * \param output   16-byte output block
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param input    The input block. This must be a readable buffer
+ *                 of size \c 16 Bytes.
+ * \param output   The output block. This must be a writable buffer
+ *                 of size \c 16 Bytes.
  *
- * \return         0 if successful
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
                     int mode,
@@ -113,9 +142,7 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
 /**
- * \brief          CAMELLIA-CBC buffer encryption/decryption
- *                 Length should be a multiple of the block
- *                 size (16 bytes)
+ * \brief          Perform a CAMELLIA-CBC buffer encryption/decryption operation.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -125,15 +152,22 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      CAMELLIA context
- * \param mode     MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
- * \param length   length of the input data
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param length   The length in Bytes of the input data \p input.
+ *                 This must be a multiple of \c 16 Bytes.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 16 Bytes. It is updated to allow streaming
+ *                 use as explained above.
+ * \param input    The buffer holding the input data. This must point to a
+ *                 readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must point to a
+ *                 writable buffer of length \p length Bytes.
  *
- * \return         0 if successful, or
- *                 MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
                     int mode,
@@ -145,11 +179,14 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CFB)
 /**
- * \brief          CAMELLIA-CFB128 buffer encryption/decryption
+ * \brief          Perform a CAMELLIA-CFB128 buffer encryption/decryption
+ *                 operation.
  *
- * Note: Due to the nature of CFB you should use the same key schedule for
- * both encryption and decryption. So a context initialized with
- * mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT.
+ * \note           Due to the nature of CFB mode, you should use the same
+ *                 key for both encryption and decryption. In particular, calls
+ *                 to this function should be preceded by a key-schedule via
+ *                 mbedtls_camellia_setkey_enc() regardless of whether \p mode
+ *                 is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
  *
  * \note           Upon exit, the content of the IV is updated so that you can
  *                 call the function same function again on the following
@@ -159,16 +196,24 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
  *                 IV, you should either save it manually or use the cipher
  *                 module instead.
  *
- * \param ctx      CAMELLIA context
- * \param mode     MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
- * \param length   length of the input data
- * \param iv_off   offset in IV (updated after use)
- * \param iv       initialization vector (updated after use)
- * \param input    buffer holding the input data
- * \param output   buffer holding the output data
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param length   The length of the input data \p input. Any value is allowed.
+ * \param iv_off   The current offset in the IV. This must be smaller
+ *                 than \c 16 Bytes. It is updated after this call to allow
+ *                 the aforementioned streaming usage.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 16 Bytes. It is updated after this call to
+ *                 allow the aforementioned streaming usage.
+ * \param input    The buffer holding the input data. This must be a readable
+ *                 buffer of size \p length Bytes.
+ * \param output   The buffer to hold the output data. This must be a writable
+ *                 buffer of length \p length Bytes.
  *
- * \return         0 if successful, or
- *                 MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
  */
 int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
                        int mode,
@@ -181,26 +226,78 @@ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
 
 #if defined(MBEDTLS_CIPHER_MODE_CTR)
 /**
- * \brief               CAMELLIA-CTR buffer encryption/decryption
+ * \brief      Perform a CAMELLIA-CTR buffer encryption/decryption operation.
+ *
+ * *note       Due to the nature of CTR mode, you should use the same
+ *             key for both encryption and decryption. In particular, calls
+ *             to this function should be preceded by a key-schedule via
+ *             mbedtls_camellia_setkey_enc() regardless of whether \p mode
+ *             is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
  *
- * Warning: You have to keep the maximum use of your counter in mind!
+ *             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.
  *
- * 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.
+ *             With this strategy, you must not encrypt more than 2**128
+ *             blocks of data with the same key.
  *
- * \param ctx           CAMELLIA context
- * \param length        The length of the data
- * \param nc_off        The offset in the current stream_block (for resuming
+ *             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 \c 12 Bytes for the
+ *             per-message nonce, and the last \c 4 Bytes for internal use.
+ *             In that case, before calling this function on a new message you
+ *             need to set the first \c 12 Bytes of \p nonce_counter to your
+ *             chosen nonce value, the last four to \c 0, and \p nc_off to \c 0
+ *             (which will cause \p stream_block to be ignored). That way, you
+ *             can encrypt at most \c 2**96 messages of up to \c 2**32 blocks
+ *             each  with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be
+ *             unique. The recommended way to ensure uniqueness is to use a
+ *             message counter. An alternative is to generate random nonces,
+ *             but this limits the number of messages that can be securely
+ *             encrypted: for example, with 96-bit random nonces, you should
+ *             not encrypt more than 2**32 messages with the same key.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that a CAMELLIA block is \c 16 Bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
+ *
+ * \param ctx           The CAMELLIA context to use. This must be initialized
+ *                      and bound to a key.
+ * \param length        The length of the input data \p input in Bytes.
+ *                      Any value is allowed.
+ * \param nc_off        The offset in the current \p stream_block (for resuming
  *                      within current cipher stream). The offset pointer to
- *                      should be 0 at the start of a stream.
- * \param nonce_counter The 128-bit nonce and counter.
- * \param stream_block  The saved stream-block for resuming. Is overwritten
- *                      by the function.
- * \param input         The input data stream
- * \param output        The output data stream
- *
- * \return         0 if successful
+ *                      should be \c 0 at the start of a stream. It is updated
+ *                      at the end of this call.
+ * \param nonce_counter The 128-bit nonce and counter. This must be a read/write
+ *                      buffer of length \c 16 Bytes.
+ * \param stream_block  The saved stream-block for resuming. This must be a
+ *                      read/write buffer of length \c 16 Bytes.
+ * \param input         The input data stream. This must be a readable buffer of
+ *                      size \p length Bytes.
+ * \param output        The output data stream. This must be a writable buffer
+ *                      of size \p length Bytes.
+ *
+ * \return              \c 0 if successful.
+ * \return              A negative error code on failure.
  */
 int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
                        size_t length,
@@ -211,17 +308,7 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
                        unsigned char *output );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_CAMELLIA_ALT */
-#include "camellia_alt.h"
-#endif /* MBEDTLS_CAMELLIA_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#if defined(MBEDTLS_SELF_TEST)
 
 /**
  * \brief          Checkup routine
@@ -230,6 +317,8 @@ extern "C" {
  */
 int mbedtls_camellia_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 181 - 47
app/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
@@ -34,35 +49,48 @@
 #ifndef MBEDTLS_CCM_H
 #define MBEDTLS_CCM_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "cipher.h"
 
 #define MBEDTLS_ERR_CCM_BAD_INPUT       -0x000D /**< Bad input parameters to the function. */
 #define MBEDTLS_ERR_CCM_AUTH_FAILED     -0x000F /**< Authenticated decryption failed. */
-#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
 
-#if !defined(MBEDTLS_CCM_ALT)
-// Regular implementation
-//
+/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_CCM_ALT)
+// Regular implementation
+//
+
 /**
  * \brief    The CCM context-type definition. The CCM context is passed
  *           to the APIs called.
  */
-typedef struct {
+typedef struct mbedtls_ccm_context
+{
     mbedtls_cipher_context_t cipher_ctx;    /*!< The cipher context used. */
 }
 mbedtls_ccm_context;
 
+#else  /* MBEDTLS_CCM_ALT */
+#include "ccm_alt.h"
+#endif /* MBEDTLS_CCM_ALT */
+
 /**
  * \brief           This function initializes the specified CCM context,
  *                  to make references valid, and prepare the context
  *                  for mbedtls_ccm_setkey() or mbedtls_ccm_free().
  *
- * \param ctx       The CCM context to initialize.
+ * \param ctx       The CCM context to initialize. This must not be \c NULL.
  */
 void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
 
@@ -70,12 +98,14 @@ void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
  * \brief           This function initializes the CCM context set in the
  *                  \p ctx parameter and sets the encryption key.
  *
- * \param ctx       The CCM context to initialize.
+ * \param ctx       The CCM context to initialize. This must be an initialized
+ *                  context.
  * \param cipher    The 128-bit block cipher to use.
- * \param key       The encryption key.
+ * \param key       The encryption key. This must not be \c NULL.
  * \param keybits   The key size in bits. This must be acceptable by the cipher.
  *
- * \return          \c 0 on success, 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,
@@ -86,36 +116,96 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
  * \brief   This function releases and clears the specified CCM context
  *          and underlying cipher sub-context.
  *
- * \param ctx       The CCM context to clear.
+ * \param ctx       The CCM context to clear. If this is \c NULL, the function
+ *                  has no effect. Otherwise, this must be initialized.
  */
 void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
 
 /**
  * \brief           This function encrypts a buffer using CCM.
  *
- * \param ctx       The CCM context to use for encryption.
+ * \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. This must be
+ *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
- * \param iv        Initialization vector (nonce).
- * \param iv_len    The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
- * \param add       The additional data field.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. If \p add_len is greater than
+ *                  zero, \p add must be a readable buffer of at least that
+ *                  length.
  * \param add_len   The length of additional data in Bytes.
- *                  Must be less than 2^16 - 2^8.
- * \param input     The buffer holding the input data.
- * \param output    The buffer holding the output data.
- *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the tag.
- * \param tag_len   The length of the tag to generate in Bytes:
+ *                  This must be less than `2^16 - 2^8`.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  4, 6, 8, 10, 12, 14 or 16.
  *
+ * \return          \c 0 on success.
+ * \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. This must be
+ *                  initialized and bound to a key.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. This must be a readable buffer of
+ *                  at least \p add_len Bytes.
+ * \param add_len   The length of additional data in Bytes.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
+ *                  0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning         Passing \c 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,
@@ -125,22 +215,32 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
  * \brief           This function performs a CCM authenticated decryption of a
  *                  buffer.
  *
- * \param ctx       The CCM context to use for decryption.
+ * \param ctx       The CCM context to use for decryption. This must be
+ *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
- * \param iv        Initialization vector.
- * \param iv_len    The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
- * \param add       The additional data field.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. This must be a readable buffer
+ *                  of at least that \p add_len Bytes..
  * \param add_len   The length of additional data in Bytes.
- *                  Must be less than 2^16 - 2^8.
- * \param input     The buffer holding the input data.
- * \param output    The buffer holding the output data.
- *                  Must be at least \p length Bytes wide.
- * \param tag       The buffer holding the tag.
- * \param tag_len   The length of the tag in Bytes.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  4, 6, 8, 10, 12, 14 or 16.
  *
- * \return          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 +248,57 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                       const unsigned char *input, unsigned char *output,
                       const unsigned char *tag, size_t tag_len );
 
-#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. This must be
+ *                  initialized and bound to a key.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. This must be a readable buffer of
+ *                  at least that \p add_len Bytes.
+ * \param add_len   The length of additional data in Bytes.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field in Bytes.
+ *                  0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning         Passing \c 0 as \p tag_len means that the message is nos
+ *                  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 */

+ 196 - 44
app/include/mbedtls/certs.h

@@ -24,74 +24,226 @@
 #ifndef MBEDTLS_CERTS_H
 #define MBEDTLS_CERTS_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include <stddef.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* List of all PEM-encoded CA certificates, terminated by NULL;
+ * PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded
+ * otherwise. */
+extern const char * mbedtls_test_cas[];
+extern const size_t mbedtls_test_cas_len[];
+
+/* List of all DER-encoded CA certificates, terminated by NULL */
+extern const unsigned char * mbedtls_test_cas_der[];
+extern const size_t mbedtls_test_cas_der_len[];
+
 #if defined(MBEDTLS_PEM_PARSE_C)
 /* Concatenation of all CA certificates in PEM format if available */
 extern const char   mbedtls_test_cas_pem[];
 extern const size_t mbedtls_test_cas_pem_len;
-#endif
-
-/* List of all CA certificates, terminated by NULL */
-extern const char * mbedtls_test_cas[];
-extern const size_t mbedtls_test_cas_len[];
+#endif /* MBEDTLS_PEM_PARSE_C */
 
 /*
- * Convenience for users who just want a certificate:
- * RSA by default, or ECDSA if RSA is not available
+ * CA test certificates
  */
+
+extern const char mbedtls_test_ca_crt_ec_pem[];
+extern const char mbedtls_test_ca_key_ec_pem[];
+extern const char mbedtls_test_ca_pwd_ec_pem[];
+extern const char mbedtls_test_ca_key_rsa_pem[];
+extern const char mbedtls_test_ca_pwd_rsa_pem[];
+extern const char mbedtls_test_ca_crt_rsa_sha1_pem[];
+extern const char mbedtls_test_ca_crt_rsa_sha256_pem[];
+
+extern const unsigned char mbedtls_test_ca_crt_ec_der[];
+extern const unsigned char mbedtls_test_ca_key_ec_der[];
+extern const unsigned char mbedtls_test_ca_key_rsa_der[];
+extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[];
+extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[];
+
+extern const size_t mbedtls_test_ca_crt_ec_pem_len;
+extern const size_t mbedtls_test_ca_key_ec_pem_len;
+extern const size_t mbedtls_test_ca_pwd_ec_pem_len;
+extern const size_t mbedtls_test_ca_key_rsa_pem_len;
+extern const size_t mbedtls_test_ca_pwd_rsa_pem_len;
+extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len;
+extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len;
+
+extern const size_t mbedtls_test_ca_crt_ec_der_len;
+extern const size_t mbedtls_test_ca_key_ec_der_len;
+extern const size_t mbedtls_test_ca_pwd_ec_der_len;
+extern const size_t mbedtls_test_ca_key_rsa_der_len;
+extern const size_t mbedtls_test_ca_pwd_rsa_der_len;
+extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len;
+extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len;
+
+/* Config-dependent dispatch between PEM and DER encoding
+ * (PEM if enabled, otherwise DER) */
+
+extern const char mbedtls_test_ca_crt_ec[];
+extern const char mbedtls_test_ca_key_ec[];
+extern const char mbedtls_test_ca_pwd_ec[];
+extern const char mbedtls_test_ca_key_rsa[];
+extern const char mbedtls_test_ca_pwd_rsa[];
+extern const char mbedtls_test_ca_crt_rsa_sha1[];
+extern const char mbedtls_test_ca_crt_rsa_sha256[];
+
+extern const size_t mbedtls_test_ca_crt_ec_len;
+extern const size_t mbedtls_test_ca_key_ec_len;
+extern const size_t mbedtls_test_ca_pwd_ec_len;
+extern const size_t mbedtls_test_ca_key_rsa_len;
+extern const size_t mbedtls_test_ca_pwd_rsa_len;
+extern const size_t mbedtls_test_ca_crt_rsa_sha1_len;
+extern const size_t mbedtls_test_ca_crt_rsa_sha256_len;
+
+/* Config-dependent dispatch between SHA-1 and SHA-256
+ * (SHA-256 if enabled, otherwise SHA-1) */
+
+extern const char mbedtls_test_ca_crt_rsa[];
+extern const size_t mbedtls_test_ca_crt_rsa_len;
+
+/* Config-dependent dispatch between EC and RSA
+ * (RSA if enabled, otherwise EC) */
+
 extern const char * mbedtls_test_ca_crt;
-extern const size_t mbedtls_test_ca_crt_len;
 extern const char * mbedtls_test_ca_key;
-extern const size_t mbedtls_test_ca_key_len;
 extern const char * mbedtls_test_ca_pwd;
+extern const size_t mbedtls_test_ca_crt_len;
+extern const size_t mbedtls_test_ca_key_len;
 extern const size_t mbedtls_test_ca_pwd_len;
+
+/*
+ * Server test certificates
+ */
+
+extern const char mbedtls_test_srv_crt_ec_pem[];
+extern const char mbedtls_test_srv_key_ec_pem[];
+extern const char mbedtls_test_srv_pwd_ec_pem[];
+extern const char mbedtls_test_srv_key_rsa_pem[];
+extern const char mbedtls_test_srv_pwd_rsa_pem[];
+extern const char mbedtls_test_srv_crt_rsa_sha1_pem[];
+extern const char mbedtls_test_srv_crt_rsa_sha256_pem[];
+
+extern const unsigned char mbedtls_test_srv_crt_ec_der[];
+extern const unsigned char mbedtls_test_srv_key_ec_der[];
+extern const unsigned char mbedtls_test_srv_key_rsa_der[];
+extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[];
+extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[];
+
+extern const size_t mbedtls_test_srv_crt_ec_pem_len;
+extern const size_t mbedtls_test_srv_key_ec_pem_len;
+extern const size_t mbedtls_test_srv_pwd_ec_pem_len;
+extern const size_t mbedtls_test_srv_key_rsa_pem_len;
+extern const size_t mbedtls_test_srv_pwd_rsa_pem_len;
+extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len;
+extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len;
+
+extern const size_t mbedtls_test_srv_crt_ec_der_len;
+extern const size_t mbedtls_test_srv_key_ec_der_len;
+extern const size_t mbedtls_test_srv_pwd_ec_der_len;
+extern const size_t mbedtls_test_srv_key_rsa_der_len;
+extern const size_t mbedtls_test_srv_pwd_rsa_der_len;
+extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len;
+extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len;
+
+/* Config-dependent dispatch between PEM and DER encoding
+ * (PEM if enabled, otherwise DER) */
+
+extern const char mbedtls_test_srv_crt_ec[];
+extern const char mbedtls_test_srv_key_ec[];
+extern const char mbedtls_test_srv_pwd_ec[];
+extern const char mbedtls_test_srv_key_rsa[];
+extern const char mbedtls_test_srv_pwd_rsa[];
+extern const char mbedtls_test_srv_crt_rsa_sha1[];
+extern const char mbedtls_test_srv_crt_rsa_sha256[];
+
+extern const size_t mbedtls_test_srv_crt_ec_len;
+extern const size_t mbedtls_test_srv_key_ec_len;
+extern const size_t mbedtls_test_srv_pwd_ec_len;
+extern const size_t mbedtls_test_srv_key_rsa_len;
+extern const size_t mbedtls_test_srv_pwd_rsa_len;
+extern const size_t mbedtls_test_srv_crt_rsa_sha1_len;
+extern const size_t mbedtls_test_srv_crt_rsa_sha256_len;
+
+/* Config-dependent dispatch between SHA-1 and SHA-256
+ * (SHA-256 if enabled, otherwise SHA-1) */
+
+extern const char mbedtls_test_srv_crt_rsa[];
+extern const size_t mbedtls_test_srv_crt_rsa_len;
+
+/* Config-dependent dispatch between EC and RSA
+ * (RSA if enabled, otherwise EC) */
+
 extern const char * mbedtls_test_srv_crt;
-extern const size_t mbedtls_test_srv_crt_len;
 extern const char * mbedtls_test_srv_key;
+extern const char * mbedtls_test_srv_pwd;
+extern const size_t mbedtls_test_srv_crt_len;
 extern const size_t mbedtls_test_srv_key_len;
-extern const char * mbedtls_test_cli_crt;
-extern const size_t mbedtls_test_cli_crt_len;
-extern const char * mbedtls_test_cli_key;
-extern const size_t mbedtls_test_cli_key_len;
+extern const size_t mbedtls_test_srv_pwd_len;
+
+/*
+ * Client test certificates
+ */
+
+extern const char mbedtls_test_cli_crt_ec_pem[];
+extern const char mbedtls_test_cli_key_ec_pem[];
+extern const char mbedtls_test_cli_pwd_ec_pem[];
+extern const char mbedtls_test_cli_key_rsa_pem[];
+extern const char mbedtls_test_cli_pwd_rsa_pem[];
+extern const char mbedtls_test_cli_crt_rsa_pem[];
+
+extern const unsigned char mbedtls_test_cli_crt_ec_der[];
+extern const unsigned char mbedtls_test_cli_key_ec_der[];
+extern const unsigned char mbedtls_test_cli_key_rsa_der[];
+extern const unsigned char mbedtls_test_cli_crt_rsa_der[];
+
+extern const size_t mbedtls_test_cli_crt_ec_pem_len;
+extern const size_t mbedtls_test_cli_key_ec_pem_len;
+extern const size_t mbedtls_test_cli_pwd_ec_pem_len;
+extern const size_t mbedtls_test_cli_key_rsa_pem_len;
+extern const size_t mbedtls_test_cli_pwd_rsa_pem_len;
+extern const size_t mbedtls_test_cli_crt_rsa_pem_len;
+
+extern const size_t mbedtls_test_cli_crt_ec_der_len;
+extern const size_t mbedtls_test_cli_key_ec_der_len;
+extern const size_t mbedtls_test_cli_key_rsa_der_len;
+extern const size_t mbedtls_test_cli_crt_rsa_der_len;
+
+/* Config-dependent dispatch between PEM and DER encoding
+ * (PEM if enabled, otherwise DER) */
+
+extern const char mbedtls_test_cli_crt_ec[];
+extern const char mbedtls_test_cli_key_ec[];
+extern const char mbedtls_test_cli_pwd_ec[];
+extern const char mbedtls_test_cli_key_rsa[];
+extern const char mbedtls_test_cli_pwd_rsa[];
+extern const char mbedtls_test_cli_crt_rsa[];
 
-#if defined(MBEDTLS_ECDSA_C)
-extern const char   mbedtls_test_ca_crt_ec[];
-extern const size_t mbedtls_test_ca_crt_ec_len;
-extern const char   mbedtls_test_ca_key_ec[];
-extern const size_t mbedtls_test_ca_key_ec_len;
-extern const char   mbedtls_test_ca_pwd_ec[];
-extern const size_t mbedtls_test_ca_pwd_ec_len;
-extern const char   mbedtls_test_srv_crt_ec[];
-extern const size_t mbedtls_test_srv_crt_ec_len;
-extern const char   mbedtls_test_srv_key_ec[];
-extern const size_t mbedtls_test_srv_key_ec_len;
-extern const char   mbedtls_test_cli_crt_ec[];
 extern const size_t mbedtls_test_cli_crt_ec_len;
-extern const char   mbedtls_test_cli_key_ec[];
 extern const size_t mbedtls_test_cli_key_ec_len;
-#endif
-
-#if defined(MBEDTLS_RSA_C)
-extern const char   mbedtls_test_ca_crt_rsa[];
-extern const size_t mbedtls_test_ca_crt_rsa_len;
-extern const char   mbedtls_test_ca_key_rsa[];
-extern const size_t mbedtls_test_ca_key_rsa_len;
-extern const char   mbedtls_test_ca_pwd_rsa[];
-extern const size_t mbedtls_test_ca_pwd_rsa_len;
-extern const char   mbedtls_test_srv_crt_rsa[];
-extern const size_t mbedtls_test_srv_crt_rsa_len;
-extern const char   mbedtls_test_srv_key_rsa[];
-extern const size_t mbedtls_test_srv_key_rsa_len;
-extern const char   mbedtls_test_cli_crt_rsa[];
-extern const size_t mbedtls_test_cli_crt_rsa_len;
-extern const char   mbedtls_test_cli_key_rsa[];
+extern const size_t mbedtls_test_cli_pwd_ec_len;
 extern const size_t mbedtls_test_cli_key_rsa_len;
-#endif
+extern const size_t mbedtls_test_cli_pwd_rsa_len;
+extern const size_t mbedtls_test_cli_crt_rsa_len;
+
+/* Config-dependent dispatch between EC and RSA
+ * (RSA if enabled, otherwise EC) */
+
+extern const char * mbedtls_test_cli_crt;
+extern const char * mbedtls_test_cli_key;
+extern const char * mbedtls_test_cli_pwd;
+extern const size_t mbedtls_test_cli_crt_len;
+extern const size_t mbedtls_test_cli_key_len;
+extern const size_t mbedtls_test_cli_pwd_len;
 
 #ifdef __cplusplus
 }

+ 226 - 0
app/include/mbedtls/chacha20.h

@@ -0,0 +1,226 @@
+/**
+ * \file chacha20.h
+ *
+ * \brief   This file contains ChaCha20 definitions and functions.
+ *
+ *          ChaCha20 is a stream cipher that can encrypt and decrypt
+ *          information. ChaCha was created by Daniel Bernstein as a variant of
+ *          its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf
+ *          ChaCha20 is the variant with 20 rounds, that was also standardized
+ *          in RFC 7539.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ */
+
+/*  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
+ *  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_CHACHA20_H
+#define MBEDTLS_CHACHA20_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA         -0x0051 /**< Invalid input parameter(s). */
+
+/* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be
+ * used. */
+#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE    -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */
+
+/* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED        -0x0055  /**< Chacha20 hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_CHACHA20_ALT)
+
+typedef struct mbedtls_chacha20_context
+{
+    uint32_t state[16];          /*! The state (before round operations). */
+    uint8_t  keystream8[64];     /*! Leftover keystream bytes. */
+    size_t keystream_bytes_used; /*! Number of keystream bytes already used. */
+}
+mbedtls_chacha20_context;
+
+#else  /* MBEDTLS_CHACHA20_ALT */
+#include "chacha20_alt.h"
+#endif /* MBEDTLS_CHACHA20_ALT */
+
+/**
+ * \brief           This function initializes the specified ChaCha20 context.
+ *
+ *                  It must be the first API called before using
+ *                  the context.
+ *
+ *                  It is usually followed by calls to
+ *                  \c mbedtls_chacha20_setkey() and
+ *                  \c mbedtls_chacha20_starts(), then one or more calls to
+ *                  to \c mbedtls_chacha20_update(), and finally to
+ *                  \c mbedtls_chacha20_free().
+ *
+ * \param ctx       The ChaCha20 context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx );
+
+/**
+ * \brief           This function releases and clears the specified
+ *                  ChaCha20 context.
+ *
+ * \param ctx       The ChaCha20 context to clear. This may be \c NULL,
+ *                  in which case this function is a no-op. If it is not
+ *                  \c NULL, it must point to an initialized context.
+ *
+ */
+void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx );
+
+/**
+ * \brief           This function sets the encryption/decryption key.
+ *
+ * \note            After using this function, you must also call
+ *                  \c mbedtls_chacha20_starts() to set a nonce before you
+ *                  start encrypting/decrypting data with
+ *                  \c mbedtls_chacha_update().
+ *
+ * \param ctx       The ChaCha20 context to which the key should be bound.
+ *                  It must be initialized.
+ * \param key       The encryption/decryption key. This must be \c 32 Bytes
+ *                  in length.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL.
+ */
+int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
+                             const unsigned char key[32] );
+
+/**
+ * \brief           This function sets the nonce and initial counter value.
+ *
+ * \note            A ChaCha20 context can be re-used with the same key by
+ *                  calling this function to change the nonce.
+ *
+ * \warning         You must never use the same nonce twice with the same key.
+ *                  This would void any confidentiality guarantees for the
+ *                  messages encrypted with the same nonce and key.
+ *
+ * \param ctx       The ChaCha20 context to which the nonce should be bound.
+ *                  It must be initialized and bound to a key.
+ * \param nonce     The nonce. This must be \c 12 Bytes in size.
+ * \param counter   The initial counter value. This is usually \c 0.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is
+ *                  NULL.
+ */
+int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
+                             const unsigned char nonce[12],
+                             uint32_t counter );
+
+/**
+ * \brief           This function encrypts or decrypts data.
+ *
+ *                  Since ChaCha20 is a stream cipher, the same operation is
+ *                  used for encrypting and decrypting data.
+ *
+ * \note            The \p input and \p output pointers must either be equal or
+ *                  point to non-overlapping buffers.
+ *
+ * \note            \c mbedtls_chacha20_setkey() and
+ *                  \c mbedtls_chacha20_starts() must be called at least once
+ *                  to setup the context before this function can be called.
+ *
+ * \note            This function can be called multiple times in a row in
+ *                  order to encrypt of decrypt data piecewise with the same
+ *                  key and nonce.
+ *
+ * \param ctx       The ChaCha20 context to use for encryption or decryption.
+ *                  It must be initialized and bound to a key and nonce.
+ * \param size      The length of the input data in Bytes.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `size == 0`.
+ * \param output    The buffer holding the output data.
+ *                  This must be able to hold \p size Bytes.
+ *                  This pointer can be \c NULL if `size == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
+                             size_t size,
+                             const unsigned char *input,
+                             unsigned char *output );
+
+/**
+ * \brief           This function encrypts or decrypts data with ChaCha20 and
+ *                  the given key and nonce.
+ *
+ *                  Since ChaCha20 is a stream cipher, the same operation is
+ *                  used for encrypting and decrypting data.
+ *
+ * \warning         You must never use the same (key, nonce) pair more than
+ *                  once. This would void any confidentiality guarantees for
+ *                  the messages encrypted with the same nonce and key.
+ *
+ * \note            The \p input and \p output pointers must either be equal or
+ *                  point to non-overlapping buffers.
+ *
+ * \param key       The encryption/decryption key.
+ *                  This must be \c 32 Bytes in length.
+ * \param nonce     The nonce. This must be \c 12 Bytes in size.
+ * \param counter   The initial counter value. This is usually \c 0.
+ * \param size      The length of the input data in Bytes.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `size == 0`.
+ * \param output    The buffer holding the output data.
+ *                  This must be able to hold \p size Bytes.
+ *                  This pointer can be \c NULL if `size == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chacha20_crypt( const unsigned char key[32],
+                            const unsigned char nonce[12],
+                            uint32_t counter,
+                            size_t size,
+                            const unsigned char* input,
+                            unsigned char* output );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief           The ChaCha20 checkup routine.
+ *
+ * \return          \c 0 on success.
+ * \return          \c 1 on failure.
+ */
+int mbedtls_chacha20_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CHACHA20_H */

+ 358 - 0
app/include/mbedtls/chachapoly.h

@@ -0,0 +1,358 @@
+/**
+ * \file chachapoly.h
+ *
+ * \brief   This file contains the AEAD-ChaCha20-Poly1305 definitions and
+ *          functions.
+ *
+ *          ChaCha20-Poly1305 is an algorithm for Authenticated Encryption
+ *          with Associated Data (AEAD) that can be used to encrypt and
+ *          authenticate data. It is based on ChaCha20 and Poly1305 by Daniel
+ *          Bernstein and was standardized in RFC 7539.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ */
+
+/*  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
+ *  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_CHACHAPOLY_H
+#define MBEDTLS_CHACHAPOLY_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/* for shared error codes */
+#include "poly1305.h"
+
+#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE            -0x0054 /**< The requested operation is not permitted in the current state. */
+#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED          -0x0056 /**< Authenticated decryption failed: data was not authentic. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+    MBEDTLS_CHACHAPOLY_ENCRYPT,     /**< The mode value for performing encryption. */
+    MBEDTLS_CHACHAPOLY_DECRYPT      /**< The mode value for performing decryption. */
+}
+mbedtls_chachapoly_mode_t;
+
+#if !defined(MBEDTLS_CHACHAPOLY_ALT)
+
+#include "chacha20.h"
+
+typedef struct mbedtls_chachapoly_context
+{
+    mbedtls_chacha20_context chacha20_ctx;  /**< The ChaCha20 context. */
+    mbedtls_poly1305_context poly1305_ctx;  /**< The Poly1305 context. */
+    uint64_t aad_len;                       /**< The length (bytes) of the Additional Authenticated Data. */
+    uint64_t ciphertext_len;                /**< The length (bytes) of the ciphertext. */
+    int state;                              /**< The current state of the context. */
+    mbedtls_chachapoly_mode_t mode;         /**< Cipher mode (encrypt or decrypt). */
+}
+mbedtls_chachapoly_context;
+
+#else /* !MBEDTLS_CHACHAPOLY_ALT */
+#include "chachapoly_alt.h"
+#endif /* !MBEDTLS_CHACHAPOLY_ALT */
+
+/**
+ * \brief           This function initializes the specified ChaCha20-Poly1305 context.
+ *
+ *                  It must be the first API called before using
+ *                  the context. It must be followed by a call to
+ *                  \c mbedtls_chachapoly_setkey() before any operation can be
+ *                  done, and to \c mbedtls_chachapoly_free() once all
+ *                  operations with that context have been finished.
+ *
+ *                  In order to encrypt or decrypt full messages at once, for
+ *                  each message you should make a single call to
+ *                  \c mbedtls_chachapoly_crypt_and_tag() or
+ *                  \c mbedtls_chachapoly_auth_decrypt().
+ *
+ *                  In order to encrypt messages piecewise, for each
+ *                  message you should make a call to
+ *                  \c mbedtls_chachapoly_starts(), then 0 or more calls to
+ *                  \c mbedtls_chachapoly_update_aad(), then 0 or more calls to
+ *                  \c mbedtls_chachapoly_update(), then one call to
+ *                  \c mbedtls_chachapoly_finish().
+ *
+ * \warning         Decryption with the piecewise API is discouraged! Always
+ *                  use \c mbedtls_chachapoly_auth_decrypt() when possible!
+ *
+ *                  If however this is not possible because the data is too
+ *                  large to fit in memory, you need to:
+ *
+ *                  - call \c mbedtls_chachapoly_starts() and (if needed)
+ *                  \c mbedtls_chachapoly_update_aad() as above,
+ *                  - call \c mbedtls_chachapoly_update() multiple times and
+ *                  ensure its output (the plaintext) is NOT used in any other
+ *                  way than placing it in temporary storage at this point,
+ *                  - call \c mbedtls_chachapoly_finish() to compute the
+ *                  authentication tag and compared it in constant time to the
+ *                  tag received with the ciphertext.
+ *
+ *                  If the tags are not equal, you must immediately discard
+ *                  all previous outputs of \c mbedtls_chachapoly_update(),
+ *                  otherwise you can now safely use the plaintext.
+ *
+ * \param ctx       The ChachaPoly context to initialize. Must not be \c NULL.
+ */
+void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx );
+
+/**
+ * \brief           This function releases and clears the specified
+ *                  ChaCha20-Poly1305 context.
+ *
+ * \param ctx       The ChachaPoly context to clear. This may be \c NULL, in which
+ *                  case this function is a no-op.
+ */
+void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx );
+
+/**
+ * \brief           This function sets the ChaCha20-Poly1305
+ *                  symmetric encryption key.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to which the key should be
+ *                  bound. This must be initialized.
+ * \param key       The \c 256 Bit (\c 32 Bytes) key.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
+                               const unsigned char key[32] );
+
+/**
+ * \brief           This function starts a ChaCha20-Poly1305 encryption or
+ *                  decryption operation.
+ *
+ * \warning         You must never use the same nonce twice with the same key.
+ *                  This would void any confidentiality and authenticity
+ *                  guarantees for the messages encrypted with the same nonce
+ *                  and key.
+ *
+ * \note            If the context is being used for AAD only (no data to
+ *                  encrypt or decrypt) then \p mode can be set to any value.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
+ *                  and bound to a key.
+ * \param nonce     The nonce/IV to use for the message.
+ *                  This must be a redable buffer of length \c 12 Bytes.
+ * \param mode      The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
+ *                  #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
+                               const unsigned char nonce[12],
+                               mbedtls_chachapoly_mode_t mode );
+
+/**
+ * \brief           This function feeds additional data to be authenticated
+ *                  into an ongoing ChaCha20-Poly1305 operation.
+ *
+ *                  The Additional Authenticated Data (AAD), also called
+ *                  Associated Data (AD) is only authenticated but not
+ *                  encrypted nor included in the encrypted output. It is
+ *                  usually transmitted separately from the ciphertext or
+ *                  computed locally by each party.
+ *
+ * \note            This function is called before data is encrypted/decrypted.
+ *                  I.e. call this function to process the AAD before calling
+ *                  \c mbedtls_chachapoly_update().
+ *
+ *                  You may call this function multiple times to process
+ *                  an arbitrary amount of AAD. It is permitted to call
+ *                  this function 0 times, if no AAD is used.
+ *
+ *                  This function cannot be called any more if data has
+ *                  been processed by \c mbedtls_chachapoly_update(),
+ *                  or if the context has been finished.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
+ *                  and bound to a key.
+ * \param aad_len   The length in Bytes of the AAD. The length has no
+ *                  restrictions.
+ * \param aad       Buffer containing the AAD.
+ *                  This pointer can be \c NULL if `aad_len == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
+ *                  if \p ctx or \p aad are NULL.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
+ *                  if the operations has not been started or has been
+ *                  finished, or if the AAD has been finished.
+ */
+int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
+                                   const unsigned char *aad,
+                                   size_t aad_len );
+
+/**
+ * \brief           Thus function feeds data to be encrypted or decrypted
+ *                  into an on-going ChaCha20-Poly1305
+ *                  operation.
+ *
+ *                  The direction (encryption or decryption) depends on the
+ *                  mode that was given when calling
+ *                  \c mbedtls_chachapoly_starts().
+ *
+ *                  You may call this function multiple times to process
+ *                  an arbitrary amount of data. It is permitted to call
+ *                  this function 0 times, if no data is to be encrypted
+ *                  or decrypted.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
+ * \param len       The length (in bytes) of the data to encrypt or decrypt.
+ * \param input     The buffer containing the data to encrypt or decrypt.
+ *                  This pointer can be \c NULL if `len == 0`.
+ * \param output    The buffer to where the encrypted or decrypted data is
+ *                  written. This must be able to hold \p len bytes.
+ *                  This pointer can be \c NULL if `len == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
+ *                  if the operation has not been started or has been
+ *                  finished.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
+                               size_t len,
+                               const unsigned char *input,
+                               unsigned char *output );
+
+/**
+ * \brief           This function finished the ChaCha20-Poly1305 operation and
+ *                  generates the MAC (authentication tag).
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
+ * \param mac       The buffer to where the 128-bit (16 bytes) MAC is written.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
+ *                  if the operation has not been started or has been
+ *                  finished.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
+                               unsigned char mac[16] );
+
+/**
+ * \brief           This function performs a complete ChaCha20-Poly1305
+ *                  authenticated encryption with the previously-set key.
+ *
+ * \note            Before using this function, you must set the key with
+ *                  \c mbedtls_chachapoly_setkey().
+ *
+ * \warning         You must never use the same nonce twice with the same key.
+ *                  This would void any confidentiality and authenticity
+ *                  guarantees for the messages encrypted with the same nonce
+ *                  and key.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
+ *                  This must be initialized.
+ * \param length    The length (in bytes) of the data to encrypt or decrypt.
+ * \param nonce     The 96-bit (12 bytes) nonce/IV to use.
+ * \param aad       The buffer containing the additional authenticated
+ *                  data (AAD). This pointer can be \c NULL if `aad_len == 0`.
+ * \param aad_len   The length (in bytes) of the AAD data to process.
+ * \param input     The buffer containing the data to encrypt or decrypt.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param output    The buffer to where the encrypted or decrypted data
+ *                  is written. This pointer can be \c NULL if `ilen == 0`.
+ * \param tag       The buffer to where the computed 128-bit (16 bytes) MAC
+ *                  is written. This must not be \c NULL.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
+                                        size_t length,
+                                        const unsigned char nonce[12],
+                                        const unsigned char *aad,
+                                        size_t aad_len,
+                                        const unsigned char *input,
+                                        unsigned char *output,
+                                        unsigned char tag[16] );
+
+/**
+ * \brief           This function performs a complete ChaCha20-Poly1305
+ *                  authenticated decryption with the previously-set key.
+ *
+ * \note            Before using this function, you must set the key with
+ *                  \c mbedtls_chachapoly_setkey().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
+ * \param length    The length (in Bytes) of the data to decrypt.
+ * \param nonce     The \c 96 Bit (\c 12 bytes) nonce/IV to use.
+ * \param aad       The buffer containing the additional authenticated data (AAD).
+ *                  This pointer can be \c NULL if `aad_len == 0`.
+ * \param aad_len   The length (in bytes) of the AAD data to process.
+ * \param tag       The buffer holding the authentication tag.
+ *                  This must be a readable buffer of length \c 16 Bytes.
+ * \param input     The buffer containing the data to decrypt.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param output    The buffer to where the decrypted data is written.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
+ *                  if the data was not authentic.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char tag[16],
+                                     const unsigned char *input,
+                                     unsigned char *output );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief           The ChaCha20-Poly1305 checkup routine.
+ *
+ * \return          \c 0 on success.
+ * \return          \c 1 on failure.
+ */
+int mbedtls_chachapoly_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CHACHAPOLY_H */

+ 34 - 4
app/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
@@ -87,6 +87,11 @@
 #error "MBEDTLS_CMAC_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_NIST_KW_C) && \
+    ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
+#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
 #error "MBEDTLS_ECDH_C defined, but not all prerequisites"
 #endif
@@ -103,11 +108,22 @@
 #error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)           && \
+    ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
+      defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)     || \
+      defined(MBEDTLS_ECDSA_SIGN_ALT)          || \
+      defined(MBEDTLS_ECDSA_VERIFY_ALT)        || \
+      defined(MBEDTLS_ECDSA_GENKEY_ALT)        || \
+      defined(MBEDTLS_ECP_INTERNAL_ALT)        || \
+      defined(MBEDTLS_ECP_ALT) )
+#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
+#endif
+
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
 #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || (   \
+#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || (    \
     !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) &&                  \
     !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) &&                  \
     !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) &&                  \
@@ -118,7 +134,9 @@
     !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)   &&                  \
     !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) &&                  \
     !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) &&                  \
-    !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
+    !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) &&                 \
+    !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
 #error "MBEDTLS_ECP_C defined, but not all prerequisites"
 #endif
 
@@ -195,6 +213,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
@@ -259,6 +281,14 @@
 #error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites"
+#endif
+
+#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
+#endif
+
 #if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
 #error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
 #endif
@@ -671,7 +701,7 @@
 /*
  * Avoid warning from -pedantic. This is a convenient place for this
  * workaround since this is included by every single file before the
- * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
+ * #if defined(MBEDTLS_xxx_C) that results in empty translation units.
  */
 typedef int mbedtls_iso_c_forbids_empty_translation_units;
 

+ 357 - 237
app/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>
  */
@@ -34,8 +36,9 @@
 #endif
 
 #include <stddef.h>
+#include "platform_util.h"
 
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 #define MBEDTLS_CIPHER_MODE_AEAD
 #endif
 
@@ -43,7 +46,8 @@
 #define MBEDTLS_CIPHER_MODE_WITH_PADDING
 #endif
 
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
+    defined(MBEDTLS_CHACHA20_C)
 #define MBEDTLS_CIPHER_MODE_STREAM
 #endif
 
@@ -59,6 +63,8 @@
 #define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED  -0x6280  /**< Decryption of block requires a full block. */
 #define MBEDTLS_ERR_CIPHER_AUTH_FAILED          -0x6300  /**< Authentication failed (for AEAD modes). */
 #define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT      -0x6380  /**< The context is invalid. For example, because it was freed. */
+
+/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED      -0x6400  /**< Cipher hardware accelerator failed. */
 
 #define MBEDTLS_CIPHER_VARIABLE_IV_LEN     0x01    /**< Cipher accepts IVs of variable length. */
@@ -69,93 +75,122 @@ extern "C" {
 #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_CHACHA20,  /**< The ChaCha20 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_AES_128_XTS,          /**< AES 128-bit cipher in XTS block mode. */
+    MBEDTLS_CIPHER_AES_256_XTS,          /**< AES 256-bit cipher in XTS block mode. */
+    MBEDTLS_CIPHER_CHACHA20,             /**< ChaCha20 stream cipher. */
+    MBEDTLS_CIPHER_CHACHA20_POLY1305,    /**< ChaCha20-Poly1305 AEAD cipher. */
 } 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_MODE_XTS,                    /**< The XTS cipher mode. */
+    MBEDTLS_MODE_CHACHAPOLY,             /**< The ChaCha-Poly cipher mode. */
 } mbedtls_cipher_mode_t;
 
 /** Supported cipher padding types. */
@@ -163,8 +198,8 @@ typedef enum {
     MBEDTLS_PADDING_PKCS7 = 0,     /**< PKCS7 padding (default).        */
     MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding.         */
     MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding.             */
-    MBEDTLS_PADDING_ZEROS,         /**< zero padding (not reversible). */
-    MBEDTLS_PADDING_NONE,          /**< never pad (full blocks only).   */
+    MBEDTLS_PADDING_ZEROS,         /**< Zero padding (not reversible). */
+    MBEDTLS_PADDING_NONE,          /**< Never pad (full blocks only).   */
 } mbedtls_cipher_padding_t;
 
 /** Type of operation. */
@@ -204,7 +239,8 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
  * Cipher information. Allows calling cipher functions
  * in a generic way.
  */
-typedef struct {
+typedef struct mbedtls_cipher_info_t
+{
     /** Full cipher identifier. For example,
      * MBEDTLS_CIPHER_AES_256_CBC.
      */
@@ -228,7 +264,10 @@ typedef struct {
      */
     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. */
@@ -242,7 +281,8 @@ typedef struct {
 /**
  * Generic cipher context.
  */
-typedef struct {
+typedef struct mbedtls_cipher_context_t
+{
     /** Information about the associated cipher. */
     const mbedtls_cipher_info_t *cipher_info;
 
@@ -268,7 +308,8 @@ typedef struct {
     /** Number of Bytes that have not been processed yet. */
     size_t unprocessed_len;
 
-    /** Current IV or NONCE_COUNTER for CTR-mode. */
+    /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number
+     * for XTS-mode. */
     unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
 
     /** IV size in Bytes, for ciphers with variable-length IVs. */
@@ -296,10 +337,12 @@ const int *mbedtls_cipher_list( void );
  * \brief               This function retrieves the cipher-information
  *                      structure associated with the given cipher name.
  *
- * \param cipher_name   Name of the cipher to search for.
+ * \param cipher_name   Name of the cipher to search for. This must not be
+ *                      \c NULL.
  *
  * \return              The cipher information structure associated with the
- *                      given \p cipher_name, or NULL if not found.
+ *                      given \p cipher_name.
+ * \return              \c NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
 
@@ -310,7 +353,8 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher
  * \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              \c NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
 
@@ -325,7 +369,8 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher
  * \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              \c NULL if the associated cipher information is not found.
  */
 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
                                               int key_bitlen,
@@ -333,6 +378,8 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_ciph
 
 /**
  * \brief               This function initializes a \p cipher_context as NONE.
+ *
+ * \param ctx           The context to be initialized. This must not be \c NULL.
  */
 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
 
@@ -340,6 +387,10 @@ void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
  * \brief               This function frees and clears the cipher-specific
  *                      context of \p ctx. Freeing \p ctx itself remains the
  *                      responsibility of the caller.
+ *
+ * \param ctx           The context to be freed. If this is \c NULL, the
+ *                      function has no effect, otherwise this must point to an
+ *                      initialized context.
  */
 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
 
@@ -349,31 +400,35 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
  *                      structure with the appropriate values. It also clears
  *                      the structure.
  *
- * \param ctx           The context to initialize. May not be NULL.
+ * \param ctx           The context to initialize. This must be initialized.
  * \param cipher_info   The cipher to use.
  *
- * \return              \c 0 on success,
- *                      #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
  * mbedtls_cipher_init() on the structure first.
  */
-int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info );
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
+                          const mbedtls_cipher_info_t *cipher_info );
 
 /**
  * \brief        This function returns the block size of the given cipher.
  *
- * \param ctx    The context of the cipher. Must be initialized.
+ * \param ctx    The context of the cipher. This must be initialized.
  *
- * \return       The size of the blocks of the cipher, or zero if \p ctx
- *               has not been initialized.
+ * \return       The block size of the underlying cipher.
+ * \return       \c 0 if \p ctx has not been initialized.
  */
-static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
+static inline unsigned int mbedtls_cipher_get_block_size(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
         return 0;
 
     return ctx->cipher_info->block_size;
@@ -383,14 +438,16 @@ static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_c
  * \brief        This function returns the mode of operation for
  *               the cipher. For example, MBEDTLS_MODE_CBC.
  *
- * \param ctx    The context of the cipher. Must be initialized.
+ * \param ctx    The context of the cipher. This must be initialized.
  *
- * \return       The mode of operation, 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 )
+static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_MODE_NONE;
 
     return ctx->cipher_info->mode;
@@ -400,15 +457,17 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtl
  * \brief       This function returns the size of the IV or nonce
  *              of the cipher, in Bytes.
  *
- * \param ctx   The context of the cipher. Must be initialized.
+ * \param ctx   The context of the cipher. This must be initialized.
  *
- * \return      <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 )
+static inline int mbedtls_cipher_get_iv_size(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
         return 0;
 
     if( ctx->iv_size != 0 )
@@ -420,14 +479,17 @@ static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ct
 /**
  * \brief               This function returns the type of the given cipher.
  *
- * \param ctx           The context of the cipher. Must be initialized.
+ * \param ctx           The context of the cipher. This must be initialized.
  *
- * \return              The type of the cipher, 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 )
+static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_CIPHER_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_CIPHER_NONE;
 
     return ctx->cipher_info->type;
@@ -437,14 +499,16 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_ciphe
  * \brief               This function returns the name of the given cipher
  *                      as a string.
  *
- * \param ctx           The context of the cipher. Must be initialized.
+ * \param ctx           The context of the cipher. This must be initialized.
  *
- * \return              The name of the cipher, 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 )
+static inline const char *mbedtls_cipher_get_name(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
         return 0;
 
     return ctx->cipher_info->name;
@@ -453,15 +517,18 @@ static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_
 /**
  * \brief               This function returns the key length of the cipher.
  *
- * \param ctx           The context of the cipher. Must be initialized.
+ * \param ctx           The context of the cipher. This must be initialized.
  *
- * \return              The key length of the cipher in bits, 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 )
+static inline int mbedtls_cipher_get_key_bitlen(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_KEY_LENGTH_NONE;
 
     return (int) ctx->cipher_info->key_bitlen;
@@ -470,15 +537,17 @@ static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t
 /**
  * \brief          This function returns the operation of the given cipher.
  *
- * \param ctx      The context of the cipher. Must be initialized.
+ * \param ctx      The context of the cipher. This must be initialized.
  *
- * \return         The type of operation: #MBEDTLS_ENCRYPT or
- *                 #MBEDTLS_DECRYPT, 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 )
+static inline mbedtls_operation_t mbedtls_cipher_get_operation(
+    const mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_OPERATION_NONE );
+    if( ctx->cipher_info == NULL )
         return MBEDTLS_OPERATION_NONE;
 
     return ctx->operation;
@@ -487,20 +556,23 @@ static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_ci
 /**
  * \brief               This function sets the key to use with the given context.
  *
- * \param ctx           The generic cipher context. May not be NULL. Must have
- *                      been initialized using mbedtls_cipher_info_from_type()
- *                      or mbedtls_cipher_info_from_string().
- * \param key           The key to use.
- * \param key_bitlen    The key length to use, in bits.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a cipher information structure.
+ * \param key           The key to use. This must be a readable buffer of at
+ *                      least \p key_bitlen Bits.
+ * \param key_bitlen    The key length to use, in Bits.
  * \param operation     The operation that the key will be used for:
  *                      #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
  *
- * \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 );
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *key,
+                           int key_bitlen,
+                           const mbedtls_operation_t operation );
 
 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
 /**
@@ -509,59 +581,71 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *k
  *
  *                      The default passing mode is PKCS7 padding.
  *
- * \param ctx           The generic cipher context.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a cipher information structure.
  * \param mode          The padding mode.
  *
- * \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 );
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+                                     mbedtls_cipher_padding_t mode );
 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
 
 /**
  * \brief           This function sets the initialization vector (IV)
  *                  or nonce.
  *
- * \param ctx       The generic cipher context.
- * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * \note            Some ciphers do not use IVs nor nonce. For these
+ *                  ciphers, this function has no effect.
+ *
+ * \param ctx       The generic cipher context. This must be initialized and
+ *                  bound to a cipher information structure.
+ * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
+ *                  must be a readable buffer of at least \p iv_len Bytes.
  * \param iv_len    The IV length for ciphers with variable-size IV.
  *                  This parameter is discarded by ciphers with fixed-size IV.
  *
- * \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 );
+                           const unsigned char *iv,
+                           size_t iv_len );
 
 /**
  * \brief         This function resets the cipher state.
  *
- * \param ctx     The generic cipher context.
+ * \param ctx     The generic cipher context. This must be initialized.
  *
- * \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 );
 
-#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 /**
  * \brief               This function adds additional data for AEAD ciphers.
- *                      Only supported with GCM. Must be called
- *                      exactly once, after mbedtls_cipher_reset().
+ *                      Currently supported with GCM and ChaCha20+Poly1305.
+ *                      This must be called exactly once, after
+ *                      mbedtls_cipher_reset().
  *
- * \param ctx           The generic cipher context.
- * \param ad            The additional data to use.
- * \param ad_len        the Length of \p ad.
+ * \param ctx           The generic cipher context. This must be initialized.
+ * \param ad            The additional data to use. This must be a readable
+ *                      buffer of at least \p ad_len Bytes.
+ * \param ad_len        the Length of \p ad Bytes.
  *
- * \return              \c 0 on success, 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 );
-#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
 
 /**
  * \brief               The generic cipher update function. It encrypts or
@@ -573,25 +657,29 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
  *                      Exception: For MBEDTLS_MODE_ECB, expects a single block
  *                      in size. For example, 16 Bytes for AES.
  *
- * \param ctx           The generic cipher context.
- * \param input         The buffer holding the input data.
+ * \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. This must be initialized and
+ *                      bound to a key.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
  * \param ilen          The length of the input data.
- * \param output        The buffer for the output data. Must be able to hold at
- *                      least \p ilen + block_size. Must not be the same buffer
- *                      as input.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least `ilen + block_size`. This must not be the
+ *                      same buffer as \p input.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
  *
- * \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 );
@@ -602,78 +690,94 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
  *                      contained in it is padded to the size of
  *                      the last block, and written to the \p output buffer.
  *
- * \param ctx           The generic cipher context.
- * \param output        The buffer to write data to. Needs block_size available.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
+ * \param output        The buffer to write data to. This needs to be a writable
+ *                      buffer of at least \p block_size Bytes.
  * \param olen          The length of the data written to the \p output buffer.
+ *                      This may not be \c NULL.
  *
- * \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 );
 
-#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 /**
  * \brief               This function writes a tag for AEAD ciphers.
- *                      Only supported with GCM.
- *                      Must be called after mbedtls_cipher_finish().
- *
- * \param ctx           The generic cipher context.
- * \param tag           The buffer to write the tag to.
+ *                      Currently supported with GCM and ChaCha20+Poly1305.
+ *                      This must be called after mbedtls_cipher_finish().
+ *
+ * \param ctx           The generic cipher context. This must be initialized,
+ *                      bound to a key, and have just completed a cipher
+ *                      operation through mbedtls_cipher_finish() the tag for
+ *                      which should be written.
+ * \param tag           The buffer to write the tag to. This must be a writable
+ *                      buffer of at least \p tag_len Bytes.
  * \param tag_len       The length of the tag to write.
  *
- * \return              \c 0 on success, 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 );
 
 /**
  * \brief               This function checks the tag for AEAD ciphers.
- *                      Only supported with GCM.
- *                      Must be called after mbedtls_cipher_finish().
+ *                      Currently supported with GCM and ChaCha20+Poly1305.
+ *                      This must be called after mbedtls_cipher_finish().
  *
- * \param ctx           The generic cipher context.
- * \param tag           The buffer holding the tag.
+ * \param ctx           The generic cipher context. This must be initialized.
+ * \param tag           The buffer holding the tag. This must be a readable
+ *                      buffer of at least \p tag_len Bytes.
  * \param tag_len       The length of the tag to check.
  *
- * \return              \c 0 on success, 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 );
-#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
 
 /**
  * \brief               The generic all-in-one encryption/decryption function,
  *                      for all ciphers except AEAD constructs.
  *
- * \param ctx           The generic cipher context.
+ * \param ctx           The generic cipher context. This must be initialized.
  * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
  * \param iv_len        The IV length for ciphers with variable-size IV.
  *                      This parameter is discarded by ciphers with fixed-size
  *                      IV.
- * \param input         The buffer holding the input data.
- * \param ilen          The length of the input data.
- * \param output        The buffer for the output data. Must be able to hold at
- *                      least \p ilen + block_size. Must not be the same buffer
- *                      as input.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
+ * \param ilen          The length of the input data in Bytes.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least `ilen + block_size`. This must not be the
+ *                      same buffer as \p input.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
  *
  * \note                Some ciphers do not use IVs nor nonce. For these
  *                      ciphers, use \p iv = NULL and \p iv_len = 0.
  *
- * \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,
@@ -684,24 +788,32 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
 /**
  * \brief               The generic autenticated encryption (AEAD) function.
  *
- * \param ctx           The generic cipher context.
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
  * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
  * \param iv_len        The IV length for ciphers with variable-size IV.
  *                      This parameter is discarded by ciphers with fixed-size IV.
- * \param ad            The additional data to authenticate.
+ * \param ad            The additional data to authenticate. This must be a
+ *                      readable buffer of at least \p ad_len Bytes.
  * \param ad_len        The length of \p ad.
- * \param input         The buffer holding the input data.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
  * \param ilen          The length of the input data.
- * \param output        The buffer for the output data.
- *                      Must be able to hold at least \p ilen.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least \p ilen Bytes.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
- * \param tag           The buffer for the authentication tag.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ * \param tag           The buffer for the authentication tag. This must be a
+ *                      writable buffer of at least \p tag_len Bytes.
  * \param tag_len       The desired length of the authentication tag.
  *
- * \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,29 +825,37 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
 /**
  * \brief               The generic autenticated decryption (AEAD) function.
  *
- * \param ctx           The generic cipher context.
+ * \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. This must be initialized and
+ *                      and bound to a key.
  * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
  * \param iv_len        The IV length for ciphers with variable-size IV.
  *                      This parameter is discarded by ciphers with fixed-size IV.
- * \param ad            The additional data to be authenticated.
+ * \param ad            The additional data to be authenticated. This must be a
+ *                      readable buffer of at least \p ad_len Bytes.
  * \param ad_len        The length of \p ad.
- * \param input         The buffer holding the input data.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
  * \param ilen          The length of the input data.
  * \param output        The buffer for the output data.
- *                      Must be able to hold at least \p ilen.
+ *                      This must be able to hold at least \p ilen Bytes.
  * \param olen          The length of the output data, to be updated with the
- *                      actual number of Bytes written.
- * \param tag           The buffer holding the authentication tag.
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ * \param tag           The buffer holding the authentication tag. This must be
+ *                      a readable buffer of at least \p tag_len Bytes.
  * \param tag_len       The length of the authentication tag.
  *
- * \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,

+ 15 - 0
app/include/mbedtls/cipher_internal.h

@@ -64,6 +64,14 @@ struct mbedtls_cipher_base_t
                      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,
@@ -71,6 +79,13 @@ struct mbedtls_cipher_base_t
                      const unsigned char *input, unsigned char *output );
 #endif
 
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    /** Encrypt or decrypt using XTS. */
+    int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
+                     const unsigned char data_unit[16],
+                     const unsigned char *input, unsigned char *output );
+#endif
+
 #if defined(MBEDTLS_CIPHER_MODE_STREAM)
     /** Encrypt using STREAM */
     int (*stream_func)( void *ctx, size_t length,

+ 33 - 28
app/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
@@ -26,21 +28,28 @@
 #ifndef MBEDTLS_CMAC_H
 #define MBEDTLS_CMAC_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "cipher.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A  /**< CMAC hardware accelerator failed. */
 
 #define MBEDTLS_AES_BLOCK_SIZE          16
 #define MBEDTLS_DES3_BLOCK_SIZE         8
 
 #if defined(MBEDTLS_AES_C)
-#define MBEDTLS_CIPHER_BLKSIZE_MAX      16  /* 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 +70,25 @@ struct mbedtls_cmac_context_t
     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 +105,9 @@ int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
  * \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 +123,8 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
  * \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 +140,8 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
  *
  * \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 +164,8 @@ int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
  * \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 +196,12 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
                               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 ) */

+ 8 - 1
app/include/mbedtls/compat-1.3.h

@@ -25,6 +25,12 @@
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
 
 #if defined(MBEDTLS_DEPRECATED_WARNING)
@@ -1378,7 +1384,8 @@
 #define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED
 #define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED
 #define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED
-#define SSL_BUFFER_LEN MBEDTLS_SSL_BUFFER_LEN
+#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \
+                         ? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) )
 #define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES
 #define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT
 #define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED

+ 536 - 34
app/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
@@ -84,6 +88,28 @@
  */
 //#define MBEDTLS_NO_UDBL_DIVISION
 
+/**
+ * \def MBEDTLS_NO_64BIT_MULTIPLICATION
+ *
+ * The platform lacks support for 32x32 -> 64-bit multiplication.
+ *
+ * Used in:
+ *      library/poly1305.c
+ *
+ * Some parts of the library may use multiplication of two unsigned 32-bit
+ * operands with a 64-bit result in order to speed up computations. On some
+ * platforms, this is not available in hardware and has to be implemented in
+ * software, usually in a library provided by the toolchain.
+ *
+ * Sometimes it is not desirable to have to link to that library. This option
+ * removes the dependency of that library on platforms that lack a hardware
+ * 64-bit multiplier by embedding a software implementation in Mbed TLS.
+ *
+ * Note that depending on the compiler, this may decrease performance compared
+ * to using the library function provided by the toolchain.
+ */
+//#define MBEDTLS_NO_64BIT_MULTIPLICATION
+
 /**
  * \def MBEDTLS_HAVE_SSE2
  *
@@ -111,12 +137,21 @@
 /**
  * \def MBEDTLS_HAVE_TIME_DATE
  *
- * System has time.h and time(), gmtime() and the clock is correct.
- * The time needs to be correct (not necesarily very accurate, but at least
+ * System has time.h, time(), and an implementation for
+ * mbedtls_platform_gmtime_r() (see below).
+ * The time needs to be correct (not necessarily very accurate, but at least
  * the date should be correct). This is used to verify the validity period of
  * X.509 certificates.
  *
  * Comment if your system does not have a correct clock.
+ *
+ * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
+ * behaves similarly to the gmtime_r() function from the C standard. Refer to
+ * the documentation for mbedtls_platform_gmtime_r() for more information.
+ *
+ * \note It is possible to configure an implementation for
+ * mbedtls_platform_gmtime_r() at compile-time by using the macro
+ * MBEDTLS_PLATFORM_GMTIME_R_ALT.
  */
 #define MBEDTLS_HAVE_TIME_DATE
 
@@ -221,6 +256,72 @@
  */
 //#define MBEDTLS_DEPRECATED_REMOVED
 
+/**
+ * \def MBEDTLS_CHECK_PARAMS
+ *
+ * This configuration option controls whether the library validates more of
+ * the parameters passed to it.
+ *
+ * When this flag is not defined, the library only attempts to validate an
+ * input parameter if: (1) they may come from the outside world (such as the
+ * network, the filesystem, etc.) or (2) not validating them could result in
+ * internal memory errors such as overflowing a buffer controlled by the
+ * library. On the other hand, it doesn't attempt to validate parameters whose
+ * values are fully controlled by the application (such as pointers).
+ *
+ * When this flag is defined, the library additionally attempts to validate
+ * parameters that are fully controlled by the application, and should always
+ * be valid if the application code is fully correct and trusted.
+ *
+ * For example, when a function accepts as input a pointer to a buffer that may
+ * contain untrusted data, and its documentation mentions that this pointer
+ * must not be NULL:
+ * - The pointer is checked to be non-NULL only if this option is enabled.
+ * - The content of the buffer is always validated.
+ *
+ * When this flag is defined, if a library function receives a parameter that
+ * is invalid:
+ * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED().
+ * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function
+ *   will immediately return. If the function returns an Mbed TLS error code,
+ *   the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
+ *
+ * When defining this flag, you also need to arrange a definition for
+ * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods:
+ * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a
+ *   function mbedtls_param_failed(), but the library does not define this
+ *   function. If you do not make any other arrangements, you must provide
+ *   the function mbedtls_param_failed() in your application.
+ *   See `platform_util.h` for its prototype.
+ * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
+ *   library defines #MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
+ *   You can still supply an alternative definition of
+ *   MBEDTLS_PARAM_FAILED(), which may call `assert`.
+ * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
+ *   or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`,
+ *   the library will call the macro that you defined and will not supply
+ *   its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`,
+ *   you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source
+ *   files include `<assert.h>`.
+ *
+ * Uncomment to enable validation of application-controlled parameters.
+ */
+//#define MBEDTLS_CHECK_PARAMS
+
+/**
+ * \def MBEDTLS_CHECK_PARAMS_ASSERT
+ *
+ * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to
+ * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined.
+ *
+ * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to
+ * calling a function mbedtls_param_failed(). See the documentation of
+ * #MBEDTLS_CHECK_PARAMS for details.
+ *
+ * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`.
+ */
+//#define MBEDTLS_CHECK_PARAMS_ASSERT
+
 /* \} name SECTION: System support */
 
 /**
@@ -271,23 +372,29 @@
  */
 //#define MBEDTLS_AES_ALT
 //#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_ARIA_ALT
 //#define MBEDTLS_BLOWFISH_ALT
 //#define MBEDTLS_CAMELLIA_ALT
 //#define MBEDTLS_CCM_ALT
+//#define MBEDTLS_CHACHA20_ALT
+//#define MBEDTLS_CHACHAPOLY_ALT
 //#define MBEDTLS_CMAC_ALT
 //#define MBEDTLS_DES_ALT
 //#define MBEDTLS_DHM_ALT
 //#define MBEDTLS_ECJPAKE_ALT
 //#define MBEDTLS_GCM_ALT
+//#define MBEDTLS_NIST_KW_ALT
 //#define MBEDTLS_MD2_ALT
 //#define MBEDTLS_MD4_ALT
 //#define MBEDTLS_MD5_ALT
+//#define MBEDTLS_POLY1305_ALT
 //#define MBEDTLS_RIPEMD160_ALT
 //#define MBEDTLS_RSA_ALT
 //#define MBEDTLS_SHA1_ALT
 //#define MBEDTLS_SHA256_ALT
 //#define MBEDTLS_SHA512_ALT
 //#define MBEDTLS_XTEA_ALT
+
 /*
  * When replacing the elliptic curve module, pleace consider, that it is
  * implemented with two .c files:
@@ -318,7 +425,7 @@
  * \note Because of a signature change, the core AES encryption and decryption routines are
  *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
  *       respectively. When setting up alternative implementations, these functions should
- *       be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ *       be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
  *       must stay untouched.
  *
  * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
@@ -333,6 +440,16 @@
  *            dependencies on them, and considering stronger message digests
  *            and ciphers instead.
  *
+ * \warning   If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are
+ *            enabled, then the deterministic ECDH signature functions pass the
+ *            the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore
+ *            alternative implementations should use the RNG only for generating
+ *            the ephemeral key and nothing else. If this is not possible, then
+ *            MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative
+ *            implementation should be provided for mbedtls_ecdsa_sign_det_ext()
+ *            (and for mbedtls_ecdsa_sign_det() too if backward compatibility is
+ *            desirable).
+ *
  */
 //#define MBEDTLS_MD2_PROCESS_ALT
 //#define MBEDTLS_MD4_PROCESS_ALT
@@ -373,11 +490,11 @@
  *      unsigned char mbedtls_internal_ecp_grp_capable(
  *          const mbedtls_ecp_group *grp )
  *      int  mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
- *      void mbedtls_internal_ecp_deinit( const mbedtls_ecp_group *grp )
+ *      void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp )
  * The mbedtls_internal_ecp_grp_capable function should return 1 if the
  * replacement functions implement arithmetic for the given group and 0
  * otherwise.
- * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_deinit are
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are
  * called before and after each point operation and provide an opportunity to
  * implement optimized set up and tear down instructions.
  *
@@ -440,12 +557,45 @@
 /**
  * \def MBEDTLS_AES_ROM_TABLES
  *
- * Store the AES tables in ROM.
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
  *
- * Uncomment this macro to store the AES tables in ROM.
  */
 //#define MBEDTLS_AES_ROM_TABLES
 
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
 /**
  * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
  *
@@ -476,6 +626,20 @@
  */
 #define MBEDTLS_CIPHER_MODE_CTR
 
+/**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback mode (OFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_XTS
+ *
+ * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES.
+ */
+#define MBEDTLS_CIPHER_MODE_XTS
+
 /**
  * \def MBEDTLS_CIPHER_NULL_CIPHER
  *
@@ -525,6 +689,13 @@
 #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
 #define MBEDTLS_CIPHER_PADDING_ZEROS
 
+/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+ *
+ * Uncomment this macro to use a 128-bit key in the CTR_DRBG module.
+ * By default, CTR_DRBG uses a 256-bit key.
+ */
+//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+
 /**
  * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
  *
@@ -556,6 +727,26 @@
  */
 #define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 
+/**
+ * \def MBEDTLS_REMOVE_3DES_CIPHERSUITES
+ *
+ * Remove 3DES ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on 3DES from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible
+ * to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including
+ * them explicitly.
+ *
+ * A man-in-the-browser attacker can recover authentication tokens sent through
+ * a TLS connection using a 3DES based cipher suite (see "On the Practical
+ * (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan
+ * Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls
+ * in your threat model or you are unsure, then you should keep this option
+ * enabled to remove 3DES based cipher suites.
+ *
+ * Comment this macro to keep 3DES in the default ciphersuite list.
+ */
+#define MBEDTLS_REMOVE_3DES_CIPHERSUITES
+
 /**
  * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
  *
@@ -576,6 +767,7 @@
 #define MBEDTLS_ECP_DP_BP384R1_ENABLED
 #define MBEDTLS_ECP_DP_BP512R1_ENABLED
 #define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#define MBEDTLS_ECP_DP_CURVE448_ENABLED
 
 /**
  * \def MBEDTLS_ECP_NIST_OPTIM
@@ -588,6 +780,30 @@
  */
 #define MBEDTLS_ECP_NIST_OPTIM
 
+/**
+ * \def MBEDTLS_ECP_RESTARTABLE
+ *
+ * Enable "non-blocking" ECC operations that can return early and be resumed.
+ *
+ * This allows various functions to pause by returning
+ * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
+ * order to further progress and eventually complete their operation. This is
+ * controlled through mbedtls_ecp_set_max_ops() which limits the maximum
+ * number of ECC operations a function may perform before pausing; see
+ * mbedtls_ecp_set_max_ops() for more information.
+ *
+ * This is useful in non-threaded environments if you want to avoid blocking
+ * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
+ *
+ * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
+ */
+//#define MBEDTLS_ECP_RESTARTABLE
+
 /**
  * \def MBEDTLS_ECDSA_DETERMINISTIC
  *
@@ -1094,6 +1310,17 @@
  */
 #define MBEDTLS_SSL_ALL_ALERT_MESSAGES
 
+/**
+ * \def MBEDTLS_SSL_ASYNC_PRIVATE
+ *
+ * Enable asynchronous external private key operations in SSL. This allows
+ * you to configure an SSL connection to call an external cryptographic
+ * module to perform private key operations instead of performing the
+ * operation inside the library.
+ *
+ */
+//#define MBEDTLS_SSL_ASYNC_PRIVATE
+
 /**
  * \def MBEDTLS_SSL_DEBUG_ALL
  *
@@ -1372,7 +1599,7 @@
  * \def MBEDTLS_SSL_SESSION_TICKETS
  *
  * Enable support for RFC 5077 session tickets in SSL.
- * Client-side, provides full support for session tickets (maintainance of a
+ * Client-side, provides full support for session tickets (maintenance of a
  * session store remains the responsibility of the application, though).
  * Server-side, you also need to provide callbacks for writing and parsing
  * tickets, including authenticated encryption and key management. Example
@@ -1538,10 +1765,13 @@
  *
  * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
  * CRIME attack. Before enabling this option, you should examine with care if
- * CRIME or similar exploits may be a applicable to your use case.
+ * CRIME or similar exploits may be applicable to your use case.
  *
  * \note Currently compression can't be used with DTLS.
  *
+ * \deprecated This feature is deprecated and will be removed
+ *             in the next major revision of the library.
+ *
  * Used in: library/ssl_tls.c
  *          library/ssl_cli.c
  *          library/ssl_srv.c
@@ -1580,7 +1810,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
  *
@@ -1655,7 +1885,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):
@@ -1749,7 +1979,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):
@@ -1798,6 +2028,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
  *
@@ -1824,6 +2106,26 @@
  */
 #define MBEDTLS_CERTS_C
 
+/**
+ * \def MBEDTLS_CHACHA20_C
+ *
+ * Enable the ChaCha20 stream cipher.
+ *
+ * Module:  library/chacha20.c
+ */
+#define MBEDTLS_CHACHA20_C
+
+/**
+ * \def MBEDTLS_CHACHAPOLY_C
+ *
+ * Enable the ChaCha20-Poly1305 AEAD algorithm.
+ *
+ * Module:  library/chachapoly.c
+ *
+ * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
+ */
+#define MBEDTLS_CHACHAPOLY_C
+
 /**
  * \def MBEDTLS_CIPHER_C
  *
@@ -1852,14 +2154,20 @@
 /**
  * \def MBEDTLS_CTR_DRBG_C
  *
- * Enable the CTR_DRBG AES-256-based random generator.
+ * Enable the CTR_DRBG AES-based random generator.
+ * The CTR_DRBG generator uses AES-256 by default.
+ * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
+ *
+ * \note To achieve a 256-bit security strength with CTR_DRBG,
+ *       you must use AES-256 *and* use sufficient entropy.
+ *       See ctr_drbg.h for more details.
  *
  * Module:  library/ctr_drbg.c
  * Caller:
  *
  * Requires: MBEDTLS_AES_C
  *
- * This module provides the CTR_DRBG AES-256 random number generator.
+ * This module provides the CTR_DRBG AES random number generator.
  */
 #define MBEDTLS_CTR_DRBG_C
 
@@ -1884,7 +2192,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):
@@ -2054,6 +2362,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
  *
@@ -2068,6 +2391,19 @@
  */
 #define MBEDTLS_HMAC_DRBG_C
 
+/**
+ * \def MBEDTLS_NIST_KW_C
+ *
+ * Enable the Key Wrapping mode for 128-bit block ciphers,
+ * as defined in NIST SP 800-38F. Only KW and KWP modes
+ * are supported. At the moment, only AES is approved by NIST.
+ *
+ * Module:  library/nist_kw.c
+ *
+ * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C
+ */
+//#define MBEDTLS_NIST_KW_C
+
 /**
  * \def MBEDTLS_MD_C
  *
@@ -2351,6 +2687,16 @@
  */
 #define MBEDTLS_PLATFORM_C
 
+/**
+ * \def MBEDTLS_POLY1305_C
+ *
+ * Enable the Poly1305 MAC algorithm.
+ *
+ * Module:  library/poly1305.c
+ * Caller:  library/chachapoly.c
+ */
+#define MBEDTLS_POLY1305_C
+
 /**
  * \def MBEDTLS_RIPEMD160_C
  *
@@ -2734,7 +3080,7 @@
 //#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
 //#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
-/* Note: your snprintf must correclty zero-terminate the buffer! */
+/* Note: your snprintf must correctly zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
@@ -2751,17 +3097,145 @@
 //#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
 //#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
-/* Note: your snprintf must correclty zero-terminate the buffer! */
+/* Note: your snprintf must correctly zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
 //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 
+/**
+ * \brief       This macro is invoked by the library when an invalid parameter
+ *              is detected that is only checked with #MBEDTLS_CHECK_PARAMS
+ *              (see the documentation of that option for context).
+ *
+ *              When you leave this undefined here, the library provides
+ *              a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT
+ *              is defined, the default definition is `assert(cond)`,
+ *              otherwise the default definition calls a function
+ *              mbedtls_param_failed(). This function is declared in
+ *              `platform_util.h` for the benefit of the library, but
+ *              you need to define in your application.
+ *
+ *              When you define this here, this replaces the default
+ *              definition in platform_util.h (which no longer declares the
+ *              function mbedtls_param_failed()) and it is your responsibility
+ *              to make sure this macro expands to something suitable (in
+ *              particular, that all the necessary declarations are visible
+ *              from within the library - you can ensure that by providing
+ *              them in this file next to the macro definition).
+ *              If you define this macro to call `assert`, also define
+ *              #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files
+ *              include `<assert.h>`.
+ *
+ *              Note that you may define this macro to expand to nothing, in
+ *              which case you don't have to worry about declarations or
+ *              definitions. However, you will then be notified about invalid
+ *              parameters only in non-void functions, and void function will
+ *              just silently return early on invalid parameters, which
+ *              partially negates the benefits of enabling
+ *              #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
+ *
+ * \param cond  The expression that should evaluate to true, but doesn't.
+ */
+//#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
+
 /* SSL Cache options */
 //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
 //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
 
 /* SSL options */
-//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
+
+/** \def MBEDTLS_SSL_MAX_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming and outgoing plaintext fragments.
+ *
+ * This determines the size of both the incoming and outgoing TLS I/O buffers
+ * in such a way that both are capable of holding the specified amount of
+ * plaintext data, regardless of the protection mechanism used.
+ *
+ * To configure incoming and outgoing I/O buffers separately, use
+ * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN,
+ * which overwrite the value set by this option.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of both
+ * incoming and outgoing I/O buffers.
+ */
+//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_IN_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming plaintext fragments.
+ *
+ * This determines the size of the incoming TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option is undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of the incoming I/O buffer
+ * independently of the outgoing I/O buffer.
+ */
+//#define MBEDTLS_SSL_IN_CONTENT_LEN              16384
+
+/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of outgoing plaintext fragments.
+ *
+ * This determines the size of the outgoing TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * It is possible to save RAM by setting a smaller outward buffer, while keeping
+ * the default inward 16384 byte buffer to conform to the TLS specification.
+ *
+ * The minimum required outward buffer size is determined by the handshake
+ * protocol's usage. Handshaking will fail if the outward buffer is too small.
+ * The specific size requirement depends on the configured ciphers and any
+ * certificate data which is sent during the handshake.
+ *
+ * Uncomment to set the maximum plaintext size of the outgoing I/O buffer
+ * independently of the incoming I/O buffer.
+ */
+//#define MBEDTLS_SSL_OUT_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING
+ *
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ *
+ * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * to account for a reassembled handshake message of maximum size,
+ * together with its reassembly bitmap.
+ *
+ * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default)
+ * should be sufficient for all practical situations as it allows
+ * to reassembly a large handshake message (such as a certificate)
+ * while buffering multiple smaller handshake messages.
+ *
+ */
+//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING             32768
+
 //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
 //#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
 //#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
@@ -2815,25 +3289,53 @@
  */
 #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
 
-/* \} name SECTION: Customisation configuration options */
-
-/* Target and application specific configurations */
-//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "target_config.h"
+/**
+ * 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
+
+/**
+ * Uncomment the macro to let Mbed TLS use your alternate implementation of
+ * mbedtls_platform_gmtime_r(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * gmtime() is not a thread-safe function as defined in the C standard. The
+ * library will try to use safer implementations of this function, such as
+ * gmtime_r() when available. However, if Mbed TLS cannot identify the target
+ * system, the implementation of mbedtls_platform_gmtime_r() will default to
+ * using the standard gmtime(). In this case, calls from the library to
+ * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
+ * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
+ * library are also guarded with this mutex to avoid race conditions. However,
+ * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
+ * unconditionally use the implementation for mbedtls_platform_gmtime_r()
+ * supplied at compile time.
+ */
+//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
 
-#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE)
-#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE
-#endif
+/* \} name SECTION: Customisation configuration options */
 
-/*
+/* Target and application specific configurations
+ *
  * Allow user to override any previous default.
  *
- * Use two macro names for that, as:
- * - with yotta the prefix YOTTA_CFG_ is forced
- * - without yotta is looks weird to have a YOTTA prefix.
  */
-#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
-#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
-#elif defined(MBEDTLS_USER_CONFIG_FILE)
+#if defined(MBEDTLS_USER_CONFIG_FILE)
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 

+ 248 - 87
app/include/mbedtls/ctr_drbg.h

@@ -1,13 +1,44 @@
 /**
  * \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 definitions and functions for the
+ *           CTR_DRBG pseudorandom generator.
+ *
+ * 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 (default) or AES-128
+ * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
+ * as the underlying block cipher, with a derivation function.
+ * The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
+ * See the documentation of mbedtls_ctr_drbg_seed() for more details.
+ *
+ * Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
+ * here are the security strengths achieved in typical configuration:
+ * - 256 bits under the default configuration of the library, with AES-256
+ *   and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
+ * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
+ *   to 32 or more, and the DRBG is initialized with an explicit
+ *   nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
+ * - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
+ *   between 24 and 47 and the DRBG is not initialized with an explicit
+ *   nonce (see mbedtls_ctr_drbg_seed()).
+ * - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
+ *   and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
+ *   always the case unless it is explicitly set to a different value
+ *   in config.h).
+ *
+ * Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
+ * - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
+ *   \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
+ *   This is the default configuration of the library.
+ * - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
+ * - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
  */
 /*
- *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  Copyright (C) 2006-2019, 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
@@ -46,7 +77,23 @@
 #define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR                -0x003A  /**< Read or write error in file. */
 
 #define MBEDTLS_CTR_DRBG_BLOCKSIZE          16 /**< The block size used by the cipher. */
-#define MBEDTLS_CTR_DRBG_KEYSIZE            32 /**< The key size used by the cipher. */
+
+#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
+#define MBEDTLS_CTR_DRBG_KEYSIZE            16
+/**< The key size in bytes used by the cipher.
+ *
+ * Compile-time choice: 16 bytes (128 bits)
+ * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled.
+ */
+#else
+#define MBEDTLS_CTR_DRBG_KEYSIZE            32
+/**< The key size in bytes used by the cipher.
+ *
+ * Compile-time choice: 32 bytes (256 bits)
+ * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled.
+ */
+#endif
+
 #define MBEDTLS_CTR_DRBG_KEYBITS            ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
 #define MBEDTLS_CTR_DRBG_SEEDLEN            ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
 
@@ -59,21 +106,31 @@
  * \{
  */
 
+/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN
+ *
+ * \brief The amount of entropy used per seed by default, in bytes.
+ */
 #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
 #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
+/** This is 48 bytes because the entropy module uses SHA-512
+ * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled).
+ */
 #define MBEDTLS_CTR_DRBG_ENTROPY_LEN        48
-/**< The amount of entropy used per seed by default:
- * <ul><li>48 with SHA-512.</li>
- * <li>32 with SHA-256.</li></ul>
+
+#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
+
+/** This is 32 bytes because the entropy module uses SHA-256
+ * (the SHA512 module is disabled or
+ * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
  */
-#else
-#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        32
-/**< Amount of entropy used per seed by default:
- * <ul><li>48 with SHA-512.</li>
- * <li>32 with SHA-256.</li></ul>
+#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
+/** \warning To achieve a 256-bit security strength, you must pass a nonce
+ *           to mbedtls_ctr_drbg_seed().
  */
-#endif
-#endif
+#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
+#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        32
+#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
+#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
 
 #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
 #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL    10000
@@ -92,7 +149,7 @@
 
 #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
 #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT     384
-/**< The maximum size of seed or reseed buffer. */
+/**< The maximum size of seed or reseed buffer in bytes. */
 #endif
 
 /* \} name SECTION: Module settings */
@@ -109,7 +166,7 @@ extern "C" {
 /**
  * \brief          The CTR_DRBG context structure.
  */
-typedef struct
+typedef struct mbedtls_ctr_drbg_context
 {
     unsigned char counter[16];  /*!< The counter (V). */
     int reseed_counter;         /*!< The reseed counter. */
@@ -150,20 +207,71 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
  * \brief               This function seeds and sets up the CTR_DRBG
  *                      entropy source for future reseeds.
  *
- * \note Personalization data can be provided in addition to the more generic
- *       entropy source, to make this instantiation as unique as possible.
- *
+ * A typical choice for the \p f_entropy and \p p_entropy parameters is
+ * to use the entropy module:
+ * - \p f_entropy is mbedtls_entropy_func();
+ * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
+ *   with mbedtls_entropy_init() (which registers the platform's default
+ *   entropy sources).
+ *
+ * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
+ * You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
+ *
+ * You can provide a personalization string in addition to the
+ * entropy source, to make this instantiation as unique as possible.
+ *
+ * \note                The _seed_material_ value passed to the derivation
+ *                      function in the CTR_DRBG Instantiate Process
+ *                      described in NIST SP 800-90A §10.2.1.3.2
+ *                      is the concatenation of the string obtained from
+ *                      calling \p f_entropy and the \p custom string.
+ *                      The origin of the nonce depends on the value of
+ *                      the entropy length relative to the security strength.
+ *                      - If the entropy length is at least 1.5 times the
+ *                        security strength then the nonce is taken from the
+ *                        string obtained with \p f_entropy.
+ *                      - If the entropy length is less than the security
+ *                        strength, then the nonce is taken from \p custom.
+ *                        In this case, for compliance with SP 800-90A,
+ *                        you must pass a unique value of \p custom at
+ *                        each invocation. See SP 800-90A §8.6.7 for more
+ *                        details.
+ */
+#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
+/** \warning            When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than
+ *                      #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the
+ *                      maximum security strength permitted by CTR_DRBG,
+ *                      you must pass a value of \p custom that is a nonce:
+ *                      this value must never be repeated in subsequent
+ *                      runs of the same application or on a different
+ *                      device.
+ */
+#endif
+/**
  * \param ctx           The CTR_DRBG context to seed.
+ *                      It must have been initialized with
+ *                      mbedtls_ctr_drbg_init().
+ *                      After a successful call to mbedtls_ctr_drbg_seed(),
+ *                      you may not call mbedtls_ctr_drbg_seed() again on
+ *                      the same context unless you call
+ *                      mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
+ *                      again first.
  * \param f_entropy     The entropy callback, taking as arguments the
  *                      \p p_entropy context, the buffer to fill, and the
-                        length of the buffer.
- * \param p_entropy     The entropy context.
- * \param custom        Personalization data, that is device-specific
-                        identifiers. Can be NULL.
- * \param len           The length of the personalization data.
- *
- * \return              \c 0 on success, or
- *                      #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
+ *                      length of the buffer.
+ *                      \p f_entropy is always called with a buffer size
+ *                      equal to the entropy length.
+ * \param p_entropy     The entropy context to pass to \p f_entropy.
+ * \param custom        The personalization string.
+ *                      This can be \c NULL, in which case the personalization
+ *                      string is empty regardless of the value of \p len.
+ * \param len           The length of the personalization string.
+ *                      This must be at most
+ *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
+ *                      - #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
+ *
+ * \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),
@@ -183,7 +291,8 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
  *                      The default value is off.
  *
  * \note                If enabled, entropy is gathered at the beginning of
- *                      every call to mbedtls_ctr_drbg_random_with_add().
+ *                      every call to mbedtls_ctr_drbg_random_with_add()
+ *                      or mbedtls_ctr_drbg_random().
  *                      Only use this if your entropy source has sufficient
  *                      throughput.
  *
@@ -195,18 +304,37 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
 
 /**
  * \brief               This function sets the amount of entropy grabbed on each
- *                      seed or reseed. The default value is
- *                      #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
+ *                      seed or reseed.
+ *
+ * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
+ *
+ * \note                The security strength of CTR_DRBG is bounded by the
+ *                      entropy length. Thus:
+ *                      - When using AES-256
+ *                        (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled,
+ *                        which is the default),
+ *                        \p len must be at least 32 (in bytes)
+ *                        to achieve a 256-bit strength.
+ *                      - When using AES-128
+ *                        (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled)
+ *                        \p len must be at least 16 (in bytes)
+ *                        to achieve a 128-bit strength.
  *
  * \param ctx           The CTR_DRBG context.
- * \param len           The amount of entropy to grab.
+ * \param len           The amount of entropy to grab, in bytes.
+ *                      This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
  */
 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
                                size_t len );
 
 /**
  * \brief               This function sets the reseed interval.
- *                      The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
+ *
+ * The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
+ * or mbedtls_ctr_drbg_random_with_add() after which the entropy function
+ * is called again.
+ *
+ * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
  *
  * \param ctx           The CTR_DRBG context.
  * \param interval      The reseed interval.
@@ -219,67 +347,62 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
  *                      extracts data from the entropy source.
  *
  * \param ctx           The CTR_DRBG context.
- * \param additional    Additional data to add to the state. Can be NULL.
+ * \param additional    Additional data to add to the state. Can be \c NULL.
  * \param len           The length of the additional data.
+ *                      This must be less than
+ *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
+ *                      where \c entropy_len is the entropy length
+ *                      configured for the context.
  *
- * \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.
- *
- * \param ctx           The CTR_DRBG context.
- * \param additional    The data to update the state with.
- * \param add_len       Length of \p additional in bytes. This must be at
- *                      most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
- *
- * \return              \c 0 on success.
- * \return              #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
- *                      \p add_len is more than
- *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
- * \return              An error from the underlying AES cipher on failure.
+ * \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. This must not be
+ *                     \c NULL unless \p add_len is \c 0.
+ * \param add_len      Length of \p additional in bytes. This must be at
+ *                     most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ *
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
+ *                     \p add_len is more than
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ * \return             An error from the underlying AES cipher on failure.
  */
 int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
                                  const unsigned char *additional,
                                  size_t add_len );
 
-/**
- * \brief               This function updates the state of the CTR_DRBG context.
- *
- * \warning             This function cannot report errors. You should use
- *                      mbedtls_ctr_drbg_update_ret() instead.
- *
- * \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 );
-
 /**
  * \brief   This function updates a CTR_DRBG instance with additional
  *          data and uses it to generate random data.
  *
- * \note    The function automatically reseeds if the reseed counter is exceeded.
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
  *
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
- * \param output_len    The length of the buffer.
- * \param additional    Additional data to update. Can be NULL.
- * \param add_len       The length of the additional data.
- *
- * \return    \c 0 on success, or
- *            #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * \param output_len    The length of the buffer in bytes.
+ * \param additional    Additional data to update. Can be \c NULL, in which
+ *                      case the additional data is empty regardless of
+ *                      the value of \p add_len.
+ * \param add_len       The length of the additional data
+ *                      if \p additional is not \c NULL.
+ *                      This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT
+ *                      and less than
+ *                      #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
+ *                      where \c entropy_len is the entropy length
+ *                      configured for the context.
+ *
+ * \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,
@@ -289,20 +412,51 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
 /**
  * \brief   This function uses CTR_DRBG to generate random data.
  *
- * \note    The function automatically reseeds if the reseed counter is exceeded.
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
+ *
  *
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
- * \param output_len    The length of the buffer.
+ * \param output_len    The length of the buffer in bytes.
  *
- * \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,
                      unsigned char *output, size_t output_len );
 
+
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief              This function updates the state of the CTR_DRBG context.
+ *
+ * \deprecated         Superseded by mbedtls_ctr_drbg_update_ret()
+ *                     in 2.16.0.
+ *
+ * \note               If \p add_len is greater than
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
+ *                     The remaining Bytes are silently discarded.
+ *
+ * \param ctx          The CTR_DRBG context.
+ * \param additional   The data to update the state with.
+ * \param add_len      Length of \p additional data.
+ */
+MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
+    mbedtls_ctr_drbg_context *ctx,
+    const unsigned char *additional,
+    size_t add_len );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
 #if defined(MBEDTLS_FS_IO)
 /**
  * \brief               This function writes a seed file.
@@ -310,9 +464,9 @@ int mbedtls_ctr_drbg_random( void *p_rng,
  * \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 reseed
  *                      failure.
  */
 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
@@ -324,21 +478,28 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
  * \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
- *                      #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
+ * \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
+ *                      reseed failure.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
+ *                      seed file is too large.
  */
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
 #endif /* MBEDTLS_FS_IO */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \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 );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 /* Internal functions (do not call directly) */
 int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *,
                                int (*)(void *, unsigned char *, size_t), void *,

+ 36 - 0
app/include/mbedtls/debug.h

@@ -65,6 +65,11 @@
     mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt )
 #endif
 
+#if defined(MBEDTLS_ECDH_C)
+#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr )               \
+    mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr )
+#endif
+
 #else /* MBEDTLS_DEBUG_C */
 
 #define MBEDTLS_SSL_DEBUG_MSG( level, args )            do { } while( 0 )
@@ -73,6 +78,7 @@
 #define MBEDTLS_SSL_DEBUG_MPI( level, text, X )         do { } while( 0 )
 #define MBEDTLS_SSL_DEBUG_ECP( level, text, X )         do { } while( 0 )
 #define MBEDTLS_SSL_DEBUG_CRT( level, text, crt )       do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr )     do { } while( 0 )
 
 #endif /* MBEDTLS_DEBUG_C */
 
@@ -221,6 +227,36 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
                       const char *text, const mbedtls_x509_crt *crt );
 #endif
 
+#if defined(MBEDTLS_ECDH_C)
+typedef enum
+{
+    MBEDTLS_DEBUG_ECDH_Q,
+    MBEDTLS_DEBUG_ECDH_QP,
+    MBEDTLS_DEBUG_ECDH_Z,
+} mbedtls_debug_ecdh_attr;
+
+/**
+ * \brief   Print a field of the ECDH structure in the SSL context to the debug
+ *          output. This function is always used through the
+ *          MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
+ *          and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param ecdh      the ECDH context
+ * \param attr      the identifier of the attribute being output
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
+                                const char *file, int line,
+                                const mbedtls_ecdh_context *ecdh,
+                                mbedtls_debug_ecdh_attr attr );
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 15 - 16
app/include/mbedtls/des.h

@@ -42,18 +42,20 @@
 #define MBEDTLS_DES_DECRYPT     0
 
 #define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH              -0x0032  /**< The data input has an invalid length. */
+
+/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_DES_HW_ACCEL_FAILED                   -0x0033  /**< DES hardware accelerator failed. */
 
 #define MBEDTLS_DES_KEY_SIZE    8
 
-#if !defined(MBEDTLS_DES_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_DES_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          DES context structure
  *
@@ -61,7 +63,7 @@ extern "C" {
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
-typedef struct
+typedef struct mbedtls_des_context
 {
     uint32_t sk[32];            /*!<  DES subkeys       */
 }
@@ -70,12 +72,16 @@ mbedtls_des_context;
 /**
  * \brief          Triple-DES context structure
  */
-typedef struct
+typedef struct mbedtls_des3_context
 {
     uint32_t sk[96];            /*!<  3DES subkeys      */
 }
 mbedtls_des3_context;
 
+#else  /* MBEDTLS_DES_ALT */
+#include "des_alt.h"
+#endif /* MBEDTLS_DES_ALT */
+
 /**
  * \brief          Initialize DES context
  *
@@ -331,17 +337,8 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
  */
 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
+#if defined(MBEDTLS_SELF_TEST)
 
 /**
  * \brief          Checkup routine
@@ -350,6 +347,8 @@ extern "C" {
  */
 int mbedtls_des_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 141 - 106
app/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
@@ -79,17 +84,22 @@
 #define MBEDTLS_ERR_DHM_INVALID_FORMAT                    -0x3380  /**< The ASN.1 data is not formatted correctly. */
 #define MBEDTLS_ERR_DHM_ALLOC_FAILED                      -0x3400  /**< Allocation of memory failed. */
 #define MBEDTLS_ERR_DHM_FILE_IO_ERROR                     -0x3480  /**< Read or write of file failed. */
+
+/* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED                   -0x3500  /**< DHM hardware accelerator failed. */
+
 #define MBEDTLS_ERR_DHM_SET_GROUP_FAILED                  -0x3580  /**< Setting the modulus and generator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_DHM_ALT)
+
 /**
  * \brief          The DHM context structure.
  */
-typedef struct
+typedef struct mbedtls_dhm_context
 {
     size_t len;         /*!<  The size of \p P in Bytes. */
     mbedtls_mpi P;      /*!<  The prime modulus. */
@@ -105,6 +115,10 @@ typedef struct
 }
 mbedtls_dhm_context;
 
+#else /* MBEDTLS_DHM_ALT */
+#include "dhm_alt.h"
+#endif /* MBEDTLS_DHM_ALT */
+
 /**
  * \brief          This function initializes the DHM context.
  *
@@ -113,9 +127,15 @@ mbedtls_dhm_context;
 void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
 
 /**
- * \brief          This function parses the ServerKeyExchange parameters.
+ * \brief          This function parses the DHM parameters in a
+ *                 TLS ServerKeyExchange handshake message
+ *                 (DHM modulus, generator, and public key).
+ *
+ * \note           In a TLS handshake, this is the how the client
+ *                 sets up its DHM context from the server's public
+ *                 DHM key material.
  *
- * \param ctx      The DHM context.
+ * \param ctx      The DHM context to use. This must be initialized.
  * \param p        On input, *p must be the start of the input buffer.
  *                 On output, *p is updated to point to the end of the data
  *                 that has been read. On success, this is the first byte
@@ -125,38 +145,44 @@ void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
  *                 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,
-                     const unsigned char *end );
+                             unsigned char **p,
+                             const unsigned char *end );
 
 /**
- * \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.
- *                 It is the responsibility of the caller to ensure that enough
- *                 space is available. Refer to \c mbedtls_mpi_size to computing
- *                 the byte-size of an MPI.
+ * \brief          This function generates a DHM key pair and exports its
+ *                 public part together with the DHM parameters in the format
+ *                 used in a TLS ServerKeyExchange handshake message.
  *
- * \note           This function assumes that \c ctx->P and \c ctx->G
- *                 have already been properly set. For that, use
+ * \note           This function assumes that the DHM parameters \c ctx->P
+ *                 and \c ctx->G have already been properly set. For that, use
  *                 mbedtls_dhm_set_group() below in conjunction with
  *                 mbedtls_mpi_read_binary() and mbedtls_mpi_read_string().
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \note           In a TLS handshake, this is the how the server generates
+ *                 and exports its DHM key material.
+ *
+ * \param ctx      The DHM context to use. This must be initialized
+ *                 and have the DHM parameters set. It may or may not
+ *                 already have imported the peer's public key.
+ * \param x_size   The private key size in Bytes.
+ * \param olen     The address at which to store the number of Bytes
+ *                 written on success. This must not be \c NULL.
+ * \param output   The destination buffer. This must be a writable buffer of
+ *                 sufficient size to hold the reduced binary presentation of
+ *                 the modulus, the generator and the public key, each wrapped
+ *                 with a 2-byte length field. It is the responsibility of the
+ *                 caller to ensure that enough space is available. Refer to
+ *                 mbedtls_mpi_size() to computing the byte-size of an MPI.
+ * \param f_rng    The RNG function. Must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context parameter.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
                      unsigned char *output, size_t *olen,
@@ -164,54 +190,66 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
                      void *p_rng );
 
 /**
- * \brief          Set prime modulus and generator
+ * \brief          This function sets the prime modulus and generator.
  *
- * \param ctx      The DHM context.
- * \param P        The MPI holding DHM prime modulus.
- * \param G        The MPI holding DHM generator.
+ * \note           This function can be used to set \c ctx->P, \c ctx->G
+ *                 in preparation for mbedtls_dhm_make_params().
  *
- * \note           This function can be used to set P, G
- *                 in preparation for \c mbedtls_dhm_make_params.
+ * \param ctx      The DHM context to configure. This must be initialized.
+ * \param P        The MPI holding the DHM prime modulus. This must be
+ *                 an initialized MPI.
+ * \param G        The MPI holding the DHM generator. This must be an
+ *                 initialized MPI.
  *
- * \return         \c 0 if successful, 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 raw public value of the peer.
  *
- * \param ctx      The DHM context.
- * \param input    The input buffer.
- * \param ilen     The size of the input buffer.
+ * \note           In a TLS handshake, this is the how the server imports
+ *                 the Client's public DHM key.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \param ctx      The DHM context to use. This must be initialized and have
+ *                 its DHM parameters set, e.g. via mbedtls_dhm_set_group().
+ *                 It may or may not already have generated its own private key.
+ * \param input    The input buffer containing the \c G^Y value of the peer.
+ *                 This must be a readable buffer of size \p ilen Bytes.
+ * \param ilen     The size of the input buffer \p input in Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
  */
 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
- *                 exports \c G^X.
+ * \brief          This function creates a DHM key pair and exports
+ *                 the raw public key in big-endian format.
  *
- * \param ctx      The DHM context.
- * \param x_size   The private value size in Bytes.
- * \param output   The destination buffer.
- * \param olen     The length of the destination buffer. Must be at least
-                   equal to ctx->len (the size of \c P).
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG parameter.
+ * \note           The destination buffer is always fully written
+ *                 so as to contain a big-endian representation of G^X mod P.
+ *                 If it is larger than \c ctx->len, it is padded accordingly
+ *                 with zero-bytes at the beginning.
  *
- * \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.
+ * \param ctx      The DHM context to use. This must be initialized and
+ *                 have the DHM parameters set. It may or may not already
+ *                 have imported the peer's public key.
+ * \param x_size   The private key size in Bytes.
+ * \param output   The destination buffer. This must be a writable buffer of
+ *                 size \p olen Bytes.
+ * \param olen     The length of the destination buffer. This must be at least
+ *                 equal to `ctx->len` (the size of \c P).
+ * \param f_rng    The RNG function. This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng doesn't need a context argument.
  *
- * \return         \c 0 on success, 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,
@@ -219,25 +257,30 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
                      void *p_rng );
 
 /**
- * \brief               This function derives and exports the shared secret
- *                      \c (G^Y)^X mod \c P.
+ * \brief          This function derives and exports the shared secret
+ *                 \c (G^Y)^X mod \c P.
  *
- * \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.
- * \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.
+ * \note           If \p f_rng is not \c NULL, it is used to blind the input as
+ *                 a countermeasure against timing attacks. Blinding is used
+ *                 only if our private key \c X is re-used, and not used
+ *                 otherwise. We recommend always passing a non-NULL
+ *                 \p f_rng argument.
  *
- * \return         \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code
- *                 on failure.
+ * \param ctx           The DHM context to use. This must be initialized
+ *                      and have its own private key generated and the peer's
+ *                      public key imported.
+ * \param output        The buffer to write the generated shared key to. This
+ *                      must be a writable buffer of size \p output_size Bytes.
+ * \param output_size   The size of the destination buffer. This must be at
+ *                      least the size of \c ctx->len (the size of \c P).
+ * \param olen          On exit, holds the actual number of Bytes written.
+ * \param f_rng         The RNG function, for blinding purposes. This may
+ *                      b \c NULL if blinding isn't needed.
+ * \param p_rng         The RNG context. This may be \c NULL if \p f_rng
+ *                      doesn't need a context argument.
  *
- * \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,9 +288,12 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
                      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.
+ * \param ctx      The DHM context to free and clear. This may be \c NULL,
+ *                 in which case this function is a no-op. If it is not \c NULL,
+ *                 it must point to an initialized DHM context.
  */
 void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
 
@@ -256,16 +302,19 @@ void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
 /**
  * \brief             This function parses DHM parameters in PEM or DER format.
  *
- * \param dhm         The DHM context to initialize.
- * \param dhmin       The input buffer.
- * \param dhminlen    The size of the buffer, including the terminating null
- *                    Byte for PEM data.
+ * \param dhm         The DHM context to import the DHM parameters into.
+ *                    This must be initialized.
+ * \param dhmin       The input buffer. This must be a readable buffer of
+ *                    length \p dhminlen Bytes.
+ * \param dhminlen    The size of the input buffer \p dhmin, including the
+ *                    terminating \c NULL Byte for PEM data.
  *
- * \return            \c 0 on success, 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 on failure.
  */
 int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
-                   size_t dhminlen );
+                           size_t dhminlen );
 
 #if defined(MBEDTLS_FS_IO)
 /** \ingroup x509_module */
@@ -273,34 +322,29 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
  * \brief          This function loads and parses DHM parameters from a file.
  *
  * \param dhm      The DHM context to load the parameters to.
+ *                 This must be initialized.
  * \param path     The filename to read the DHM parameters from.
+ *                 This must not be \c NULL.
  *
- * \return         \c 0 on success, 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 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
+#if defined(MBEDTLS_SELF_TEST)
 
 /**
  * \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 );
 
+#endif /* MBEDTLS_SELF_TEST */
 #ifdef __cplusplus
 }
 #endif
@@ -348,15 +392,6 @@ int mbedtls_dhm_self_test( int verbose );
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-#define MBEDTLS_DEPRECATED __attribute__((deprecated))
-MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_constant_t;
-#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL )       \
-    ( (mbedtls_deprecated_constant_t) ( VAL ) )
-#else
-#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
-#endif /* ! MBEDTLS_DEPRECATED_WARNING */
-
 /**
  * \warning The origin of the primes in RFC 5114 is not documented and
  *          their use therefore constitutes a security risk!

+ 266 - 103
app/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
@@ -33,28 +34,82 @@
 #ifndef MBEDTLS_ECDH_H
 #define MBEDTLS_ECDH_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "ecp.h"
 
+/*
+ * Use a backward compatible ECDH context.
+ *
+ * This flag is always enabled for now and future versions might add a
+ * configuration option that conditionally undefines this flag.
+ * The configuration option in question may have a different name.
+ *
+ * Features undefining this flag, must have a warning in their description in
+ * config.h stating that the feature breaks backward compatibility.
+ */
+#define MBEDTLS_ECDH_LEGACY_CONTEXT
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * 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;
 
+#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+/**
+ * Defines the ECDH implementation used.
+ *
+ * Later versions of the library may add new variants, therefore users should
+ * not make any assumptions about them.
+ */
+typedef enum
+{
+    MBEDTLS_ECDH_VARIANT_NONE = 0,   /*!< Implementation not defined. */
+    MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
+} mbedtls_ecdh_variant;
+
 /**
+ * The context used by the default ECDH implementation.
+ *
+ * Later versions might change the structure of this context, therefore users
+ * should not make any assumptions about the structure of
+ * mbedtls_ecdh_context_mbed.
+ */
+typedef struct mbedtls_ecdh_context_mbed
+{
+    mbedtls_ecp_group grp;   /*!< The elliptic curve used. */
+    mbedtls_mpi d;           /*!< The private key. */
+    mbedtls_ecp_point Q;     /*!< The public key. */
+    mbedtls_ecp_point Qp;    /*!< The value of the public key of the peer. */
+    mbedtls_mpi z;           /*!< The shared secret. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
+#endif
+} mbedtls_ecdh_context_mbed;
+#endif
+
+/**
+ *
+ * \warning         Performing multiple operations concurrently on the same
+ *                  ECDSA context is not supported; objects of this type
+ *                  should not be shared between multiple threads.
  * \brief           The ECDH context structure.
  */
-typedef struct
+typedef struct mbedtls_ecdh_context
 {
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     mbedtls_ecp_group grp;   /*!< The elliptic curve used. */
     mbedtls_mpi d;           /*!< The private key. */
     mbedtls_ecp_point Q;     /*!< The public key. */
@@ -64,6 +119,29 @@ typedef struct
     mbedtls_ecp_point Vi;    /*!< The blinding value. */
     mbedtls_ecp_point Vf;    /*!< The unblinding value. */
     mbedtls_mpi _d;          /*!< The previous \p d. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    int restart_enabled;        /*!< The flag for restartable mode. */
+    mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#else
+    uint8_t point_format;       /*!< The format of point export in TLS messages
+                                  as defined in RFC 4492. */
+    mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */
+    mbedtls_ecdh_variant var;   /*!< The ECDH implementation/structure used. */
+    union
+    {
+        mbedtls_ecdh_context_mbed   mbed_ecdh;
+    } ctx;                      /*!< Implementation-specific context. The
+                                  context in use is specified by the \c var
+                                  field. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    uint8_t restart_enabled;    /*!< The flag for restartable mode. Functions of
+                                  an alternative implementation not supporting
+                                  restartable mode must return
+                                  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error
+                                  if this flag is set. */
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
 }
 mbedtls_ecdh_context;
 
@@ -75,16 +153,22 @@ mbedtls_ecdh_context;
  *                  implemented during the ECDH key exchange. The second core
  *                  computation is performed by mbedtls_ecdh_compute_shared().
  *
- * \param grp       The ECP group.
+ * \see             ecp.h
+ *
+ * \param grp       The ECP group to use. This must be initialized and have
+ *                  domain parameters loaded, for example through
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
  * \param d         The destination MPI (private key).
+ *                  This must be initialized.
  * \param Q         The destination point (public key).
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ *                  This must be initialized.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
+ * \return          \c 0 on success.
+ * \return          Another \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 +181,32 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
  *                  implemented during the ECDH key exchange. The first core
  *                  computation is performed by mbedtls_ecdh_gen_public().
  *
- * \param grp       The ECP group.
+ * \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 to use. This must be initialized and have
+ *                  domain parameters loaded, for example through
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
  * \param z         The destination MPI (shared secret).
+ *                  This must be initialized.
  * \param Q         The public key from another party.
+ *                  This must be initialized.
  * \param d         Our secret exponent (private key).
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
- *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX or
+ *                  This must be initialized.
+ * \param f_rng     The RNG function. This may be \c NULL if randomization
+ *                  of intermediate results during the ECP computations is
+ *                  not needed (discouraged). See the documentation of
+ *                  mbedtls_ecp_mul() for more.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't need a
+ *                  context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX or
  *                  \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,
@@ -121,39 +216,62 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
 /**
  * \brief           This function initializes an ECDH context.
  *
- * \param ctx       The ECDH context to initialize.
+ * \param ctx       The ECDH context to initialize. This must not be \c NULL.
  */
 void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
 
 /**
- * \brief           This function frees a context.
+ * \brief           This function sets up the ECDH context with the information
+ *                  given.
  *
- * \param ctx       The context to free.
- */
-void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
-
-/**
- * \brief           This function generates a public key and a TLS
- *                  ServerKeyExchange payload.
+ *                  This function should be called after mbedtls_ecdh_init() but
+ *                  before mbedtls_ecdh_make_params(). There is no need to call
+ *                  this function before mbedtls_ecdh_read_params().
  *
  *                  This is the first function used by a TLS server for ECDHE
  *                  ciphersuites.
  *
- * \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 ctx       The ECDH context to set up. This must be initialized.
+ * \param grp_id    The group id of the group to set up the context for.
  *
- * \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.
+ */
+int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx,
+                        mbedtls_ecp_group_id grp_id );
+
+/**
+ * \brief           This function frees a context.
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
+ * \param ctx       The context to free. This may be \c NULL, in which
+ *                  case this function does nothing. If it is not \c NULL,
+ *                  it must point to an initialized ECDH context.
+ */
+void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
+
+/**
+ * \brief           This function generates an EC key pair and exports its
+ *                  in the format used in a TLS ServerKeyExchange handshake
+ *                  message.
+ *
+ *                  This is the second function used by a TLS server for ECDHE
+ *                  ciphersuites. (It is called after mbedtls_ecdh_setup().)
  *
  * \see             ecp.h
+ *
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and bound to a group, for example via mbedtls_ecdh_setup().
+ * \param olen      The address at which to store the number of Bytes written.
+ * \param buf       The destination buffer. This must be a writable buffer of
+ *                  length \p blen Bytes.
+ * \param blen      The length of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \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,
@@ -161,23 +279,32 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
                       void *p_rng );
 
 /**
- * \brief           This function parses and processes a TLS ServerKeyExhange
- *                  payload.
+ * \brief           This function parses the ECDHE parameters in a
+ *                  TLS ServerKeyExchange handshake message.
  *
- *                  This is the first function used by a TLS client for ECDHE
- *                  ciphersuites.
+ * \note            In a TLS handshake, this is the how the client
+ *                  sets up its ECDHE context from the server's public
+ *                  ECDHE key material.
+ *
+ * \see             ecp.h
  *
- * \param ctx       The ECDH context.
- * \param buf       The pointer to the start of the input buffer.
- * \param end       The address for one Byte past the end of the buffer.
+ * \param ctx       The ECDHE context to use. This must be initialized.
+ * \param buf       On input, \c *buf must be the start of the input buffer.
+ *                  On output, \c *buf is updated to point to the end of the
+ *                  data that has been read. On success, this is the first byte
+ *                  past the end of the ServerKeyExchange parameters.
+ *                  On error, this is the point at which an error has been
+ *                  detected, which is usually not useful except to debug
+ *                  failures.
+ * \param end       The end of the input buffer.
  *
- * \return          \c 0 on success, 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 );
+                              const unsigned char **buf,
+                              const unsigned char *end );
 
 /**
  * \brief           This function sets up an ECDH context from an EC key.
@@ -186,38 +313,47 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
  *                  ServerKeyEchange for static ECDH, and imports ECDH
  *                  parameters from the EC key information of a certificate.
  *
- * \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>
+ * \see             ecp.h
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
+ * \param ctx       The ECDH context to set up. This must be initialized.
+ * \param key       The EC key to use. This must be initialized.
+ * \param side      Defines the source of the key. Possible values are:
+ *                  - #MBEDTLS_ECDH_OURS: The key is ours.
+ *                  - #MBEDTLS_ECDH_THEIRS: The key is that of the peer.
+ *
+ * \return          \c 0 on success.
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
  *
- * \see             ecp.h
  */
-int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
-                     mbedtls_ecdh_side side );
+int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
+                             const mbedtls_ecp_keypair *key,
+                             mbedtls_ecdh_side side );
 
 /**
- * \brief           This function generates a public key and a TLS
- *                  ClientKeyExchange payload.
+ * \brief           This function generates a public key and exports it
+ *                  as a TLS ClientKeyExchange payload.
  *
  *                  This is the second function used by a TLS client for ECDH(E)
  *                  ciphersuites.
  *
- * \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.
- *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
- *
  * \see             ecp.h
+ *
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and bound to a group, the latter usually by
+ *                  mbedtls_ecdh_read_params().
+ * \param olen      The address at which to store the number of Bytes written.
+ *                  This must not be \c NULL.
+ * \param buf       The destination buffer. This must be a writable buffer
+ *                  of length \p blen Bytes.
+ * \param blen      The size of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \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,
@@ -225,23 +361,26 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
                       void *p_rng );
 
 /**
- * \brief       This function parses and processes a TLS ClientKeyExchange
- *              payload.
+ * \brief       This function parses and processes the ECDHE payload of a
+ *              TLS ClientKeyExchange message.
  *
- *              This is the second function used by a TLS server for ECDH(E)
- *              ciphersuites.
+ *              This is the third function used by a TLS server for ECDH(E)
+ *              ciphersuites. (It is called after mbedtls_ecdh_setup() and
+ *              mbedtls_ecdh_make_params().)
  *
- * \param ctx   The ECDH context.
- * \param buf   The start of the input buffer.
- * \param blen  The length of the input buffer.
+ * \see         ecp.h
  *
- * \return      \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *              on failure.
+ * \param ctx   The ECDH context to use. This must be initialized
+ *              and bound to a group, for example via mbedtls_ecdh_setup().
+ * \param buf   The pointer to the ClientKeyExchange payload. This must
+ *              be a readable buffer of length \p blen Bytes.
+ * \param blen  The length of the input buffer \p buf in Bytes.
  *
- * \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 );
+                              const unsigned char *buf, size_t blen );
 
 /**
  * \brief           This function derives and exports the shared secret.
@@ -249,27 +388,51 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
  *                  This is the last function used by both TLS client
  *                  and servers.
  *
- * \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.
- *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code
- *                  on failure.
+ * \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
- *
- * \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().
+
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and have its own private key generated and the peer's
+ *                  public key imported.
+ * \param olen      The address at which to store the total number of
+ *                  Bytes written on success. This must not be \c NULL.
+ * \param buf       The buffer to write the generated shared key to. This
+ *                  must be a writable buffer of size \p blen Bytes.
+ * \param blen      The length of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function, for blinding purposes. This may
+ *                  b \c NULL if blinding isn't needed.
+ * \param p_rng     The RNG context. This may be \c NULL if \p f_rng
+ *                  doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \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,
                       int (*f_rng)(void *, unsigned char *, size_t),
                       void *p_rng );
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           This function enables restartable EC computations for this
+ *                  context.  (Default: disabled.)
+ *
+ * \see             \c mbedtls_ecp_set_max_ops()
+ *
+ * \note            It is not possible to safely disable restartable
+ *                  computations once enabled, except by free-ing the context,
+ *                  which cancels possible in-progress operations.
+ *
+ * \param ctx       The ECDH context to use. This must be initialized.
+ */
+void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
 #ifdef __cplusplus
 }
 #endif

+ 385 - 115
app/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>.
@@ -31,6 +32,12 @@
 #ifndef MBEDTLS_ECDSA_H
 #define MBEDTLS_ECDSA_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "ecp.h"
 #include "md.h"
 
@@ -54,29 +61,71 @@
 /** The maximal size of an ECDSA signature in Bytes. */
 #define MBEDTLS_ECDSA_MAX_LEN  ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \brief           The ECDSA context structure.
+ *
+ * \warning         Performing multiple operations concurrently on the same
+ *                  ECDSA context is not supported; objects of this type
+ *                  should not be shared between multiple threads.
  */
 typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
 
-#ifdef __cplusplus
-extern "C" {
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+
+/**
+ * \brief           Internal restart context for ecdsa_verify()
+ *
+ * \note            Opaque struct, defined in ecdsa.c
+ */
+typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx;
+
+/**
+ * \brief           Internal restart context for ecdsa_sign()
+ *
+ * \note            Opaque struct, defined in ecdsa.c
+ */
+typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx;
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+/**
+ * \brief           Internal restart context for ecdsa_sign_det()
+ *
+ * \note            Opaque struct, defined in ecdsa.c
+ */
+typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx;
 #endif
 
+/**
+ * \brief           General context for resuming ECDSA operations
+ */
+typedef struct
+{
+    mbedtls_ecp_restart_ctx ecp;        /*!<  base context for ECP restart and
+                                              shared administrative info    */
+    mbedtls_ecdsa_restart_ver_ctx *ver; /*!<  ecdsa_verify() sub-context    */
+    mbedtls_ecdsa_restart_sig_ctx *sig; /*!<  ecdsa_sign() sub-context      */
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+    mbedtls_ecdsa_restart_det_ctx *det; /*!<  ecdsa_sign_det() sub-context  */
+#endif
+} mbedtls_ecdsa_restart_ctx;
+
+#else /* MBEDTLS_ECP_RESTARTABLE */
+
+/* Now we can declare functions that take a pointer to that */
+typedef void mbedtls_ecdsa_restart_ctx;
+
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
 /**
  * \brief           This function computes the ECDSA signature of a
  *                  previously-hashed message.
  *
- * \note            The deterministic version is usually preferred.
- *
- * \param grp       The ECP group.
- * \param r         The first output integer.
- * \param s         The second output integer.
- * \param d         The private signing key.
- * \param buf       The message hash.
- * \param blen      The length of \p buf.
- * \param f_rng     The RNG function.
- * \param p_rng     The RNG parameter.
+ * \note            The deterministic version implemented in
+ *                  mbedtls_ecdsa_sign_det() is usually preferred.
  *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated
@@ -84,10 +133,28 @@ extern "C" {
  *                  (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 error code on failure.
- *
  * \see             ecp.h
+ *
+ * \param grp       The context for the elliptic curve to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param r         The MPI context in which to store the first part
+ *                  the signature. This must be initialized.
+ * \param s         The MPI context in which to store the second part
+ *                  the signature. This must be initialized.
+ * \param d         The private signing key. This must be initialized.
+ * \param buf       The content to be signed. This is usually the hash of
+ *                  the original data to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng doesn't need a context parameter.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX
+ *                  or \c MBEDTLS_MPI_XXX error code on failure.
  */
 int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
@@ -97,62 +164,139 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
 /**
  * \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>.
  *
- * \param grp       The ECP group.
- * \param r         The first output integer.
- * \param s         The second output integer.
- * \param d         The private signing key.
- * \param buf       The message hash.
- * \param blen      The length of \p buf.
- * \param md_alg    The MD algorithm used to hash the message.
- *
  * \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
+ * \warning         Since the output of the internal RNG is always the same for
+ *                  the same key and message, this limits the efficiency of
+ *                  blinding and leaks information through side channels. For
+ *                  secure behavior use mbedtls_ecdsa_sign_det_ext() instead.
+ *
+ *                  (Optimally the blinding is a random value that is different
+ *                  on every execution. In this case the blinding is still
+ *                  random from the attackers perspective, but is the same on
+ *                  each execution. This means that this blinding does not
+ *                  prevent attackers from recovering secrets by combining
+ *                  several measurement traces, but may prevent some attacks
+ *                  that exploit relationships between secret data.)
+ *
+ * \see             ecp.h
+ *
+ * \param grp       The context for the elliptic curve to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param r         The MPI context in which to store the first part
+ *                  the signature. This must be initialized.
+ * \param s         The MPI context in which to store the second part
+ *                  the signature. This must be initialized.
+ * \param d         The private signing key. This must be initialized
+ *                  and setup, for example through mbedtls_ecp_gen_privkey().
+ * \param buf       The hashed content to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param md_alg    The hash algorithm used to hash the original data.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
  *                  error code on failure.
+ */
+int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+                            mbedtls_mpi *s, const mbedtls_mpi *d,
+                            const unsigned char *buf, size_t blen,
+                            mbedtls_md_type_t md_alg );
+/**
+ * \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 context for the elliptic curve to use.
+ *                      This must be initialized and have group parameters
+ *                      set, for example through mbedtls_ecp_group_load().
+ * \param r             The MPI context in which to store the first part
+ *                      the signature. This must be initialized.
+ * \param s             The MPI context in which to store the second part
+ *                      the signature. This must be initialized.
+ * \param d             The private signing key. This must be initialized
+ *                      and setup, for example through mbedtls_ecp_gen_privkey().
+ * \param buf           The hashed content to be signed. This must be a readable
+ *                      buffer of length \p blen Bytes. It may be \c NULL if
+ *                      \p blen is zero.
+ * \param blen          The length of \p buf in Bytes.
+ * \param md_alg        The hash algorithm used to hash the original data.
+ * \param f_rng_blind   The RNG function used for blinding. This must not be
+ *                      \c NULL.
+ * \param p_rng_blind   The RNG context to be passed to \p f_rng. This may be
+ *                      \c NULL if \p f_rng doesn't need a context parameter.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ *                  error code on failure.
  */
-int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
-                    const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
-                    mbedtls_md_type_t md_alg );
+int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+                                mbedtls_mpi *s, const mbedtls_mpi *d,
+                                const unsigned char *buf, size_t blen,
+                                mbedtls_md_type_t md_alg,
+                                int (*f_rng_blind)(void *, unsigned char *,
+                                                   size_t),
+                                void *p_rng_blind );
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
 /**
  * \brief           This function verifies the ECDSA signature of a
  *                  previously-hashed message.
  *
- * \param grp       The ECP group.
- * \param buf       The message hash.
- * \param blen      The length of \p buf.
- * \param Q         The public key to use for verification.
- * \param r         The first integer of the signature.
- * \param s         The second integer of the signature.
- *
  * \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
- *                  error code on failure for any other reason.
- *
  * \see             ecp.h
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param buf       The hashed content that was signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param Q         The public key to use for verification. This must be
+ *                  initialized and setup.
+ * \param r         The first integer of the signature.
+ *                  This must be initialized.
+ * \param s         The second integer of the signature.
+ *                  This must be initialized.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
+ *                  is invalid.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ *                  error code on failure for any other reason.
  */
 int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
-                  const unsigned char *buf, size_t blen,
-                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s);
+                          const unsigned char *buf, size_t blen,
+                          const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
+                          const mbedtls_mpi *s);
 
 /**
  * \brief           This function computes the ECDSA signature and writes it
@@ -169,38 +313,92 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
  *                  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
- *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
- *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
  *                  defined in <em>Standards for Efficient Cryptography Group
  *                  (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 to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
+ * \param md_alg    The message digest that was used to hash the message.
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param f_rng     The RNG function. This must not be \c NULL if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ *                  it is unused and may be set to \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
+ *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
  */
-int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
+int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
+                                   mbedtls_md_type_t md_alg,
                            const unsigned char *hash, size_t hlen,
                            unsigned char *sig, size_t *slen,
                            int (*f_rng)(void *, unsigned char *, size_t),
                            void *p_rng );
 
+/**
+ * \brief           This function computes the ECDSA signature and writes it
+ *                  to a buffer, in a restartable way.
+ *
+ * \see             \c mbedtls_ecdsa_write_signature()
+ *
+ * \note            This function is like \c mbedtls_ecdsa_write_signature()
+ *                  but it can return early and restart according to the limit
+ *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
+ * \param md_alg    The message digest that was used to hash the message.
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param f_rng     The RNG function. This must not be \c NULL if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ *                  it is unused and may be set to \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
+ * \param rs_ctx    The restart context to use. This may be \c NULL to disable
+ *                  restarting. If it is not \c NULL, it must point to an
+ *                  initialized restart context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \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_restartable( mbedtls_ecdsa_context *ctx,
+                           mbedtls_md_type_t md_alg,
+                           const unsigned char *hash, size_t hlen,
+                           unsigned char *sig, size_t *slen,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           mbedtls_ecdsa_restart_ctx *rs_ctx );
+
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
 #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
 #if defined(MBEDTLS_DEPRECATED_WARNING)
@@ -209,31 +407,17 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
 #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
- *                  256-bit curve is used. A buffer length of
- *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
  *
  * \note            If the bitlength of the message hash is larger than the
  *                  bitlength of the group order, then the hash is truncated as
@@ -241,11 +425,29 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
  *                  (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 to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param md_alg    The message digest that was used to hash the message.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
+ *                  \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,75 +460,143 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
 /**
  * \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 to use. This must be initialized
+ *                  and have a group and public key bound to it.
+ * \param hash      The message hash that was signed. This must be a readable
+ *                  buffer of length \p size Bytes.
+ * \param hlen      The size of the hash \p hash.
+ * \param sig       The signature to read and verify. This must be a readable
+ *                  buffer of length \p slen Bytes.
+ * \param slen      The size of \p sig in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+ * \return          #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in \p sig, but its length is less than \p siglen.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on failure for any other reason.
  */
 int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
                           const unsigned char *hash, size_t hlen,
                           const unsigned char *sig, size_t slen );
 
+/**
+ * \brief           This function reads and verifies an ECDSA signature,
+ *                  in a restartable way.
+ *
+ * \see             \c mbedtls_ecdsa_read_signature()
+ *
+ * \note            This function is like \c mbedtls_ecdsa_read_signature()
+ *                  but it can return early and restart according to the limit
+ *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and public key bound to it.
+ * \param hash      The message hash that was signed. This must be a readable
+ *                  buffer of length \p size Bytes.
+ * \param hlen      The size of the hash \p hash.
+ * \param sig       The signature to read and verify. This must be a readable
+ *                  buffer of length \p slen Bytes.
+ * \param slen      The size of \p sig in Bytes.
+ * \param rs_ctx    The restart context to use. This may be \c NULL to disable
+ *                  restarting. If it is not \c NULL, it must point to an
+ *                  initialized restart context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+ * \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          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on failure for any other reason.
+ */
+int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
+                          const unsigned char *hash, size_t hlen,
+                          const unsigned char *sig, size_t slen,
+                          mbedtls_ecdsa_restart_ctx *rs_ctx );
+
 /**
  * \brief          This function generates an ECDSA keypair on the given curve.
  *
+ * \see            ecp.h
+ *
  * \param ctx      The ECDSA context to store the keypair in.
+ *                 This must be initialized.
  * \param gid      The elliptic curve to use. One of the various
  *                 \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
- * \param f_rng    The RNG function.
- * \param p_rng    The RNG parameter.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context argument.
  *
- * \return         \c 0 on success, 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 );
 
 /**
- * \brief           This function sets an ECDSA context from an EC key pair.
+ * \brief           This function sets up an ECDSA context from an EC key pair.
  *
- * \param ctx       The ECDSA context to set.
- * \param key       The EC key to use.
+ * \see             ecp.h
  *
- * \return          \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on
- *                  failure.
+ * \param ctx       The ECDSA context to setup. This must be initialized.
+ * \param key       The EC key to use. This must be initialized and hold
+ *                  a private-public key pair or a public key. In the former
+ *                  case, the ECDSA context may be used for signature creation
+ *                  and verification after this call. In the latter case, it
+ *                  may be used for signature verification.
  *
- * \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 );
+int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
+                                const mbedtls_ecp_keypair *key );
 
 /**
  * \brief           This function initializes an ECDSA context.
  *
  * \param ctx       The ECDSA context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
 
 /**
  * \brief           This function frees an ECDSA context.
  *
- * \param ctx       The ECDSA context to free.
+ * \param ctx       The ECDSA context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it
+ *                  is not \c NULL, it must be initialized.
  */
 void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context.
+ *
+ * \param ctx       The restart context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context.
+ *
+ * \param ctx       The restart context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it
+ *                  is not \c NULL, it must be initialized.
+ */
+void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
 #ifdef __cplusplus
 }
 #endif

+ 96 - 74
app/include/mbedtls/ecjpake.h

@@ -40,12 +40,15 @@
  * The payloads are serialized in a way suitable for use in TLS, but could
  * also be use outside TLS.
  */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
 
 #include "ecp.h"
 #include "md.h"
 
-#if !defined(MBEDTLS_ECJPAKE_ALT)
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -58,6 +61,7 @@ typedef enum {
     MBEDTLS_ECJPAKE_SERVER,             /**< Server                         */
 } mbedtls_ecjpake_role;
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
 /**
  * EC J-PAKE context structure.
  *
@@ -69,7 +73,7 @@ typedef enum {
  * convetion from the Thread v1.0 spec. Correspondance is indicated in the
  * description as a pair C: client name, S: server name
  */
-typedef struct
+typedef struct mbedtls_ecjpake_context
 {
     const mbedtls_md_info_t *md_info;   /**< Hash to use                    */
     mbedtls_ecp_group grp;              /**< Elliptic curve                 */
@@ -88,29 +92,38 @@ typedef struct
     mbedtls_mpi s;                      /**< Pre-shared secret (passphrase) */
 } mbedtls_ecjpake_context;
 
+#else  /* MBEDTLS_ECJPAKE_ALT */
+#include "ecjpake_alt.h"
+#endif /* MBEDTLS_ECJPAKE_ALT */
+
 /**
- * \brief           Initialize a context
- *                  (just makes it ready for setup() or free()).
+ * \brief           Initialize an ECJPAKE context.
  *
- * \param ctx       context to initialize
+ * \param ctx       The ECJPAKE context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
 
 /**
- * \brief           Set up a context for use
+ * \brief           Set up an ECJPAKE context for use.
  *
  * \note            Currently the only values for hash/curve allowed by the
- *                  standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1.
+ *                  standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
  *
- * \param ctx       context to set up
- * \param role      Our role: client or server
- * \param hash      hash function to use (MBEDTLS_MD_XXX)
- * \param curve     elliptic curve identifier (MBEDTLS_ECP_DP_XXX)
- * \param secret    pre-shared secret (passphrase)
- * \param len       length of the shared secret
+ * \param ctx       The ECJPAKE context to set up. This must be initialized.
+ * \param role      The role of the caller. This must be either
+ *                  #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
+ * \param hash      The identifier of the hash function to use,
+ *                  for example #MBEDTLS_MD_SHA256.
+ * \param curve     The identifier of the elliptic curve to use,
+ *                  for example #MBEDTLS_ECP_DP_SECP256R1.
+ * \param secret    The pre-shared secret (passphrase). This must be
+ *                  a readable buffer of length \p len Bytes. It need
+ *                  only be valid for the duration of this call.
+ * \param len       The length of the pre-shared secret \p secret.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
                            mbedtls_ecjpake_role role,
@@ -120,29 +133,34 @@ int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
                            size_t len );
 
 /**
- * \brief           Check if a context is ready for use
+ * \brief           Check if an ECJPAKE context is ready for use.
  *
- * \param ctx       Context to check
+ * \param ctx       The ECJPAKE context to check. This must be
+ *                  initialized.
  *
- * \return          0 if the context is ready for use,
- *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
+ * \return          \c 0 if the context is ready for use.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
  */
 int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
 
 /**
  * \brief           Generate and write the first round message
  *                  (TLS: contents of the Client/ServerHello extension,
- *                  excluding extension type and length bytes)
+ *                  excluding extension type and length bytes).
  *
- * \param ctx       Context to use
- * \param buf       Buffer to write the contents to
- * \param len       Buffer size
- * \param olen      Will be updated with the number of bytes written
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param ctx       The ECJPAKE context to use. This must be
+ *                  initialized and set up.
+ * \param buf       The buffer to write the contents to. This must be a
+ *                  writable buffer of length \p len Bytes.
+ * \param len       The length of \p buf in Bytes.
+ * \param olen      The address at which to store the total number
+ *                  of Bytes written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
                             unsigned char *buf, size_t len, size_t *olen,
@@ -152,14 +170,16 @@ int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
 /**
  * \brief           Read and process the first round message
  *                  (TLS: contents of the Client/ServerHello extension,
- *                  excluding extension type and length bytes)
+ *                  excluding extension type and length bytes).
  *
- * \param ctx       Context to use
- * \param buf       Pointer to extension contents
- * \param len       Extension length
+ * \param ctx       The ECJPAKE context to use. This must be initialized
+ *                  and set up.
+ * \param buf       The buffer holding the first round message. This must
+ *                  be a readable buffer of length \p len Bytes.
+ * \param len       The length in Bytes of \p buf.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
                                     const unsigned char *buf,
@@ -167,17 +187,21 @@ int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
 
 /**
  * \brief           Generate and write the second round message
- *                  (TLS: contents of the Client/ServerKeyExchange)
+ *                  (TLS: contents of the Client/ServerKeyExchange).
  *
- * \param ctx       Context to use
- * \param buf       Buffer to write the contents to
- * \param len       Buffer size
- * \param olen      Will be updated with the number of bytes written
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param ctx       The ECJPAKE context to use. This must be initialized,
+ *                  set up, and already have performed round one.
+ * \param buf       The buffer to write the round two contents to.
+ *                  This must be a writable buffer of length \p len Bytes.
+ * \param len       The size of \p buf in Bytes.
+ * \param olen      The address at which to store the total number of Bytes
+ *                  written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
                             unsigned char *buf, size_t len, size_t *olen,
@@ -186,14 +210,16 @@ int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
 
 /**
  * \brief           Read and process the second round message
- *                  (TLS: contents of the Client/ServerKeyExchange)
+ *                  (TLS: contents of the Client/ServerKeyExchange).
  *
- * \param ctx       Context to use
- * \param buf       Pointer to the message
- * \param len       Message length
+ * \param ctx       The ECJPAKE context to use. This must be initialized
+ *                  and set up and already have performed round one.
+ * \param buf       The buffer holding the second round message. This must
+ *                  be a readable buffer of length \p len Bytes.
+ * \param len       The length in Bytes of \p buf.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
                                     const unsigned char *buf,
@@ -201,17 +227,21 @@ int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
 
 /**
  * \brief           Derive the shared secret
- *                  (TLS: Pre-Master Secret)
+ *                  (TLS: Pre-Master Secret).
  *
- * \param ctx       Context to use
- * \param buf       Buffer to write the contents to
- * \param len       Buffer size
- * \param olen      Will be updated with the number of bytes written
- * \param f_rng     RNG function
- * \param p_rng     RNG parameter
+ * \param ctx       The ECJPAKE context to use. This must be initialized,
+ *                  set up and have performed both round one and two.
+ * \param buf       The buffer to write the derived secret to. This must
+ *                  be a writable buffer of length \p len Bytes.
+ * \param len       The length of \p buf in Bytes.
+ * \param olen      The address at which to store the total number of Bytes
+ *                  written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
  *
- * \return          0 if successfull,
- *                  a negative error code otherwise
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
  */
 int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
                             unsigned char *buf, size_t len, size_t *olen,
@@ -219,26 +249,17 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
                             void *p_rng );
 
 /**
- * \brief           Free a context's content
+ * \brief           This clears an ECJPAKE context and frees any
+ *                  embedded data structure.
  *
- * \param ctx       context to free
+ * \param ctx       The ECJPAKE context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it is not
+ *                  \c NULL, it must point to an initialized ECJPAKE context.
  */
 void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
 
-#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 +267,11 @@ extern "C" {
  */
 int mbedtls_ecjpake_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* MBEDTLS_SELF_TEST */
 
 #endif /* ecjpake.h */

File diff suppressed because it is too large
+ 820 - 370
app/include/mbedtls/ecp.h


+ 6 - 0
app/include/mbedtls/ecp_internal.h

@@ -61,6 +61,12 @@
 #ifndef MBEDTLS_ECP_INTERNAL_H
 #define MBEDTLS_ECP_INTERNAL_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
 
 /**

+ 3 - 3
app/include/mbedtls/entropy.h

@@ -107,7 +107,7 @@ typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, s
 /**
  * \brief           Entropy source state
  */
-typedef struct
+typedef struct mbedtls_entropy_source_state
 {
     mbedtls_entropy_f_source_ptr    f_source;   /**< The entropy source callback */
     void *          p_source;   /**< The callback data pointer */
@@ -120,7 +120,7 @@ mbedtls_entropy_source_state;
 /**
  * \brief           Entropy context structure
  */
-typedef struct
+typedef struct mbedtls_entropy_context
 {
     int accumulator_started;
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
@@ -166,7 +166,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
  * \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.

+ 21 - 9
app/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
@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_ERROR_H
 #define MBEDTLS_ERROR_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include <stddef.h>
 
 /**
@@ -53,7 +59,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
@@ -62,7 +68,8 @@
  * DES       2  0x0032-0x0032   0x0033-0x0033
  * CTR_DBRG  4  0x0034-0x003A
  * ENTROPY   3  0x003C-0x0040   0x003D-0x003F
- * NET      11  0x0042-0x0052   0x0043-0x0045
+ * NET      13  0x0042-0x0052   0x0043-0x0049
+ * ARIA      4  0x0058-0x005E
  * ASN1      7  0x0060-0x006C
  * CMAC      1  0x007A-0x007A
  * PBKDF2    1  0x007C-0x007C
@@ -73,9 +80,13 @@
  * MD4       1                  0x002D-0x002D
  * MD5       1                  0x002F-0x002F
  * RIPEMD160 1                  0x0031-0x0031
- * SHA1      1                  0x0035-0x0035
- * SHA256    1                  0x0037-0x0037
- * SHA512    1                  0x0039-0x0039
+ * SHA1      1                  0x0035-0x0035 0x0073-0x0073
+ * SHA256    1                  0x0037-0x0037 0x0074-0x0074
+ * SHA512    1                  0x0039-0x0039 0x0075-0x0075
+ * CHACHA20  3                  0x0051-0x0055
+ * POLY1305  3                  0x0057-0x005B
+ * CHACHAPOLY 2 0x0054-0x0056
+ * PLATFORM  1  0x0070-0x0072
  *
  * High-level module nr (3 bits - 0x0...-0x7...)
  * Name      ID  Nr of Errors
@@ -86,11 +97,12 @@
  * DHM       3   11
  * PK        3   15 (Started from top)
  * RSA       4   11
- * ECP       4   9 (Started from top)
+ * ECP       4   10 (Started from top)
  * MD        5   5
+ * HKDF      5   1 (Started from top)
  * CIPHER    6   8
- * SSL       6   17 (Started from top)
- * SSL       7   31
+ * SSL       6   23 (Started from top)
+ * SSL       7   32
  *
  * Module dependent error code (5 bits 0x.00.-0x.F8.)
  */

+ 104 - 67
app/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>.
@@ -31,6 +33,12 @@
 #ifndef MBEDTLS_GCM_H
 #define MBEDTLS_GCM_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "cipher.h"
 
 #include <stdint.h>
@@ -39,19 +47,23 @@
 #define MBEDTLS_GCM_DECRYPT     0
 
 #define MBEDTLS_ERR_GCM_AUTH_FAILED                       -0x0012  /**< Authenticated decryption failed. */
+
+/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
 #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)
+#define MBEDTLS_ERR_GCM_BAD_INPUT                         -0x0014  /**< Bad input parameters to function. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_GCM_ALT)
+
 /**
  * \brief          The GCM context structure.
  */
-typedef struct {
+typedef struct mbedtls_gcm_context
+{
     mbedtls_cipher_context_t cipher_ctx;  /*!< The cipher context used. */
     uint64_t HL[16];                      /*!< Precalculated HTable low. */
     uint64_t HH[16];                      /*!< Precalculated HTable high. */
@@ -66,6 +78,10 @@ typedef struct {
 }
 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
@@ -75,7 +91,7 @@ mbedtls_gcm_context;
  *                  cipher, nor set the key. For this purpose, use
  *                  mbedtls_gcm_setkey().
  *
- * \param ctx       The GCM context to initialize.
+ * \param ctx       The GCM context to initialize. This must not be \c NULL.
  */
 void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
 
@@ -83,15 +99,17 @@ void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
  * \brief           This function associates a GCM context with a
  *                  cipher algorithm and a key.
  *
- * \param ctx       The GCM context to initialize.
+ * \param ctx       The GCM context. This must be initialized.
  * \param cipher    The 128-bit block cipher to use.
- * \param key       The encryption key.
+ * \param key       The encryption key. This must be a readable buffer of at
+ *                  least \p keybits bits.
  * \param keybits   The key size in bits. Valid options are:
  *                  <ul><li>128 bits</li>
  *                  <li>192 bits</li>
  *                  <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,17 +119,18 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
 /**
  * \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 ctx       The GCM context to use for encryption or decryption. This
+ *                  must be initialized.
  * \param mode      The operation to perform:
  *                  - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
  *                    The ciphertext is written to \p output and the
@@ -125,22 +144,28 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
  *                    calling this function in decryption mode.
  * \param length    The length of the input data, which is equal to the length
  *                  of the output data.
- * \param iv        The initialization vector.
+ * \param iv        The initialization vector. This must be a readable buffer of
+ *                  at least \p iv_len Bytes.
  * \param iv_len    The length of the IV.
- * \param add       The buffer holding the additional data.
+ * \param add       The buffer holding the additional data. This must be of at
+ *                  least that size in Bytes.
  * \param add_len   The length of the additional data.
- * \param input     The buffer holding the input data. Its size is \b length.
- * \param output    The buffer for holding the output data. It must have room
- *                  for \b length bytes.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size in Bytes.
+ * \param output    The buffer for holding the output data. If \p length is greater
+ *                  than zero, this must be a writable buffer of at least that
+ *                  size in Bytes.
  * \param tag_len   The length of the tag to generate.
- * \param tag       The buffer for holding the tag.
+ * \param tag       The buffer for holding the tag. This must be a readable
+ *                  buffer of at least \p tag_len Bytes.
  *
  * \return          \c 0 if the encryption or decryption was performed
  *                  successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
  *                  this does not indicate that the data is authentic.
- * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
- * \return          #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
- *                  error code if the encryption or decryption failed.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ *                  not valid or a cipher-specific error code if the encryption
+ *                  or decryption failed.
  */
 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
                        int mode,
@@ -158,28 +183,34 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
  * \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 ctx       The GCM context. This must be initialized.
  * \param length    The length of the ciphertext to decrypt, which is also
  *                  the length of the decrypted plaintext.
- * \param iv        The initialization vector.
+ * \param iv        The initialization vector. This must be a readable buffer
+ *                  of at least \p iv_len Bytes.
  * \param iv_len    The length of the IV.
- * \param add       The buffer holding the additional data.
+ * \param add       The buffer holding the additional data. This must be of at
+ *                  least that size in Bytes.
  * \param add_len   The length of the additional data.
- * \param tag       The buffer holding the tag to verify.
+ * \param tag       The buffer holding the tag to verify. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the tag to verify.
- * \param input     The buffer holding the ciphertext. Its size is \b length.
- * \param output    The buffer for holding the decrypted plaintext. It must
- *                  have room for \b length bytes.
+ * \param input     The buffer holding the ciphertext. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size.
+ * \param output    The buffer for holding the decrypted plaintext. If \p length
+ *                  is greater than zero, this must be a writable buffer of at
+ *                  least that size.
  *
  * \return          \c 0 if successful and authenticated.
  * \return          #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
- * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
- * \return          #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
- *                  error code if the decryption failed.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ *                  not valid or a cipher-specific error code if the decryption
+ *                  failed.
  */
 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
                       size_t length,
@@ -196,15 +227,18 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
  * \brief           This function starts a GCM encryption or decryption
  *                  operation.
  *
- * \param ctx       The GCM context.
+ * \param ctx       The GCM context. This must be initialized.
  * \param mode      The operation to perform: #MBEDTLS_GCM_ENCRYPT or
  *                  #MBEDTLS_GCM_DECRYPT.
- * \param iv        The initialization vector.
+ * \param iv        The initialization vector. This must be a readable buffer of
+ *                  at least \p iv_len Bytes.
  * \param iv_len    The length of the IV.
- * \param add       The buffer holding the additional data, or NULL if \p add_len is 0.
- * \param add_len   The length of the additional data. If 0, \p  add is NULL.
+ * \param add       The buffer holding the additional data, or \c NULL
+ *                  if \p add_len is \c 0.
+ * \param add_len   The length of the additional data. If \c 0,
+ *                  \p add may be \c NULL.
  *
- * \return         \c 0 on success.
+ * \return          \c 0 on success.
  */
 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
                 int mode,
@@ -221,16 +255,22 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
  *                  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 input     The buffer holding the input data.
- * \param output    The buffer for holding the output data.
+ * \param ctx       The GCM context. This must be initialized.
+ * \param length    The length of the input data. This must be a multiple of
+ *                  16 except in the last call before mbedtls_gcm_finish().
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size in Bytes.
+ * \param output    The buffer for holding the output data. If \p length is
+ *                  greater than zero, this must be a writable buffer of at
+ *                  least that size in Bytes.
  *
- * \return         \c 0 on success, 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,
@@ -244,11 +284,14 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
  *                  It wraps up the GCM stream, and generates the
  *                  tag. The tag can have a maximum length of 16 Bytes.
  *
- * \param ctx       The GCM context.
- * \param tag       The buffer for holding the tag.
- * \param tag_len   The length of the tag to generate. Must be at least four.
+ * \param ctx       The GCM context. This must be initialized.
+ * \param tag       The buffer for holding the tag. This must be a readable
+ *                  buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the tag to generate. This must be at least
+ *                  four.
  *
- * \return          \c 0 on success, 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,
@@ -258,29 +301,23 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
  * \brief           This function clears a GCM context and the underlying
  *                  cipher sub-context.
  *
- * \param ctx       The GCM context to clear.
+ * \param ctx       The GCM context to clear. If this is \c NULL, the call has
+ *                  no effect. Otherwise, this must be initialized.
  */
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* !MBEDTLS_GCM_ALT */
-#include "gcm_alt.h"
-#endif /* !MBEDTLS_GCM_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#if defined(MBEDTLS_SELF_TEST)
 
 /**
  * \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 );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 7 - 1
app/include/mbedtls/havege.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_HAVEGE_H
 #define MBEDTLS_HAVEGE_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include <stddef.h>
 
 #define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
@@ -35,7 +41,7 @@ extern "C" {
 /**
  * \brief          HAVEGE state structure
  */
-typedef struct
+typedef struct mbedtls_havege_state
 {
     int PT1, PT2, offset[2];
     int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];

+ 141 - 0
app/include/mbedtls/hkdf.h

@@ -0,0 +1,141 @@
+/**
+ * \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-2019, 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
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#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.
+ *
+ *  \warning    This function should only be used if the security of it has been
+ *              studied and established in that particular context (eg. TLS 1.3
+ *              key schedule). For standard HKDF security guarantees use
+ *              \c mbedtls_hkdf instead.
+ *
+ *  \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.
+ *
+ *  \warning    This function should only be used if the security of it has been
+ *              studied and established in that particular context (eg. TLS 1.3
+ *              key schedule). For standard HKDF security guarantees use
+ *              \c mbedtls_hkdf instead.
+ *
+ *  \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 */

+ 215 - 126
app/include/mbedtls/hmac_drbg.h

@@ -1,10 +1,14 @@
 /**
  * \file hmac_drbg.h
  *
- * \brief HMAC_DRBG (NIST SP 800-90A)
+ * \brief The HMAC_DRBG pseudorandom generator.
+ *
+ * This module implements the HMAC_DRBG pseudorandom generator described
+ * in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using
+ * Deterministic Random Bit Generators</em>.
  */
 /*
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -80,9 +84,9 @@ extern "C" {
 /**
  * HMAC_DRBG context.
  */
-typedef struct
+typedef struct mbedtls_hmac_drbg_context
 {
-    /* Working state: the key K is not stored explicitely,
+    /* Working state: the key K is not stored explicitly,
      * but is implied by the HMAC context */
     mbedtls_md_context_t md_ctx;                    /*!< HMAC context (inc. K)  */
     unsigned char V[MBEDTLS_MD_MAX_SIZE];  /*!< V in the spec          */
@@ -104,38 +108,72 @@ typedef struct
 } mbedtls_hmac_drbg_context;
 
 /**
- * \brief               HMAC_DRBG context initialization
- *                      Makes the context ready for mbedtls_hmac_drbg_seed(),
- *                      mbedtls_hmac_drbg_seed_buf() or
- *                      mbedtls_hmac_drbg_free().
+ * \brief               HMAC_DRBG context initialization.
+ *
+ * This function makes the context ready for mbedtls_hmac_drbg_seed(),
+ * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
  *
- * \param ctx           HMAC_DRBG context to be initialized
+ * \param ctx           HMAC_DRBG context to be initialized.
  */
 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
 
 /**
- * \brief               HMAC_DRBG initial seeding
- *                      Seed and setup entropy source for future reseeds.
- *
- * \param ctx           HMAC_DRBG context to be seeded
- * \param md_info       MD algorithm to use for HMAC_DRBG
- * \param f_entropy     Entropy callback (p_entropy, buffer to fill, buffer
- *                      length)
- * \param p_entropy     Entropy context
- * \param custom        Personalization data (Device specific identifiers)
- *                      (Can be NULL)
- * \param len           Length of personalization data
- *
- * \note                The "security strength" as defined by NIST is set to:
- *                      128 bits if md_alg is SHA-1,
- *                      192 bits if md_alg is SHA-224,
- *                      256 bits if md_alg is SHA-256 or higher.
- *                      Note that SHA-256 is just as efficient as SHA-224.
+ * \brief               HMAC_DRBG initial seeding.
+ *
+ * Set the initial seed and set up the entropy source for future reseeds.
+ *
+ * A typical choice for the \p f_entropy and \p p_entropy parameters is
+ * to use the entropy module:
+ * - \p f_entropy is mbedtls_entropy_func();
+ * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
+ *   with mbedtls_entropy_init() (which registers the platform's default
+ *   entropy sources).
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
- *                      MBEDTLS_ERR_MD_ALLOC_FAILED, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED.
+ * You can provide a personalization string in addition to the
+ * entropy source, to make this instantiation as unique as possible.
+ *
+ * \note                By default, the security strength as defined by NIST is:
+ *                      - 128 bits if \p md_info is SHA-1;
+ *                      - 192 bits if \p md_info is SHA-224;
+ *                      - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512.
+ *                      Note that SHA-256 is just as efficient as SHA-224.
+ *                      The security strength can be reduced if a smaller
+ *                      entropy length is set with
+ *                      mbedtls_hmac_drbg_set_entropy_len().
+ *
+ * \note                The default entropy length is the security strength
+ *                      (converted from bits to bytes). You can override
+ *                      it by calling mbedtls_hmac_drbg_set_entropy_len().
+ *
+ * \note                During the initial seeding, this function calls
+ *                      the entropy source to obtain a nonce
+ *                      whose length is half the entropy length.
+ *
+ * \param ctx           HMAC_DRBG context to be seeded.
+ * \param md_info       MD algorithm to use for HMAC_DRBG.
+ * \param f_entropy     The entropy callback, taking as arguments the
+ *                      \p p_entropy context, the buffer to fill, and the
+ *                      length of the buffer.
+ *                      \p f_entropy is always called with a length that is
+ *                      less than or equal to the entropy length.
+ * \param p_entropy     The entropy context to pass to \p f_entropy.
+ * \param custom        The personalization string.
+ *                      This can be \c NULL, in which case the personalization
+ *                      string is empty regardless of the value of \p len.
+ * \param len           The length of the personalization string.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
+ *                      and also at most
+ *                      #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2
+ *                      where \p entropy_len is the entropy length
+ *                      described above.
+ *
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
+ *                      invalid.
+ * \return              #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
+ *                      memory to allocate context data.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if the call to \p f_entropy failed.
  */
 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
                     const mbedtls_md_info_t * md_info,
@@ -146,115 +184,131 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
 
 /**
  * \brief               Initilisation of simpified HMAC_DRBG (never reseeds).
- *                      (For use with deterministic ECDSA.)
  *
- * \param ctx           HMAC_DRBG context to be initialised
- * \param md_info       MD algorithm to use for HMAC_DRBG
- * \param data          Concatenation of entropy string and additional data
- * \param data_len      Length of data in bytes
+ * This function is meant for use in algorithms that need a pseudorandom
+ * input such as deterministic ECDSA.
+ *
+ * \param ctx           HMAC_DRBG context to be initialised.
+ * \param md_info       MD algorithm to use for HMAC_DRBG.
+ * \param data          Concatenation of the initial entropy string and
+ *                      the additional data.
+ * \param data_len      Length of \p data in bytes.
  *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
- *                      MBEDTLS_ERR_MD_ALLOC_FAILED.
+ * \return              \c 0 if successful. or
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
+ *                      invalid.
+ * \return              #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
+ *                      memory to allocate context data.
  */
 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
                         const mbedtls_md_info_t * md_info,
                         const unsigned char *data, size_t data_len );
 
 /**
- * \brief               Enable / disable prediction resistance (Default: Off)
+ * \brief               This function turns prediction resistance on or off.
+ *                      The default value is off.
  *
- * Note: If enabled, entropy is used for ctx->entropy_len before each call!
- *       Only use this if you have ample supply of good entropy!
+ * \note                If enabled, entropy is gathered at the beginning of
+ *                      every call to mbedtls_hmac_drbg_random_with_add()
+ *                      or mbedtls_hmac_drbg_random().
+ *                      Only use this if your entropy source has sufficient
+ *                      throughput.
  *
- * \param ctx           HMAC_DRBG context
- * \param resistance    MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF
+ * \param ctx           The HMAC_DRBG context.
+ * \param resistance    #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF.
  */
 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
                                           int resistance );
 
 /**
- * \brief               Set the amount of entropy grabbed on each reseed
- *                      (Default: given by the security strength, which
- *                      depends on the hash used, see \c mbedtls_hmac_drbg_init() )
+ * \brief               This function sets the amount of entropy grabbed on each
+ *                      seed or reseed.
  *
- * \param ctx           HMAC_DRBG context
- * \param len           Amount of entropy to grab, in bytes
+ * See the documentation of mbedtls_hmac_drbg_seed() for the default value.
+ *
+ * \param ctx           The HMAC_DRBG context.
+ * \param len           The amount of entropy to grab, in bytes.
  */
 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
                                 size_t len );
 
 /**
- * \brief               Set the reseed interval
- *                      (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
+ * \brief               Set the reseed interval.
+ *
+ * The reseed interval is the number of calls to mbedtls_hmac_drbg_random()
+ * or mbedtls_hmac_drbg_random_with_add() after which the entropy function
+ * is called again.
  *
- * \param ctx           HMAC_DRBG context
- * \param interval      Reseed interval
+ * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL.
+ *
+ * \param ctx           The HMAC_DRBG context.
+ * \param interval      The reseed interval.
  */
 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
                                     int interval );
 
 /**
- * \brief               HMAC_DRBG update state
+ * \brief               This function updates the state of the HMAC_DRBG context.
  *
- * \param ctx           HMAC_DRBG context
- * \param additional    Additional data to update state with, or NULL
- * \param add_len       Length of additional data, or 0
+ * \param ctx           The HMAC_DRBG context.
+ * \param additional    The data to update the state with.
+ *                      If this is \c NULL, there is no additional data.
+ * \param add_len       Length of \p additional in bytes.
+ *                      Unused if \p additional is \c NULL.
  *
  * \return              \c 0 on success, or an error from the underlying
  *                      hash calculation.
- *
- * \note                Additional data is optional, pass NULL and 0 as second
- *                      third argument if no additional data is being used.
  */
 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
                        const unsigned char *additional, size_t add_len );
 
 /**
- * \brief               HMAC_DRBG update state
- *
- * \warning             This function cannot report errors. You should use
- *                      mbedtls_hmac_drbg_update_ret() instead.
- *
- * \param ctx           HMAC_DRBG context
- * \param additional    Additional data to update state with, or NULL
- * \param add_len       Length of additional data, or 0
- *
- * \note                Additional data is optional, pass NULL and 0 as second
- *                      third argument if no additional data is being used.
- */
-void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
-                               const unsigned char *additional,
-                               size_t add_len );
-
-/**
- * \brief               HMAC_DRBG reseeding (extracts data from entropy source)
- *
- * \param ctx           HMAC_DRBG context
- * \param additional    Additional data to add to state (Can be NULL)
- * \param len           Length of additional data
- *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ * \brief               This function reseeds the HMAC_DRBG context, that is
+ *                      extracts data from the entropy source.
+ *
+ * \param ctx           The HMAC_DRBG context.
+ * \param additional    Additional data to add to the state.
+ *                      If this is \c NULL, there is no additional data
+ *                      and \p len should be \c 0.
+ * \param len           The length of the additional data.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
+ *                      and also at most
+ *                      #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len
+ *                      where \p entropy_len is the entropy length
+ *                      (see mbedtls_hmac_drbg_set_entropy_len()).
+ *
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if a call to the entropy function failed.
  */
 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
                       const unsigned char *additional, size_t len );
 
 /**
- * \brief               HMAC_DRBG generate random with additional update input
- *
- * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
- *
- * \param p_rng         HMAC_DRBG context
- * \param output        Buffer to fill
- * \param output_len    Length of the buffer
- * \param additional    Additional data to update with (can be NULL)
- * \param add_len       Length of additional data (can be 0)
- *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
- *                      MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or
- *                      MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG.
+ * \brief   This function updates an HMAC_DRBG instance with additional
+ *          data and uses it to generate random data.
+ *
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
+ *
+ * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
+ *                      #mbedtls_hmac_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param output_len    The length of the buffer in bytes.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
+ * \param additional    Additional data to update with.
+ *                      If this is \c NULL, there is no additional data
+ *                      and \p add_len should be \c 0.
+ * \param add_len       The length of the additional data.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT.
+ *
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if a call to the entropy source failed.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
+ *                      \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if
+ *                      \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT.
  */
 int mbedtls_hmac_drbg_random_with_add( void *p_rng,
                                unsigned char *output, size_t output_len,
@@ -262,49 +316,83 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
                                size_t add_len );
 
 /**
- * \brief               HMAC_DRBG generate random
- *
- * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
- *
- * \param p_rng         HMAC_DRBG context
- * \param output        Buffer to fill
- * \param out_len       Length of the buffer
- *
- * \return              0 if successful, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
- *                      MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG
+ * \brief   This function uses HMAC_DRBG to generate random data.
+ *
+ * This function automatically reseeds if the reseed counter is exceeded
+ * or prediction resistance is enabled.
+ *
+ * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
+ *                      #mbedtls_hmac_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param out_len       The length of the buffer in bytes.
+ *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
+ *
+ * \return              \c 0 if successful.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ *                      if a call to the entropy source failed.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
+ *                      \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
  */
 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
 
 /**
  * \brief               Free an HMAC_DRBG context
  *
- * \param ctx           HMAC_DRBG context to free.
+ * \param ctx           The HMAC_DRBG context to free.
  */
 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
 
-#if defined(MBEDTLS_FS_IO)
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
 /**
- * \brief               Write a seed file
+ * \brief               This function updates the state of the HMAC_DRBG context.
  *
- * \param ctx           HMAC_DRBG context
- * \param path          Name of the file
+ * \deprecated          Superseded by mbedtls_hmac_drbg_update_ret()
+ *                      in 2.16.0.
  *
- * \return              0 if successful, 1 on file error, or
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ * \param ctx           The HMAC_DRBG context.
+ * \param additional    The data to update the state with.
+ *                      If this is \c NULL, there is no additional data.
+ * \param add_len       Length of \p additional in bytes.
+ *                      Unused if \p additional is \c NULL.
  */
-int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
+MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
+    mbedtls_hmac_drbg_context *ctx,
+    const unsigned char *additional, size_t add_len );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_FS_IO)
 /**
- * \brief               Read and update a seed file. Seed is added to this
- *                      instance
+ * \brief               This function writes a seed file.
  *
- * \param ctx           HMAC_DRBG context
- * \param path          Name of the file
+ * \param ctx           The HMAC_DRBG context.
+ * \param path          The name of the file.
  *
- * \return              0 if successful, 1 on file error,
- *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or
- *                      MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed
+ *                      failure.
+ */
+int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
+
+/**
+ * \brief               This function reads and updates a seed file. The seed
+ *                      is added to this instance.
+ *
+ * \param ctx           The HMAC_DRBG context.
+ * \param path          The name of the file.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on
+ *                      reseed failure.
+ * \return              #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing
+ *                      seed file is too large.
  */
 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
 #endif /* MBEDTLS_FS_IO */
@@ -312,9 +400,10 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch
 
 #if defined(MBEDTLS_SELF_TEST)
 /**
- * \brief               Checkup routine
+ * \brief               The HMAC_DRBG Checkup routine.
  *
- * \return              0 if successful, or 1 if the test failed
+ * \return              \c 0 if successful.
+ * \return              \c 1 if the test failed.
  */
 int mbedtls_hmac_drbg_self_test( int verbose );
 #endif

+ 63 - 48
app/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>
  */
@@ -39,6 +39,8 @@
 #define MBEDTLS_ERR_MD_BAD_INPUT_DATA                     -0x5100  /**< Bad input parameters to function. */
 #define MBEDTLS_ERR_MD_ALLOC_FAILED                       -0x5180  /**< Failed to allocate memory. */
 #define MBEDTLS_ERR_MD_FILE_IO_ERROR                      -0x5200  /**< Opening or reading of file failed. */
+
+/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_MD_HW_ACCEL_FAILED                    -0x5280  /**< MD hardware accelerator failed. */
 
 #ifdef __cplusplus
@@ -46,7 +48,7 @@ extern "C" {
 #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 +56,16 @@ extern "C" {
  *
  */
 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)
@@ -80,7 +82,8 @@ typedef struct mbedtls_md_info_t mbedtls_md_info_t;
 /**
  * The generic message-digest context.
  */
-typedef struct {
+typedef struct mbedtls_md_context_t
+{
     /** Information about the associated message digest. */
     const mbedtls_md_info_t *md_info;
 
@@ -108,8 +111,8 @@ const int *mbedtls_md_list( void );
  *
  * \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 +122,8 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
  *
  * \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 +171,10 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx );
  * \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 +191,13 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_
  * \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 +217,8 @@ int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_inf
  * \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 +265,9 @@ const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
  *
  * \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 +283,9 @@ int mbedtls_md_starts( mbedtls_md_context_t *ctx );
  * \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 +303,9 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si
  * \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 +323,9 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
  * \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 +343,10 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si
  * \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 +366,9 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
  * \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 +388,9 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
  * \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 +409,9 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
  *                  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 +426,9 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
  * \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 +450,9 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
  * \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,

+ 14 - 17
app/include/mbedtls/md2.h

@@ -37,16 +37,17 @@
 
 #include <stddef.h>
 
+/* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */
 #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
  *
@@ -55,7 +56,7 @@ extern "C" {
  *                 stronger message digests instead.
  *
  */
-typedef struct
+typedef struct mbedtls_md2_context
 {
     unsigned char cksum[16];    /*!< checksum of the data block */
     unsigned char state[48];    /*!< intermediate digest state  */
@@ -64,6 +65,10 @@ typedef struct
 }
 mbedtls_md2_context;
 
+#else  /* MBEDTLS_MD2_ALT */
+#include "md2_alt.h"
+#endif /* MBEDTLS_MD2_ALT */
+
 /**
  * \brief          Initialize MD2 context
  *
@@ -235,18 +240,6 @@ MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx );
 #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 )
  *
@@ -290,6 +283,8 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -302,6 +297,8 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
  */
 int mbedtls_md2_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 14 - 17
app/include/mbedtls/md4.h

@@ -38,16 +38,17 @@
 #include <stddef.h>
 #include <stdint.h>
 
+/* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */
 #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
  *
@@ -56,7 +57,7 @@ extern "C" {
  *                 stronger message digests instead.
  *
  */
-typedef struct
+typedef struct mbedtls_md4_context
 {
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[4];          /*!< intermediate digest state  */
@@ -64,6 +65,10 @@ typedef struct
 }
 mbedtls_md4_context;
 
+#else  /* MBEDTLS_MD4_ALT */
+#include "md4_alt.h"
+#endif /* MBEDTLS_MD4_ALT */
+
 /**
  * \brief          Initialize MD4 context
  *
@@ -238,18 +243,6 @@ MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx,
 #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 )
  *
@@ -295,6 +288,8 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -307,6 +302,8 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
  */
 int mbedtls_md4_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 14 - 17
app/include/mbedtls/md5.h

@@ -37,16 +37,17 @@
 #include <stddef.h>
 #include <stdint.h>
 
+/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */
 #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
  *
@@ -55,7 +56,7 @@ extern "C" {
  *                 stronger message digests instead.
  *
  */
-typedef struct
+typedef struct mbedtls_md5_context
 {
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[4];          /*!< intermediate digest state  */
@@ -63,6 +64,10 @@ typedef struct
 }
 mbedtls_md5_context;
 
+#else  /* MBEDTLS_MD5_ALT */
+#include "md5_alt.h"
+#endif /* MBEDTLS_MD5_ALT */
+
 /**
  * \brief          Initialize MD5 context
  *
@@ -238,18 +243,6 @@ MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
 #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 )
  *
@@ -295,6 +288,8 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -307,6 +302,8 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
  */
 int mbedtls_md5_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 5 - 0
app/include/mbedtls/net.h

@@ -23,6 +23,11 @@
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 #include "net_sockets.h"

+ 46 - 2
app/include/mbedtls/net_sockets.h

@@ -1,7 +1,23 @@
 /**
  * \file net_sockets.h
  *
- * \brief Network communication functions
+ * \brief   Network sockets abstraction layer to integrate Mbed TLS into a
+ *          BSD-style sockets API.
+ *
+ *          The network sockets module provides an example integration of the
+ *          Mbed TLS library into a BSD sockets implementation. The module is
+ *          intended to be an example of how Mbed TLS can be integrated into a
+ *          networking stack, as well as to be Mbed TLS's network integration
+ *          for its supported platforms.
+ *
+ *          The module is intended only to be used with the Mbed TLS library and
+ *          is not intended to be used by third party application software
+ *          directly.
+ *
+ *          The supported platforms are as follows:
+ *              * Microsoft Windows and Windows CE
+ *              * POSIX/Unix platforms including Linux, OS X
+ *
  */
 /*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@@ -46,12 +62,17 @@
 #define MBEDTLS_ERR_NET_UNKNOWN_HOST                      -0x0052  /**< Failed to get an IP address for the given hostname. */
 #define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL                  -0x0043  /**< Buffer is too small to hold the data. */
 #define MBEDTLS_ERR_NET_INVALID_CONTEXT                   -0x0045  /**< The context is invalid, eg because it was free()ed. */
+#define MBEDTLS_ERR_NET_POLL_FAILED                       -0x0047  /**< Polling the net context failed. */
+#define MBEDTLS_ERR_NET_BAD_INPUT_DATA                    -0x0049  /**< Input invalid. */
 
 #define MBEDTLS_NET_LISTEN_BACKLOG         10 /**< The backlog that listen() should use. */
 
 #define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */
 #define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */
 
+#define MBEDTLS_NET_POLL_READ  1 /**< Used in \c mbedtls_net_poll to check for pending data  */
+#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -63,7 +84,7 @@ extern "C" {
  * (eg two file descriptors for combined IPv4 + IPv6 support, or additional
  * structures for hand-made UDP demultiplexing).
  */
-typedef struct
+typedef struct mbedtls_net_context
 {
     int fd;             /**< The underlying file descriptor                 */
 }
@@ -133,6 +154,29 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
                         mbedtls_net_context *client_ctx,
                         void *client_ip, size_t buf_size, size_t *ip_len );
 
+/**
+ * \brief          Check and wait for the context to be ready for read/write
+ *
+ * \param ctx      Socket to check
+ * \param rw       Bitflag composed of MBEDTLS_NET_POLL_READ and
+ *                 MBEDTLS_NET_POLL_WRITE specifying the events
+ *                 to wait for:
+ *                 - If MBEDTLS_NET_POLL_READ is set, the function
+ *                   will return as soon as the net context is available
+ *                   for reading.
+ *                 - If MBEDTLS_NET_POLL_WRITE is set, the function
+ *                   will return as soon as the net context is available
+ *                   for writing.
+ * \param timeout  Maximal amount of time to wait before returning,
+ *                 in milliseconds. If \c timeout is zero, the
+ *                 function returns immediately. If \c timeout is
+ *                 -1u, the function blocks potentially indefinitely.
+ *
+ * \return         Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE
+ *                 on success or timeout, or a negative return code otherwise.
+ */
+int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout );
+
 /**
  * \brief          Set the socket blocking
  *

+ 184 - 0
app/include/mbedtls/nist_kw.h

@@ -0,0 +1,184 @@
+/**
+ * \file nist_kw.h
+ *
+ * \brief This file provides an API for key wrapping (KW) and key wrapping with
+ *        padding (KWP) as defined in NIST SP 800-38F.
+ *        https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
+ *
+ *        Key wrapping specifies a deterministic authenticated-encryption mode
+ *        of operation, according to <em>NIST SP 800-38F: Recommendation for
+ *        Block Cipher Modes of Operation: Methods for Key Wrapping</em>. Its
+ *        purpose is to protect cryptographic keys.
+ *
+ *        Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP.
+ *        https://tools.ietf.org/html/rfc3394
+ *        https://tools.ietf.org/html/rfc5649
+ *
+ */
+/*
+ *  Copyright (C) 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
+ *  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_NIST_KW_H
+#define MBEDTLS_NIST_KW_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+    MBEDTLS_KW_MODE_KW = 0,
+    MBEDTLS_KW_MODE_KWP = 1
+} mbedtls_nist_kw_mode_t;
+
+#if !defined(MBEDTLS_NIST_KW_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief    The key wrapping context-type definition. The key wrapping context is passed
+ *           to the APIs called.
+ *
+ * \note     The definition of this type may change in future library versions.
+ *           Don't make any assumptions on this context!
+ */
+typedef struct {
+    mbedtls_cipher_context_t cipher_ctx;    /*!< The cipher context used. */
+} mbedtls_nist_kw_context;
+
+#else  /* MBEDTLS_NIST_key wrapping_ALT */
+#include "nist_kw_alt.h"
+#endif /* MBEDTLS_NIST_KW_ALT */
+
+/**
+ * \brief           This function initializes the specified key wrapping context
+ *                  to make references valid and prepare the context
+ *                  for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free().
+ *
+ * \param ctx       The key wrapping context to initialize.
+ *
+ */
+void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx );
+
+/**
+ * \brief           This function initializes the key wrapping context set in the
+ *                  \p ctx parameter and sets the encryption key.
+ *
+ * \param ctx       The key wrapping context.
+ * \param cipher    The 128-bit block cipher to use. Only AES is supported.
+ * \param key       The Key Encryption Key (KEK).
+ * \param keybits   The KEK size in bits. This must be acceptable by the cipher.
+ * \param is_wrap   Specify whether the operation within the context is wrapping or unwrapping
+ *
+ * \return          \c 0 on success.
+ * \return          \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input.
+ * \return          \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers
+ *                  which are not supported.
+ * \return          cipher-specific error code on failure of the underlying cipher.
+ */
+int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
+                            mbedtls_cipher_id_t cipher,
+                            const unsigned char *key,
+                            unsigned int keybits,
+                            const int is_wrap );
+
+/**
+ * \brief   This function releases and clears the specified key wrapping context
+ *          and underlying cipher sub-context.
+ *
+ * \param ctx       The key wrapping context to clear.
+ */
+void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx );
+
+/**
+ * \brief           This function encrypts a buffer using key wrapping.
+ *
+ * \param ctx       The key wrapping context to use for encryption.
+ * \param mode      The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
+ * \param input     The buffer holding the input data.
+ * \param in_len    The length of the input data in Bytes.
+ *                  The input uses units of 8 Bytes called semiblocks.
+ *                  <ul><li>For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive. </li>
+ *                  <li>For KWP mode: any length between 1 and 2^32-1 inclusive.</li></ul>
+ * \param[out] output    The buffer holding the output data.
+ *                  <ul><li>For KW mode: Must be at least 8 bytes larger than \p in_len.</li>
+ *                  <li>For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of
+ *                  8 bytes for KWP (15 bytes at most).</li></ul>
+ * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
+ * \param[in] out_size The capacity of the output buffer.
+ *
+ * \return          \c 0 on success.
+ * \return          \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
+ * \return          cipher-specific error code on failure of the underlying cipher.
+ */
+int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
+                          const unsigned char *input, size_t in_len,
+                          unsigned char *output, size_t* out_len, size_t out_size );
+
+/**
+ * \brief           This function decrypts a buffer using key wrapping.
+ *
+ * \param ctx       The key wrapping context to use for decryption.
+ * \param mode      The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
+ * \param input     The buffer holding the input data.
+ * \param in_len    The length of the input data in Bytes.
+ *                  The input uses units of 8 Bytes called semiblocks.
+ *                  The input must be a multiple of semiblocks.
+ *                  <ul><li>For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive. </li>
+ *                  <li>For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.</li></ul>
+ * \param[out] output    The buffer holding the output data.
+ *                  The output buffer's minimal length is 8 bytes shorter than \p in_len.
+ * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
+ *                  For KWP mode, the length could be up to 15 bytes shorter than \p in_len,
+ *                  depending on how much padding was added to the data.
+ * \param[in] out_size The capacity of the output buffer.
+ *
+ * \return          \c 0 on success.
+ * \return          \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
+ * \return          \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext.
+ * \return          cipher-specific error code on failure of the underlying cipher.
+ */
+int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
+                            const unsigned char *input, size_t in_len,
+                            unsigned char *output, size_t* out_len, size_t out_size);
+
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+/**
+ * \brief          The key wrapping checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_nist_kw_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_NIST_KW_H */

+ 21 - 5
app/include/mbedtls/oid.h

@@ -97,6 +97,8 @@
 /* ISO arc for standard certificate and CRL extensions */
 #define MBEDTLS_OID_ID_CE                       MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER  ::=  {joint-iso-ccitt(2) ds(5) 29} */
 
+#define MBEDTLS_OID_NIST_ALG                    MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */
+
 /**
  * Private Internet Extensions
  * { iso(1) identified-organization(3) dod(6) internet(1)
@@ -219,12 +221,12 @@
 #define MBEDTLS_OID_DIGEST_ALG_MD4              MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */
 #define MBEDTLS_OID_DIGEST_ALG_MD5              MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
 #define MBEDTLS_OID_DIGEST_ALG_SHA1             MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
-#define MBEDTLS_OID_DIGEST_ALG_SHA224           MBEDTLS_OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
-#define MBEDTLS_OID_DIGEST_ALG_SHA256           MBEDTLS_OID_GOV "\x03\x04\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA224           MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA256           MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
 
-#define MBEDTLS_OID_DIGEST_ALG_SHA384           MBEDTLS_OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA384           MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
 
-#define MBEDTLS_OID_DIGEST_ALG_SHA512           MBEDTLS_OID_GOV "\x03\x04\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA512           MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
 
 #define MBEDTLS_OID_HMAC_SHA1                   MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
 
@@ -241,7 +243,20 @@
  */
 #define MBEDTLS_OID_DES_CBC                     MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
 #define MBEDTLS_OID_DES_EDE3_CBC                MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
+#define MBEDTLS_OID_AES                         MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
 
+/*
+ * Key Wrapping algorithms
+ */
+/*
+ * RFC 5649
+ */
+#define MBEDTLS_OID_AES128_KW                   MBEDTLS_OID_AES "\x05" /** id-aes128-wrap     OBJECT IDENTIFIER ::= { aes 5 } */
+#define MBEDTLS_OID_AES128_KWP                  MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */
+#define MBEDTLS_OID_AES192_KW                   MBEDTLS_OID_AES "\x19" /** id-aes192-wrap     OBJECT IDENTIFIER ::= { aes 25 } */
+#define MBEDTLS_OID_AES192_KWP                  MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */
+#define MBEDTLS_OID_AES256_KW                   MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap     OBJECT IDENTIFIER ::= { aes 45 } */
+#define MBEDTLS_OID_AES256_KWP                  MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */
 /*
  * PKCS#5 OIDs
  */
@@ -388,7 +403,8 @@ extern "C" {
 /**
  * \brief Base OID descriptor structure
  */
-typedef struct {
+typedef struct mbedtls_oid_descriptor_t
+{
     const char *asn1;               /*!< OID ASN.1 representation       */
     size_t asn1_len;                /*!< length of asn1                 */
     const char *name;               /*!< official name (e.g. from RFC)  */

+ 30 - 12
app/include/mbedtls/padlock.h

@@ -3,6 +3,9 @@
  *
  * \brief VIA PadLock ACE for HW encryption/decryption supported by some
  *        processors
+ *
+ * \warning These functions are only for internal use by other library
+ *          functions; you must not call them directly.
  */
 /*
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@@ -25,6 +28,12 @@
 #ifndef MBEDTLS_PADLOCK_H
 #define MBEDTLS_PADLOCK_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "aes.h"
 
 #define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED               -0x0030  /**< Input data should be aligned. */
@@ -50,14 +59,17 @@
 #define MBEDTLS_PADLOCK_PHE 0x0C00
 #define MBEDTLS_PADLOCK_PMM 0x3000
 
-#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15))
+#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15))
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * \brief          PadLock detection routine
+ * \brief          Internal PadLock detection routine
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param feature  The feature to detect
  *
@@ -66,7 +78,10 @@ extern "C" {
 int mbedtls_padlock_has_support( int feature );
 
 /**
- * \brief          PadLock AES-ECB block en(de)cryption
+ * \brief          Internal PadLock AES-ECB block en(de)cryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param ctx      AES context
  * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@@ -76,12 +91,15 @@ int mbedtls_padlock_has_support( int feature );
  * \return         0 if success, 1 if operation failed
  */
 int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
-                       int mode,
-                       const unsigned char input[16],
-                       unsigned char output[16] );
+                               int mode,
+                               const unsigned char input[16],
+                               unsigned char output[16] );
 
 /**
- * \brief          PadLock AES-CBC buffer en(de)cryption
+ * \brief          Internal PadLock AES-CBC buffer en(de)cryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
  *
  * \param ctx      AES context
  * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
@@ -93,11 +111,11 @@ int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
  * \return         0 if success, 1 if operation failed
  */
 int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
-                       int mode,
-                       size_t length,
-                       unsigned char iv[16],
-                       const unsigned char *input,
-                       unsigned char *output );
+                               int mode,
+                               size_t length,
+                               unsigned char iv[16],
+                               const unsigned char *input,
+                               unsigned char *output );
 
 #ifdef __cplusplus
 }

+ 7 - 1
app/include/mbedtls/pem.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_PEM_H
 #define MBEDTLS_PEM_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include <stddef.h>
 
 /**
@@ -51,7 +57,7 @@ extern "C" {
 /**
  * \brief       PEM context structure
  */
-typedef struct
+typedef struct mbedtls_pem_context
 {
     unsigned char *buf;     /*!< buffer for decoded data             */
     size_t buflen;          /*!< length of the buffer                */

+ 183 - 46
app/include/mbedtls/pk.h

@@ -64,6 +64,8 @@
 #define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00  /**< Elliptic curve is unsupported (only NIST curves are supported). */
 #define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980  /**< Unavailable feature, e.g. RSA disabled for RSA key. */
 #define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH    -0x3900  /**< The buffer contains a valid signature followed by more data. */
+
+/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_PK_HW_ACCEL_FAILED     -0x3880  /**< PK hardware accelerator failed. */
 
 #ifdef __cplusplus
@@ -87,7 +89,7 @@ typedef enum {
  * \brief           Options for RSASSA-PSS signature verification.
  *                  See \c mbedtls_rsa_rsassa_pss_verify_ext()
  */
-typedef struct
+typedef struct mbedtls_pk_rsassa_pss_options
 {
     mbedtls_md_type_t mgf1_hash_id;
     int expected_salt_len;
@@ -107,7 +109,7 @@ typedef enum
 /**
  * \brief           Item to send to the debug module
  */
-typedef struct
+typedef struct mbedtls_pk_debug_item
 {
     mbedtls_pk_debug_type type;
     const char *name;
@@ -125,12 +127,26 @@ typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
 /**
  * \brief           Public key container
  */
-typedef struct
+typedef struct mbedtls_pk_context
 {
-    const mbedtls_pk_info_t *   pk_info; /**< Public key informations        */
+    const mbedtls_pk_info_t *   pk_info; /**< Public key information         */
     void *                      pk_ctx;  /**< Underlying public key context  */
 } mbedtls_pk_context;
 
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Context for resuming operations
+ */
+typedef struct
+{
+    const mbedtls_pk_info_t *   pk_info; /**< Public key information         */
+    void *                      rs_ctx;  /**< Underlying restart context     */
+} mbedtls_pk_restart_ctx;
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+/* Now we can declare functions that take a pointer to that */
+typedef void mbedtls_pk_restart_ctx;
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
 #if defined(MBEDTLS_RSA_C)
 /**
  * Quick access to an RSA context inside a PK context.
@@ -181,20 +197,45 @@ typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx );
 const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type );
 
 /**
- * \brief           Initialize a mbedtls_pk_context (as NONE)
+ * \brief           Initialize a #mbedtls_pk_context (as NONE).
+ *
+ * \param ctx       The context to initialize.
+ *                  This must not be \c NULL.
  */
 void mbedtls_pk_init( mbedtls_pk_context *ctx );
 
 /**
- * \brief           Free a mbedtls_pk_context
+ * \brief           Free the components of a #mbedtls_pk_context.
+ *
+ * \param ctx       The context to clear. It must have been initialized.
+ *                  If this is \c NULL, this function does nothing.
  */
 void mbedtls_pk_free( mbedtls_pk_context *ctx );
 
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context
+ *
+ * \param ctx       The context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context
+ *
+ * \param ctx       The context to clear. It must have been initialized.
+ *                  If this is \c NULL, this function does nothing.
+ */
+void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
 /**
  * \brief           Initialize a PK context with the information given
  *                  and allocates the type-specific PK subcontext.
  *
- * \param ctx       Context to initialize. Must be empty (type NONE).
+ * \param ctx       Context to initialize. It must not have been set
+ *                  up yet (type #MBEDTLS_PK_NONE).
  * \param info      Information to use
  *
  * \return          0 on success,
@@ -210,7 +251,8 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
 /**
  * \brief           Initialize an RSA-alt context
  *
- * \param ctx       Context to initialize. Must be empty (type NONE).
+ * \param ctx       Context to initialize. It must not have been set
+ *                  up yet (type #MBEDTLS_PK_NONE).
  * \param key       RSA key pointer
  * \param decrypt_func  Decryption function
  * \param sign_func     Signing function
@@ -230,7 +272,7 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
 /**
  * \brief           Get the size in bits of the underlying key
  *
- * \param ctx       Context to use
+ * \param ctx       The context to query. It must have been initialized.
  *
  * \return          Key size in bits, or 0 on error
  */
@@ -238,7 +280,8 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx );
 
 /**
  * \brief           Get the length in bytes of the underlying key
- * \param ctx       Context to use
+ *
+ * \param ctx       The context to query. It must have been initialized.
  *
  * \return          Key length in bytes, or 0 on error
  */
@@ -250,18 +293,21 @@ static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx )
 /**
  * \brief           Tell if a context can do the operation given by type
  *
- * \param ctx       Context to test
- * \param type      Target type
+ * \param ctx       The context to query. It must have been initialized.
+ * \param type      The desired type.
  *
- * \return          0 if context can't do the operations,
- *                  1 otherwise.
+ * \return          1 if the context can do operations on the given type.
+ * \return          0 if the context cannot do the operations on the given
+ *                  type. This is always the case for a context that has
+ *                  been initialized but not set up, or that has been
+ *                  cleared with mbedtls_pk_free().
  */
 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
 
 /**
  * \brief           Verify signature (including padding if relevant).
  *
- * \param ctx       PK context to use
+ * \param ctx       The PK context to use. It must have been set up.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -286,13 +332,39 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
                const unsigned char *hash, size_t hash_len,
                const unsigned char *sig, size_t sig_len );
 
+/**
+ * \brief           Restartable version of \c mbedtls_pk_verify()
+ *
+ * \note            Performs the same job as \c mbedtls_pk_verify(), but can
+ *                  return early and restart according to the limit set with
+ *                  \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
+ *                  operations. For RSA, same as \c mbedtls_pk_verify().
+ *
+ * \param ctx       The PK context to use. It must have been set up.
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Signature to verify
+ * \param sig_len   Signature length
+ * \param rs_ctx    Restart context (NULL to disable restart)
+ *
+ * \return          See \c mbedtls_pk_verify(), or
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ */
+int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
+               mbedtls_md_type_t md_alg,
+               const unsigned char *hash, size_t hash_len,
+               const unsigned char *sig, size_t sig_len,
+               mbedtls_pk_restart_ctx *rs_ctx );
+
 /**
  * \brief           Verify signature, with options.
  *                  (Includes verification of the padding depending on type.)
  *
  * \param type      Signature type (inc. possible padding type) to verify
  * \param options   Pointer to type-specific options, or NULL
- * \param ctx       PK context to use
+ * \param ctx       The PK context to use. It must have been set up.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -323,7 +395,8 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
 /**
  * \brief           Make signature, including padding if relevant.
  *
- * \param ctx       PK context to use - must hold a private key
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
  * \param hash_len  Hash length or 0 (see notes)
@@ -343,16 +416,55 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
  *
  * \note            For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
  *                  For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
+ *
+ * \note            In order to ensure enough space for the signature, the
+ *                  \p sig buffer size must be of at least
+ *                  `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
  */
 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
              unsigned char *sig, size_t *sig_len,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
+/**
+ * \brief           Restartable version of \c mbedtls_pk_sign()
+ *
+ * \note            Performs the same job as \c mbedtls_pk_sign(), but can
+ *                  return early and restart according to the limit set with
+ *                  \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
+ *                  operations. For RSA, same as \c mbedtls_pk_sign().
+ *
+ * \note            In order to ensure enough space for the signature, the
+ *                  \p sig buffer size must be of at least
+ *                  `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
+ *
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Place to write the signature
+ * \param sig_len   Number of bytes written
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ * \param rs_ctx    Restart context (NULL to disable restart)
+ *
+ * \return          See \c mbedtls_pk_sign(), or
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ */
+int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
+             mbedtls_md_type_t md_alg,
+             const unsigned char *hash, size_t hash_len,
+             unsigned char *sig, size_t *sig_len,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+             mbedtls_pk_restart_ctx *rs_ctx );
+
 /**
  * \brief           Decrypt message (including padding if relevant).
  *
- * \param ctx       PK context to use - must hold a private key
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
  * \param input     Input to decrypt
  * \param ilen      Input size
  * \param output    Decrypted output
@@ -373,7 +485,7 @@ int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
 /**
  * \brief           Encrypt message (including padding if relevant).
  *
- * \param ctx       PK context to use
+ * \param ctx       The PK context to use. It must have been set up.
  * \param input     Message to encrypt
  * \param ilen      Message size
  * \param output    Encrypted output
@@ -404,7 +516,7 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
 /**
  * \brief           Export debug information
  *
- * \param ctx       Context to use
+ * \param ctx       The PK context to use. It must have been initialized.
  * \param items     Place to write debug items
  *
  * \return          0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
@@ -414,7 +526,7 @@ int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *item
 /**
  * \brief           Access the type name
  *
- * \param ctx       Context to use
+ * \param ctx       The PK context to use. It must have been initialized.
  *
  * \return          Type name on success, or "invalid PK"
  */
@@ -423,9 +535,10 @@ const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx );
 /**
  * \brief           Get the key type
  *
- * \param ctx       Context to use
+ * \param ctx       The PK context to use. It must have been initialized.
  *
- * \return          Type on success, or MBEDTLS_PK_NONE
+ * \return          Type on success.
+ * \return          #MBEDTLS_PK_NONE for a context that has not been set up.
  */
 mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
 
@@ -434,12 +547,22 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
 /**
  * \brief           Parse a private key in PEM or DER format
  *
- * \param ctx       key to be initialized
- * \param key       input buffer
- * \param keylen    size of the buffer
- *                  (including the terminating null byte for PEM data)
- * \param pwd       password for decryption (optional)
- * \param pwdlen    size of the password
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param key       Input buffer to parse.
+ *                  The buffer must contain the input exactly, with no
+ *                  extra trailing material. For PEM, the buffer must
+ *                  contain a null-terminated string.
+ * \param keylen    Size of \b key in bytes.
+ *                  For PEM data, this includes the terminating null byte,
+ *                  so \p keylen must be equal to `strlen(key) + 1`.
+ * \param pwd       Optional password for decryption.
+ *                  Pass \c NULL if expecting a non-encrypted key.
+ *                  Pass a string of \p pwdlen bytes if expecting an encrypted
+ *                  key; a non-encrypted key will also be accepted.
+ *                  The empty password is not supported.
+ * \param pwdlen    Size of the password in bytes.
+ *                  Ignored if \p pwd is \c NULL.
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -457,10 +580,15 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *ctx,
 /**
  * \brief           Parse a public key in PEM or DER format
  *
- * \param ctx       key to be initialized
- * \param key       input buffer
- * \param keylen    size of the buffer
- *                  (including the terminating null byte for PEM data)
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param key       Input buffer to parse.
+ *                  The buffer must contain the input exactly, with no
+ *                  extra trailing material. For PEM, the buffer must
+ *                  contain a null-terminated string.
+ * \param keylen    Size of \b key in bytes.
+ *                  For PEM data, this includes the terminating null byte,
+ *                  so \p keylen must be equal to `strlen(key) + 1`.
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -478,9 +606,14 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
 /**
  * \brief           Load and parse a private key
  *
- * \param ctx       key to be initialized
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
  * \param path      filename to read the private key from
- * \param password  password to decrypt the file (can be NULL)
+ * \param password  Optional password to decrypt the file.
+ *                  Pass \c NULL if expecting a non-encrypted key.
+ *                  Pass a null-terminated string if expecting an encrypted
+ *                  key; a non-encrypted key will also be accepted.
+ *                  The empty password is not supported.
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -497,7 +630,8 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
 /**
  * \brief           Load and parse a public key
  *
- * \param ctx       key to be initialized
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
  * \param path      filename to read the public key from
  *
  * \note            On entry, ctx must be empty, either freshly initialised
@@ -520,7 +654,7 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
  *                        return value to determine where you should start
  *                        using the buffer
  *
- * \param ctx       private to write away
+ * \param ctx       PK context which must contain a valid private key.
  * \param buf       buffer to write to
  * \param size      size of the buffer
  *
@@ -535,7 +669,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_
  *                        return value to determine where you should start
  *                        using the buffer
  *
- * \param ctx       public key to write away
+ * \param ctx       PK context which must contain a valid public or private key.
  * \param buf       buffer to write to
  * \param size      size of the buffer
  *
@@ -548,9 +682,10 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, si
 /**
  * \brief           Write a public key to a PEM string
  *
- * \param ctx       public key to write away
- * \param buf       buffer to write to
- * \param size      size of the buffer
+ * \param ctx       PK context which must contain a valid public or private key.
+ * \param buf       Buffer to write to. The output includes a
+ *                  terminating null byte.
+ * \param size      Size of the buffer in bytes.
  *
  * \return          0 if successful, or a specific error code
  */
@@ -559,9 +694,10 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, si
 /**
  * \brief           Write a private key to a PKCS#1 or SEC1 PEM string
  *
- * \param ctx       private to write away
- * \param buf       buffer to write to
- * \param size      size of the buffer
+ * \param ctx       PK context which must contain a valid private key.
+ * \param buf       Buffer to write to. The output includes a
+ *                  terminating null byte.
+ * \param size      Size of the buffer in bytes.
  *
  * \return          0 if successful, or a specific error code
  */
@@ -580,7 +716,8 @@ int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_
  *
  * \param p         the position in the ASN.1 data
  * \param end       end of the buffer
- * \param pk        the key to fill
+ * \param pk        The PK context to fill. It must have been initialized
+ *                  but not set up.
  *
  * \return          0 if successful, or a specific PK error code
  */
@@ -595,7 +732,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
  *
  * \param p         reference to current position pointer
  * \param start     start of the buffer (for bounds-checking)
- * \param key       public key to write away
+ * \param key       PK context which must contain a valid public or private key.
  *
  * \return          the length written or a negative error code
  */

+ 23 - 0
app/include/mbedtls/pk_internal.h

@@ -59,6 +59,21 @@ struct mbedtls_pk_info_t
                       int (*f_rng)(void *, unsigned char *, size_t),
                       void *p_rng );
 
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /** Verify signature (restartable) */
+    int (*verify_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
+                           const unsigned char *hash, size_t hash_len,
+                           const unsigned char *sig, size_t sig_len,
+                           void *rs_ctx );
+
+    /** Make signature (restartable) */
+    int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
+                         const unsigned char *hash, size_t hash_len,
+                         unsigned char *sig, size_t *sig_len,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng, void *rs_ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
     /** Decrypt message */
     int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
                          unsigned char *output, size_t *olen, size_t osize,
@@ -80,6 +95,14 @@ struct mbedtls_pk_info_t
     /** Free the given context */
     void (*ctx_free_func)( void *ctx );
 
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /** Allocate the restart context */
+    void * (*rs_alloc_func)( void );
+
+    /** Free the restart context */
+    void (*rs_free_func)( void *rs_ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
     /** Interface with the debug module */
     void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items );
 

+ 2 - 1
app/include/mbedtls/pkcs11.h

@@ -50,7 +50,8 @@ extern "C" {
 /**
  * Context for PKCS #11 private keys.
  */
-typedef struct {
+typedef struct mbedtls_pkcs11_context
+{
         pkcs11h_certificate_t pkcs11h_cert;
         int len;
 } mbedtls_pkcs11_context;

+ 4 - 0
app/include/mbedtls/pkcs5.h

@@ -91,6 +91,8 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
                        unsigned int iteration_count,
                        uint32_t key_length, unsigned char *output );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -98,6 +100,8 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
  */
 int mbedtls_pkcs5_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 49 - 30
app/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
@@ -34,6 +43,9 @@
 #include "platform_time.h"
 #endif
 
+#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED     -0x0070 /**< Hardware accelerator failed */
+#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -102,7 +114,7 @@ extern "C" {
 /* \} name SECTION: Module settings */
 
 /*
- * The function pointers for calloc and free
+ * The function pointers for calloc and free.
  */
 #if defined(MBEDTLS_PLATFORM_MEMORY)
 #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
@@ -112,11 +124,12 @@ extern "C" {
 #else
 /* For size_t */
 #include <stddef.h>
-extern void * (*mbedtls_calloc)( size_t n, size_t size );
-extern void (*mbedtls_free)( void *ptr );
+extern void *mbedtls_calloc( size_t n, size_t size );
+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 +153,9 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
 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 +178,9 @@ int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char
 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 +213,12 @@ int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
 extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
 
 /**
- * \brief   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, ... ) );
@@ -211,8 +227,8 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
 #define mbedtls_snprintf   MBEDTLS_PLATFORM_SNPRINTF_MACRO
 #define mbedtls_vsnprintf  MBEDTLS_PLATFORM_VSNPRINTF_MACRO
 #else
-#define mbedtls_snprintf   snprintf
 #define mbedtls_vsnprintf  vsnprintf
+#define mbedtls_snprintf   MBEDTLS_PLATFORM_STD_SNPRINTF
 #endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
 #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
 
@@ -223,12 +239,13 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
 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
@@ -303,8 +320,9 @@ int mbedtls_platform_set_nv_seed(
  * \note    This structure may be used to assist platform-specific
  *          setup or teardown operations.
  */
-typedef struct {
-    char dummy; /**< Placeholder member, as empty structs are not portable. */
+typedef struct mbedtls_platform_context
+{
+    char dummy; /**< A placeholder member, as empty structs are not portable. */
 }
 mbedtls_platform_context;
 
@@ -313,33 +331,34 @@ mbedtls_platform_context;
 #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 );
 

+ 196 - 0
app/include/mbedtls/platform_util.h

@@ -0,0 +1,196 @@
+/**
+ * \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
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+#include "platform_time.h"
+#include <time.h>
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_CHECK_PARAMS)
+
+#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
+ * (which is what our config.h suggests). */
+#include <assert.h>
+#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
+
+#if defined(MBEDTLS_PARAM_FAILED)
+/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
+ *
+ * This flag can be used to check whether it is safe to assume that
+ * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
+ */
+#define MBEDTLS_PARAM_FAILED_ALT
+
+#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
+#define MBEDTLS_PARAM_FAILED_ALT
+
+#else /* MBEDTLS_PARAM_FAILED */
+#define MBEDTLS_PARAM_FAILED( cond ) \
+    mbedtls_param_failed( #cond, __FILE__, __LINE__ )
+
+/**
+ * \brief       User supplied callback function for parameter validation failure.
+ *              See #MBEDTLS_CHECK_PARAMS for context.
+ *
+ *              This function will be called unless an alternative treatement
+ *              is defined through the #MBEDTLS_PARAM_FAILED macro.
+ *
+ *              This function can return, and the operation will be aborted, or
+ *              alternatively, through use of setjmp()/longjmp() can resume
+ *              execution in the application code.
+ *
+ * \param failure_condition The assertion that didn't hold.
+ * \param file  The file where the assertion failed.
+ * \param line  The line in the file where the assertion failed.
+ */
+void mbedtls_param_failed( const char *failure_condition,
+                           const char *file,
+                           int line );
+#endif /* MBEDTLS_PARAM_FAILED */
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret )  \
+    do {                                            \
+        if( !(cond) )                               \
+        {                                           \
+            MBEDTLS_PARAM_FAILED( cond );           \
+            return( ret );                          \
+        }                                           \
+    } while( 0 )
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE( cond )           \
+    do {                                            \
+        if( !(cond) )                               \
+        {                                           \
+            MBEDTLS_PARAM_FAILED( cond );           \
+            return;                                 \
+        }                                           \
+    } while( 0 )
+
+#else /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal macros meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret )  do { } while( 0 )
+#define MBEDTLS_INTERNAL_VALIDATE( cond )           do { } while( 0 )
+
+#endif /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal helper macros for deprecating API constants. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here
+ * to avoid conflict with other headers which define and use
+ * it, too. We might want to move all these definitions here at
+ * some point for uniformity. */
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t;
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL )       \
+    ( (mbedtls_deprecated_string_constant_t) ( VAL ) )
+MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL )       \
+    ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) )
+#undef MBEDTLS_DEPRECATED
+#else /* MBEDTLS_DEPRECATED_WARNING */
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief       Securely zeroize a buffer
+ *
+ *              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 );
+
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+/**
+ * \brief      Platform-specific implementation of gmtime_r()
+ *
+ *             The function is a thread-safe abstraction that behaves
+ *             similarly to the gmtime_r() function from Unix/POSIX.
+ *
+ *             Mbed TLS will try to identify the underlying platform and
+ *             make use of an appropriate underlying implementation (e.g.
+ *             gmtime_r() for POSIX and gmtime_s() for Windows). If this is
+ *             not possible, then gmtime() will be used. In this case, calls
+ *             from the library to gmtime() will be guarded by the mutex
+ *             mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is
+ *             enabled. It is recommended that calls from outside the library
+ *             are also guarded by this mutex.
+ *
+ *             If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will
+ *             unconditionally use the alternative implementation for
+ *             mbedtls_platform_gmtime_r() supplied by the user at compile time.
+ *
+ * \param tt     Pointer to an object containing time (in seconds) since the
+ *               epoch to be converted
+ * \param tm_buf Pointer to an object where the results will be stored
+ *
+ * \return      Pointer to an object of type struct tm on success, otherwise
+ *              NULL
+ */
+struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
+                                      struct tm *tm_buf );
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_PLATFORM_UTIL_H */

+ 192 - 0
app/include/mbedtls/poly1305.h

@@ -0,0 +1,192 @@
+/**
+ * \file poly1305.h
+ *
+ * \brief   This file contains Poly1305 definitions and functions.
+ *
+ *          Poly1305 is a one-time message authenticator that can be used to
+ *          authenticate messages. Poly1305-AES was created by Daniel
+ *          Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic
+ *          Poly1305 algorithm (not tied to AES) was also standardized in RFC
+ *          7539.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ */
+
+/*  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
+ *  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_POLY1305_H
+#define MBEDTLS_POLY1305_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA         -0x0057 /**< Invalid input parameter(s). */
+
+/* MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE is deprecated and should not be
+ * used. */
+#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE    -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */
+
+/* MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED        -0x005B  /**< Poly1305 hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_POLY1305_ALT)
+
+typedef struct mbedtls_poly1305_context
+{
+    uint32_t r[4];      /** The value for 'r' (low 128 bits of the key). */
+    uint32_t s[4];      /** The value for 's' (high 128 bits of the key). */
+    uint32_t acc[5];    /** The accumulator number. */
+    uint8_t queue[16];  /** The current partial block of data. */
+    size_t queue_len;   /** The number of bytes stored in 'queue'. */
+}
+mbedtls_poly1305_context;
+
+#else  /* MBEDTLS_POLY1305_ALT */
+#include "poly1305_alt.h"
+#endif /* MBEDTLS_POLY1305_ALT */
+
+/**
+ * \brief           This function initializes the specified Poly1305 context.
+ *
+ *                  It must be the first API called before using
+ *                  the context.
+ *
+ *                  It is usually followed by a call to
+ *                  \c mbedtls_poly1305_starts(), then one or more calls to
+ *                  \c mbedtls_poly1305_update(), then one call to
+ *                  \c mbedtls_poly1305_finish(), then finally
+ *                  \c mbedtls_poly1305_free().
+ *
+ * \param ctx       The Poly1305 context to initialize. This must
+ *                  not be \c NULL.
+ */
+void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx );
+
+/**
+ * \brief           This function releases and clears the specified
+ *                  Poly1305 context.
+ *
+ * \param ctx       The Poly1305 context to clear. This may be \c NULL, in which
+ *                  case this function is a no-op. If it is not \c NULL, it must
+ *                  point to an initialized Poly1305 context.
+ */
+void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx );
+
+/**
+ * \brief           This function sets the one-time authentication key.
+ *
+ * \warning         The key must be unique and unpredictable for each
+ *                  invocation of Poly1305.
+ *
+ * \param ctx       The Poly1305 context to which the key should be bound.
+ *                  This must be initialized.
+ * \param key       The buffer containing the \c 32 Byte (\c 256 Bit) key.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
+                             const unsigned char key[32] );
+
+/**
+ * \brief           This functions feeds an input buffer into an ongoing
+ *                  Poly1305 computation.
+ *
+ *                  It is called between \c mbedtls_cipher_poly1305_starts() and
+ *                  \c mbedtls_cipher_poly1305_finish().
+ *                  It can be called repeatedly to process a stream of data.
+ *
+ * \param ctx       The Poly1305 context to use for the Poly1305 operation.
+ *                  This must be initialized and bound to a key.
+ * \param ilen      The length of the input data in Bytes.
+ *                  Any value is accepted.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
+                             const unsigned char *input,
+                             size_t ilen );
+
+/**
+ * \brief           This function generates the Poly1305 Message
+ *                  Authentication Code (MAC).
+ *
+ * \param ctx       The Poly1305 context to use for the Poly1305 operation.
+ *                  This must be initialized and bound to a key.
+ * \param mac       The buffer to where the MAC is written. This must
+ *                  be a writable buffer of length \c 16 Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
+                             unsigned char mac[16] );
+
+/**
+ * \brief           This function calculates the Poly1305 MAC of the input
+ *                  buffer with the provided key.
+ *
+ * \warning         The key must be unique and unpredictable for each
+ *                  invocation of Poly1305.
+ *
+ * \param key       The buffer containing the \c 32 Byte (\c 256 Bit) key.
+ * \param ilen      The length of the input data in Bytes.
+ *                  Any value is accepted.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param mac       The buffer to where the MAC is written. This must be
+ *                  a writable buffer of length \c 16 Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_mac( const unsigned char key[32],
+                          const unsigned char *input,
+                          size_t ilen,
+                          unsigned char mac[16] );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief           The Poly1305 checkup routine.
+ *
+ * \return          \c 0 on success.
+ * \return          \c 1 on failure.
+ */
+int mbedtls_poly1305_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_POLY1305_H */

+ 15 - 17
app/include/mbedtls/ripemd160.h

@@ -33,20 +33,22 @@
 #include <stddef.h>
 #include <stdint.h>
 
+/* MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
 #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
  */
-typedef struct
+typedef struct mbedtls_ripemd160_context
 {
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[5];          /*!< intermediate digest state  */
@@ -54,6 +56,10 @@ typedef struct
 }
 mbedtls_ripemd160_context;
 
+#else  /* MBEDTLS_RIPEMD160_ALT */
+#include "ripemd160.h"
+#endif /* MBEDTLS_RIPEMD160_ALT */
+
 /**
  * \brief          Initialize RIPEMD-160 context
  *
@@ -178,18 +184,6 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160_process(
 #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 )
  *
@@ -225,6 +219,8 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -232,6 +228,8 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input,
  */
 int mbedtls_ripemd160_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

File diff suppressed because it is too large
+ 379 - 303
app/include/mbedtls/rsa.h


+ 113 - 83
app/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
@@ -37,16 +40,18 @@
 #include <stddef.h>
 #include <stdint.h>
 
+/* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
-
-#if !defined(MBEDTLS_SHA1_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA                   -0x0073  /**< SHA-1 input data was malformed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA1_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          The SHA-1 context structure.
  *
@@ -55,7 +60,7 @@ extern "C" {
  *                 stronger message digests instead.
  *
  */
-typedef struct
+typedef struct mbedtls_sha1_context
 {
     uint32_t total[2];          /*!< The number of Bytes processed.  */
     uint32_t state[5];          /*!< The intermediate digest state.  */
@@ -63,40 +68,48 @@ typedef struct
 }
 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.
+ *                 This must not be \c NULL.
+ *
  */
 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. This may be \c NULL,
+ *                 in which case this function does nothing. If it is
+ *                 not \c NULL, it must point to an initialized
+ *                 SHA-1 context.
+ *
  */
 void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
 
 /**
  * \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. This must be initialized.
+ * \param src      The SHA-1 context to clone from. This must be initialized.
+ *
  */
 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
                          const mbedtls_sha1_context *src );
@@ -104,14 +117,15 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
 /**
  * \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. This must be initialized.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ *
  */
 int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
 
@@ -119,16 +133,18 @@ int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
  * \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. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
                              const unsigned char *input,
@@ -138,31 +154,35 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
  * \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 to use. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-1 checksum result. This must be a writable
+ *                 buffer of length \c 20 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
                              unsigned char output[20] );
 
 /**
- * \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 to use. This must be initialized.
+ * \param data     The data block being processed. This must be a
+ *                 readable buffer of length \c 64 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ *
  */
 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
                                    const unsigned char data[64] );
@@ -174,65 +194,71 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
 #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. This must be initialized.
+ *
  */
 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. This must be initialized and
+ *                 have a hash operation started.
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ *
  */
 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. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-1 checksum result.
+ *                 This must be a writable buffer of length \c 20 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
                                              unsigned char output[20] );
 
 /**
- * \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. This must be initialized.
+ * \param data     The data block being processed.
+ *                 This must be a readable buffer of length \c 64 bytes.
+ *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
                                               const unsigned char data[64] );
@@ -240,18 +266,6 @@ MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
 #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,16 +275,19 @@ extern "C" {
  *                 The SHA-1 result is calculated as
  *                 output = SHA-1(input buffer).
  *
- * \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.
  *
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ * \param output   The SHA-1 checksum result.
+ *                 This must be a writable buffer of length \c 20 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ *
  */
 int mbedtls_sha1_ret( const unsigned char *input,
                       size_t ilen,
@@ -283,18 +300,26 @@ int mbedtls_sha1_ret( const unsigned char *input,
 #define MBEDTLS_DEPRECATED
 #endif
 /**
- * \brief          Output = SHA-1( input buffer )
+ * \brief          This function calculates the SHA-1 checksum of a buffer.
  *
- * \deprecated     Superseded by mbedtls_sha1_ret() in 2.7.0
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
  *
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-1 checksum result.
+ *                 The SHA-1 result is calculated as
+ *                 output = SHA-1(input buffer).
  *
  * \warning        SHA-1 is considered a weak message digest and its use
  *                 constitutes a security risk. We recommend considering
  *                 stronger message digests instead.
  *
+ * \deprecated     Superseded by mbedtls_sha1_ret() in 2.7.0
+ *
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ * \param output   The SHA-1 checksum result. This must be a writable
+ *                 buffer of size \c 20 Bytes.
+ *
  */
 MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input,
                                       size_t ilen,
@@ -303,18 +328,23 @@ MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \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 );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 78 - 59
app/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
@@ -33,16 +36,18 @@
 #include <stddef.h>
 #include <stdint.h>
 
+/* MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
-
-#if !defined(MBEDTLS_SHA256_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA                 -0x0074  /**< SHA-256 input data was malformed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA256_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          The SHA-256 context structure.
  *
@@ -50,36 +55,41 @@ extern "C" {
  *                 checksum calculations. The choice between these two is
  *                 made in the call to mbedtls_sha256_starts_ret().
  */
-typedef struct
+typedef struct mbedtls_sha256_context
 {
     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.
  *
- * \param ctx      The SHA-256 context to initialize.
+ * \param ctx      The SHA-256 context to initialize. This must not be \c NULL.
  */
 void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
 
 /**
  * \brief          This function clears a SHA-256 context.
  *
- * \param ctx      The SHA-256 context to clear.
+ * \param ctx      The SHA-256 context to clear. This may be \c NULL, in which
+ *                 case this function returns immediately. If it is not \c NULL,
+ *                 it must point to an initialized SHA-256 context.
  */
 void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
 
 /**
  * \brief          This function clones the state of a SHA-256 context.
  *
- * \param dst      The destination context.
- * \param src      The context to clone.
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The context to clone. This must be initialized.
  */
 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
                            const mbedtls_sha256_context *src );
@@ -88,12 +98,12 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
  * \brief          This function starts a SHA-224 or SHA-256 checksum
  *                 calculation.
  *
- * \param ctx      The context to initialize.
- * \param is224    Determines which function to use.
- *                 <ul><li>0: Use SHA-256.</li>
- *                 <li>1: Use SHA-224.</li></ul>
+ * \param ctx      The context to use. This must be initialized.
+ * \param is224    This determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 );
 
@@ -101,11 +111,14 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 );
  * \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. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
                                const unsigned char *input,
@@ -115,10 +128,13 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
  * \brief          This function finishes the SHA-256 operation, and writes
  *                 the result to the output buffer.
  *
- * \param ctx      The SHA-256 context.
+ * \param ctx      The SHA-256 context. This must be initialized
+ *                 and have a hash operation started.
  * \param output   The SHA-224 or SHA-256 checksum result.
+ *                 This must be a writable buffer of length \c 32 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
                                unsigned char output[32] );
@@ -128,10 +144,12 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
  *                 the ongoing SHA-256 computation. This function is for
  *                 internal use only.
  *
- * \param ctx      The SHA-256 context.
- * \param data     The buffer holding one block of data.
+ * \param ctx      The SHA-256 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must
+ *                 be a readable buffer of length \c 64 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
                                      const unsigned char data[64] );
@@ -143,14 +161,14 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
 #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 use. This must be initialized.
+ * \param is224    Determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
                                                int is224 );
@@ -161,9 +179,11 @@ MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
  *
  * \deprecated     Superseded by mbedtls_sha256_update_ret() in 2.7.0.
  *
- * \param ctx      The SHA-256 context to initialize.
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
+ * \param ctx      The SHA-256 context to use. This must be
+ *                 initialized and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
                                                const unsigned char *input,
@@ -175,8 +195,10 @@ MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
  *
  * \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 ctx      The SHA-256 context. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must be
+ *                 a writable buffer of length \c 32 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
                                                unsigned char output[32] );
@@ -188,25 +210,15 @@ MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
  *
  * \deprecated     Superseded by mbedtls_internal_sha256_process() in 2.7.0.
  *
- * \param ctx      The SHA-256 context.
- * \param data     The buffer holding one block of data.
+ * \param ctx      The SHA-256 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must be
+ *                 a readable buffer of size \c 64 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
                                                 const unsigned char data[64] );
 
 #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
@@ -218,12 +230,13 @@ extern "C" {
  *                 The SHA-256 result is calculated as
  *                 output = SHA-256(input buffer).
  *
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-224 or SHA-256 checksum result.
- * \param is224    Determines which function to use.
- *                 <ul><li>0: Use SHA-256.</li>
- *                 <li>1: Use SHA-224.</li></ul>
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must
+ *                 be a writable buffer of length \c 32 Bytes.
+ * \param is224    Determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
  */
 int mbedtls_sha256_ret( const unsigned char *input,
                         size_t ilen,
@@ -249,12 +262,13 @@ int mbedtls_sha256_ret( const unsigned char *input,
  *
  * \deprecated     Superseded by mbedtls_sha256_ret() in 2.7.0.
  *
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-224 or SHA-256 checksum result.
- * \param is224    Determines which function to use.
- *                 <ul><li>0: Use SHA-256.</li>
- *                 <li>1: Use SHA-224.</li></ul>
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must be
+ *                 a writable buffer of length \c 32 Bytes.
+ * \param is224    Determines which function to use. This must be either
+ *                 \c 0 for SHA-256, or \c 1 for SHA-224.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input,
                                         size_t ilen,
@@ -264,13 +278,18 @@ MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input,
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \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 );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 81 - 61
app/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
@@ -33,16 +35,18 @@
 #include <stddef.h>
 #include <stdint.h>
 
+/* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
-
-#if !defined(MBEDTLS_SHA512_ALT)
-// Regular implementation
-//
+#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA                 -0x0075  /**< SHA-512 input data was malformed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_SHA512_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          The SHA-512 context structure.
  *
@@ -50,36 +54,43 @@ extern "C" {
  *                 checksum calculations. The choice between these two is
  *                 made in the call to mbedtls_sha512_starts_ret().
  */
-typedef struct
+typedef struct mbedtls_sha512_context
 {
     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.
  *
- * \param ctx      The SHA-512 context to initialize.
+ * \param ctx      The SHA-512 context to initialize. This must
+ *                 not be \c NULL.
  */
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
 
 /**
  * \brief          This function clears a SHA-512 context.
  *
- * \param ctx      The SHA-512 context to clear.
+ * \param ctx      The SHA-512 context to clear. This may be \c NULL,
+ *                 in which case this function does nothing. If it
+ *                 is not \c NULL, it must point to an initialized
+ *                 SHA-512 context.
  */
 void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
 
 /**
  * \brief          This function clones the state of a SHA-512 context.
  *
- * \param dst      The destination context.
- * \param src      The context to clone.
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The context to clone. This must be initialized.
  */
 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
                            const mbedtls_sha512_context *src );
@@ -88,12 +99,12 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
  * \brief          This function starts a SHA-384 or SHA-512 checksum
  *                 calculation.
  *
- * \param ctx      The SHA-512 context to initialize.
- * \param is384    Determines which function to use.
- *                 <ul><li>0: Use SHA-512.</li>
- *                 <li>1: Use SHA-384.</li></ul>
+ * \param ctx      The SHA-512 context to use. This must be initialized.
+ * \param is384    Determines which function to use. This must be
+ *                 either \c for SHA-512, or \c 1 for SHA-384.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 );
 
@@ -101,11 +112,14 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 );
  * \brief          This function feeds an input buffer into an ongoing
  *                 SHA-512 checksum calculation.
  *
- * \param ctx      The SHA-512 context.
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
                     const unsigned char *input,
@@ -116,10 +130,13 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
  *                 the result to the output buffer. This function is for
  *                 internal use only.
  *
- * \param ctx      The SHA-512 context.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
  * \param output   The SHA-384 or SHA-512 checksum result.
+ *                 This must be a writable buffer of length \c 64 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
                                unsigned char output[64] );
@@ -128,10 +145,12 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
  * \brief          This function processes a single data block within
  *                 the ongoing SHA-512 computation.
  *
- * \param ctx      The SHA-512 context.
- * \param data     The buffer holding one block of data.
+ * \param ctx      The SHA-512 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This
+ *                 must be a readable buffer of length \c 128 Bytes.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
                                      const unsigned char data[128] );
@@ -147,10 +166,9 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
  *
  * \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 ctx      The SHA-512 context to use. This must be initialized.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512 or \c 1 for SHA-384.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
                                                int is384 );
@@ -159,11 +177,13 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
  * \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.
- * \param ilen     The length of the input data.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
                                                const unsigned char *input,
@@ -173,10 +193,12 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
  * \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.
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param output   The SHA-384 or SHA-512 checksum result. This must
+ *                 be a writable buffer of size \c 64 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
                                                unsigned char output[64] );
@@ -186,10 +208,11 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
  *                 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.
+ * \param ctx      The SHA-512 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must be
+ *                 a readable buffer of length \c 128 Bytes.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512_process(
                                             mbedtls_sha512_context *ctx,
@@ -198,18 +221,6 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_process(
 #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.
@@ -220,14 +231,16 @@ extern "C" {
  *                 The SHA-512 result is calculated as
  *                 output = SHA-512(input buffer).
  *
- * \param input    The buffer holding the input data.
- * \param ilen     The length of the input data.
+ * \param input    The buffer holding the input data. This must be
+ *                 a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
  * \param output   The SHA-384 or SHA-512 checksum result.
- * \param is384    Determines which function to use.
- *                 <ul><li>0: Use SHA-512.</li>
- *                 <li>1: Use SHA-384.</li></ul>
+ *                 This must be a writable buffer of length \c 64 Bytes.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512, or \c 1 for SHA-384.
  *
  * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha512_ret( const unsigned char *input,
                         size_t ilen,
@@ -240,6 +253,7 @@ int mbedtls_sha512_ret( const unsigned char *input,
 #else
 #define MBEDTLS_DEPRECATED
 #endif
+
 /**
  * \brief          This function calculates the SHA-512 or SHA-384
  *                 checksum of a buffer.
@@ -252,12 +266,13 @@ int mbedtls_sha512_ret( const unsigned char *input,
  *
  * \deprecated     Superseded by mbedtls_sha512_ret() in 2.7.0
  *
- * \param input    The buffer holding the data.
- * \param ilen     The length of the input data.
- * \param output   The SHA-384 or SHA-512 checksum result.
- * \param is384    Determines which function to use.
- *                 <ul><li>0: Use SHA-512.</li>
- *                 <li>1: Use SHA-384.</li></ul>
+ * \param input    The buffer holding the data. This must be a
+ *                 readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-384 or SHA-512 checksum result. This must
+ *                 be a writable buffer of length \c 64 Bytes.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512, or \c 1 for SHA-384.
  */
 MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input,
                                         size_t ilen,
@@ -266,12 +281,17 @@ MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input,
 
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
  /**
  * \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 );
+#endif /* MBEDTLS_SELF_TEST */
 
 #ifdef __cplusplus
 }

File diff suppressed because it is too large
+ 692 - 83
app/include/mbedtls/ssl.h


+ 6 - 0
app/include/mbedtls/ssl_cache.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_SSL_CACHE_H
 #define MBEDTLS_SSL_CACHE_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "ssl.h"
 
 #if defined(MBEDTLS_THREADING_C)

+ 54 - 0
app/include/mbedtls/ssl_ciphersuites.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_SSL_CIPHERSUITES_H
 #define MBEDTLS_SSL_CIPHERSUITES_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "pk.h"
 #include "cipher.h"
 #include "md.h"
@@ -169,6 +175,45 @@ extern "C" {
 #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! */
@@ -232,6 +277,15 @@ extern "C" {
 
 #define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8          0xC0FF  /**< experimental */
 
+/* RFC 7905 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   0xCCA8 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256     0xCCAA /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256         0xCCAB /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256   0xCCAC /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256     0xCCAD /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256     0xCCAE /**< TLS 1.2 */
+
 /* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange.
  * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below
  */

+ 7 - 1
app/include/mbedtls/ssl_cookie.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_SSL_COOKIE_H
 #define MBEDTLS_SSL_COOKIE_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "ssl.h"
 
 #if defined(MBEDTLS_THREADING_C)
@@ -50,7 +56,7 @@ extern "C" {
 /**
  * \brief          Context for the default cookie functions.
  */
-typedef struct
+typedef struct mbedtls_ssl_cookie_ctx
 {
     mbedtls_md_context_t    hmac_ctx;   /*!< context for the HMAC portion   */
 #if !defined(MBEDTLS_HAVE_TIME)

+ 141 - 24
app/include/mbedtls/ssl_internal.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_SSL_INTERNAL_H
 #define MBEDTLS_SSL_INTERNAL_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #include "ssl.h"
 #include "cipher.h"
 
@@ -93,6 +99,14 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_1 */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
+/* Shorthand for restartable ECC */
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+    defined(MBEDTLS_SSL_CLI_C) && \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#define MBEDTLS_SSL__ECP_RESTARTABLE
+#endif
+
 #define MBEDTLS_SSL_INITIAL_HANDSHAKE           0
 #define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS   1   /* In progress */
 #define MBEDTLS_SSL_RENEGOTIATION_DONE          2   /* Done or aborted */
@@ -143,32 +157,76 @@
 #define MBEDTLS_SSL_PADDING_ADD              0
 #endif
 
-#define MBEDTLS_SSL_PAYLOAD_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN    \
-                        + MBEDTLS_SSL_COMPRESSION_ADD            \
-                        + MBEDTLS_MAX_IV_LENGTH                  \
-                        + MBEDTLS_SSL_MAC_ADD                    \
-                        + MBEDTLS_SSL_PADDING_ADD                \
-                        )
+#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD +    \
+                                       MBEDTLS_MAX_IV_LENGTH +          \
+                                       MBEDTLS_SSL_MAC_ADD +            \
+                                       MBEDTLS_SSL_PADDING_ADD          \
+                                       )
+
+#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \
+                                     ( MBEDTLS_SSL_IN_CONTENT_LEN ) )
+
+#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \
+                                      ( MBEDTLS_SSL_OUT_CONTENT_LEN ) )
+
+/* The maximum number of buffered handshake messages. */
+#define MBEDTLS_SSL_MAX_BUFFERED_HS 4
+
+/* Maximum length we can advertise as our max content length for
+   RFC 6066 max_fragment_length extension negotiation purposes
+   (the lesser of both sizes, if they are unequal.)
+ */
+#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN (                            \
+        (MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN)   \
+        ? ( MBEDTLS_SSL_OUT_CONTENT_LEN )                            \
+        : ( MBEDTLS_SSL_IN_CONTENT_LEN )                             \
+        )
 
 /*
  * Check that we obey the standard's message size bounds
  */
 
 #if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384
-#error Bad configuration - record content too large.
+#error "Bad configuration - record content too large."
+#endif
+
+#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN
+#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN."
+#endif
+
+#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN
+#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN."
 #endif
 
-#if MBEDTLS_SSL_PAYLOAD_LEN > 16384 + 2048
-#error Bad configuration - protected record payload too large.
+#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048
+#error "Bad configuration - incoming protected record payload too large."
 #endif
 
+#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048
+#error "Bad configuration - outgoing protected record payload too large."
+#endif
+
+/* Calculate buffer sizes */
+
 /* Note: Even though the TLS record header is only 5 bytes
    long, we're internally using 8 bytes to store the
    implicit sequence number. */
 #define MBEDTLS_SSL_HEADER_LEN 13
 
-#define MBEDTLS_SSL_BUFFER_LEN  \
-    ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_PAYLOAD_LEN ) )
+#define MBEDTLS_SSL_IN_BUFFER_LEN  \
+    ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) )
+
+#define MBEDTLS_SSL_OUT_BUFFER_LEN  \
+    ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) )
+
+#ifdef MBEDTLS_ZLIB_SUPPORT
+/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */
+#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN (                               \
+        ( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN )      \
+        ? MBEDTLS_SSL_IN_BUFFER_LEN                                     \
+        : MBEDTLS_SSL_OUT_BUFFER_LEN                                    \
+        )
+#endif
 
 /*
  * TLS extension flags (for extensions with outgoing ServerHello content
@@ -243,6 +301,18 @@ struct mbedtls_ssl_handshake_params
     mbedtls_x509_crl *sni_ca_crl;       /*!< trusted CAs CRLs from SNI      */
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    int ecrs_enabled;                   /*!< Handshake supports EC restart? */
+    mbedtls_x509_crt_restart_ctx ecrs_ctx;  /*!< restart context            */
+    enum { /* this complements ssl->state with info on intra-state operations */
+        ssl_ecrs_none = 0,              /*!< nothing going on (yet)         */
+        ssl_ecrs_crt_verify,            /*!< Certificate: crt_verify()      */
+        ssl_ecrs_ske_start_processing,  /*!< ServerKeyExchange: pk_verify() */
+        ssl_ecrs_cke_ecdh_calc_secret,  /*!< ClientKeyExchange: ECDH step 2 */
+        ssl_ecrs_crt_vrfy_sign,         /*!< CertificateVerify: pk_sign()   */
+    } ecrs_state;                       /*!< current (or last) operation    */
+    size_t ecrs_n;                      /*!< place for saving a length      */
+#endif
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     unsigned int out_msg_seq;           /*!<  Outgoing handshake sequence number */
     unsigned int in_msg_seq;            /*!<  Incoming handshake sequence number */
@@ -252,18 +322,45 @@ struct mbedtls_ssl_handshake_params
     unsigned char verify_cookie_len;    /*!<  Cli: cookie length
                                               Srv: flag for sending a cookie */
 
-    unsigned char *hs_msg;              /*!<  Reassembled handshake message  */
-
     uint32_t retransmit_timeout;        /*!<  Current value of timeout       */
     unsigned char retransmit_state;     /*!<  Retransmission state           */
-    mbedtls_ssl_flight_item *flight;            /*!<  Current outgoing flight        */
-    mbedtls_ssl_flight_item *cur_msg;           /*!<  Current message in flight      */
+    mbedtls_ssl_flight_item *flight;    /*!<  Current outgoing flight        */
+    mbedtls_ssl_flight_item *cur_msg;   /*!<  Current message in flight      */
+    unsigned char *cur_msg_p;           /*!<  Position in current message    */
     unsigned int in_flight_start_seq;   /*!<  Minimum message sequence in the
                                               flight being received          */
     mbedtls_ssl_transform *alt_transform_out;   /*!<  Alternative transform for
                                               resending messages             */
     unsigned char alt_out_ctr[8];       /*!<  Alternative record epoch/counter
                                               for resending messages         */
+
+    struct
+    {
+        size_t total_bytes_buffered; /*!< Cumulative size of heap allocated
+                                      *   buffers used for message buffering. */
+
+        uint8_t seen_ccs;               /*!< Indicates if a CCS message has
+                                         *   been seen in the current flight. */
+
+        struct mbedtls_ssl_hs_buffer
+        {
+            unsigned is_valid      : 1;
+            unsigned is_fragmented : 1;
+            unsigned is_complete   : 1;
+            unsigned char *data;
+            size_t data_len;
+        } hs[MBEDTLS_SSL_MAX_BUFFERED_HS];
+
+        struct
+        {
+            unsigned char *data;
+            size_t len;
+            unsigned epoch;
+        } future_record;
+
+    } buffering;
+
+    uint16_t mtu;                       /*!<  Handshake mtu, used to fragment outgoing messages */
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
     /*
@@ -307,8 +404,23 @@ struct mbedtls_ssl_handshake_params
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
     int extended_ms;                    /*!< use Extended Master Secret? */
 #endif
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    /** Asynchronous operation context. This field is meant for use by the
+     * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start,
+     * mbedtls_ssl_config::f_async_decrypt_start,
+     * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel).
+     * The library does not use it internally. */
+    void *user_async_ctx;
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 };
 
+typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer;
+
 /*
  * This structure contains a full set of runtime transform parameters
  * either in negotiation or active.
@@ -410,9 +522,9 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
  * \brief           Free referenced items in an SSL handshake context and clear
  *                  memory
  *
- * \param handshake SSL handshake context
+ * \param ssl       SSL context
  */
-void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake );
+void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
 
 int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
@@ -423,7 +535,6 @@ int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl );
 
-int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
@@ -435,7 +546,10 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
  *              of the logic of (D)TLS from the implementation
  *              of the secure transport.
  *
- * \param  ssl  SSL context to use
+ * \param  ssl              The SSL context to use.
+ * \param  update_hs_digest This indicates if the handshake digest
+ *                          should be automatically updated in case
+ *                          a handshake message is found.
  *
  * \return      0 or non-zero error code.
  *
@@ -501,10 +615,12 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
  *              following the above definition.
  *
  */
-int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
+                             unsigned update_hs_digest );
 int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
 
-int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
 int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
 
 int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl );
@@ -613,6 +729,7 @@ static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
 void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_resend( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl );
 #endif
 
 /* Visible for testing purposes only */
@@ -652,9 +769,9 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
 int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
-                                        unsigned char *output,
-                                        unsigned char *data, size_t data_len,
-                                        mbedtls_md_type_t md_alg );
+                                            unsigned char *hash, size_t *hashlen,
+                                            unsigned char *data, size_t data_len,
+                                            mbedtls_md_type_t md_alg );
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
           MBEDTLS_SSL_PROTO_TLS1_2 */
 

+ 10 - 4
app/include/mbedtls/ssl_ticket.h

@@ -24,6 +24,12 @@
 #ifndef MBEDTLS_SSL_TICKET_H
 #define MBEDTLS_SSL_TICKET_H
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 /*
  * This implementation of the session ticket callbacks includes key
  * management, rotating the keys periodically in order to preserve forward
@@ -44,7 +50,7 @@ extern "C" {
 /**
  * \brief   Information for session ticket protection
  */
-typedef struct
+typedef struct mbedtls_ssl_ticket_key
 {
     unsigned char name[4];          /*!< random key identifier              */
     uint32_t generation_time;       /*!< key generation timestamp (seconds) */
@@ -55,7 +61,7 @@ mbedtls_ssl_ticket_key;
 /**
  * \brief   Context for session ticket handling functions
  */
-typedef struct
+typedef struct mbedtls_ssl_ticket_context
 {
     mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys             */
     unsigned char active;           /*!< index of the currently active key  */
@@ -111,14 +117,14 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
 /**
  * \brief           Implementation of the ticket write callback
  *
- * \note            See \c mbedlts_ssl_ticket_write_t for description
+ * \note            See \c mbedtls_ssl_ticket_write_t for description
  */
 mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write;
 
 /**
  * \brief           Implementation of the ticket parse callback
  *
- * \note            See \c mbedlts_ssl_ticket_parse_t for description
+ * \note            See \c mbedtls_ssl_ticket_parse_t for description
  */
 mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse;
 

+ 14 - 3
app/include/mbedtls/threading.h

@@ -36,13 +36,16 @@
 extern "C" {
 #endif
 
+/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be
+ * used. */
 #define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE         -0x001A  /**< The selected feature is not available. */
+
 #define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA              -0x001C  /**< Bad input parameters to function. */
 #define MBEDTLS_ERR_THREADING_MUTEX_ERROR                 -0x001E  /**< Locking / unlocking / free failed with error code. */
 
 #if defined(MBEDTLS_THREADING_PTHREAD)
 #include <pthread.h>
-typedef struct
+typedef struct mbedtls_threading_mutex_t
 {
     pthread_mutex_t mutex;
     char is_valid;
@@ -99,9 +102,17 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex );
 #if defined(MBEDTLS_FS_IO)
 extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
 #endif
-#if defined(MBEDTLS_HAVE_TIME_DATE)
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+/* This mutex may or may not be used in the default definition of
+ * mbedtls_platform_gmtime_r(), but in order to determine that,
+ * we need to check POSIX features, hence modify _POSIX_C_SOURCE.
+ * With the current approach, this declaration is orphaned, lacking
+ * an accompanying definition, in case mbedtls_platform_gmtime_r()
+ * doesn't need it, but that's not a problem. */
 extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
-#endif
+#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
+
 #endif /* MBEDTLS_THREADING_C */
 
 #ifdef __cplusplus

+ 9 - 17
app/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
  */
@@ -51,13 +51,17 @@ struct mbedtls_timing_hr_time
 /**
  * \brief          Context for mbedtls_timing_set/get_delay()
  */
-typedef struct
+typedef struct mbedtls_timing_delay_context
 {
     struct mbedtls_timing_hr_time   timer;
     uint32_t                        int_ms;
     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 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
  */
 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

+ 5 - 5
app/include/mbedtls/version.h

@@ -39,17 +39,17 @@
  * Major, Minor, Patchlevel
  */
 #define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  7
-#define MBEDTLS_VERSION_PATCH  9
+#define MBEDTLS_VERSION_MINOR  16
+#define MBEDTLS_VERSION_PATCH  3
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02070900
-#define MBEDTLS_VERSION_STRING         "2.7.9"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.7.9"
+#define MBEDTLS_VERSION_NUMBER         0x02100300
+#define MBEDTLS_VERSION_STRING         "2.16.3"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.3"
 
 #if defined(MBEDTLS_VERSION_C)
 

+ 7 - 3
app/include/mbedtls/x509.h

@@ -77,7 +77,7 @@
 #define MBEDTLS_ERR_X509_ALLOC_FAILED                     -0x2880  /**< Allocation of memory failed. */
 #define MBEDTLS_ERR_X509_FILE_IO_ERROR                    -0x2900  /**< Read/write of file failed. */
 #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL                 -0x2980  /**< Destination buffer is too small. */
-#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000  /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */
+#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000  /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */
 /* \} name */
 
 /**
@@ -250,7 +250,7 @@ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *se
  *
  * \param to       mbedtls_x509_time to check
  *
- * \return         1 if the given time is in the past or an error occured,
+ * \return         1 if the given time is in the past or an error occurred,
  *                 0 otherwise.
  */
 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to );
@@ -264,11 +264,13 @@ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to );
  *
  * \param from     mbedtls_x509_time to check
  *
- * \return         1 if the given time is in the future or an error occured,
+ * \return         1 if the given time is in the future or an error occurred,
  *                 0 otherwise.
  */
 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -276,6 +278,8 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
  */
 int mbedtls_x509_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 /*
  * Internal module functions. You probably do not want to use these unless you
  * know you do.

+ 2 - 2
app/include/mbedtls/x509_crl.h

@@ -111,7 +111,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
 /**
  * \brief          Parse one or more CRLs and append them to the chained list
  *
- * \note           Mutliple CRLs are accepted only if using PEM format
+ * \note           Multiple CRLs are accepted only if using PEM format
  *
  * \param chain    points to the start of the chain
  * \param buf      buffer holding the CRL data in PEM or DER format
@@ -126,7 +126,7 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s
 /**
  * \brief          Load one or more CRLs and append them to the chained list
  *
- * \note           Mutliple CRLs are accepted only if using PEM format
+ * \note           Multiple CRLs are accepted only if using PEM format
  *
  * \param chain    points to the start of the chain
  * \param path     filename to read the CRLs from (in PEM or DER encoding)

+ 102 - 2
app/include/mbedtls/x509_crt.h

@@ -98,14 +98,14 @@ mbedtls_x509_crt;
  * Build flag from an algorithm/curve identifier (pk, md, ecp)
  * Since 0 is always XXX_NONE, ignore it.
  */
-#define MBEDTLS_X509_ID_FLAG( id )   ( 1 << ( id - 1 ) )
+#define MBEDTLS_X509_ID_FLAG( id )   ( 1 << ( (id) - 1 ) )
 
 /**
  * Security profile for certificate verification.
  *
  * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG().
  */
-typedef struct
+typedef struct mbedtls_x509_crt_profile
 {
     uint32_t allowed_mds;       /**< MDs for signatures         */
     uint32_t allowed_pks;       /**< PK algs for signatures     */
@@ -143,6 +143,63 @@ typedef struct mbedtls_x509write_cert
 }
 mbedtls_x509write_cert;
 
+/**
+ * Item in a verification chain: cert and flags for it
+ */
+typedef struct {
+    mbedtls_x509_crt *crt;
+    uint32_t flags;
+} mbedtls_x509_crt_verify_chain_item;
+
+/**
+ * Max size of verification chain: end-entity + intermediates + trusted root
+ */
+#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE  ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
+
+/**
+ * Verification chain as built by \c mbedtls_crt_verify_chain()
+ */
+typedef struct
+{
+    mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE];
+    unsigned len;
+} mbedtls_x509_crt_verify_chain;
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+
+/**
+ * \brief       Context for resuming X.509 verify operations
+ */
+typedef struct
+{
+    /* for check_signature() */
+    mbedtls_pk_restart_ctx pk;
+
+    /* for find_parent_in() */
+    mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */
+    mbedtls_x509_crt *fallback_parent;
+    int fallback_signature_is_good;
+
+    /* for find_parent() */
+    int parent_is_trusted; /* -1 if find_parent is not in progress */
+
+    /* for verify_chain() */
+    enum {
+        x509_crt_rs_none,
+        x509_crt_rs_find_parent,
+    } in_progress;  /* none if no operation is in progress */
+    int self_cnt;
+    mbedtls_x509_crt_verify_chain ver_chain;
+
+} mbedtls_x509_crt_restart_ctx;
+
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+/* Now we can declare functions that take a pointer to that */
+typedef void mbedtls_x509_crt_restart_ctx;
+
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 /**
  * Default security profile. Should provide a good balance between security
@@ -368,6 +425,37 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
                      void *p_vrfy );
 
+/**
+ * \brief          Restartable version of \c mbedtls_crt_verify_with_profile()
+ *
+ * \note           Performs the same job as \c mbedtls_crt_verify_with_profile()
+ *                 but can return early and restart according to the limit
+ *                 set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param crt      a certificate (chain) to be verified
+ * \param trust_ca the list of trusted CAs
+ * \param ca_crl   the list of CRLs for trusted CAs
+ * \param profile  security profile for verification
+ * \param cn       expected Common Name (can be set to
+ *                 NULL if the CN must not be verified)
+ * \param flags    result of the verification
+ * \param f_vrfy   verification function
+ * \param p_vrfy   verification parameter
+ * \param rs_ctx   restart context (NULL to disable restart)
+ *
+ * \return         See \c mbedtls_crt_verify_with_profile(), or
+ * \return         #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                 operations was reached: see \c mbedtls_ecp_set_max_ops().
+ */
+int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const mbedtls_x509_crt_profile *profile,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy,
+                     mbedtls_x509_crt_restart_ctx *rs_ctx );
+
 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
 /**
  * \brief          Check usage of certificate against keyUsage extension.
@@ -439,6 +527,18 @@ void mbedtls_x509_crt_init( mbedtls_x509_crt *crt );
  * \param crt      Certificate chain to free
  */
 void mbedtls_x509_crt_free( mbedtls_x509_crt *crt );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context
+ */
+void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context
+ */
+void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
 /* \} name */

+ 8 - 0
app/include/mbedtls/x509_csr.h

@@ -205,6 +205,14 @@ void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_ty
  * \param key_usage key usage flags to set
  *
  * \return          0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ *
+ * \note            The <code>decipherOnly</code> flag from the Key Usage
+ *                  extension is represented by bit 8 (i.e.
+ *                  <code>0x8000</code>), which cannot typically be represented
+ *                  in an unsigned char. Therefore, the flag
+ *                  <code>decipherOnly</code> (i.e.
+ *                  #MBEDTLS_X509_KU_DECIPHER_ONLY) cannot be set using this
+ *                  function.
  */
 int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage );
 

+ 14 - 16
app/include/mbedtls/xtea.h

@@ -37,25 +37,31 @@
 #define MBEDTLS_XTEA_DECRYPT     0
 
 #define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH             -0x0028  /**< The data input has an invalid length. */
-#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED                  -0x0029  /**< XTEA hardware accelerator failed. */
 
-#if !defined(MBEDTLS_XTEA_ALT)
-// Regular implementation
-//
+/* MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED                  -0x0029  /**< XTEA hardware accelerator failed. */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_XTEA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief          XTEA context structure
  */
-typedef struct
+typedef struct mbedtls_xtea_context
 {
     uint32_t k[4];       /*!< key */
 }
 mbedtls_xtea_context;
 
+#else  /* MBEDTLS_XTEA_ALT */
+#include "xtea_alt.h"
+#endif /* MBEDTLS_XTEA_ALT */
+
 /**
  * \brief          Initialize XTEA context
  *
@@ -115,17 +121,7 @@ int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx,
                     unsigned char *output);
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
-#ifdef __cplusplus
-}
-#endif
-
-#else  /* MBEDTLS_XTEA_ALT */
-#include "xtea_alt.h"
-#endif /* MBEDTLS_XTEA_ALT */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#if defined(MBEDTLS_SELF_TEST)
 
 /**
  * \brief          Checkup routine
@@ -134,6 +130,8 @@ extern "C" {
  */
 int mbedtls_xtea_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif

+ 0 - 33
app/include/sys/Espconn_mem.h

@@ -1,33 +0,0 @@
-/*
- * ESPRSSIF MIT License
- *
- * Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
- *
- * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
- * it is free of charge, to any person obtaining a copy of this software and associated
- * documentation files (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
- * to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef ESPCONN_MEM_H_
-#define ESPCONN_MEM_H_
-
-void *espconn_memzalloc(size_t size);
-void espconn_memfree(void *fp);
-void *espconn_memcpy(void *dst, const void *src, size_t size);
-
-#endif
-

+ 1 - 14
app/include/sys/espconn_mbedtls.h

@@ -38,16 +38,6 @@
 #include "mbedtls/ctr_drbg.h"
 typedef struct espconn *pmbedtls_espconn;
 typedef struct espconn mbedtls_espconn;
-typedef struct{
-	int record_len;
-}mbedtls_record;
-
-#if defined(ESP8266_PLATFORM)
-typedef struct{
-	uint8*	finished_buf;
-	int 	finished_len;
-}mbedtls_finished, *pmbedtls_finished;
-#endif
 
 typedef struct{
 //	mbedtls_entropy_context entropy;
@@ -58,10 +48,7 @@ typedef struct{
 
 typedef struct{
 	bool quiet;
-	mbedtls_record		record;
-#if defined(ESP8266_PLATFORM)
-	pmbedtls_finished	pfinished;
-#endif
+	int	record_len;
 	pmbedtls_session	psession;
 	mbedtls_net_context fd;
 	mbedtls_net_context listen_fd;

+ 2 - 12
app/include/sys/socket.h

@@ -102,20 +102,10 @@ typedef enum{
 		}\
 	}while(0)
 
-#define lwIP_EVENT_PARSE(s, error)                          \
-  do {                                                         \
-	  mbedtls_parse_internal(s, error);                              \
-  } while (0)
-
-#define lwIP_EVENT_THREAD(s, event, error)	\
-  do {	\
-		mbedtls_parse_thread(s, event, error); \
-  }while(0)
-
 typedef enum{
-	ENTCONN_EVENT_NONE = 0,
+	NETCONN_EVENT_NONE = 0,
 	NETCONN_EVENT_ESTABLISHED = 1,
-	ENTCONN_EVENT_RECV = 2,
+	NETCONN_EVENT_RECV = 2,
 	NETCONN_EVENT_SEND = 3,
 	NETCONN_EVENT_ERROR = 4,
 	NETCONN_EVENT_CLOSE = 5,

+ 0 - 1
app/include/user_config.h

@@ -94,7 +94,6 @@
 // are by firmware code, and can be enabled if you need this functionality.
 
 //#define CLIENT_SSL_ENABLE
-//#define MD2_ENABLE
 #define SHA2_ENABLE
 #define SSL_BUFFER_SIZE 4096
 #define SSL_MAX_FRAGMENT_LENGTH_CODE	MBEDTLS_SSL_MAX_FRAG_LEN_4096

+ 2 - 2
app/include/user_mbedtls.h

@@ -151,7 +151,7 @@
 
 #undef MBEDTLS_SSL_PROTO_SSL3
 #undef MBEDTLS_SSL_PROTO_TLS1
-#define MBEDTLS_SSL_PROTO_TLS1_1
+#undef MBEDTLS_SSL_PROTO_TLS1_1
 #define MBEDTLS_SSL_PROTO_TLS1_2
 #undef MBEDTLS_SSL_PROTO_DTLS
 
@@ -214,7 +214,7 @@
 #define MBEDTLS_MD_C
 #undef MBEDTLS_MD2_C
 #undef MBEDTLS_MD4_C
-#define MBEDTLS_MD5_C	/* Remove when we drop support for TLS 1.1 */
+#undef MBEDTLS_MD5_C
 #undef MBEDTLS_MEMORY_BUFFER_ALLOC_C
 #define MBEDTLS_NET_C
 #define MBEDTLS_OID_C

+ 0 - 73
app/mbedtls/app/Espconn_mem.c

@@ -1,73 +0,0 @@
-#include <stdint.h>
-#include "mem.h"
-#include "user_interface.h"
-
-void *espconn_memzalloc(size_t size, char* file, int line)
-{
-	void *mp = NULL;
-	if ((mp = (void*)os_malloc(size)) == NULL){
-
-	} else{
-		//os_printf("%s %d %p %d\n",file, line, mp, size);
-		os_memset(mp, 0, size);
-	}
-	return mp;
-}
-
-void espconn_memfree(void *fp, char* file, int line)
-{
-	//os_printf("%s %d %p\n",file, line, fp);
-	os_free(fp);
-	fp = NULL;
-}
-
-void *espconn_memcpy(void *dst, const void *src, size_t size, char *file, int line)
-{
-	char *psrc = NULL;
-	char *pdst = NULL;
-
-	if(NULL == dst || NULL == src)
-	{
-		return NULL;
-	}
-	//os_printf("%s %d %p %p %d\n",file, line, dst, src, size);
-	if((src < dst) && (char *)src + size > (char *)dst)
-	{
-		psrc = (char *)src + size - 1;
-		pdst = (char *)dst + size - 1;
-		while(size--)
-		{
-			*pdst-- = *psrc--;
-		}
-	}
-	else
-	{
-		psrc = (char *)src;
-		pdst = (char *)dst;
-		while(size--)
-		{
-			*pdst++ = *psrc++;
-		}
-	}
-
-	return dst;
-
-}
-
-void *espconn_memcalloc(size_t count, size_t size)
-{
-	void *cp = NULL;
-	cp = espconn_memzalloc(count * size, __FILE__, __LINE__);
-	return cp;
-}
-
-void espconn_memFree(void *fp)
-{
-	espconn_memfree(fp, __FILE__, __LINE__);
-}
-
-void *espconn_memCpy(void *dst, const void *src, size_t size)
-{
-	return espconn_memcpy(dst, src, size, __FILE__, __LINE__);
-}
-

+ 232 - 342
app/mbedtls/app/espconn_mbedtls.c

@@ -48,29 +48,21 @@ static espconn_msg *plink_server = NULL;
 static pmbedtls_parame def_certificate = NULL;
 static pmbedtls_parame def_private_key = NULL;
 
-#if defined(ESP8266_PLATFORM)
-#define MBEDTLS_SSL_OUTBUFFER_LEN  ( MBEDTLS_SSL_PLAIN_ADD               \
-                        + MBEDTLS_SSL_COMPRESSION_ADD               \
-                        + 29 /* counter + header + IV */    \
-                        + MBEDTLS_SSL_MAC_ADD                       \
-                        + MBEDTLS_SSL_PADDING_ADD                   \
-                        )
-#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;
+	volatile unsigned char *p = v;
+	while( n-- ) *p++ = 0;
 }
 
 static pmbedtls_parame mbedtls_parame_new(size_t capacity)
 {
 	pmbedtls_parame rb = (pmbedtls_parame)os_zalloc(sizeof(mbedtls_parame));
-	if (rb && capacity != 0){
+	if (rb && capacity != 0) {
 		rb->parame_datalen = capacity;
 		rb->parame_data = (uint8*)os_zalloc(rb->parame_datalen + 1);
-		if (rb->parame_data){
+		if (rb->parame_data) {
 
-		} else{
+		} else {
 			os_free(rb);
 			rb = NULL;
 		}
@@ -94,44 +86,44 @@ bool mbedtls_load_default_obj(uint32 flash_sector, int obj_type, const unsigned
 	uint32 mbedtls_head = 0;
 	bool mbedtls_load_flag = false;
 
-	if (flash_sector != 0){
+	if (flash_sector != 0) {
 		spi_flash_read(flash_sector * FLASH_SECTOR_SIZE, (uint32*)&mbedtls_head, 4);
-		if (mbedtls_head != ESPCONN_INVALID_TYPE){
+		if (mbedtls_head != ESPCONN_INVALID_TYPE) {
 			mbedtls_write = mbedtls_parame_new(0);
 			mbedtls_write->parame_datalen = length;
 		}
-	} else{
+	} else {
 		const char* const begin = "-----BEGIN";
 		int format_type = ESPCONN_FORMAT_INIT;
 		/*
-	     * Determine data content. data contains either one DER certificate or
-	     * one or more PEM certificates.
-	     */
-		if ((char*)os_strstr(load_buf, begin) != NULL){
+		 * Determine data content. data contains either one DER certificate or
+		 * one or more PEM certificates.
+		 */
+		if ((char*)os_strstr(load_buf, begin) != NULL) {
 			format_type = ESPCONN_FORMAT_PEM;
-		}else{
+		} else {
 			format_type = ESPCONN_FORMAT_DER;
 		}
 
-		if (format_type == ESPCONN_FORMAT_PEM){
+		if (format_type == ESPCONN_FORMAT_PEM) {
 			length += 1;
 		}
 
 		mbedtls_write = mbedtls_parame_new(length);
-		if (mbedtls_write){
+		if (mbedtls_write) {
 			os_memcpy(mbedtls_write->parame_data, load_buf, length);
 			if (format_type == ESPCONN_FORMAT_PEM)
 				mbedtls_write->parame_data[length - 1] = '\0';
 		}
 	}
 
-	if (mbedtls_write){
+	if (mbedtls_write) {
 		mbedtls_load_flag = true;
 		mbedtls_write->parame_type = obj_type;
 		mbedtls_write->parame_sec = flash_sector;
-		if (obj_type == ESPCONN_PK){
+		if (obj_type == ESPCONN_PK) {
 			def_private_key = mbedtls_write;
-		} else{
+		} else {
 			def_certificate = mbedtls_write;
 		}
 	}
@@ -144,29 +136,29 @@ static unsigned char* mbedtls_get_default_obj(uint32 *sec, uint32 type, uint32 *
 	unsigned char *parame_data = NULL;
 	pmbedtls_parame mbedtls_obj = NULL;
 
-	if (type == ESPCONN_PK){
+	if (type == ESPCONN_PK) {
 		mbedtls_obj = def_private_key;
-	} else{
+	} else {
 		mbedtls_obj = def_certificate;
 	}
 
-	if (mbedtls_obj->parame_sec != 0){
-		#define DATA_OFFSET	4
+	if (mbedtls_obj->parame_sec != 0) {
+#define DATA_OFFSET	4
 		uint32  data_len = mbedtls_obj->parame_datalen;
 		parame_data = (unsigned char *)os_zalloc(data_len + DATA_OFFSET);
-		if (parame_data){
+		if (parame_data) {
 			spi_flash_read(mbedtls_obj->parame_sec * FLASH_SECTOR_SIZE, (uint32*)parame_data, data_len);
 			/*
-		     * Determine buffer content. Buffer contains either one DER certificate or
-		     * one or more PEM certificates.
-		     */
-			if ((char*)os_strstr(parame_data, begin) != NULL){
+			 * Determine buffer content. Buffer contains either one DER certificate or
+			 * one or more PEM certificates.
+			 */
+			if ((char*)os_strstr(parame_data, begin) != NULL) {
 				data_len ++;
 				parame_data[data_len - 1] = '\0';
 			}
 		}
 		*len = data_len;
-	} else{
+	} else {
 		parame_data = mbedtls_obj->parame_data;
 		*len = mbedtls_obj->parame_datalen;
 	}
@@ -201,43 +193,13 @@ exit:
 	return ret;
 }
 
-#if defined(ESP8266_PLATFORM)
-static pmbedtls_finished mbedtls_finished_new(int len)
-{
-    pmbedtls_finished finished = (pmbedtls_finished)os_zalloc(sizeof(mbedtls_finished));
-    if (finished)
-    {
-        finished->finished_len = len;
-        finished->finished_buf = (uint8*)os_zalloc(finished->finished_len + 1);
-        if (finished->finished_buf)
-        {
-
-        }
-        else
-        {
-            os_free(finished);
-            finished = NULL;
-        }
-    }
-    return finished;
-}
-
-static void mbedtls_finished_free(pmbedtls_finished *pfinished)
-{
-    lwIP_ASSERT(pfinished);
-    lwIP_ASSERT(*pfinished);
-    os_free((*pfinished)->finished_buf);
-    os_free(*pfinished);
-    *pfinished = NULL;
-}
-#endif
 static pmbedtls_espconn mbedtls_espconn_new(void)
 {
 	pmbedtls_espconn mbedtls_conn = NULL;
 	mbedtls_conn = (pmbedtls_espconn)os_zalloc(sizeof(mbedtls_espconn));
-	if (mbedtls_conn){
+	if (mbedtls_conn) {
 		mbedtls_conn->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
-		if (mbedtls_conn->proto.tcp == NULL){
+		if (mbedtls_conn->proto.tcp == NULL) {
 			os_free(mbedtls_conn);
 			mbedtls_conn = NULL;
 		}
@@ -261,7 +223,7 @@ static void mbedtls_espconn_free(pmbedtls_espconn *mbedtlsconn)
 static pmbedtls_session mbedtls_session_new(void)
 {
 	pmbedtls_session session = (pmbedtls_session)os_zalloc(sizeof(mbedtls_session));
-	if (session){
+	if (session) {
 		mbedtls_x509_crt_init(&session->cacert);
 		mbedtls_x509_crt_init(&session->clicert);
 		mbedtls_pk_init(&session->pkey);
@@ -289,7 +251,7 @@ static pmbedtls_msg mbedtls_msg_new(void)
 	if (msg) {
 		os_bzero(msg, sizeof(mbedtls_msg));
 		msg->psession = mbedtls_session_new();
-		if (msg->psession){
+		if (msg->psession) {
 			mbedtls_net_init(&msg->listen_fd);
 			mbedtls_net_init(&msg->fd);
 			mbedtls_ssl_init(&msg->ssl);
@@ -299,7 +261,7 @@ static pmbedtls_msg mbedtls_msg_new(void)
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && defined(SSL_MAX_FRAGMENT_LENGTH_CODE)
 			mbedtls_ssl_conf_max_frag_len(&msg->conf, SSL_MAX_FRAGMENT_LENGTH_CODE);
 #endif
-		} else{
+		} else {
 			os_free(msg);
 			msg = NULL;
 		}
@@ -312,17 +274,9 @@ static void mbedtls_msg_server_step(pmbedtls_msg msg)
 	lwIP_ASSERT(msg);
 
 	/*to prevent memory leaks, ensure that each allocated is deleted at every handshake*/
-	if (msg->psession){
+	if (msg->psession) {
 		mbedtls_session_free(&msg->psession);
 	}
-#if defined(ESP8266_PLATFORM)
-    if (msg->quiet && msg->ssl.out_buf)
-    {
-        mbedtls_zeroize(msg->ssl.out_buf, MBEDTLS_SSL_OUTBUFFER_LEN);
-        os_free(msg->ssl.out_buf);
-        msg->ssl.out_buf = NULL;
-    }
-#endif
 	mbedtls_entropy_free(&msg->entropy);
 	mbedtls_ssl_free(&msg->ssl);
 	mbedtls_ssl_config_free(&msg->conf);
@@ -331,7 +285,7 @@ static void mbedtls_msg_server_step(pmbedtls_msg msg)
 	/*New connection ensure that each initial for next handshake */
 	os_bzero(msg, sizeof(mbedtls_msg));
 	msg->psession = mbedtls_session_new();
-	if (msg->psession){
+	if (msg->psession) {
 		mbedtls_net_init(&msg->fd);
 		mbedtls_ssl_init(&msg->ssl);
 		mbedtls_ssl_config_init(&msg->conf);
@@ -346,19 +300,9 @@ static void mbedtls_msg_free(pmbedtls_msg *msg)
 	lwIP_ASSERT(*msg);
 
 	/*to prevent memory leaks, ensure that each allocated is deleted at every handshake*/
-	if ((*msg)->psession){
+	if ((*msg)->psession) {
 		mbedtls_session_free(&((*msg)->psession));
 	}
-#if defined(ESP8266_PLATFORM)
-    if ((*msg)->quiet && (*msg)->ssl.out_buf)
-    {
-        mbedtls_zeroize((*msg)->ssl.out_buf, MBEDTLS_SSL_OUTBUFFER_LEN);
-        os_free((*msg)->ssl.out_buf);
-        (*msg)->ssl.out_buf = NULL;
-    }
-    if((*msg)->pfinished != NULL)
-        mbedtls_finished_free(&(*msg)->pfinished);
-#endif
 	mbedtls_entropy_free(&(*msg)->entropy);
 	mbedtls_ssl_free(&(*msg)->ssl);
 	mbedtls_ssl_config_free(&(*msg)->conf);
@@ -374,15 +318,15 @@ static espconn_msg* mbedtls_msg_find(int sock)
 	pmbedtls_msg msg = NULL;
 
 	for (plist = plink_active; plist != NULL; plist = plist->pnext) {
-		if(plist->pssl != NULL){
+		if(plist->pssl != NULL) {
 			msg = plist->pssl;
 			if (msg->fd.fd == sock)
 				return plist;
 		}
 	}
 
-	for (plist = plink_server; plist != NULL; plist = plist->pnext){
-		if(plist->pssl != NULL){
+	for (plist = plink_server; plist != NULL; plist = plist->pnext) {
+		if(plist->pssl != NULL) {
 			msg = plist->pssl;
 			if (msg->listen_fd.fd == sock)
 				return plist;
@@ -408,7 +352,7 @@ static bool mbedtls_handshake_result(const pmbedtls_msg Threadmsg)
 		else
 			ret = ssl_option.server.cert_ca_sector.flag;
 
-		if (ret == 1){
+		if (ret == 1) {
 			ret = mbedtls_ssl_get_verify_result(&Threadmsg->ssl);
 			if (ret != 0) {
 				char vrfy_buf[512];
@@ -421,7 +365,7 @@ static bool mbedtls_handshake_result(const pmbedtls_msg Threadmsg)
 				return true;
 		} else
 			return true;
-	}else
+	} else
 		return false;
 }
 
@@ -436,14 +380,14 @@ static void mbedtls_fail_info(espconn_msg *pinfo, int ret)
 	 * up.  That's entirely normal and not worthy of the confusion it sows!
 	 */
 	if (ret != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
-		if (TLSmsg->quiet){
+		if (TLSmsg->quiet) {
 			if (pinfo->preverse != NULL) {
 				os_printf("server's data invalid protocol\n");
 			} else {
 				os_printf("client's data invalid protocol\n");
 			}
 			mbedtls_ssl_close_notify(&TLSmsg->ssl);
-		} else{
+		} else {
 			if (pinfo->preverse != NULL) {
 				os_printf("server handshake failed!\n");
 			} else {
@@ -455,9 +399,9 @@ static void mbedtls_fail_info(espconn_msg *pinfo, int ret)
 	os_printf("Reason:[-0x%2x]\n",-ret);
 	/*Error code convert*/
 	ret = -ret;
-	if ((ret & 0xFF) != 0){
+	if ((ret & 0xFF) != 0) {
 		ret = ((ret >> 8) + ret);
-	} else{
+	} else {
 		ret >>= 8;
 	}
 	pinfo->hs_status = -ret;
@@ -469,82 +413,37 @@ exit:
 	return;
 }
 
-#if defined(ESP8266_PLATFORM)
-int mbedtls_write_finished(mbedtls_ssl_context *ssl)
-{
-    lwIP_ASSERT(ssl);
-    lwIP_ASSERT(ssl->p_bio);
-    int ret = ERR_OK;
-    int fd = ((mbedtls_net_context *) ssl->p_bio)->fd;
-    espconn_msg *Threadmsg = mbedtls_msg_find(fd);
-    lwIP_REQUIRE_ACTION(Threadmsg, exit, ret = ERR_MEM);
-    pmbedtls_msg TLSmsg = Threadmsg->pssl;
-    lwIP_REQUIRE_ACTION(TLSmsg, exit, ret = ERR_MEM);
-    TLSmsg->pfinished = mbedtls_finished_new(ssl->out_msglen + 29);
-    lwIP_REQUIRE_ACTION(TLSmsg->pfinished, exit, ret = ERR_MEM);
-    os_memcpy(TLSmsg->pfinished->finished_buf, ssl->out_ctr, TLSmsg->pfinished->finished_len);
-exit:
-    return ret;
-}
-
-static int mbedtls_hanshake_finished(mbedtls_msg *msg)
-{
-    lwIP_ASSERT(msg);
-    int ret = ERR_OK;
-    const size_t len = MBEDTLS_SSL_OUTBUFFER_LEN;
-
-	mbedtls_ssl_context *ssl = &msg->ssl;
-    lwIP_REQUIRE_ACTION(ssl, exit, ret = ERR_MEM);
-
-	pmbedtls_finished finished = msg->pfinished;
-    lwIP_REQUIRE_ACTION(finished, exit, ret = ERR_MEM);
-
-	ssl->out_buf = (unsigned char*)os_zalloc(len);
-	lwIP_REQUIRE_ACTION(ssl->out_buf, exit, ret = MBEDTLS_ERR_SSL_ALLOC_FAILED);
-
-    ssl->out_ctr = ssl->out_buf;
-    ssl->out_hdr = ssl->out_buf +  8;
-    ssl->out_len = ssl->out_buf + 11;
-    ssl->out_iv  = ssl->out_buf + 13;
-    ssl->out_msg = ssl->out_buf + 29;
-    os_memcpy(ssl->out_ctr, finished->finished_buf, finished->finished_len);
-    mbedtls_finished_free(&msg->pfinished);
-
-exit:
-    return ret;
-}
-#endif
 static void mbedtls_handshake_succ(mbedtls_ssl_context *ssl)
 {
 	lwIP_ASSERT(ssl);
 	if( ssl->handshake )
-    {
-        mbedtls_ssl_handshake_free( ssl->handshake );
-        mbedtls_ssl_transform_free( ssl->transform_negotiate );
-        mbedtls_ssl_session_free( ssl->session_negotiate );
-
-        os_free( ssl->handshake );
-        os_free( ssl->transform_negotiate );
-        os_free( ssl->session_negotiate );
+	{
+		mbedtls_ssl_handshake_free( ssl );
+		mbedtls_ssl_transform_free( ssl->transform_negotiate );
+		mbedtls_ssl_session_free( ssl->session_negotiate );
+
+		os_free( ssl->handshake );
+		os_free( ssl->transform_negotiate );
+		os_free( ssl->session_negotiate );
 		ssl->handshake = NULL;
 		ssl->transform_negotiate = NULL;
 		ssl->session_negotiate = NULL;
-    }
+	}
 
-    if( ssl->session )
-    {
-        mbedtls_ssl_session_free( ssl->session );
-        os_free( ssl->session );
+	if( ssl->session )
+	{
+		mbedtls_ssl_session_free( ssl->session );
+		os_free( ssl->session );
 		ssl->session = NULL;
-    }
+	}
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
-    if( ssl->hostname != NULL )
-    {
-        mbedtls_zeroize( ssl->hostname, os_strlen( ssl->hostname ) );
-        os_free( ssl->hostname );
+	if( ssl->hostname != NULL )
+	{
+		mbedtls_zeroize( ssl->hostname, os_strlen( ssl->hostname ) );
+		os_free( ssl->hostname );
 		ssl->hostname = NULL;
-    }
+	}
 #endif
 }
 
@@ -557,10 +456,10 @@ static void mbedtls_handshake_succ(mbedtls_ssl_context *ssl)
 static void espconn_close_internal(void *arg, netconn_event event_type)
 {
 	espconn_msg *pssl_recon = arg;
-    struct espconn *espconn = NULL;
-    sint8 ssl_reerr = 0;
-    sint16 hs_status = 0;
-    lwIP_ASSERT(pssl_recon);
+	struct espconn *espconn = NULL;
+	sint8 ssl_reerr = 0;
+	sint16 hs_status = 0;
+	lwIP_ASSERT(pssl_recon);
 
 	espconn = pssl_recon->preverse;
 	ssl_reerr = pssl_recon->pcommon.err;
@@ -579,21 +478,21 @@ static void espconn_close_internal(void *arg, netconn_event event_type)
 	}
 
 	espconn_kill_oldest_pcb();
-	switch (event_type){
-		case NETCONN_EVENT_ERROR:
-			if (hs_status == ESPCONN_OK)
-				ESPCONN_EVENT_ERROR(espconn, ssl_reerr);
-			else
-				ESPCONN_EVENT_ERROR(espconn, hs_status);
-			break;
-		case NETCONN_EVENT_CLOSE:
-			if (hs_status == ESPCONN_OK)
-				ESPCONN_EVENT_CLOSED(espconn);
-			else
-				ESPCONN_EVENT_ERROR(espconn, hs_status);
-			break;
-		default:
-			break;
+	switch (event_type) {
+	case NETCONN_EVENT_ERROR:
+		if (hs_status == ESPCONN_OK)
+			ESPCONN_EVENT_ERROR(espconn, ssl_reerr);
+		else
+			ESPCONN_EVENT_ERROR(espconn, hs_status);
+		break;
+	case NETCONN_EVENT_CLOSE:
+		if (hs_status == ESPCONN_OK)
+			ESPCONN_EVENT_CLOSED(espconn);
+		else
+			ESPCONN_EVENT_ERROR(espconn, hs_status);
+		break;
+	default:
+		break;
 	}
 }
 
@@ -611,35 +510,35 @@ static bool espconn_ssl_read_param_from_flash(void *param, uint16 len, int32 off
 
 	uint32 FILE_PARAM_START_SEC = 0x3B;
 	switch (auth_info->auth_level) {
-		case ESPCONN_CLIENT:
-			switch (auth_info->auth_type) {
-				case ESPCONN_CERT_AUTH:
-					FILE_PARAM_START_SEC = ssl_option.client.cert_ca_sector.sector;
-					break;
-				case ESPCONN_CERT_OWN:
-				case ESPCONN_PK:
-					FILE_PARAM_START_SEC = ssl_option.client.cert_req_sector.sector;
-					break;
-				default:
-					return false;
-			}
+	case ESPCONN_CLIENT:
+		switch (auth_info->auth_type) {
+		case ESPCONN_CERT_AUTH:
+			FILE_PARAM_START_SEC = ssl_option.client.cert_ca_sector.sector;
 			break;
-		case ESPCONN_SERVER:
-			switch (auth_info->auth_type) {
-				case ESPCONN_CERT_AUTH:
-					FILE_PARAM_START_SEC = ssl_option.server.cert_ca_sector.sector;
-					break;
-				case ESPCONN_CERT_OWN:
-				case ESPCONN_PK:
-					FILE_PARAM_START_SEC = ssl_option.server.cert_req_sector.sector;
-					break;
-				default:
-					return false;
-			}
+		case ESPCONN_CERT_OWN:
+		case ESPCONN_PK:
+			FILE_PARAM_START_SEC = ssl_option.client.cert_req_sector.sector;
 			break;
 		default:
 			return false;
+		}
+		break;
+	case ESPCONN_SERVER:
+		switch (auth_info->auth_type) {
+		case ESPCONN_CERT_AUTH:
+			FILE_PARAM_START_SEC = ssl_option.server.cert_ca_sector.sector;
+			break;
+		case ESPCONN_CERT_OWN:
+		case ESPCONN_PK:
+			FILE_PARAM_START_SEC = ssl_option.server.cert_req_sector.sector;
 			break;
+		default:
+			return false;
+		}
+		break;
+	default:
+		return false;
+		break;
 	}
 
 	spi_flash_read(FILE_PARAM_START_SEC * 4096 + offset, param, len);
@@ -651,53 +550,50 @@ static bool mbedtls_msg_info_load(mbedtls_msg *msg, mbedtls_auth_info *auth_info
 {
 	const char* const begin = "-----BEGIN";
 	const char* const type_name  = "private_key";
-	#define FILE_OFFSET	4
+#define FILE_OFFSET	4
 	int ret = 0;
 	int32 offerset = 0;
 	uint8* load_buf = NULL;
 	size_t load_len = 0;
-	file_param *pfile_param = NULL;
-	pfile_param = (file_param *)os_zalloc( sizeof(file_param));
-	if (pfile_param==NULL)
-		return false;
+	file_param file_param;
+
+	bzero(&file_param, sizeof(file_param));
 
 again:
-	espconn_ssl_read_param_from_flash(&pfile_param->file_head, sizeof(file_head), offerset, auth_info);
-	pfile_param->file_offerset = offerset;
-	os_printf("%s %d, type[%s],length[%d]\n", __FILE__, __LINE__, pfile_param->file_head.file_name, pfile_param->file_head.file_length);
-	if (pfile_param->file_head.file_length == 0xFFFF){
-		os_free(pfile_param);
+	espconn_ssl_read_param_from_flash(&file_param.file_head, sizeof(file_head), offerset, auth_info);
+	file_param.file_offerset = offerset;
+	os_printf("%s %d, type[%s],length[%d]\n", __FILE__, __LINE__, file_param.file_head.file_name, file_param.file_head.file_length);
+	if (file_param.file_head.file_length == 0xFFFF) {
 		return false;
-	} else{
+	} else {
 		/*Optional is load the private key*/
-		if (auth_info->auth_type == ESPCONN_PK && os_memcmp(pfile_param->file_head.file_name, type_name, os_strlen(type_name)) != 0){
-			offerset += sizeof(file_head) + pfile_param->file_head.file_length;
+		if (auth_info->auth_type == ESPCONN_PK && os_memcmp(&file_param.file_head.file_name, type_name, os_strlen(type_name)) != 0) {
+			offerset += sizeof(file_head) + file_param.file_head.file_length;
 			goto again;
 		}
 		/*Optional is load the cert*/
-		if (auth_info->auth_type == ESPCONN_CERT_OWN && os_memcmp(pfile_param->file_head.file_name, "certificate", os_strlen("certificate")) != 0){
-			offerset += sizeof(file_head) + pfile_param->file_head.file_length;
+		if (auth_info->auth_type == ESPCONN_CERT_OWN && os_memcmp(file_param.file_head.file_name, "certificate", os_strlen("certificate")) != 0) {
+			offerset += sizeof(file_head) + file_param.file_head.file_length;
 			goto again;
 		}
-		load_buf = (uint8_t *) os_zalloc( pfile_param->file_head.file_length + FILE_OFFSET);
-		if (load_buf == NULL){
-			os_free(pfile_param);
+		load_buf = (uint8_t *) os_zalloc( file_param.file_head.file_length + FILE_OFFSET);
+		if (load_buf == NULL) {
 			return false;
 		}
-		offerset = sizeof(file_head) + pfile_param->file_offerset;
-		espconn_ssl_read_param_from_flash(load_buf,	pfile_param->file_head.file_length, offerset, auth_info);
+		offerset = sizeof(file_head) + file_param.file_offerset;
+		espconn_ssl_read_param_from_flash(load_buf,	file_param.file_head.file_length, offerset, auth_info);
 	}
 
-	load_len = pfile_param->file_head.file_length;
-	 /*
-     * Determine buffer content. Buffer contains either one DER certificate or
-     * one or more PEM certificates.
-     */
-	if ((char*)os_strstr(load_buf, begin) != NULL){
+	load_len = file_param.file_head.file_length;
+	/*
+	* Determine buffer content. Buffer contains either one DER certificate or
+	* one or more PEM certificates.
+	*/
+	if ((char*)os_strstr(load_buf, begin) != NULL) {
 		load_len += 1;
 		load_buf[load_len - 1] = '\0';
 	}
-	switch (auth_info->auth_type){
+	switch (auth_info->auth_type) {
 	case ESPCONN_CERT_AUTH:
 		/*Optional is not optimal for security*/
 		ret = mbedtls_x509_crt_parse(&msg->psession->cacert, (const uint8*) load_buf,load_len);
@@ -716,10 +612,9 @@ again:
 	}
 exit:
 	os_free(load_buf);
-	os_free(pfile_param);
-	if (ret < 0){
+	if (ret < 0) {
 		return false;
-	}else{
+	} else {
 		return true;
 	}
 }
@@ -739,7 +634,7 @@ static bool mbedtls_msg_config(mbedtls_msg *msg)
 	mbedtls_auth_info auth_info;
 
 	/*end_point mode*/
-	if (msg->listen_fd.fd == -1){
+	if (msg->listen_fd.fd == -1) {
 		pers = "client";
 		auth_type = MBEDTLS_SSL_IS_CLIENT;
 	} else {
@@ -751,10 +646,11 @@ static bool mbedtls_msg_config(mbedtls_msg *msg)
 	ret = mbedtls_ctr_drbg_seed(&msg->ctr_drbg, mbedtls_entropy_func, &msg->entropy, (const unsigned char*) pers, os_strlen(pers));
 	lwIP_REQUIRE_NOERROR(ret, exit);
 
-	if (auth_type == MBEDTLS_SSL_IS_SERVER){
+	if (auth_type == MBEDTLS_SSL_IS_SERVER) {
 		uint32 flash_sector = 0;
 		/*Load the certificate*/
-		unsigned int def_certificate_len = 0;unsigned char *def_certificate = NULL;
+		unsigned int def_certificate_len = 0;
+		unsigned char *def_certificate = NULL;
 		def_certificate = (unsigned char *)mbedtls_get_default_obj(&flash_sector,ESPCONN_CERT_OWN, &def_certificate_len);
 		lwIP_REQUIRE_ACTION(def_certificate, exit, ret = MBEDTLS_ERR_SSL_ALLOC_FAILED);
 		ret = mbedtls_x509_crt_parse(&msg->psession->clicert, (const unsigned char *)def_certificate, def_certificate_len);
@@ -763,7 +659,8 @@ static bool mbedtls_msg_config(mbedtls_msg *msg)
 		lwIP_REQUIRE_NOERROR(ret, exit);
 
 		/*Load the private RSA key*/
-		unsigned int def_private_key_len = 0;unsigned char *def_private_key = NULL;
+		unsigned int def_private_key_len = 0;
+		unsigned char *def_private_key = NULL;
 		def_private_key = (unsigned char *)mbedtls_get_default_obj(&flash_sector,ESPCONN_PK, &def_private_key_len);
 		lwIP_REQUIRE_ACTION(def_private_key, exit, ret = MBEDTLS_ERR_SSL_ALLOC_FAILED);
 		ret = mbedtls_pk_parse_key(&msg->psession->pkey, (const unsigned char *)def_private_key, def_private_key_len, NULL, 0);
@@ -780,7 +677,7 @@ static bool mbedtls_msg_config(mbedtls_msg *msg)
 			load_flag = mbedtls_msg_info_load(msg, &auth_info);
 			lwIP_REQUIRE_ACTION(load_flag, exit, ret = ESPCONN_MEM);
 		}
-	} else{
+	} else {
 		/*Load the certificate and private RSA key*/
 		if (ssl_option.client.cert_req_sector.flag) {
 			auth_info.auth_level = ESPCONN_CLIENT;
@@ -793,7 +690,7 @@ static bool mbedtls_msg_config(mbedtls_msg *msg)
 		}
 
 		/*Load the trusted CA*/
-		if(ssl_option.client.cert_ca_sector.flag){
+		if(ssl_option.client.cert_ca_sector.flag) {
 			auth_info.auth_level = ESPCONN_CLIENT;
 			auth_info.auth_type = ESPCONN_CERT_AUTH;
 			load_flag = mbedtls_msg_info_load(msg, &auth_info);
@@ -806,7 +703,7 @@ static bool mbedtls_msg_config(mbedtls_msg *msg)
 	lwIP_REQUIRE_NOERROR(ret, exit);
 
 	/*OPTIONAL is not optimal for security, but makes interop easier in this session*/
-	if (auth_type == MBEDTLS_SSL_IS_CLIENT && ssl_option.client.cert_ca_sector.flag == false){
+	if (auth_type == MBEDTLS_SSL_IS_CLIENT && ssl_option.client.cert_ca_sector.flag == false) {
 		mbedtls_ssl_conf_authmode(&msg->conf, MBEDTLS_SSL_VERIFY_NONE);
 	}
 	mbedtls_ssl_conf_rng(&msg->conf, mbedtls_ctr_drbg_random, &msg->ctr_drbg);
@@ -818,14 +715,14 @@ static bool mbedtls_msg_config(mbedtls_msg *msg)
 	mbedtls_ssl_set_bio(&msg->ssl, &msg->fd, mbedtls_net_send, mbedtls_net_recv, NULL);
 
 exit:
-	if (ret != 0){
+	if (ret != 0) {
 		return false;
-	} else{
+	} else {
 		return true;
 	}
 }
 
-int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
+int espconn_mbedtls_parse_internal(int socket, sint8 error)
 {
 	int ret = ERR_OK;
 	bool config_flag = false;
@@ -836,8 +733,8 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 	TLSmsg = Threadmsg->pssl;
 	lwIP_REQUIRE_ACTION(TLSmsg, exit, ret = ERR_MEM);
 
-	if (error == ERR_OK){
-		if (TLSmsg->quiet){
+	if (error == ERR_OK) {
+		if (TLSmsg->quiet) {
 			uint8 *TheadBuff = NULL;
 			size_t ThreadLen = MBEDTLS_SSL_PLAIN_ADD;
 			TheadBuff = (uint8 *)os_zalloc(ThreadLen + 1);
@@ -845,16 +742,16 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 			do {
 				os_memset(TheadBuff, 0, ThreadLen);
 				ret = mbedtls_ssl_read(&TLSmsg->ssl, TheadBuff, ThreadLen);
-				if (ret > 0){
+				if (ret > 0) {
 					ESPCONN_EVENT_RECV(Threadmsg->pespconn, TheadBuff, ret);
-				} else{
-					if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == 0){
+				} else {
+					if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == 0) {
 						ret = ESPCONN_OK;
 						break;
-					} else if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY){
+					} else if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
 						ret = ESPCONN_OK;
 						mbedtls_ssl_close_notify(&TLSmsg->ssl);
-					} else{
+					} else {
 						break;
 					}
 				}
@@ -862,15 +759,15 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 			os_free(TheadBuff);
 			TheadBuff = NULL;
 			lwIP_REQUIRE_NOERROR(ret, exit);
-		} else{
-			if (TLSmsg->ssl.state == MBEDTLS_SSL_HELLO_REQUEST){
-				if (Threadmsg->preverse != NULL){
+		} else {
+			if (TLSmsg->ssl.state == MBEDTLS_SSL_HELLO_REQUEST) {
+				if (Threadmsg->preverse != NULL) {
 					struct espconn *accept_conn = NULL;
 					struct espconn *espconn = Threadmsg->preverse;
 					struct sockaddr_in name;
 					socklen_t name_len = sizeof(name);
 					remot_info *pinfo = NULL;
-					espconn_get_connection_info(espconn, &pinfo , ESPCONN_SSL);
+					espconn_get_connection_info(espconn, &pinfo, ESPCONN_SSL);
 					if (espconn->link_cnt == 0x01)
 						return ERR_ISCONN;
 
@@ -892,14 +789,14 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 					/*insert the node to the active connection list*/
 					espconn_list_creat(&plink_active, Threadmsg);
 					os_printf("server handshake start.\n");
-				} else{
+				} else {
 					os_printf("client handshake start.\n");
 				}
 				config_flag = mbedtls_msg_config(TLSmsg);
-				if (config_flag){
+				if (config_flag) {
 //					mbedtls_keep_alive(TLSmsg->fd.fd, 1, SSL_KEEP_IDLE, SSL_KEEP_INTVL, SSL_KEEP_CNT);
 					system_overclock();
-				} else{
+				} else {
 					ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
 					lwIP_REQUIRE_NOERROR(ret, exit);
 				}
@@ -914,7 +811,7 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 				if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
 					ret = ESPCONN_OK;
 					break;
-				} else{
+				} else {
 					break;
 				}
 			}
@@ -923,7 +820,7 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 			lwIP_REQUIRE_NOERROR(ret, exit);
 			/**/
 			TLSmsg->quiet = mbedtls_handshake_result(TLSmsg);
-			if (TLSmsg->quiet){
+			if (TLSmsg->quiet) {
 				if (Threadmsg->preverse != NULL) {
 					os_printf("server handshake ok!\n");
 				} else {
@@ -932,18 +829,15 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 //				mbedtls_keep_alive(TLSmsg->fd.fd, 0, SSL_KEEP_IDLE, SSL_KEEP_INTVL, SSL_KEEP_CNT);
 				mbedtls_session_free(&TLSmsg->psession);
 				mbedtls_handshake_succ(&TLSmsg->ssl);
-#if defined(ESP8266_PLATFORM)
-                mbedtls_hanshake_finished(TLSmsg);
-#endif
 				system_restoreclock();
 
 				TLSmsg->SentFnFlag = true;
 				ESPCONN_EVENT_CONNECTED(Threadmsg->pespconn);
-			} else{
+			} else {
 				lwIP_REQUIRE_NOERROR_ACTION(TLSmsg->verify_result, exit, ret = TLSmsg->verify_result);
 			}
 		}
-	} else if (error < 0){
+	} else if (error < 0) {
 		Threadmsg->pcommon.err = error;
 		Threadmsg->pespconn->state = ESPCONN_CLOSE;
 		mbedtls_net_free(&TLSmsg->fd);
@@ -954,9 +848,9 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error)
 	}
 
 exit:
-	if (ret != ESPCONN_OK){
+	if (ret != ESPCONN_OK) {
 		mbedtls_fail_info(Threadmsg, ret);
-		if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY){
+		if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
 			Threadmsg->hs_status = ESPCONN_OK;
 		}
 		ets_post(lwIPThreadPrio, NETCONN_EVENT_CLOSE,(uint32)Threadmsg);
@@ -964,7 +858,7 @@ exit:
 	return ret;
 }
 
-int __attribute__((weak)) mbedtls_parse_thread(int socket, int event, int error)
+int espconn_mbedtls_parse_thread(int socket, int event, int error)
 {
 	int ret = ERR_OK;
 	espconn_msg *Threadmsg = NULL;
@@ -973,25 +867,21 @@ int __attribute__((weak)) mbedtls_parse_thread(int socket, int event, int error)
 	lwIP_REQUIRE_ACTION(Threadmsg, exit, ret = ERR_MEM);
 	TLSmsg = Threadmsg->pssl;
 	lwIP_REQUIRE_ACTION(TLSmsg, exit, ret = ERR_MEM);
-	if (TLSmsg->quiet){
+	if (TLSmsg->quiet) {
 		int	out_msglen = TLSmsg->ssl.out_msglen + 5;
 		if (Threadmsg->pcommon.write_flag)
-			TLSmsg->record.record_len += error;
+			TLSmsg->record_len += error;
 
-		if (TLSmsg->record.record_len == out_msglen){
-			TLSmsg->record.record_len = 0;
+		if (TLSmsg->record_len == out_msglen) {
+			TLSmsg->record_len = 0;
 			Threadmsg->pcommon.write_flag = false;
-			if (Threadmsg->pcommon.cntr != 0){
+			if (Threadmsg->pcommon.cntr != 0) {
 				espconn_ssl_sent(Threadmsg, Threadmsg->pcommon.ptrbuf, Threadmsg->pcommon.cntr);
-			} else{
+			} else {
 				TLSmsg->SentFnFlag = true;
 				ESPCONN_EVENT_SEND(Threadmsg->pespconn);
 			}
-		} else{
-
 		}
-	} else{
-
 	}
 exit:
 	return ret;
@@ -1017,34 +907,34 @@ mbedtls_thread(os_event_t *events)
 	lwIP_REQUIRE_ACTION(Threadmsg->pespconn,exit,ret = ERR_ARG);
 
 	/*find the active connection*/
-	for (ListMsg = plink_active; ListMsg != NULL; ListMsg = ListMsg->pnext){
-		if (Threadmsg == ListMsg){
+	for (ListMsg = plink_active; ListMsg != NULL; ListMsg = ListMsg->pnext) {
+		if (Threadmsg == ListMsg) {
 			active_flag = true;
 			break;
 		}
 	}
 
-	if (active_flag){
+	if (active_flag) {
 		/*remove the node from the active connection list*/
 		espconn_list_delete(&plink_active, Threadmsg);
-		if (TLSmsg->listen_fd.fd != -1){
+		if (TLSmsg->listen_fd.fd != -1) {
 			mbedtls_msg_server_step(TLSmsg);
 			espconn_copy_partial(Threadmsg->preverse, Threadmsg->pespconn);
 			mbedtls_espconn_free(&Threadmsg->pespconn);
-		} else{
+		} else {
 			mbedtls_msg_free(&TLSmsg);
 			Threadmsg->pssl = NULL;
 		}
 
-		switch (events->sig){
-			case NETCONN_EVENT_ERROR:
-				espconn_close_internal(Threadmsg, NETCONN_EVENT_ERROR);
-				break;
-			case NETCONN_EVENT_CLOSE:
-				espconn_close_internal(Threadmsg, NETCONN_EVENT_CLOSE);
-				break;
-			default:
-				break;
+		switch (events->sig) {
+		case NETCONN_EVENT_ERROR:
+			espconn_close_internal(Threadmsg, NETCONN_EVENT_ERROR);
+			break;
+		case NETCONN_EVENT_CLOSE:
+			espconn_close_internal(Threadmsg, NETCONN_EVENT_CLOSE);
+			break;
+		default:
+			break;
 		}
 	}
 exit:
@@ -1074,7 +964,7 @@ sint8 espconn_ssl_client(struct espconn *espconn)
 	mbedTLSMsg = mbedtls_msg_new();
 	lwIP_REQUIRE_ACTION(mbedTLSMsg, exit, ret = ESPCONN_MEM);
 	IP4_ADDR(&ipaddr, espconn->proto.tcp->remote_ip[0],espconn->proto.tcp->remote_ip[1],
-	                  espconn->proto.tcp->remote_ip[2],espconn->proto.tcp->remote_ip[3]);
+	         espconn->proto.tcp->remote_ip[2],espconn->proto.tcp->remote_ip[3]);
 	server_name = ipaddr_ntoa(&ipaddr);
 	server_port = (const char *)sys_itoa(espconn->proto.tcp->remote_port);
 
@@ -1088,7 +978,7 @@ sint8 espconn_ssl_client(struct espconn *espconn)
 	/*insert the node to the active connection list*/
 	espconn_list_creat(&plink_active, pclient);
 exit:
-	if (ret != ESPCONN_OK){
+	if (ret != ESPCONN_OK) {
 		if (mbedTLSMsg != NULL)
 			mbedtls_msg_free(&mbedTLSMsg);
 		if (pclient != NULL)
@@ -1204,19 +1094,19 @@ void espconn_ssl_sent(void *arg, uint8 *psent, uint16 length)
 	pmbedtls_msg mbedTLSMsg = Threadmsg->pssl;
 	lwIP_ASSERT(mbedTLSMsg);
 
-	if (length > MBEDTLS_SSL_PLAIN_ADD){
+	if (length > MBEDTLS_SSL_PLAIN_ADD) {
 		out_msglen = MBEDTLS_SSL_PLAIN_ADD;
 	}
 
 	Threadmsg->pcommon.write_flag = true;
 	ret = mbedtls_ssl_write(&mbedTLSMsg->ssl, psent, out_msglen);
-	if (ret > 0){
+	if (ret > 0) {
 		Threadmsg->pcommon.ptrbuf = psent + ret;
 		Threadmsg->pcommon.cntr = length - ret;
-	} else{
+	} else {
 		if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == 0) {
 
-		} else{
+		} else {
 			mbedtls_fail_info(Threadmsg, ret);
 			ets_post(lwIPThreadPrio, NETCONN_EVENT_CLOSE,(uint32)Threadmsg);
 		}
@@ -1246,60 +1136,60 @@ void espconn_ssl_disconnect(espconn_msg *Threadmsg)
 int mbedtls_x509_test(int verbose,  char *ca_crt,  size_t ca_crt_len, char *cli_crt, size_t cli_crt_len)
 {
 #if defined(MBEDTLS_SHA1_C)
-    int ret;
-    uint32_t flags;
-    mbedtls_x509_crt cacert;
-    mbedtls_x509_crt clicert;
+	int ret;
+	uint32_t flags;
+	mbedtls_x509_crt cacert;
+	mbedtls_x509_crt clicert;
 
-    if( verbose != 0 )
-        os_printf( "  X.509 certificate load: " );
+	if( verbose != 0 )
+		os_printf( "  X.509 certificate load: " );
 
-    mbedtls_x509_crt_init( &clicert );
+	mbedtls_x509_crt_init( &clicert );
 
-    ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) cli_crt,
-                           cli_crt_len );
-    if( ret != 0 )
-    {
-        if( verbose != 0 )
-            os_printf( "failed\n" );
+	ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) cli_crt,
+	                              cli_crt_len );
+	if( ret != 0 )
+	{
+		if( verbose != 0 )
+			os_printf( "failed\n" );
 
-        return( ret );
-    }
+		return( ret );
+	}
 
-    mbedtls_x509_crt_init( &cacert );
+	mbedtls_x509_crt_init( &cacert );
 
-    ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) ca_crt,
-                          ca_crt_len );
-    if( ret != 0 )
-    {
-        if( verbose != 0 )
-            os_printf( "failed\n" );
+	ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) ca_crt,
+	                              ca_crt_len );
+	if( ret != 0 )
+	{
+		if( verbose != 0 )
+			os_printf( "failed\n" );
 
-        return( ret );
-    }
+		return( ret );
+	}
 
-    if( verbose != 0 )
-        os_printf( "passed\n  X.509 signature verify: ");
+	if( verbose != 0 )
+		os_printf( "passed\n  X.509 signature verify: ");
 
-    ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
-    if( ret != 0 )
-    {
-        if( verbose != 0 )
-            os_printf( "failed\n" );
+	ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
+	if( ret != 0 )
+	{
+		if( verbose != 0 )
+			os_printf( "failed\n" );
 
-        return( ret );
-    }
+		return( ret );
+	}
 
-    if( verbose != 0 )
-        os_printf( "passed\n\n");
+	if( verbose != 0 )
+		os_printf( "passed\n\n");
 
-    mbedtls_x509_crt_free( &cacert  );
-    mbedtls_x509_crt_free( &clicert );
+	mbedtls_x509_crt_free( &cacert  );
+	mbedtls_x509_crt_free( &clicert );
 
-    return( 0 );
+	return( 0 );
 #else
-    ((void) verbose);
-    return( 0 );
+	((void) verbose);
+	return( 0 );
 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
 }
 

+ 6 - 234
app/mbedtls/app/lwIPSocket.c

@@ -45,48 +45,6 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
 /** The global array of available sockets */
 static lwIP_sock sockets[NUM_SOCKETS];
 
-/** Table to quickly map an lwIP error (err_t) to a socket error
-  * by using -err as an index */
-static const int err_to_errno_table[] =
-{
-    0,             /* ERR_OK          0      No error, everything OK. */
-//  ENOMEM,        /* ERR_MEM        -1      Out of memory error.     */
-//  ENOBUFS,       /* ERR_BUF        -2      Buffer error.            */
-//  EWOULDBLOCK,   /* ERR_TIMEOUT    -3      Timeout                  */
-//  EHOSTUNREACH,  /* ERR_RTE        -4      Routing problem.         */
-//  EINPROGRESS,   /* ERR_INPROGRESS -5      Operation in progress    */
-//  EINVAL,        /* ERR_VAL        -6      Illegal value.           */
-//  EWOULDBLOCK,   /* ERR_WOULDBLOCK -7      Operation would block.   */
-//  ECONNABORTED,  /* ERR_ABRT       -8      Connection aborted.      */
-//  ECONNRESET,    /* ERR_RST        -9      Connection reset.        */
-//  ESHUTDOWN,     /* ERR_CLSD       -10     Connection closed.       */
-//  ENOTCONN,      /* ERR_CONN       -11     Not connected.           */
-//  EIO,           /* ERR_ARG        -12     Illegal argument.        */
-//  EADDRINUSE,    /* ERR_USE        -13     Address in use.          */
-    -1,            /* ERR_IF         -14     Low-level netif error    */
-    -1,            /* ERR_ISCONN     -15     Already connected.       */
-};
-
-#define ERR_TO_ERRNO_TABLE_SIZE \
-  (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0]))
-
-#define err_to_errno(err) \
-  ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \
-    err_to_errno_table[-(err)] : EIO)
-
-#ifdef ERRNO
-#ifndef set_errno
-#define set_errno(err) errno = (err)
-#endif
-#else /* ERRNO */
-#define set_errno(err)
-#endif /* ERRNO */
-
-#define sock_set_errno(sk, e) do { \
-  sk->err = (e); \
-  set_errno(sk->err); \
-} while (0)
-
 static lwIP_sock *get_socket(int s);
 
 static int find_socket(lwIP_netconn *newconn)
@@ -197,7 +155,7 @@ static err_t recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
                 ringbuf_memcpy_into(newconn->readbuf, pthis->payload, pthis->len);
                 tcp_recved(newconn->tcp, pthis->len);
 				newconn->state = NETCONN_STATE_ESTABLISHED;
-                lwIP_EVENT_PARSE(find_socket(newconn), ERR_OK);
+                espconn_mbedtls_parse_internal(find_socket(newconn), ERR_OK);
             }
 			pbuf_free(p);
         }
@@ -210,7 +168,7 @@ static err_t recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
     }
     else
     {
-        lwIP_EVENT_PARSE(find_socket(newconn), NETCONN_EVENT_CLOSE);
+        espconn_mbedtls_parse_internal(find_socket(newconn), NETCONN_EVENT_CLOSE);
     }
 exit:
     return err;
@@ -229,7 +187,7 @@ static err_t sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
     lwIP_netconn *conn = arg;
     lwIP_ASSERT(conn);
     conn->state = NETCONN_STATE_ESTABLISHED;
-	lwIP_EVENT_THREAD(find_socket(conn), NETCONN_EVENT_SEND, len);
+    espconn_mbedtls_parse_thread(find_socket(conn), NETCONN_EVENT_SEND, len);
     return ERR_OK;
 }
 
@@ -257,7 +215,7 @@ static void err_tcp(void *arg, err_t err)
             break;
     }
 
-    lwIP_EVENT_PARSE(find_socket(conn), err);
+    espconn_mbedtls_parse_internal(find_socket(conn), err);
     return;
 }
 
@@ -275,7 +233,7 @@ static err_t do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
     conn->state = NETCONN_STATE_ESTABLISHED;
     conn->readbuf = ringbuf_new(TCP_SND_BUF);
     lwIP_REQUIRE_ACTION(conn->readbuf, exit, err = ESP_MEM);
-    lwIP_EVENT_PARSE(find_socket(conn), ERR_OK);
+    espconn_mbedtls_parse_internal(find_socket(conn), ERR_OK);
 exit:
     return err;
 }
@@ -325,7 +283,7 @@ static err_t do_accepted(void *arg, struct tcp_pcb *newpcb, err_t err)
     setup_tcp(newconn);
 	newconn->state = NETCONN_STATE_ESTABLISHED;
     conn->acceptmbox = newconn;
-    lwIP_EVENT_PARSE(find_socket(conn), ERR_OK);
+    espconn_mbedtls_parse_internal(find_socket(conn), ERR_OK);
 exit:
     return err;
 }
@@ -844,189 +802,3 @@ int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
 {
     return lwip_getaddrname(s, name, namelen, 0);
 }
-
-int lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
-{
-    return lwip_getaddrname(s, name, namelen, 1);
-}
-
-int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
-{
-    lwIP_sock *sock = NULL;
-    err_t err = ERR_OK;
-
-    lwIP_REQUIRE_ACTION(optval, exit, err = ESP_ARG);
-    lwIP_REQUIRE_ACTION(optlen, exit, err = ESP_ARG);
-
-    sock = get_socket(s);
-    lwIP_REQUIRE_ACTION(sock, exit, err = ESP_MEM);
-    switch (level)
-    {
-        /* Level: SOL_SOCKET */
-        case SOL_SOCKET:
-            switch (optname)
-            {
-                /* The option flags */
-                case SO_ACCEPTCONN:
-                case SO_BROADCAST:
-                case SO_KEEPALIVE:
-#if SO_REUSE
-                case SO_REUSEADDR:
-                case SO_REUSEPORT:
-#endif /* SO_REUSE */
-                    *(int*)optval = sock->conn->tcp->so_options & optname;
-                    break;
-                case SO_TYPE:
-                    switch (NETCONNTYPE_GROUP(sock->conn->type))
-                    {
-                        case NETCONN_TCP:
-                            *(int*)optval = SOCK_STREAM;
-                            break;
-                        case NETCONN_UDP:
-                            *(int*)optval = SOCK_DGRAM;
-                            break;
-                        default:
-                            *(int*)optval = sock->conn->type;
-                            break;
-                    }
-                    break;
-                    break;
-            }
-            break;
-        /* Level: IPPROTO_IP */
-        case IPPROTO_IP:
-            break;
-#if LWIP_TCP
-        /* Level: IPPROTO_TCP */
-        case IPPROTO_TCP:
-            if (*optlen < sizeof(int))
-            {
-                err = ESP_ARG;
-                lwIP_REQUIRE_NOERROR(err, exit);
-            }
-
-            /* If this is no TCP socket, ignore any options. */
-            if (sock->conn->type != NETCONN_TCP)
-            {
-                err = ESP_ARG;
-                lwIP_REQUIRE_NOERROR(err, exit);
-            }
-
-            switch (optname)
-            {
-                case TCP_NODELAY:
-                case TCP_KEEPALIVE:
-                    *(int*)optval = (int)sock->conn->tcp->keep_idle;
-                    break;
-#if LWIP_TCP_KEEPALIVE
-                case TCP_KEEPIDLE:
-                    *(int*)optval = (int)(sock->conn->tcp->keep_idle/1000);
-                    break;
-                case TCP_KEEPINTVL:
-                    *(int*)optval = (int)(sock->conn->tcp->keep_intvl/1000);
-                    break;
-                case TCP_KEEPCNT:
-                    *(int*)optval = (int)sock->conn->tcp->keep_cnt;
-#endif /* LWIP_TCP_KEEPALIVE */
-                    break;
-
-                default:
-                    err = ESP_ARG;
-                    lwIP_REQUIRE_NOERROR(err, exit);
-                    break;
-            } /* switch (optname) */
-            break;
-#endif /* LWIP_TCP */
-        default:
-            err = ESP_ARG;
-            lwIP_REQUIRE_NOERROR(err, exit);
-            break;
-    }
-
-exit:
-    return err;
-}
-
-int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
-{
-    lwIP_sock *sock = NULL;
-    err_t err = ERR_OK;
-    lwIP_REQUIRE_ACTION(optval, exit, err = ESP_ARG);
-
-    sock = get_socket(s);
-    lwIP_REQUIRE_ACTION(sock, exit, err = ESP_MEM);
-    lwIP_REQUIRE_ACTION(sock->conn, exit, err = ESP_MEM);
-    lwIP_REQUIRE_ACTION(sock->conn->tcp, exit, err = ESP_MEM);
-    switch (level)
-    {
-        /* Level: SOL_SOCKET */
-        case SOL_SOCKET:
-            switch (optname)
-            {
-                case SO_KEEPALIVE:
-                    if (optlen < sizeof(int))
-                    {
-                        err = ESP_ARG;
-                        lwIP_REQUIRE_NOERROR(err, exit);
-                    }
-                    if (*(int*)optval)
-                    {
-                        sock->conn->tcp->so_options |= optname;
-                    }
-                    else
-                    {
-                        sock->conn->tcp->so_options &= ~optname;
-                    }
-                    break;
-            }
-            break;
-        /* Level: IPPROTO_IP */
-        case IPPROTO_IP:
-            break;
-        /* Level: IPPROTO_TCP */
-        case IPPROTO_TCP:
-            if (optlen < sizeof(int))
-            {
-                err = ESP_ARG;
-                lwIP_REQUIRE_NOERROR(err, exit);
-            }
-
-            /* If this is no TCP socket, ignore any options. */
-            if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP)
-            {
-                err = ESP_ARG;
-                lwIP_REQUIRE_NOERROR(err, exit);
-            }
-            switch (optname)
-            {
-                case TCP_KEEPALIVE:
-                    sock->conn->tcp->keep_idle = (u32_t) (*(int*) optval);
-                    break;
-
-#if LWIP_TCP_KEEPALIVE
-                case TCP_KEEPIDLE:
-                    sock->conn->tcp->keep_idle = 1000 * (u32_t) (*(int*) optval);
-                    break;
-                case TCP_KEEPINTVL:
-                    sock->conn->tcp->keep_intvl = 1000 * (u32_t) (*(int*) optval);
-                    break;
-                case TCP_KEEPCNT:
-                    sock->conn->tcp->keep_cnt = (u32_t) (*(int*) optval);
-                    break;
-#endif /* LWIP_TCP_KEEPALIVE */
-                default:
-                    err = ESP_ARG;
-                    lwIP_REQUIRE_NOERROR(err, exit);
-                    break;
-            }
-            break;
-        /* UNDEFINED LEVEL */
-        default:
-            err = ESP_ARG;
-            lwIP_REQUIRE_NOERROR(err, exit);
-            break;
-    }
-
-exit:
-    return err;
-}

File diff suppressed because it is too large
+ 691 - 79
app/mbedtls/library/aes.c


+ 6 - 0
app/mbedtls/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>

+ 2 - 6
app/mbedtls/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 @@ void mbedtls_arc4_free( mbedtls_arc4_context *ctx )
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
 }
 
 /*

+ 1079 - 0
app/mbedtls/library/aria.c

@@ -0,0 +1,1079 @@
+/*
+ *  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
+
+/* Parameter validation macros */
+#define ARIA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA )
+#define ARIA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#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;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( key != NULL );
+
+    if( keybits != 128 && keybits != 192 && keybits != 256 )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
+
+    /* 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;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( key != NULL );
+
+    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;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( input != NULL );
+    ARIA_VALIDATE_RET( output != NULL );
+
+    GET_UINT32_LE( a, input,  0 );
+    GET_UINT32_LE( b, input,  4 );
+    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 )
+{
+    ARIA_VALIDATE( ctx != NULL );
+    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];
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+                       mode == MBEDTLS_ARIA_DECRYPT );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( iv != NULL );
+
+    if( length % MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
+
+    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;
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+                       mode == MBEDTLS_ARIA_DECRYPT );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( iv != NULL );
+    ARIA_VALIDATE_RET( iv_off != NULL );
+
+    n = *iv_off;
+
+    /* An overly large value of n can lead to an unlimited
+     * buffer overflow. Therefore, guard against this
+     * outside of parameter validation. */
+    if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
+
+    if( mode == MBEDTLS_ARIA_DECRYPT )
+    {
+        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;
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( nonce_counter != NULL );
+    ARIA_VALIDATE_RET( stream_block  != NULL );
+    ARIA_VALIDATE_RET( nc_off != NULL );
+
+    n = *nc_off;
+    /* An overly large value of n can lead to an unlimited
+     * buffer overflow. Therefore, guard against this
+     * outside of parameter validation. */
+    if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        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 )                   \
+                mbedtls_printf( "failed\n" );       \
+            return( 1 );                    \
+        } else {                            \
+            if( verbose )                   \
+                mbedtls_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 )
+            mbedtls_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 )
+            mbedtls_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 )
+        mbedtls_printf( "\n" );
+
+    /*
+     * Test set 2
+     */
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CBC encryption */
+        if( verbose )
+            mbedtls_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 )
+            mbedtls_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 )
+        mbedtls_printf( "\n" );
+
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CFB encryption */
+        if( verbose )
+            mbedtls_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 )
+            mbedtls_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 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CTR encryption */
+        if( verbose )
+            mbedtls_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 )
+            mbedtls_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 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_ARIA_C */

+ 3 - 7
app/mbedtls/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 @@ int mbedtls_asn1_get_alg( unsigned char **p,
 
     if( *p == end )
     {
-        mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) );
+        mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
         return( 0 );
     }
 
@@ -358,7 +354,7 @@ void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
     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 )

+ 34 - 28
app/mbedtls/library/asn1write.c

@@ -236,9 +236,6 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
     int ret;
     size_t len = 0;
 
-    // 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 );
 
@@ -260,56 +257,65 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
     return( (int) len );
 }
 
-int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
-                                 const char *text, size_t text_len )
+int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag,
+    const char *text, size_t text_len )
 {
     int ret;
     size_t len = 0;
 
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
-                  (const unsigned char *) text, text_len ) );
+        (const unsigned char *) text, text_len ) );
 
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
-    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
 
     return( (int) len );
 }
 
-int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
-                           const char *text, size_t text_len )
+int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
+    const char *text, size_t text_len )
 {
-    int ret;
-    size_t len = 0;
-
-    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
-                  (const unsigned char *) text, text_len ) );
+    return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) );
+}
 
-    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
-    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_IA5_STRING ) );
+int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
+                                 const char *text, size_t text_len )
+{
+    return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) );
+}
 
-    return( (int) len );
+int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
+                           const char *text, size_t text_len )
+{
+    return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) );
 }
 
 int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
                           const unsigned char *buf, size_t bits )
 {
     int ret;
-    size_t len = 0, size;
+    size_t len = 0;
+    size_t unused_bits, byte_len;
 
-    size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 );
+    byte_len = ( bits + 7 ) / 8;
+    unused_bits = ( byte_len * 8 ) - bits;
 
-    // Calculate byte length
-    //
-    if( *p < start || (size_t)( *p - start ) < size + 1 )
+    if( *p < start || (size_t)( *p - start ) < byte_len + 1 )
         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
 
-    len = size + 1;
-    (*p) -= size;
-    memcpy( *p, buf, size );
+    len = byte_len + 1;
 
-    // Write unused bits
-    //
-    *--(*p) = (unsigned char) (size * 8 - bits);
+    /* Write the bitstring. Ensure the unused bits are zeroed */
+    if( byte_len > 0 )
+    {
+        byte_len--;
+        *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 );
+        ( *p ) -= byte_len;
+        memcpy( *p, buf, byte_len );
+    }
+
+    /* Write unused bits */
+    *--( *p ) = (unsigned char)unused_bits;
 
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );

+ 377 - 112
app/mbedtls/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,15 +59,10 @@
 #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 MPI_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+#define MPI_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
 
 #define ciL    (sizeof(mbedtls_mpi_uint))         /* chars in limb  */
 #define biL    (ciL << 3)               /* bits  in limb  */
@@ -81,13 +77,18 @@ static void mbedtls_zeroize( void *v, size_t n ) {
 #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
  */
 void mbedtls_mpi_init( mbedtls_mpi *X )
 {
-    if( X == NULL )
-        return;
+    MPI_VALIDATE( X != NULL );
 
     X->s = 1;
     X->n = 0;
@@ -119,6 +120,7 @@ void mbedtls_mpi_free( mbedtls_mpi *X )
 int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
 {
     mbedtls_mpi_uint *p;
+    MPI_VALIDATE_RET( X != NULL );
 
     if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
         return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
@@ -150,6 +152,10 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
 {
     mbedtls_mpi_uint *p;
     size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
+        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
 
     /* Actually resize up in this case */
     if( X->n <= nblimbs )
@@ -184,8 +190,10 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
  */
 int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
-    int ret;
+    int ret = 0;
     size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     if( X == Y )
         return( 0 );
@@ -203,9 +211,15 @@ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
 
     X->s = Y->s;
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
+    if( X->n < i )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
+    }
+    else
+    {
+        memset( X->p + i, 0, ( X->n - i ) * ciL );
+    }
 
-    memset( X->p, 0, X->n * ciL );
     memcpy( X->p, Y->p, i * ciL );
 
 cleanup:
@@ -219,6 +233,8 @@ cleanup:
 void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
 {
     mbedtls_mpi T;
+    MPI_VALIDATE( X != NULL );
+    MPI_VALIDATE( Y != NULL );
 
     memcpy( &T,  X, sizeof( mbedtls_mpi ) );
     memcpy(  X,  Y, sizeof( mbedtls_mpi ) );
@@ -234,6 +250,8 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned
 {
     int ret = 0;
     size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     /* make sure assign is 0 or 1 in a time-constant manner */
     assign = (assign | (unsigned char)-assign) >> 7;
@@ -263,6 +281,8 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw
     int ret, s;
     size_t i;
     mbedtls_mpi_uint tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     if( X == Y )
         return( 0 );
@@ -295,6 +315,7 @@ cleanup:
 int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
 {
     int ret;
+    MPI_VALIDATE_RET( X != NULL );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
     memset( X->p, 0, X->n * ciL );
@@ -312,6 +333,8 @@ cleanup:
  */
 int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
 {
+    MPI_VALIDATE_RET( X != NULL );
+
     if( X->n * biL <= pos )
         return( 0 );
 
@@ -330,6 +353,7 @@ int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
     int ret = 0;
     size_t off = pos / biL;
     size_t idx = pos % biL;
+    MPI_VALIDATE_RET( X != NULL );
 
     if( val != 0 && val != 1 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -356,6 +380,7 @@ cleanup:
 size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
 {
     size_t i, j, count = 0;
+    MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
 
     for( i = 0; i < X->n; i++ )
         for( j = 0; j < biL; j++, count++ )
@@ -436,6 +461,8 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
     size_t i, j, slen, n;
     mbedtls_mpi_uint d;
     mbedtls_mpi T;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( s != NULL );
 
     if( radix < 2 || radix > 16 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -548,19 +575,27 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
     size_t n;
     char *p;
     mbedtls_mpi T;
+    MPI_VALIDATE_RET( X    != NULL );
+    MPI_VALIDATE_RET( olen != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
 
     if( radix < 2 || radix > 16 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
-    n = mbedtls_mpi_bitlen( X );
-    if( radix >=  4 ) n >>= 1;
-    if( radix >= 16 ) n >>= 1;
-    /*
-     * Round up the buffer length to an even value to ensure that there is
-     * enough room for hexadecimal values that can be represented in an odd
-     * number of digits.
-     */
-    n += 3 + ( ( n + 1 ) & 1 );
+    n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */
+    if( radix >=  4 ) n >>= 1;   /* Number of 4-adic digits necessary to present
+                                  * `n`. If radix > 4, this might be a strict
+                                  * overapproximation of the number of
+                                  * radix-adic digits needed to present `n`. */
+    if( radix >= 16 ) n >>= 1;   /* Number of hexadecimal digits necessary to
+                                  * present `n`. */
+
+    n += 1; /* Terminating null byte */
+    n += 1; /* Compensate for the divisions above, which round down `n`
+             * in case it's not even. */
+    n += 1; /* Potential '-'-sign. */
+    n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing,
+                     * which always uses an even number of hex-digits. */
 
     if( buflen < n )
     {
@@ -572,7 +607,10 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
     mbedtls_mpi_init( &T );
 
     if( X->s == -1 )
+    {
         *p++ = '-';
+        buflen--;
+    }
 
     if( radix == 16 )
     {
@@ -629,6 +667,12 @@ int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
      */
     char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
 
+    MPI_VALIDATE_RET( X   != NULL );
+    MPI_VALIDATE_RET( fin != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
     memset( s, 0, sizeof( s ) );
     if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
         return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
@@ -660,6 +704,10 @@ int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE
      * newline characters and '\0'
      */
     char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
     memset( s, 0, sizeof( s ) );
 
@@ -687,14 +735,109 @@ cleanup:
 }
 #endif /* MBEDTLS_FS_IO */
 
+
+/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
+ * into the storage form used by mbedtls_mpi. */
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
+{
+    uint8_t i;
+    unsigned char *x_ptr;
+    mbedtls_mpi_uint tmp = 0;
+
+    for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ )
+    {
+        tmp <<= CHAR_BIT;
+        tmp |= (mbedtls_mpi_uint) *x_ptr;
+    }
+
+    return( tmp );
+}
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
+{
+#if defined(__BYTE_ORDER__)
+
+/* Nothing to do on bigendian systems. */
+#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
+    return( x );
+#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
+
+#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
+
+/* For GCC and Clang, have builtins for byte swapping. */
+#if defined(__GNUC__) && defined(__GNUC_PREREQ)
+#if __GNUC_PREREQ(4,3)
+#define have_bswap
+#endif
+#endif
+
+#if defined(__clang__) && defined(__has_builtin)
+#if __has_builtin(__builtin_bswap32)  &&                 \
+    __has_builtin(__builtin_bswap64)
+#define have_bswap
+#endif
+#endif
+
+#if defined(have_bswap)
+    /* The compiler is hopefully able to statically evaluate this! */
+    switch( sizeof(mbedtls_mpi_uint) )
+    {
+        case 4:
+            return( __builtin_bswap32(x) );
+        case 8:
+            return( __builtin_bswap64(x) );
+    }
+#endif
+#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
+#endif /* __BYTE_ORDER__ */
+
+    /* Fall back to C-based reordering if we don't know the byte order
+     * or we couldn't use a compiler-specific builtin. */
+    return( mpi_uint_bigendian_to_host_c( x ) );
+}
+
+static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
+{
+    mbedtls_mpi_uint *cur_limb_left;
+    mbedtls_mpi_uint *cur_limb_right;
+    if( limbs == 0 )
+        return;
+
+    /*
+     * Traverse limbs and
+     * - adapt byte-order in each limb
+     * - swap the limbs themselves.
+     * For that, simultaneously traverse the limbs from left to right
+     * and from right to left, as long as the left index is not bigger
+     * than the right index (it's not a problem if limbs is odd and the
+     * indices coincide in the last iteration).
+     */
+    for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
+         cur_limb_left <= cur_limb_right;
+         cur_limb_left++, cur_limb_right-- )
+    {
+        mbedtls_mpi_uint tmp;
+        /* Note that if cur_limb_left == cur_limb_right,
+         * this code effectively swaps the bytes only once. */
+        tmp             = mpi_uint_bigendian_to_host( *cur_limb_left  );
+        *cur_limb_left  = mpi_uint_bigendian_to_host( *cur_limb_right );
+        *cur_limb_right = tmp;
+    }
+}
+
 /*
  * Import X from unsigned binary data, big endian
  */
 int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
 {
     int ret;
-    size_t i, j;
-    size_t const limbs = CHARS_TO_LIMBS( buflen );
+    size_t const limbs    = CHARS_TO_LIMBS( buflen );
+    size_t const overhead = ( limbs * ciL ) - buflen;
+    unsigned char *Xp;
+
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
 
     /* Ensure that target MPI has exactly the necessary number of limbs */
     if( X->n != limbs )
@@ -703,11 +846,17 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu
         mbedtls_mpi_init( X );
         MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
     }
-
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
 
-    for( i = buflen, j = 0; i > 0; i--, j++ )
-        X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
+    /* Avoid calling `memcpy` with NULL source argument,
+     * even if buflen is 0. */
+    if( buf != NULL )
+    {
+        Xp = (unsigned char*) X->p;
+        memcpy( Xp + overhead, buf, buflen );
+
+        mpi_bigendian_to_host( X->p, limbs );
+    }
 
 cleanup:
 
@@ -720,11 +869,16 @@ cleanup:
 int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
                               unsigned char *buf, size_t buflen )
 {
-    size_t stored_bytes = X->n * ciL;
+    size_t stored_bytes;
     size_t bytes_to_copy;
     unsigned char *p;
     size_t i;
 
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
+
+    stored_bytes = X->n * ciL;
+
     if( stored_bytes < buflen )
     {
         /* There is enough space in the output buffer. Write initial
@@ -763,6 +917,7 @@ int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
     int ret;
     size_t i, v0, t1;
     mbedtls_mpi_uint r0 = 0, r1;
+    MPI_VALIDATE_RET( X != NULL );
 
     v0 = count / (biL    );
     t1 = count & (biL - 1);
@@ -812,6 +967,7 @@ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
 {
     size_t i, v0, v1;
     mbedtls_mpi_uint r0 = 0, r1;
+    MPI_VALIDATE_RET( X != NULL );
 
     v0 = count /  biL;
     v1 = count & (biL - 1);
@@ -854,6 +1010,8 @@ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
 int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
     size_t i, j;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     for( i = X->n; i > 0; i-- )
         if( X->p[i - 1] != 0 )
@@ -884,6 +1042,8 @@ int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
 int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
     size_t i, j;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
 
     for( i = X->n; i > 0; i-- )
         if( X->p[i - 1] != 0 )
@@ -918,6 +1078,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
 {
     mbedtls_mpi Y;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
 
     *p  = ( z < 0 ) ? -z : z;
     Y.s = ( z < 0 ) ? -1 : 1;
@@ -935,6 +1096,9 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     int ret;
     size_t i, j;
     mbedtls_mpi_uint *o, *p, c, tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( X == B )
     {
@@ -1000,7 +1164,7 @@ static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
     while( c != 0 )
     {
         z = ( *d < c ); *d -= c;
-        c = z; i++; d++;
+        c = z; d++;
     }
 }
 
@@ -1012,6 +1176,9 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     mbedtls_mpi TB;
     int ret;
     size_t n;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
         return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
@@ -1052,8 +1219,12 @@ cleanup:
  */
 int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
 {
-    int ret, s = A->s;
+    int ret, s;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
+    s = A->s;
     if( A->s * B->s < 0 )
     {
         if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
@@ -1083,8 +1254,12 @@ cleanup:
  */
 int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
 {
-    int ret, s = A->s;
+    int ret, s;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
+    s = A->s;
     if( A->s * B->s > 0 )
     {
         if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
@@ -1116,6 +1291,8 @@ int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
     _B.s = ( b < 0 ) ? -1 : 1;
@@ -1132,6 +1309,8 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
     _B.s = ( b < 0 ) ? -1 : 1;
@@ -1221,6 +1400,9 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     int ret;
     size_t i, j;
     mbedtls_mpi TA, TB;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
 
@@ -1238,8 +1420,8 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
 
-    for( i++; j > 0; j-- )
-        mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
+    for( ; j > 0; j-- )
+        mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
 
     X->s = A->s * B->s;
 
@@ -1257,6 +1439,8 @@ int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     _B.s = 1;
     _B.n = 1;
@@ -1365,11 +1549,14 @@ static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
 /*
  * Division by mbedtls_mpi: A = Q * B + R  (HAC 14.20)
  */
-int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
+int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B )
 {
     int ret;
     size_t i, n, t, k;
     mbedtls_mpi X, Y, Z, T1, T2;
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
         return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
@@ -1480,10 +1667,13 @@ cleanup:
 /*
  * Division by int: A = Q * b + R
  */
-int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b )
+int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
+                         const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b )
 {
     mbedtls_mpi _B;
     mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
     _B.s = ( b < 0 ) ? -1 : 1;
@@ -1499,6 +1689,9 @@ int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, m
 int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
 {
     int ret;
+    MPI_VALIDATE_RET( R != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
 
     if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
         return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
@@ -1523,6 +1716,8 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_
 {
     size_t i;
     mbedtls_mpi_uint x, y, z;
+    MPI_VALIDATE_RET( r != NULL );
+    MPI_VALIDATE_RET( A != NULL );
 
     if( b == 0 )
         return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
@@ -1636,7 +1831,8 @@ static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi
 /*
  * Montgomery reduction: A = A * R^-1 mod N
  */
-static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
+static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
+                        mbedtls_mpi_uint mm, const mbedtls_mpi *T )
 {
     mbedtls_mpi_uint z = 1;
     mbedtls_mpi U;
@@ -1650,7 +1846,9 @@ static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint m
 /*
  * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
  */
-int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR )
+int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *E, const mbedtls_mpi *N,
+                         mbedtls_mpi *_RR )
 {
     int ret;
     size_t wbits, wsize, one = 1;
@@ -1660,6 +1858,11 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
     int neg;
 
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( E != NULL );
+    MPI_VALIDATE_RET( N != NULL );
+
     if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
@@ -1679,8 +1882,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
             ( i >  79 ) ? 4 : ( i >  23 ) ? 3 : 1;
 
+#if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
     if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
         wsize = MBEDTLS_MPI_WINDOW_SIZE;
+#endif
 
     j = N->n + 1;
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
@@ -1864,6 +2069,10 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
     size_t lz, lzt;
     mbedtls_mpi TG, TA, TB;
 
+    MPI_VALIDATE_RET( G != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
     mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
@@ -1919,16 +2128,28 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
                      void *p_rng )
 {
     int ret;
-    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    size_t const limbs = CHARS_TO_LIMBS( size );
+    size_t const overhead = ( limbs * ciL ) - size;
+    unsigned char *Xp;
 
-    if( size > MBEDTLS_MPI_MAX_SIZE )
-        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
 
-    MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
+    /* Ensure that target MPI has exactly the necessary number of limbs */
+    if( X->n != limbs )
+    {
+        mbedtls_mpi_free( X );
+        mbedtls_mpi_init( X );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
+    }
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+    Xp = (unsigned char*) X->p;
+    f_rng( p_rng, Xp + overhead, size );
+
+    mpi_bigendian_to_host( X->p, limbs );
 
 cleanup:
-    mbedtls_zeroize( buf, sizeof( buf ) );
     return( ret );
 }
 
@@ -1939,6 +2160,9 @@ int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
 {
     int ret;
     mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( N != NULL );
 
     if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@@ -2098,7 +2322,11 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
     size_t i, j, k, s;
     mbedtls_mpi W, R, T, A, RR;
 
-    mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R );
+    mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
     mbedtls_mpi_init( &RR );
 
     /*
@@ -2110,8 +2338,6 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
 
-    i = mbedtls_mpi_bitlen( X );
-
     for( i = 0; i < rounds; i++ )
     {
         /*
@@ -2128,7 +2354,8 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
             }
 
             if (count++ > 30) {
-                return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+                ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+                goto cleanup;
             }
 
         } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
@@ -2170,7 +2397,8 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
     }
 
 cleanup:
-    mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
+    mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
     mbedtls_mpi_free( &RR );
 
     return( ret );
@@ -2179,12 +2407,14 @@ cleanup:
 /*
  * Pseudo-primality test: small factors, then Miller-Rabin
  */
-static int mpi_is_prime_internal( const mbedtls_mpi *X, int rounds,
-                  int (*f_rng)(void *, unsigned char *, size_t),
-                  void *p_rng )
+int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
 {
     int ret;
     mbedtls_mpi XX;
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
 
     XX.s = 1;
     XX.n = X->n;
@@ -2208,6 +2438,7 @@ static int mpi_is_prime_internal( const mbedtls_mpi *X, int rounds,
     return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 /*
  * Pseudo-primality test, error probability 2^-80
  */
@@ -2215,22 +2446,45 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
                   int (*f_rng)(void *, unsigned char *, size_t),
                   void *p_rng )
 {
-    return mpi_is_prime_internal( X, 40, f_rng, p_rng );
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    /*
+     * In the past our key generation aimed for an error rate of at most
+     * 2^-80. Since this function is deprecated, aim for the same certainty
+     * here as well.
+     */
+    return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
 }
+#endif
 
 /*
  * Prime number generation
+ *
+ * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
+ * be either 1024 bits or 1536 bits long, and flags must contain
+ * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
  */
-int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
+int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
                    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;
     int rounds;
     mbedtls_mpi_uint r;
     mbedtls_mpi Y;
 
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
     if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
@@ -2238,78 +2492,89 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
 
     n = BITS_TO_LIMBS( nbits );
 
-    /*
-     * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
-     */
-    rounds = ( ( nbits >= 1300 ) ?  2 : ( nbits >=  850 ) ?  3 :
-               ( nbits >=  650 ) ?  4 : ( nbits >=  350 ) ?  8 :
-               ( nbits >=  250 ) ? 12 : ( nbits >=  150 ) ? 18 : 27 );
-
-    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 )
+    if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 )
     {
-        while( ( ret = mpi_is_prime_internal( X, rounds, f_rng, p_rng ) ) != 0 )
-        {
-            if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
-                goto cleanup;
-
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) );
-        }
+        /*
+         * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
+         */
+        rounds = ( ( nbits >= 1300 ) ?  2 : ( nbits >=  850 ) ?  3 :
+                   ( nbits >=  650 ) ?  4 : ( nbits >=  350 ) ?  8 :
+                   ( nbits >=  250 ) ? 12 : ( nbits >=  150 ) ? 18 : 27 );
     }
     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
+         * 2^-100 error probability, number of rounds computed based on HAC,
+         * fact 4.48
          */
+        rounds = ( ( nbits >= 1450 ) ?  4 : ( nbits >=  1150 ) ?  5 :
+                   ( nbits >= 1000 ) ?  6 : ( nbits >=   850 ) ?  7 :
+                   ( nbits >=  750 ) ?  8 : ( nbits >=   500 ) ? 13 :
+                   ( nbits >=  250 ) ? 28 : ( nbits >=   150 ) ? 40 : 51 );
+    }
 
-        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 ) );
+    while( 1 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
+        /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
+        if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
 
-        /* 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 ) );
+        k = n * biL;
+        if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
+        X->p[0] |= 1;
 
-        while( 1 )
+        if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 )
         {
-            /*
-             * 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, rounds, f_rng, p_rng  ) )
-                                                                == 0 &&
-                ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng  ) )
-                                                                == 0 )
-            {
-                break;
-            }
+            ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng );
 
             if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
                 goto cleanup;
-
+        }
+        else
+        {
             /*
-             * 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.
+             * 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
              */
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(  X,  X, 12 ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6  ) );
+
+            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 )
+            {
+                /*
+                 * 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, rounds, f_rng, p_rng  ) )
+                                                                    == 0 &&
+                    ( ret = mpi_miller_rabin( &Y, rounds, 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  ) );
+            }
         }
     }
 

+ 52 - 12
app/mbedtls/library/blowfish.c

@@ -34,15 +34,17 @@
 #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;
-}
+/* Parameter validation macros */
+#define BLOWFISH_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA )
+#define BLOWFISH_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
 
 /*
  * 32-bit integer manipulation macros (big endian)
@@ -157,6 +159,7 @@ static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t
 
 void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
 {
+    BLOWFISH_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
 }
 
@@ -165,22 +168,26 @@ void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx )
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
 }
 
 /*
  * Blowfish key schedule
  */
-int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
-                     unsigned int keybits )
+int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx,
+                             const unsigned char *key,
+                             unsigned int keybits )
 {
     unsigned int i, j, k;
     uint32_t data, datal, datar;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( key != NULL );
 
-    if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
-        ( keybits % 8 ) )
+    if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS    ||
+        keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS    ||
+        keybits % 8 != 0 )
     {
-        return( MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH );
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
     }
 
     keybits >>= 3;
@@ -235,6 +242,11 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
                     unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
 {
     uint32_t X0, X1;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( input  != NULL );
+    BLOWFISH_VALIDATE_RET( output != NULL );
 
     GET_UINT32_BE( X0, input,  0 );
     GET_UINT32_BE( X1, input,  4 );
@@ -267,6 +279,12 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
 {
     int i;
     unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( iv != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
 
     if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
         return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
@@ -321,7 +339,19 @@ int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
                        unsigned char *output )
 {
     int c;
-    size_t n = *iv_off;
+    size_t n;
+
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( iv     != NULL );
+    BLOWFISH_VALIDATE_RET( iv_off != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *iv_off;
+    if( n >= 8 )
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
 
     if( mode == MBEDTLS_BLOWFISH_DECRYPT )
     {
@@ -369,7 +399,17 @@ int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
                        unsigned char *output )
 {
     int c, i;
-    size_t n = *nc_off;
+    size_t n;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( nonce_counter != NULL );
+    BLOWFISH_VALIDATE_RET( stream_block  != NULL );
+    BLOWFISH_VALIDATE_RET( nc_off != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *nc_off;
+    if( n >= 8 )
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
 
     while( length-- )
     {

+ 59 - 17
app/mbedtls/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,10 +49,11 @@
 
 #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;
-}
+/* Parameter validation macros */
+#define CAMELLIA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA )
+#define CAMELLIA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
 
 /*
  * 32-bit integer manipulation macros (big endian)
@@ -325,6 +327,7 @@ static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
 
 void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
 {
+    CAMELLIA_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
 }
 
@@ -333,14 +336,15 @@ void mbedtls_camellia_free( mbedtls_camellia_context *ctx )
     if( ctx == NULL )
         return;
 
-    mbedtls_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
 }
 
 /*
  * Camellia key schedule (encryption)
  */
-int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits )
+int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits )
 {
     int idx;
     size_t i;
@@ -350,6 +354,9 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned c
     uint32_t KC[16];
     uint32_t TK[20];
 
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( key != NULL );
+
     RK = ctx->rk;
 
     memset( t, 0, 64 );
@@ -360,7 +367,7 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned c
         case 128: ctx->nr = 3; idx = 0; break;
         case 192:
         case 256: ctx->nr = 4; idx = 1; break;
-        default : return( MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH );
+        default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
     }
 
     for( i = 0; i < keybits / 8; ++i )
@@ -444,14 +451,17 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned c
 /*
  * Camellia key schedule (decryption)
  */
-int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
-                         unsigned int keybits )
+int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits )
 {
     int idx, ret;
     size_t i;
     mbedtls_camellia_context cty;
     uint32_t *RK;
     uint32_t *SK;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( key != NULL );
 
     mbedtls_camellia_init( &cty );
 
@@ -499,6 +509,11 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
 {
     int NR;
     uint32_t *RK, X[4];
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( input  != NULL );
+    CAMELLIA_VALIDATE_RET( output != NULL );
 
     ( (void) mode );
 
@@ -556,14 +571,20 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
  * Camellia-CBC buffer encryption/decryption
  */
 int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
-                    int mode,
-                    size_t length,
-                    unsigned char iv[16],
-                    const unsigned char *input,
-                    unsigned char *output )
+                                int mode,
+                                size_t length,
+                                unsigned char iv[16],
+                                const unsigned char *input,
+                                unsigned char *output )
 {
     int i;
     unsigned char temp[16];
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( iv != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
 
     if( length % 16 )
         return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
@@ -618,7 +639,18 @@ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
                        unsigned char *output )
 {
     int c;
-    size_t n = *iv_off;
+    size_t n;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( iv     != NULL );
+    CAMELLIA_VALIDATE_RET( iv_off != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *iv_off;
+    if( n >= 16 )
+        return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
 
     if( mode == MBEDTLS_CAMELLIA_DECRYPT )
     {
@@ -666,7 +698,17 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
                        unsigned char *output )
 {
     int c, i;
-    size_t n = *nc_off;
+    size_t n;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( nonce_counter != NULL );
+    CAMELLIA_VALIDATE_RET( stream_block  != NULL );
+    CAMELLIA_VALIDATE_RET( nc_off != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *nc_off;
+    if( n >= 16 )
+        return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
 
     while( length-- )
     {

+ 80 - 14
app/mbedtls/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,10 +52,10 @@
 
 #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_VALIDATE_RET( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
+#define CCM_VALIDATE( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
 
 #define CCM_ENCRYPT 0
 #define CCM_DECRYPT 1
@@ -64,6 +65,7 @@ static void mbedtls_zeroize( void *v, size_t n ) {
  */
 void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
 {
+    CCM_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
 }
 
@@ -75,6 +77,9 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
     int ret;
     const mbedtls_cipher_info_t *cipher_info;
 
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( key != NULL );
+
     cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
     if( cipher_info == NULL )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -101,8 +106,10 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
  */
 void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
 {
+    if( ctx == NULL )
+        return;
     mbedtls_cipher_free( &ctx->cipher_ctx );
-    mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
 }
 
 /*
@@ -127,11 +134,17 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
  * This avoids allocating one more 16 bytes buffer while allowing src == dst.
  */
 #define CTR_CRYPT( dst, src, len  )                                            \
-    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 )  \
-        return( ret );                                                         \
-                                                                               \
-    for( i = 0; i < len; i++ )                                                 \
-        dst[i] = src[i] ^ b[i];
+    do                                                                  \
+    {                                                                   \
+        if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr,       \
+                                           16, b, &olen ) ) != 0 )      \
+        {                                                               \
+            return( ret );                                              \
+        }                                                               \
+                                                                        \
+        for( i = 0; i < (len); i++ )                                    \
+            (dst)[i] = (src)[i] ^ b[i];                                 \
+    } while( 0 )
 
 /*
  * Authenticated encryption or decryption
@@ -156,8 +169,10 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
      * 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,20 +321,45 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
 /*
  * 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,
                          unsigned char *tag, size_t tag_len )
 {
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
     return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
                             add, add_len, input, output, tag, tag_len ) );
 }
 
+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 )
+{
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( tag_len == 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    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,
@@ -330,6 +370,13 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
     unsigned char i;
     int diff;
 
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
     if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
                                 iv, iv_len, add, add_len,
                                 input, output, check_tag, tag_len ) ) != 0 )
@@ -343,13 +390,32 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
 
     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 )
+{
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+    if( tag_len == 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    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)

File diff suppressed because it is too large
+ 1638 - 305
app/mbedtls/library/certs.c


+ 570 - 0
app/mbedtls/library/chacha20.c

@@ -0,0 +1,570 @@
+/**
+ * \file chacha20.c
+ *
+ * \brief ChaCha20 cipher.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ *
+ *  Copyright (C) 2006-2016, 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_CHACHA20_C)
+
+#include "mbedtls/chacha20.h"
+#include "mbedtls/platform_util.h"
+
+#include <stddef.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_CHACHA20_ALT)
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/* Parameter validation macros */
+#define CHACHA20_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
+#define CHACHA20_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#define BYTES_TO_U32_LE( data, offset )                           \
+    ( (uint32_t) (data)[offset]                                   \
+      | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 )     \
+      | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 )    \
+      | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 )    \
+    )
+
+#define ROTL32( value, amount ) \
+    ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
+
+#define CHACHA20_CTR_INDEX ( 12U )
+
+#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
+
+/**
+ * \brief           ChaCha20 quarter round operation.
+ *
+ *                  The quarter round is defined as follows (from RFC 7539):
+ *                      1.  a += b; d ^= a; d <<<= 16;
+ *                      2.  c += d; b ^= c; b <<<= 12;
+ *                      3.  a += b; d ^= a; d <<<= 8;
+ *                      4.  c += d; b ^= c; b <<<= 7;
+ *
+ * \param state     ChaCha20 state to modify.
+ * \param a         The index of 'a' in the state.
+ * \param b         The index of 'b' in the state.
+ * \param c         The index of 'c' in the state.
+ * \param d         The index of 'd' in the state.
+ */
+static inline void chacha20_quarter_round( uint32_t state[16],
+                                           size_t a,
+                                           size_t b,
+                                           size_t c,
+                                           size_t d )
+{
+    /* a += b; d ^= a; d <<<= 16; */
+    state[a] += state[b];
+    state[d] ^= state[a];
+    state[d] = ROTL32( state[d], 16 );
+
+    /* c += d; b ^= c; b <<<= 12 */
+    state[c] += state[d];
+    state[b] ^= state[c];
+    state[b] = ROTL32( state[b], 12 );
+
+    /* a += b; d ^= a; d <<<= 8; */
+    state[a] += state[b];
+    state[d] ^= state[a];
+    state[d] = ROTL32( state[d], 8 );
+
+    /* c += d; b ^= c; b <<<= 7; */
+    state[c] += state[d];
+    state[b] ^= state[c];
+    state[b] = ROTL32( state[b], 7 );
+}
+
+/**
+ * \brief           Perform the ChaCha20 inner block operation.
+ *
+ *                  This function performs two rounds: the column round and the
+ *                  diagonal round.
+ *
+ * \param state     The ChaCha20 state to update.
+ */
+static void chacha20_inner_block( uint32_t state[16] )
+{
+    chacha20_quarter_round( state, 0, 4, 8,  12 );
+    chacha20_quarter_round( state, 1, 5, 9,  13 );
+    chacha20_quarter_round( state, 2, 6, 10, 14 );
+    chacha20_quarter_round( state, 3, 7, 11, 15 );
+
+    chacha20_quarter_round( state, 0, 5, 10, 15 );
+    chacha20_quarter_round( state, 1, 6, 11, 12 );
+    chacha20_quarter_round( state, 2, 7, 8,  13 );
+    chacha20_quarter_round( state, 3, 4, 9,  14 );
+}
+
+/**
+ * \brief               Generates a keystream block.
+ *
+ * \param initial_state The initial ChaCha20 state (key, nonce, counter).
+ * \param keystream     Generated keystream bytes are written to this buffer.
+ */
+static void chacha20_block( const uint32_t initial_state[16],
+                            unsigned char keystream[64] )
+{
+    uint32_t working_state[16];
+    size_t i;
+
+    memcpy( working_state,
+            initial_state,
+            CHACHA20_BLOCK_SIZE_BYTES );
+
+    for( i = 0U; i < 10U; i++ )
+        chacha20_inner_block( working_state );
+
+    working_state[ 0] += initial_state[ 0];
+    working_state[ 1] += initial_state[ 1];
+    working_state[ 2] += initial_state[ 2];
+    working_state[ 3] += initial_state[ 3];
+    working_state[ 4] += initial_state[ 4];
+    working_state[ 5] += initial_state[ 5];
+    working_state[ 6] += initial_state[ 6];
+    working_state[ 7] += initial_state[ 7];
+    working_state[ 8] += initial_state[ 8];
+    working_state[ 9] += initial_state[ 9];
+    working_state[10] += initial_state[10];
+    working_state[11] += initial_state[11];
+    working_state[12] += initial_state[12];
+    working_state[13] += initial_state[13];
+    working_state[14] += initial_state[14];
+    working_state[15] += initial_state[15];
+
+    for( i = 0U; i < 16; i++ )
+    {
+        size_t offset = i * 4U;
+
+        keystream[offset     ] = (unsigned char)( working_state[i]       );
+        keystream[offset + 1U] = (unsigned char)( working_state[i] >>  8 );
+        keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
+        keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
+    }
+
+    mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
+}
+
+void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
+{
+    CHACHA20_VALIDATE( ctx != NULL );
+
+    mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
+    mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+
+    /* Initially, there's no keystream bytes available */
+    ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
+}
+
+void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
+{
+    if( ctx != NULL )
+    {
+        mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
+    }
+}
+
+int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
+                            const unsigned char key[32] )
+{
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( key != NULL );
+
+    /* ChaCha20 constants - the string "expand 32-byte k" */
+    ctx->state[0] = 0x61707865;
+    ctx->state[1] = 0x3320646e;
+    ctx->state[2] = 0x79622d32;
+    ctx->state[3] = 0x6b206574;
+
+    /* Set key */
+    ctx->state[4]  = BYTES_TO_U32_LE( key, 0 );
+    ctx->state[5]  = BYTES_TO_U32_LE( key, 4 );
+    ctx->state[6]  = BYTES_TO_U32_LE( key, 8 );
+    ctx->state[7]  = BYTES_TO_U32_LE( key, 12 );
+    ctx->state[8]  = BYTES_TO_U32_LE( key, 16 );
+    ctx->state[9]  = BYTES_TO_U32_LE( key, 20 );
+    ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
+    ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
+                             const unsigned char nonce[12],
+                             uint32_t counter )
+{
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( nonce != NULL );
+
+    /* Counter */
+    ctx->state[12] = counter;
+
+    /* Nonce */
+    ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
+    ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
+    ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
+
+    mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+
+    /* Initially, there's no keystream bytes available */
+    ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
+                              size_t size,
+                              const unsigned char *input,
+                              unsigned char *output )
+{
+    size_t offset = 0U;
+    size_t i;
+
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( size == 0 || input  != NULL );
+    CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
+
+    /* Use leftover keystream bytes, if available */
+    while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
+    {
+        output[offset] = input[offset]
+                       ^ ctx->keystream8[ctx->keystream_bytes_used];
+
+        ctx->keystream_bytes_used++;
+        offset++;
+        size--;
+    }
+
+    /* Process full blocks */
+    while( size >= CHACHA20_BLOCK_SIZE_BYTES )
+    {
+        /* Generate new keystream block and increment counter */
+        chacha20_block( ctx->state, ctx->keystream8 );
+        ctx->state[CHACHA20_CTR_INDEX]++;
+
+        for( i = 0U; i < 64U; i += 8U )
+        {
+            output[offset + i  ] = input[offset + i  ] ^ ctx->keystream8[i  ];
+            output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
+            output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
+            output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
+            output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
+            output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
+            output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
+            output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
+        }
+
+        offset += CHACHA20_BLOCK_SIZE_BYTES;
+        size   -= CHACHA20_BLOCK_SIZE_BYTES;
+    }
+
+    /* Last (partial) block */
+    if( size > 0U )
+    {
+        /* Generate new keystream block and increment counter */
+        chacha20_block( ctx->state, ctx->keystream8 );
+        ctx->state[CHACHA20_CTR_INDEX]++;
+
+        for( i = 0U; i < size; i++)
+        {
+            output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
+        }
+
+        ctx->keystream_bytes_used = size;
+
+    }
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_crypt( const unsigned char key[32],
+                            const unsigned char nonce[12],
+                            uint32_t counter,
+                            size_t data_len,
+                            const unsigned char* input,
+                            unsigned char* output )
+{
+    mbedtls_chacha20_context ctx;
+    int ret;
+
+    CHACHA20_VALIDATE_RET( key != NULL );
+    CHACHA20_VALIDATE_RET( nonce != NULL );
+    CHACHA20_VALIDATE_RET( data_len == 0 || input  != NULL );
+    CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
+
+    mbedtls_chacha20_init( &ctx );
+
+    ret = mbedtls_chacha20_setkey( &ctx, key );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
+
+cleanup:
+    mbedtls_chacha20_free( &ctx );
+    return( ret );
+}
+
+#endif /* !MBEDTLS_CHACHA20_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const unsigned char test_keys[2][32] =
+{
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+    }
+};
+
+static const unsigned char test_nonces[2][12] =
+{
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+    },
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x02
+    }
+};
+
+static const uint32_t test_counters[2] =
+{
+    0U,
+    1U
+};
+
+static const unsigned char test_input[2][375] =
+{
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+        0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
+        0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
+        0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
+        0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
+        0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
+        0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
+        0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
+        0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
+        0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
+        0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
+        0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
+        0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
+        0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
+        0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
+        0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
+        0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
+        0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+        0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
+        0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
+        0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
+        0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
+        0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
+        0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
+        0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
+        0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
+        0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
+        0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+        0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
+        0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+        0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
+        0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
+        0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+        0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
+        0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
+        0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
+        0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
+        0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
+        0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
+        0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
+        0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
+        0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
+        0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
+        0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
+        0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
+        0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
+        0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
+        0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
+    }
+};
+
+static const unsigned char test_output[2][375] =
+{
+    {
+        0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
+        0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
+        0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
+        0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
+        0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
+        0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
+        0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
+        0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
+    },
+    {
+        0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
+        0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
+        0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
+        0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
+        0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
+        0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
+        0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
+        0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
+        0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
+        0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
+        0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
+        0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
+        0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
+        0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
+        0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
+        0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
+        0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
+        0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
+        0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
+        0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
+        0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
+        0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
+        0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
+        0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
+        0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
+        0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
+        0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
+        0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
+        0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
+        0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
+        0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
+        0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
+        0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
+        0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
+        0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
+        0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
+        0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
+        0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
+        0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
+        0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
+        0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
+        0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
+        0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
+        0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
+        0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
+        0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
+        0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
+    }
+};
+
+static const size_t test_lengths[2] =
+{
+    64U,
+    375U
+};
+
+#define ASSERT( cond, args )            \
+    do                                  \
+    {                                   \
+        if( ! ( cond ) )                \
+        {                               \
+            if( verbose != 0 )          \
+                mbedtls_printf args;    \
+                                        \
+            return( -1 );               \
+        }                               \
+    }                                   \
+    while( 0 )
+
+int mbedtls_chacha20_self_test( int verbose )
+{
+    unsigned char output[381];
+    unsigned i;
+    int ret;
+
+    for( i = 0U; i < 2U; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  ChaCha20 test %u ", i );
+
+        ret = mbedtls_chacha20_crypt( test_keys[i],
+                                      test_nonces[i],
+                                      test_counters[i],
+                                      test_lengths[i],
+                                      test_input[i],
+                                      output );
+
+        ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
+
+        ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
+                ( "failed (output)\n" ) );
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* !MBEDTLS_CHACHA20_C */

+ 540 - 0
app/mbedtls/library/chachapoly.c

@@ -0,0 +1,540 @@
+/**
+ * \file chachapoly.c
+ *
+ * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
+ *
+ *  Copyright (C) 2006-2016, 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_CHACHAPOLY_C)
+
+#include "mbedtls/chachapoly.h"
+#include "mbedtls/platform_util.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_CHACHAPOLY_ALT)
+
+/* Parameter validation macros */
+#define CHACHAPOLY_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
+#define CHACHAPOLY_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#define CHACHAPOLY_STATE_INIT       ( 0 )
+#define CHACHAPOLY_STATE_AAD        ( 1 )
+#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
+#define CHACHAPOLY_STATE_FINISHED   ( 3 )
+
+/**
+ * \brief           Adds nul bytes to pad the AAD for Poly1305.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context.
+ */
+static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx )
+{
+    uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U );
+    unsigned char zeroes[15];
+
+    if( partial_block_len == 0U )
+        return( 0 );
+
+    memset( zeroes, 0, sizeof( zeroes ) );
+
+    return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
+                                     zeroes,
+                                     16U - partial_block_len ) );
+}
+
+/**
+ * \brief           Adds nul bytes to pad the ciphertext for Poly1305.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context.
+ */
+static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )
+{
+    uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U );
+    unsigned char zeroes[15];
+
+    if( partial_block_len == 0U )
+        return( 0 );
+
+    memset( zeroes, 0, sizeof( zeroes ) );
+    return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
+                                     zeroes,
+                                     16U - partial_block_len ) );
+}
+
+void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
+{
+    CHACHAPOLY_VALIDATE( ctx != NULL );
+
+    mbedtls_chacha20_init( &ctx->chacha20_ctx );
+    mbedtls_poly1305_init( &ctx->poly1305_ctx );
+    ctx->aad_len        = 0U;
+    ctx->ciphertext_len = 0U;
+    ctx->state          = CHACHAPOLY_STATE_INIT;
+    ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
+}
+
+void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_chacha20_free( &ctx->chacha20_ctx );
+    mbedtls_poly1305_free( &ctx->poly1305_ctx );
+    ctx->aad_len        = 0U;
+    ctx->ciphertext_len = 0U;
+    ctx->state          = CHACHAPOLY_STATE_INIT;
+    ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
+}
+
+int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
+                               const unsigned char key[32] )
+{
+    int ret;
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( key != NULL );
+
+    ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
+
+    return( ret );
+}
+
+int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
+                               const unsigned char nonce[12],
+                               mbedtls_chachapoly_mode_t mode  )
+{
+    int ret;
+    unsigned char poly1305_key[64];
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+
+    /* Set counter = 0, will be update to 1 when generating Poly1305 key */
+    ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
+    if( ret != 0 )
+        goto cleanup;
+
+    /* Generate the Poly1305 key by getting the ChaCha20 keystream output with
+     * counter = 0.  This is the same as encrypting a buffer of zeroes.
+     * Only the first 256-bits (32 bytes) of the key is used for Poly1305.
+     * The other 256 bits are discarded.
+     */
+    memset( poly1305_key, 0, sizeof( poly1305_key ) );
+    ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ),
+                                      poly1305_key, poly1305_key );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key );
+
+    if( ret == 0 )
+    {
+        ctx->aad_len        = 0U;
+        ctx->ciphertext_len = 0U;
+        ctx->state          = CHACHAPOLY_STATE_AAD;
+        ctx->mode           = mode;
+    }
+
+cleanup:
+    mbedtls_platform_zeroize( poly1305_key, 64U );
+    return( ret );
+}
+
+int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
+                                   const unsigned char *aad,
+                                   size_t aad_len )
+{
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
+
+    if( ctx->state != CHACHAPOLY_STATE_AAD )
+        return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
+
+    ctx->aad_len += aad_len;
+
+    return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) );
+}
+
+int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
+                               size_t len,
+                               const unsigned char *input,
+                               unsigned char *output )
+{
+    int ret;
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
+    CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
+
+    if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
+        ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
+    {
+        return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
+    }
+
+    if( ctx->state == CHACHAPOLY_STATE_AAD )
+    {
+        ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;
+
+        ret = chachapoly_pad_aad( ctx );
+        if( ret != 0 )
+            return( ret );
+    }
+
+    ctx->ciphertext_len += len;
+
+    if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT )
+    {
+        ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
+        if( ret != 0 )
+            return( ret );
+
+        ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len );
+        if( ret != 0 )
+            return( ret );
+    }
+    else /* DECRYPT */
+    {
+        ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len );
+        if( ret != 0 )
+            return( ret );
+
+        ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
+        if( ret != 0 )
+            return( ret );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
+                               unsigned char mac[16] )
+{
+    int ret;
+    unsigned char len_block[16];
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( mac != NULL );
+
+    if( ctx->state == CHACHAPOLY_STATE_INIT )
+    {
+        return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
+    }
+
+    if( ctx->state == CHACHAPOLY_STATE_AAD )
+    {
+        ret = chachapoly_pad_aad( ctx );
+        if( ret != 0 )
+            return( ret );
+    }
+    else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT )
+    {
+        ret = chachapoly_pad_ciphertext( ctx );
+        if( ret != 0 )
+            return( ret );
+    }
+
+    ctx->state = CHACHAPOLY_STATE_FINISHED;
+
+    /* The lengths of the AAD and ciphertext are processed by
+     * Poly1305 as the final 128-bit block, encoded as little-endian integers.
+     */
+    len_block[ 0] = (unsigned char)( ctx->aad_len       );
+    len_block[ 1] = (unsigned char)( ctx->aad_len >>  8 );
+    len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );
+    len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );
+    len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );
+    len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );
+    len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );
+    len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );
+    len_block[ 8] = (unsigned char)( ctx->ciphertext_len       );
+    len_block[ 9] = (unsigned char)( ctx->ciphertext_len >>  8 );
+    len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );
+    len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );
+    len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );
+    len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );
+    len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );
+    len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );
+
+    ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac );
+
+    return( ret );
+}
+
+static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
+                                     mbedtls_chachapoly_mode_t mode,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char *input,
+                                     unsigned char *output,
+                                     unsigned char tag[16] )
+{
+    int ret;
+
+    ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chachapoly_update( ctx, length, input, output );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chachapoly_finish( ctx, tag );
+
+cleanup:
+    return( ret );
+}
+
+int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
+                                        size_t length,
+                                        const unsigned char nonce[12],
+                                        const unsigned char *aad,
+                                        size_t aad_len,
+                                        const unsigned char *input,
+                                        unsigned char *output,
+                                        unsigned char tag[16] )
+{
+    CHACHAPOLY_VALIDATE_RET( ctx   != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+    CHACHAPOLY_VALIDATE_RET( tag   != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );
+
+    return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
+                                      length, nonce, aad, aad_len,
+                                      input, output, tag ) );
+}
+
+int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char tag[16],
+                                     const unsigned char *input,
+                                     unsigned char *output )
+{
+    int ret;
+    unsigned char check_tag[16];
+    size_t i;
+    int diff;
+    CHACHAPOLY_VALIDATE_RET( ctx   != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+    CHACHAPOLY_VALIDATE_RET( tag   != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );
+
+    if( ( ret = chachapoly_crypt_and_tag( ctx,
+                        MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
+                        aad, aad_len, input, output, check_tag ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
+        diff |= tag[i] ^ check_tag[i];
+
+    if( diff != 0 )
+    {
+        mbedtls_platform_zeroize( output, length );
+        return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_CHACHAPOLY_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const unsigned char test_key[1][32] =
+{
+    {
+        0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+        0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+        0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+        0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
+    }
+};
+
+static const unsigned char test_nonce[1][12] =
+{
+    {
+        0x07, 0x00, 0x00, 0x00,                         /* 32-bit common part */
+        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47  /* 64-bit IV */
+    }
+};
+
+static const unsigned char test_aad[1][12] =
+{
+    {
+        0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
+        0xc4, 0xc5, 0xc6, 0xc7
+    }
+};
+
+static const size_t test_aad_len[1] =
+{
+    12U
+};
+
+static const unsigned char test_input[1][114] =
+{
+    {
+        0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
+        0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
+        0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
+        0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
+        0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
+        0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
+        0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
+        0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
+        0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
+        0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
+        0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
+        0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
+        0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
+        0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
+        0x74, 0x2e
+    }
+};
+
+static const unsigned char test_output[1][114] =
+{
+    {
+        0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
+        0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
+        0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
+        0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
+        0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
+        0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
+        0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
+        0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
+        0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
+        0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
+        0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
+        0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
+        0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
+        0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
+        0x61, 0x16
+    }
+};
+
+static const size_t test_input_len[1] =
+{
+    114U
+};
+
+static const unsigned char test_mac[1][16] =
+{
+    {
+        0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
+        0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
+    }
+};
+
+#define ASSERT( cond, args )            \
+    do                                  \
+    {                                   \
+        if( ! ( cond ) )                \
+        {                               \
+            if( verbose != 0 )          \
+                mbedtls_printf args;    \
+                                        \
+            return( -1 );               \
+        }                               \
+    }                                   \
+    while( 0 )
+
+int mbedtls_chachapoly_self_test( int verbose )
+{
+    mbedtls_chachapoly_context ctx;
+    unsigned i;
+    int ret;
+    unsigned char output[200];
+    unsigned char mac[16];
+
+    for( i = 0U; i < 1U; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  ChaCha20-Poly1305 test %u ", i );
+
+        mbedtls_chachapoly_init( &ctx );
+
+        ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] );
+        ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) );
+
+        ret = mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                                  test_input_len[i],
+                                                  test_nonce[i],
+                                                  test_aad[i],
+                                                  test_aad_len[i],
+                                                  test_input[i],
+                                                  output,
+                                                  mac );
+
+        ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) );
+
+        ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ),
+                ( "failure (wrong output)\n" ) );
+
+        ASSERT( 0 == memcmp( mac, test_mac[i], 16U ),
+                ( "failure (wrong MAC)\n" ) );
+
+        mbedtls_chachapoly_free( &ctx );
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_CHACHAPOLY_C */

+ 289 - 54
app/mbedtls/library/cipher.c

@@ -33,10 +33,15 @@
 
 #include "mbedtls/cipher.h"
 #include "mbedtls/cipher_internal.h"
+#include "mbedtls/platform_util.h"
 
 #include <stdlib.h>
 #include <string.h>
 
+#if defined(MBEDTLS_CHACHAPOLY_C)
+#include "mbedtls/chachapoly.h"
+#endif
+
 #if defined(MBEDTLS_GCM_C)
 #include "mbedtls/gcm.h"
 #endif
@@ -45,6 +50,10 @@
 #include "mbedtls/ccm.h"
 #endif
 
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
 #if defined(MBEDTLS_CMAC_C)
 #include "mbedtls/cmac.h"
 #endif
@@ -56,10 +65,30 @@
 #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;
+#define CIPHER_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
+#define CIPHER_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+/* Compare the contents of two buffers in constant time.
+ * Returns 0 if the contents are bitwise identical, otherwise returns
+ * a non-zero value.
+ * This is currently only used by GCM and ChaCha20+Poly1305.
+ */
+static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
+{
+    const unsigned char *p1 = (const unsigned char*) v1;
+    const unsigned char *p2 = (const unsigned char*) v2;
+    size_t i;
+    unsigned char diff;
+
+    for( diff = 0, i = 0; i < len; i++ )
+        diff |= p1[i] ^ p2[i];
+
+    return( (int)diff );
 }
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
 
 static int supported_init = 0;
 
@@ -126,6 +155,7 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_ciph
 
 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
 {
+    CIPHER_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
 }
 
@@ -137,7 +167,8 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
 #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
@@ -145,12 +176,13 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
     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 )
 {
-    if( NULL == cipher_info || NULL == ctx )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    if( cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
@@ -174,10 +206,16 @@ int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_in
     return( 0 );
 }
 
-int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
-        int key_bitlen, const mbedtls_operation_t operation )
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *key,
+                           int key_bitlen,
+                           const mbedtls_operation_t operation )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( key != NULL );
+    CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
+                         operation == MBEDTLS_DECRYPT );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
@@ -190,34 +228,34 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *k
     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,
-                ctx->key_bitlen );
+        return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
+                                                         ctx->key_bitlen ) );
     }
 
     if( MBEDTLS_DECRYPT == operation )
-        return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
-                ctx->key_bitlen );
+        return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
+                                                         ctx->key_bitlen ) );
 
     return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 }
 
 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
-                   const unsigned char *iv, size_t iv_len )
+                           const unsigned char *iv,
+                           size_t iv_len )
 {
     size_t actual_iv_size;
-    if( NULL == ctx || NULL == ctx->cipher_info )
-        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    else if( NULL == iv && iv_len != 0  )
-        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-    if( NULL == iv && iv_len == 0 )
-        ctx->iv_size = 0;
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     /* avoid buffer overflow in ctx->iv */
     if( iv_len > MBEDTLS_MAX_IV_LENGTH )
@@ -233,6 +271,19 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
         if( actual_iv_size > iv_len )
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
+
+#if defined(MBEDTLS_CHACHA20_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
+    {
+        if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
+                                           iv,
+                                           0U ) ) /* Initial counter value */
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+    }
+#endif
+
     if ( actual_iv_size != 0 )
     {
         memcpy( ctx->iv, iv, actual_iv_size );
@@ -244,7 +295,8 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
 
 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     ctx->unprocessed_len = 0;
@@ -252,33 +304,60 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
     return( 0 );
 }
 
-#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
                       const unsigned char *ad, size_t ad_len )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
+#if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
-        return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
-                           ctx->iv, ctx->iv_size, ad, ad_len );
+        return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
+                                    ctx->iv, ctx->iv_size, ad, ad_len ) );
+    }
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        int result;
+        mbedtls_chachapoly_mode_t mode;
+
+        mode = ( ctx->operation == MBEDTLS_ENCRYPT )
+                ? MBEDTLS_CHACHAPOLY_ENCRYPT
+                : MBEDTLS_CHACHAPOLY_DECRYPT;
+
+        result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                                        ctx->iv,
+                                                        mode );
+        if ( result != 0 )
+            return( result );
+
+        return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                               ad, ad_len ) );
     }
+#endif
 
     return( 0 );
 }
-#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
 
 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
                    size_t ilen, unsigned char *output, size_t *olen )
 {
     int ret;
-    size_t block_size = 0;
+    size_t block_size;
 
-    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
-    {
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-    }
 
     *olen = 0;
     block_size = mbedtls_cipher_get_block_size( ctx );
@@ -303,14 +382,23 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
     if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
     {
         *olen = ilen;
-        return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
-                           output );
+        return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
+                                    output ) );
+    }
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
+    {
+        *olen = ilen;
+        return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                           ilen, input, output ) );
     }
 #endif
 
     if ( 0 == block_size )
     {
-        return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+        return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
     }
 
     if( input == output &&
@@ -373,7 +461,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
         {
             if( 0 == block_size )
             {
-                return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
+                return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
             }
 
             /* Encryption: only cache partial blocks
@@ -429,6 +517,21 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
     }
 #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 )
     {
@@ -445,6 +548,27 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
     }
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
+    {
+        if( ctx->unprocessed_len > 0 ) {
+            /* We can only process an entire data unit at a time. */
+            return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+        }
+
+        ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
+                ctx->operation, ilen, ctx->iv, input, output );
+        if( ret != 0 )
+        {
+            return( ret );
+        }
+
+        *olen = ilen;
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
 #if defined(MBEDTLS_CIPHER_MODE_STREAM)
     if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
     {
@@ -638,19 +762,30 @@ static int get_no_padding( unsigned char *input, size_t input_len,
 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
                    unsigned char *output, size_t *olen )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     *olen = 0;
 
     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_XTS == ctx->cipher_info->mode ||
         MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
     {
         return( 0 );
     }
 
+    if ( ( MBEDTLS_CIPHER_CHACHA20          == ctx->cipher_info->type ) ||
+         ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
+    {
+        return( 0 );
+    }
+
     if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
     {
         if( ctx->unprocessed_len != 0 )
@@ -700,8 +835,8 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
 
         /* Set output size for decryption */
         if( MBEDTLS_DECRYPT == ctx->operation )
-            return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
-                                     olen );
+            return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
+                                      olen ) );
 
         /* Set output size for encryption */
         *olen = mbedtls_cipher_get_block_size( ctx );
@@ -715,10 +850,12 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
 }
 
 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
-int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode )
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+                                     mbedtls_cipher_padding_t mode )
 {
-    if( NULL == ctx ||
-        MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+
+    if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
     {
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
@@ -762,18 +899,35 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_ciph
 }
 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
 
-#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
                       unsigned char *tag, size_t tag_len )
 {
-    if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( ctx->cipher_info == NULL )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
     if( MBEDTLS_ENCRYPT != ctx->operation )
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
+#if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
-        return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len );
+        return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
+                                    tag, tag_len ) );
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        /* Don't allow truncated MAC for Poly1305 */
+        if ( tag_len != 16U )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+        return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                           tag ) );
+    }
+#endif
 
     return( 0 );
 }
@@ -781,20 +935,22 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
                       const unsigned char *tag, size_t tag_len )
 {
+    unsigned char check_tag[16];
     int ret;
 
-    if( NULL == ctx || NULL == ctx->cipher_info ||
-        MBEDTLS_DECRYPT != ctx->operation )
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if( MBEDTLS_DECRYPT != ctx->operation )
     {
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
 
+#if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
-        unsigned char check_tag[16];
-        size_t i;
-        int diff;
-
         if( tag_len > sizeof( check_tag ) )
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
@@ -805,18 +961,38 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
         }
 
         /* Check the tag in "constant-time" */
-        for( diff = 0, i = 0; i < tag_len; i++ )
-            diff |= tag[i] ^ check_tag[i];
+        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+            return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        /* Don't allow truncated MAC for Poly1305 */
+        if ( tag_len != sizeof( check_tag ) )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
-        if( diff != 0 )
+        ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                                     check_tag );
+        if ( ret != 0 )
+        {
+            return( ret );
+        }
+
+        /* Check the tag in "constant-time" */
+        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
 
         return( 0 );
     }
+#endif /* MBEDTLS_CHACHAPOLY_C */
 
     return( 0 );
 }
-#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
 
 /*
  * Packet-oriented wrapper for non-AEAD modes
@@ -829,6 +1005,12 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
     int ret;
     size_t finish_olen;
 
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+
     if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
         return( ret );
 
@@ -857,6 +1039,14 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
                          unsigned char *output, size_t *olen,
                          unsigned char *tag, size_t tag_len )
 {
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
@@ -875,6 +1065,21 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
                                      tag, tag_len ) );
     }
 #endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        /* ChachaPoly has fixed length nonce and MAC (tag) */
+        if ( ( iv_len != ctx->cipher_info->iv_size ) ||
+             ( tag_len != 16U ) )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        *olen = ilen;
+        return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
+                                ilen, iv, ad, ad_len, input, output, tag ) );
+    }
+#endif /* MBEDTLS_CHACHAPOLY_C */
 
     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
 }
@@ -889,6 +1094,14 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
                          unsigned char *output, size_t *olen,
                          const unsigned char *tag, size_t tag_len )
 {
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
@@ -921,6 +1134,28 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
         return( ret );
     }
 #endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        int ret;
+
+        /* ChachaPoly has fixed length nonce and MAC (tag) */
+        if ( ( iv_len != ctx->cipher_info->iv_size ) ||
+             ( tag_len != 16U ) )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        *olen = ilen;
+        ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
+                                iv, ad, ad_len, tag, input, output );
+
+        if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+
+        return( ret );
+    }
+#endif /* MBEDTLS_CHACHAPOLY_C */
 
     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
 }

File diff suppressed because it is too large
+ 813 - 0
app/mbedtls/library/cipher_wrap.c


+ 16 - 20
app/mbedtls/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 @@ static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
     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 @@ static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
         goto exit;
 
 exit:
-    mbedtls_zeroize( L, sizeof( L ) );
+    mbedtls_platform_zeroize( L, sizeof( L ) );
 
     return( ret );
 }
@@ -238,7 +234,7 @@ int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
 
     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 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
     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 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
 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 @@ int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
 
     /* 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 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
                                output );
 
 exit:
-    mbedtls_zeroize( int_key, sizeof( int_key ) );
+    mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
 
     return( ret );
 }

+ 150 - 88
app/mbedtls/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
  */
@@ -66,56 +62,6 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
 #endif
 }
 
-/*
- * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
- * NIST tests to succeed (which require known length fixed entropy)
- */
-int mbedtls_ctr_drbg_seed_entropy_len(
-                   mbedtls_ctr_drbg_context *ctx,
-                   int (*f_entropy)(void *, unsigned char *, size_t),
-                   void *p_entropy,
-                   const unsigned char *custom,
-                   size_t len,
-                   size_t entropy_len )
-{
-    int ret;
-    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
-
-    memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
-
-    mbedtls_aes_init( &ctx->aes_ctx );
-
-    ctx->f_entropy = f_entropy;
-    ctx->p_entropy = p_entropy;
-
-    ctx->entropy_len = entropy_len;
-    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
-
-    /*
-     * Initialize with an empty key
-     */
-    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
-    {
-        return( ret );
-    }
-
-    if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
-    {
-        return( ret );
-    }
-    return( 0 );
-}
-
-int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
-                   int (*f_entropy)(void *, unsigned char *, size_t),
-                   void *p_entropy,
-                   const unsigned char *custom,
-                   size_t len )
-{
-    return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
-                                       MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
-}
-
 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
 {
     if( ctx == NULL )
@@ -125,7 +71,7 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
     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,21 +191,29 @@ exit:
     /*
     * 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 );
 }
 
+/* CTR_DRBG_Update (SP 800-90A &sect;10.2.1.2)
+ * ctr_drbg_update_internal(ctx, provided_data)
+ * implements
+ * CTR_DRBG_Update(provided_data, Key, V)
+ * with inputs and outputs
+ *   ctx->aes_ctx = Key
+ *   ctx->counter = V
+ */
 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
                               const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
 {
@@ -299,10 +253,22 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
     memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
 
 exit:
-    mbedtls_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
     return( ret );
 }
 
+/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
+ * mbedtls_ctr_drbg_update(ctx, additional, add_len)
+ * implements
+ * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
+ *                      security_strength) -> initial_working_state
+ * with inputs
+ *   ctx->counter = all-bits-0
+ *   ctx->aes_ctx = context from all-bits-0 key
+ *   additional[:add_len] = entropy_input || nonce || personalization_string
+ * and with outputs
+ *   ctx = initial_working_state
+ */
 int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
                                  const unsigned char *additional,
                                  size_t add_len )
@@ -319,11 +285,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
         goto exit;
 
 exit:
-    mbedtls_zeroize( add_input, sizeof( add_input ) );
+    mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
     return( ret );
 }
 
-/* Deprecated function, kept for backward compatibility. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
                               const unsigned char *additional,
                               size_t add_len )
@@ -334,7 +300,20 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
         add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
     (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
 }
-
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
+ * mbedtls_ctr_drbg_reseed(ctx, additional, len)
+ * implements
+ * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
+ *                -> new_working_state
+ * with inputs
+ *   ctx contains working_state
+ *   additional[:len] = additional_input
+ * and entropy_input comes from calling ctx->f_entropy
+ * and with output
+ *   ctx contains new_working_state
+ */
 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
                      const unsigned char *additional, size_t len )
 {
@@ -382,10 +361,86 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
     ctx->reseed_counter = 1;
 
 exit:
-    mbedtls_zeroize( seed, sizeof( seed ) );
+    mbedtls_platform_zeroize( seed, sizeof( seed ) );
     return( ret );
 }
 
+/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
+ * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
+ * implements
+ * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
+ *                      security_strength) -> initial_working_state
+ * with inputs
+ *   custom[:len] = nonce || personalization_string
+ * where entropy_input comes from f_entropy for ctx->entropy_len bytes
+ * and with outputs
+ *   ctx = initial_working_state
+ */
+int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
+                           int (*f_entropy)(void *, unsigned char *, size_t),
+                           void *p_entropy,
+                           const unsigned char *custom,
+                           size_t len )
+{
+    int ret;
+    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
+
+    memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
+
+    mbedtls_aes_init( &ctx->aes_ctx );
+
+    ctx->f_entropy = f_entropy;
+    ctx->p_entropy = p_entropy;
+
+    if( ctx->entropy_len == 0 )
+        ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
+    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
+
+    /*
+     * Initialize with an empty key
+     */
+    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
+    {
+        return( ret );
+    }
+    return( 0 );
+}
+
+/* Backward compatibility wrapper */
+int mbedtls_ctr_drbg_seed_entropy_len(
+    mbedtls_ctr_drbg_context *ctx,
+    int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
+    const unsigned char *custom, size_t len,
+    size_t entropy_len )
+{
+    mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
+    return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
+}
+
+/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
+ * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
+ * implements
+ * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
+ *                -> working_state_after_reseed
+ *                if required, then
+ * CTR_DRBG_Generate(working_state_after_reseed,
+ *                   requested_number_of_bits, additional_input)
+ *                -> status, returned_bits, new_working_state
+ * with inputs
+ *   ctx contains working_state
+ *   requested_number_of_bits = 8 * output_len
+ *   additional[:add_len] = additional_input
+ * and entropy_input comes from calling ctx->f_entropy
+ * and with outputs
+ *   status = SUCCESS (this function does the reseed internally)
+ *   returned_bits = output[:output_len]
+ *   ctx contains new_working_state
+ */
 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
                               unsigned char *output, size_t output_len,
                               const unsigned char *additional, size_t add_len )
@@ -455,8 +510,8 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
     ctx->reseed_counter++;
 
 exit:
-    mbedtls_zeroize( add_input, sizeof( add_input ) );
-    mbedtls_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
     return( 0 );
 }
 
@@ -499,7 +554,7 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
         ret = 0;
 
 exit:
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
     fclose( f );
     return( ret );
@@ -508,35 +563,36 @@ exit:
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
 {
     int ret = 0;
-    FILE *f;
+    FILE *f = NULL;
     size_t n;
     unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
+    unsigned char c;
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
         return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
 
-    fseek( f, 0, SEEK_END );
-    n = (size_t) ftell( f );
-    fseek( f, 0, SEEK_SET );
-
-    if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
+    n = fread( buf, 1, sizeof( buf ), f );
+    if( fread( &c, 1, 1, f ) != 0 )
     {
-        fclose( f );
-        return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+        ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
+        goto exit;
     }
-
-    if( fread( buf, 1, n, f ) != n )
+    if( n == 0 || ferror( f ) )
+    {
         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
-    else
-        ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
-
+        goto exit;
+    }
     fclose( f );
+    f = NULL;
 
-    mbedtls_zeroize( buf, sizeof( buf ) );
+    ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
 
+exit:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    if( f != NULL )
+        fclose( f );
     if( ret != 0 )
         return( ret );
-
     return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
 }
 #endif /* MBEDTLS_FS_IO */
@@ -617,8 +673,11 @@ int mbedtls_ctr_drbg_self_test( int verbose )
         mbedtls_printf( "  CTR_DRBG (PR = TRUE) : " );
 
     test_offset = 0;
-    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
-                                (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
+    mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+    CHK( mbedtls_ctr_drbg_seed( &ctx,
+                                ctr_drbg_self_test_entropy,
+                                (void *) entropy_source_pr,
+                                nonce_pers_pr, 16 ) );
     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
@@ -638,8 +697,11 @@ int mbedtls_ctr_drbg_self_test( int verbose )
     mbedtls_ctr_drbg_init( &ctx );
 
     test_offset = 0;
-    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
-                            (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
+    mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+    CHK( mbedtls_ctr_drbg_seed( &ctx,
+                                ctr_drbg_self_test_entropy,
+                                (void *) entropy_source_nopr,
+                                nonce_pers_nopr, 16 ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
     CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );

+ 88 - 6
app/mbedtls/library/debug.c

@@ -86,8 +86,13 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
     char str[DEBUG_BUF_SIZE];
     int ret;
 
-    if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold )
+    if( NULL == ssl              ||
+        NULL == ssl->conf        ||
+        NULL == ssl->conf->f_dbg ||
+        level > debug_threshold )
+    {
         return;
+    }
 
     va_start( argp, format );
 #if defined(_WIN32)
@@ -121,8 +126,13 @@ void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
 {
     char str[DEBUG_BUF_SIZE];
 
-    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+    if( NULL == ssl              ||
+        NULL == ssl->conf        ||
+        NULL == ssl->conf->f_dbg ||
+        level > debug_threshold )
+    {
         return;
+    }
 
     /*
      * With non-blocking I/O and examples that just retry immediately,
@@ -146,8 +156,13 @@ void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
     char txt[17];
     size_t i, idx = 0;
 
-    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+    if( NULL == ssl              ||
+        NULL == ssl->conf        ||
+        NULL == ssl->conf->f_dbg ||
+        level > debug_threshold )
+    {
         return;
+    }
 
     mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n",
               text, (unsigned int) len );
@@ -199,8 +214,13 @@ void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
 {
     char str[DEBUG_BUF_SIZE];
 
-    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+    if( NULL == ssl              ||
+        NULL == ssl->conf        ||
+        NULL == ssl->conf->f_dbg ||
+        level > debug_threshold )
+    {
         return;
+    }
 
     mbedtls_snprintf( str, sizeof( str ), "%s(X)", text );
     mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X );
@@ -219,8 +239,14 @@ void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
     int j, k, zeros = 1;
     size_t i, n, idx = 0;
 
-    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold )
+    if( NULL == ssl              ||
+        NULL == ssl->conf        ||
+        NULL == ssl->conf->f_dbg ||
+        NULL == X                ||
+        level > debug_threshold )
+    {
         return;
+    }
 
     for( n = X->n - 1; n > 0; n-- )
         if( X->p[n] != 0 )
@@ -345,8 +371,14 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
     char str[DEBUG_BUF_SIZE];
     int i = 0;
 
-    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold )
+    if( NULL == ssl              ||
+        NULL == ssl->conf        ||
+        NULL == ssl->conf->f_dbg ||
+        NULL == crt              ||
+        level > debug_threshold )
+    {
         return;
+    }
 
     while( crt != NULL )
     {
@@ -365,4 +397,54 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if defined(MBEDTLS_ECDH_C)
+static void mbedtls_debug_printf_ecdh_internal( const mbedtls_ssl_context *ssl,
+                                                int level, const char *file,
+                                                int line,
+                                                const mbedtls_ecdh_context *ecdh,
+                                                mbedtls_debug_ecdh_attr attr )
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    const mbedtls_ecdh_context* ctx = ecdh;
+#else
+    const mbedtls_ecdh_context_mbed* ctx = &ecdh->ctx.mbed_ecdh;
+#endif
+
+    switch( attr )
+    {
+        case MBEDTLS_DEBUG_ECDH_Q:
+            mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Q",
+                                     &ctx->Q );
+            break;
+        case MBEDTLS_DEBUG_ECDH_QP:
+            mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Qp",
+                                     &ctx->Qp );
+            break;
+        case MBEDTLS_DEBUG_ECDH_Z:
+            mbedtls_debug_print_mpi( ssl, level, file, line, "ECDH: z",
+                                     &ctx->z );
+            break;
+        default:
+            break;
+    }
+}
+
+void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
+                                const char *file, int line,
+                                const mbedtls_ecdh_context *ecdh,
+                                mbedtls_debug_ecdh_attr attr )
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, attr );
+#else
+    switch( ecdh->var )
+    {
+        default:
+            mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh,
+                                                attr );
+    }
+#endif
+}
+#endif /* MBEDTLS_ECDH_C */
+
 #endif /* MBEDTLS_DEBUG_C */

+ 50 - 47
app/mbedtls/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)
  */
@@ -261,50 +257,57 @@ static const uint32_t RHs[16] =
 /*
  * Initial Permutation macro
  */
-#define DES_IP(X,Y)                                             \
-{                                                               \
-    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
-    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
-    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
-    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
-    Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF;                    \
-    T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T;                   \
-    X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF;                    \
-}
+#define DES_IP(X,Y)                                                       \
+    do                                                                    \
+    {                                                                     \
+        T = (((X) >>  4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T <<  4); \
+        T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
+        T = (((Y) >>  2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T <<  2); \
+        T = (((Y) >>  8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T <<  8); \
+        (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF;                    \
+        T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T;                 \
+        (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF;                    \
+    } while( 0 )
 
 /*
  * Final Permutation macro
  */
-#define DES_FP(X,Y)                                             \
-{                                                               \
-    X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF;                    \
-    T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T;                   \
-    Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF;                    \
-    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
-    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
-    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
-    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
-}
+#define DES_FP(X,Y)                                                       \
+    do                                                                    \
+    {                                                                     \
+        (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF;                    \
+        T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T;                 \
+        (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF;                    \
+        T = (((Y) >>  8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T <<  8); \
+        T = (((Y) >>  2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T <<  2); \
+        T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
+        T = (((X) >>  4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T <<  4); \
+    } while( 0 )
 
 /*
  * DES round macro
  */
-#define DES_ROUND(X,Y)                          \
-{                                               \
-    T = *SK++ ^ X;                              \
-    Y ^= SB8[ (T      ) & 0x3F ] ^              \
-         SB6[ (T >>  8) & 0x3F ] ^              \
-         SB4[ (T >> 16) & 0x3F ] ^              \
-         SB2[ (T >> 24) & 0x3F ];               \
-                                                \
-    T = *SK++ ^ ((X << 28) | (X >> 4));         \
-    Y ^= SB7[ (T      ) & 0x3F ] ^              \
-         SB5[ (T >>  8) & 0x3F ] ^              \
-         SB3[ (T >> 16) & 0x3F ] ^              \
-         SB1[ (T >> 24) & 0x3F ];               \
-}
-
-#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
+#define DES_ROUND(X,Y)                              \
+    do                                              \
+    {                                               \
+        T = *SK++ ^ (X);                            \
+        (Y) ^= SB8[ (T      ) & 0x3F ] ^            \
+               SB6[ (T >>  8) & 0x3F ] ^            \
+               SB4[ (T >> 16) & 0x3F ] ^            \
+               SB2[ (T >> 24) & 0x3F ];             \
+                                                    \
+        T = *SK++ ^ (((X) << 28) | ((X) >> 4));     \
+        (Y) ^= SB7[ (T      ) & 0x3F ] ^            \
+               SB5[ (T >>  8) & 0x3F ] ^            \
+               SB3[ (T >> 16) & 0x3F ] ^            \
+               SB1[ (T >> 24) & 0x3F ];             \
+    } while( 0 )
+
+#define SWAP(a,b)                                       \
+    do                                                  \
+    {                                                   \
+        uint32_t t = (a); (a) = (b); (b) = t; t = 0;    \
+    } while( 0 )
 
 void mbedtls_des_init( mbedtls_des_context *ctx )
 {
@@ -316,7 +319,7 @@ void mbedtls_des_free( mbedtls_des_context *ctx )
     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 +332,7 @@ void mbedtls_des3_free( mbedtls_des3_context *ctx )
     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 +556,7 @@ int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
     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 +570,7 @@ int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
     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 +607,7 @@ int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
     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 +621,7 @@ int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
     uint32_t sk[96];
 
     des3_set3key( sk, ctx->sk, key );
-    mbedtls_zeroize( sk,  sizeof( sk ) );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }

Some files were not shown because too many files changed in this diff