Revert "Remove unused TLS, NET, and X.509 files"
This reverts commit a4308b29a42a00fcbffa7d6d041946feeddc0ce9.
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
new file mode 100644
index 0000000..736444b
--- /dev/null
+++ b/include/mbedtls/debug.h
@@ -0,0 +1,265 @@
+/**
+ * \file debug.h
+ *
+ * \brief Functions for controlling and providing debug output from the library.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_DEBUG_H
+#define MBEDTLS_DEBUG_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ssl.h"
+
+#if defined(MBEDTLS_ECP_C)
+#include "ecp.h"
+#endif
+
+#if defined(MBEDTLS_DEBUG_C)
+
+#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__
+
+#define MBEDTLS_SSL_DEBUG_MSG( level, args ) \
+ mbedtls_debug_print_msg( ssl, level, __FILE__, __LINE__, \
+ MBEDTLS_DEBUG_STRIP_PARENS args )
+
+#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) \
+ mbedtls_debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret )
+
+#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) \
+ mbedtls_debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len )
+
+#if defined(MBEDTLS_BIGNUM_C)
+#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) \
+ mbedtls_debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X )
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) \
+ mbedtls_debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X )
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \
+ 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 )
+#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 )
+#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 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Set the threshold error level to handle globally all debug output.
+ * Debug messages that have a level over the threshold value are
+ * discarded.
+ * (Default value: 0 = No debug )
+ *
+ * \param threshold theshold level of messages to filter on. Messages at a
+ * higher level will be discarded.
+ * - Debug levels
+ * - 0 No debug
+ * - 1 Error
+ * - 2 State change
+ * - 3 Informational
+ * - 4 Verbose
+ */
+void mbedtls_debug_set_threshold( int threshold );
+
+/**
+ * \brief Print a message to the debug output. This function is always used
+ * through the MBEDTLS_SSL_DEBUG_MSG() 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 message has occurred in
+ * \param line line number the message has occurred at
+ * \param format format specifier, in printf format
+ * \param ... variables used by the format specifier
+ *
+ * \attention This function is intended for INTERNAL usage within the
+ * library only.
+ */
+void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
+ const char *file, int line,
+ const char *format, ... );
+
+/**
+ * \brief Print the return value of a function to the debug output. This
+ * function is always used through the MBEDTLS_SSL_DEBUG_RET() 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 text the name of the function that returned the error
+ * \param ret the return code value
+ *
+ * \attention This function is intended for INTERNAL usage within the
+ * library only.
+ */
+void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
+ const char *file, int line,
+ const char *text, int ret );
+
+/**
+ * \brief Output a buffer of size len bytes to the debug output. This function
+ * is always used through the MBEDTLS_SSL_DEBUG_BUF() 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 text a name or label for the buffer being dumped. Normally the
+ * variable or buffer name
+ * \param buf the buffer to be outputted
+ * \param len length of the buffer
+ *
+ * \attention This function is intended for INTERNAL usage within the
+ * library only.
+ */
+void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
+ const char *file, int line, const char *text,
+ const unsigned char *buf, size_t len );
+
+#if defined(MBEDTLS_BIGNUM_C)
+/**
+ * \brief Print a MPI variable to the debug output. This function is always
+ * used through the MBEDTLS_SSL_DEBUG_MPI() 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 text a name or label for the MPI being output. Normally the
+ * variable name
+ * \param X the MPI variable
+ *
+ * \attention This function is intended for INTERNAL usage within the
+ * library only.
+ */
+void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
+ const char *file, int line,
+ const char *text, const mbedtls_mpi *X );
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+/**
+ * \brief Print an ECP point to the debug output. This function is always
+ * used through the MBEDTLS_SSL_DEBUG_ECP() 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 text a name or label for the ECP point being output. Normally the
+ * variable name
+ * \param X the ECP point
+ *
+ * \attention This function is intended for INTERNAL usage within the
+ * library only.
+ */
+void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
+ const char *file, int line,
+ const char *text, const mbedtls_ecp_point *X );
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Print a X.509 certificate structure to the debug output. This
+ * function is always used through the MBEDTLS_SSL_DEBUG_CRT() 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 text a name or label for the certificate being output
+ * \param crt X.509 certificate structure
+ *
+ * \attention This function is intended for INTERNAL usage within the
+ * library only.
+ */
+void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
+ const char *file, int line,
+ 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
+
+#endif /* debug.h */
+
diff --git a/include/mbedtls/net.h b/include/mbedtls/net.h
new file mode 100644
index 0000000..8cead58
--- /dev/null
+++ b/include/mbedtls/net.h
@@ -0,0 +1,37 @@
+/**
+ * \file net.h
+ *
+ * \brief Deprecated header file that includes net_sockets.h
+ *
+ * \deprecated Superseded by mbedtls/net_sockets.h
+ */
+/*
+ * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#include "net_sockets.h"
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
new file mode 100644
index 0000000..4c7ef00
--- /dev/null
+++ b/include/mbedtls/net_sockets.h
@@ -0,0 +1,271 @@
+/**
+ * \file net_sockets.h
+ *
+ * \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
+ * 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_NET_SOCKETS_H
+#define MBEDTLS_NET_SOCKETS_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ssl.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */
+#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */
+#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */
+#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */
+#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */
+#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */
+#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */
+#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */
+#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
+
+/**
+ * Wrapper type for sockets.
+ *
+ * Currently backed by just a file descriptor, but might be more in the future
+ * (eg two file descriptors for combined IPv4 + IPv6 support, or additional
+ * structures for hand-made UDP demultiplexing).
+ */
+typedef struct mbedtls_net_context
+{
+ int fd; /**< The underlying file descriptor */
+}
+mbedtls_net_context;
+
+/**
+ * \brief Initialize a context
+ * Just makes the context ready to be used or freed safely.
+ *
+ * \param ctx Context to initialize
+ */
+void mbedtls_net_init( mbedtls_net_context *ctx );
+
+/**
+ * \brief Initiate a connection with host:port in the given protocol
+ *
+ * \param ctx Socket to use
+ * \param host Host to connect to
+ * \param port Port to connect to
+ * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP
+ *
+ * \return 0 if successful, or one of:
+ * MBEDTLS_ERR_NET_SOCKET_FAILED,
+ * MBEDTLS_ERR_NET_UNKNOWN_HOST,
+ * MBEDTLS_ERR_NET_CONNECT_FAILED
+ *
+ * \note Sets the socket in connected mode even with UDP.
+ */
+int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto );
+
+/**
+ * \brief Create a receiving socket on bind_ip:port in the chosen
+ * protocol. If bind_ip == NULL, all interfaces are bound.
+ *
+ * \param ctx Socket to use
+ * \param bind_ip IP to bind to, can be NULL
+ * \param port Port number to use
+ * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP
+ *
+ * \return 0 if successful, or one of:
+ * MBEDTLS_ERR_NET_SOCKET_FAILED,
+ * MBEDTLS_ERR_NET_BIND_FAILED,
+ * MBEDTLS_ERR_NET_LISTEN_FAILED
+ *
+ * \note Regardless of the protocol, opens the sockets and binds it.
+ * In addition, make the socket listening if protocol is TCP.
+ */
+int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto );
+
+/**
+ * \brief Accept a connection from a remote client
+ *
+ * \param bind_ctx Relevant socket
+ * \param client_ctx Will contain the connected client socket
+ * \param client_ip Will contain the client IP address, can be NULL
+ * \param buf_size Size of the client_ip buffer
+ * \param ip_len Will receive the size of the client IP written,
+ * can be NULL if client_ip is null
+ *
+ * \return 0 if successful, or
+ * MBEDTLS_ERR_NET_ACCEPT_FAILED, or
+ * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
+ * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
+ * non-blocking and accept() would block.
+ */
+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
+ *
+ * \param ctx Socket to set
+ *
+ * \return 0 if successful, or a non-zero error code
+ */
+int mbedtls_net_set_block( mbedtls_net_context *ctx );
+
+/**
+ * \brief Set the socket non-blocking
+ *
+ * \param ctx Socket to set
+ *
+ * \return 0 if successful, or a non-zero error code
+ */
+int mbedtls_net_set_nonblock( mbedtls_net_context *ctx );
+
+/**
+ * \brief Portable usleep helper
+ *
+ * \param usec Amount of microseconds to sleep
+ *
+ * \note Real amount of time slept will not be less than
+ * select()'s timeout granularity (typically, 10ms).
+ */
+void mbedtls_net_usleep( unsigned long usec );
+
+/**
+ * \brief Read at most 'len' characters. If no error occurs,
+ * the actual amount read is returned.
+ *
+ * \param ctx Socket
+ * \param buf The buffer to write to
+ * \param len Maximum length of the buffer
+ *
+ * \return the number of bytes received,
+ * or a non-zero error code; with a non-blocking socket,
+ * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block.
+ */
+int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len );
+
+/**
+ * \brief Write at most 'len' characters. If no error occurs,
+ * the actual amount read is returned.
+ *
+ * \param ctx Socket
+ * \param buf The buffer to read from
+ * \param len The length of the buffer
+ *
+ * \return the number of bytes sent,
+ * or a non-zero error code; with a non-blocking socket,
+ * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block.
+ */
+int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
+
+/**
+ * \brief Read at most 'len' characters, blocking for at most
+ * 'timeout' seconds. If no error occurs, the actual amount
+ * read is returned.
+ *
+ * \param ctx Socket
+ * \param buf The buffer to write to
+ * \param len Maximum length of the buffer
+ * \param timeout Maximum number of milliseconds to wait for data
+ * 0 means no timeout (wait forever)
+ *
+ * \return the number of bytes received,
+ * or a non-zero error code:
+ * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *
+ * \note This function will block (until data becomes available or
+ * timeout is reached) even if the socket is set to
+ * non-blocking. Handling timeouts with non-blocking reads
+ * requires a different strategy.
+ */
+int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
+ uint32_t timeout );
+
+/**
+ * \brief Gracefully shutdown the connection and free associated data
+ *
+ * \param ctx The context to free
+ */
+void mbedtls_net_free( mbedtls_net_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* net_sockets.h */
diff --git a/include/mbedtls/pkcs11.h b/include/mbedtls/pkcs11.h
new file mode 100644
index 0000000..02427dd
--- /dev/null
+++ b/include/mbedtls/pkcs11.h
@@ -0,0 +1,175 @@
+/**
+ * \file pkcs11.h
+ *
+ * \brief Wrapper for PKCS#11 library libpkcs11-helper
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_PKCS11_H
+#define MBEDTLS_PKCS11_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PKCS11_C)
+
+#include "x509_crt.h"
+
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Context for PKCS #11 private keys.
+ */
+typedef struct mbedtls_pkcs11_context
+{
+ pkcs11h_certificate_t pkcs11h_cert;
+ int len;
+} mbedtls_pkcs11_context;
+
+/**
+ * Initialize a mbedtls_pkcs11_context.
+ * (Just making memory references valid.)
+ */
+void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx );
+
+/**
+ * Fill in a mbed TLS certificate, based on the given PKCS11 helper certificate.
+ *
+ * \param cert X.509 certificate to fill
+ * \param pkcs11h_cert PKCS #11 helper certificate
+ *
+ * \return 0 on success.
+ */
+int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert );
+
+/**
+ * Set up a mbedtls_pkcs11_context storing the given certificate. Note that the
+ * mbedtls_pkcs11_context will take over control of the certificate, freeing it when
+ * done.
+ *
+ * \param priv_key Private key structure to fill.
+ * \param pkcs11_cert PKCS #11 helper certificate
+ *
+ * \return 0 on success
+ */
+int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
+ pkcs11h_certificate_t pkcs11_cert );
+
+/**
+ * Free the contents of the given private key context. Note that the structure
+ * itself is not freed.
+ *
+ * \param priv_key Private key structure to cleanup
+ */
+void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key );
+
+/**
+ * \brief Do an RSA private key decrypt, then remove the message
+ * padding
+ *
+ * \param ctx PKCS #11 context
+ * \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param olen will contain the plaintext length
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief Do a private RSA to sign a message digest
+ *
+ * \param ctx PKCS #11 context
+ * \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
+ * \param hashlen message digest length (for MBEDTLS_MD_NONE only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an MBEDTLS_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
+ int mode,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * SSL/TLS wrappers for PKCS#11 functions
+ */
+static inline int mbedtls_ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen,
+ const unsigned char *input, unsigned char *output,
+ size_t output_max_len )
+{
+ return mbedtls_pkcs11_decrypt( (mbedtls_pkcs11_context *) ctx, mode, olen, input, output,
+ output_max_len );
+}
+
+static inline int mbedtls_ssl_pkcs11_sign( void *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
+ const unsigned char *hash, unsigned char *sig )
+{
+ ((void) f_rng);
+ ((void) p_rng);
+ return mbedtls_pkcs11_sign( (mbedtls_pkcs11_context *) ctx, mode, md_alg,
+ hashlen, hash, sig );
+}
+
+static inline size_t mbedtls_ssl_pkcs11_key_len( void *ctx )
+{
+ return ( (mbedtls_pkcs11_context *) ctx )->len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_PKCS11_C */
+
+#endif /* MBEDTLS_PKCS11_H */
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
new file mode 100644
index 0000000..135be05
--- /dev/null
+++ b/include/mbedtls/ssl.h
@@ -0,0 +1,3494 @@
+/**
+ * \file ssl.h
+ *
+ * \brief SSL/TLS functions.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SSL_H
+#define MBEDTLS_SSL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+#include "ecp.h"
+
+#include "ssl_ciphersuites.h"
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#include "x509_crt.h"
+#include "x509_crl.h"
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+#include "dhm.h"
+#endif
+
+#if defined(MBEDTLS_ECDH_C)
+#include "ecdh.h"
+#endif
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library"
+#endif
+
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set"
+#endif
+
+#include "zlib.h"
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME)
+#include "platform_time.h"
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+/*
+ * SSL Error codes
+ */
+#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE -0x7080 /**< The requested feature is not available. */
+#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA -0x7100 /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_SSL_INVALID_MAC -0x7180 /**< Verification of the message MAC failed. */
+#define MBEDTLS_ERR_SSL_INVALID_RECORD -0x7200 /**< An invalid SSL record was received. */
+#define MBEDTLS_ERR_SSL_CONN_EOF -0x7280 /**< The connection indicated an EOF. */
+#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER -0x7300 /**< An unknown cipher was received. */
+#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN -0x7380 /**< The server has no ciphersuites in common with the client. */
+#define MBEDTLS_ERR_SSL_NO_RNG -0x7400 /**< No RNG was provided to the SSL module. */
+#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 /**< No client certification received from the client, but required by the authentication mode. */
+#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE -0x7500 /**< Our own certificate(s) is/are too large to send in an SSL message. */
+#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED -0x7580 /**< The own certificate is not set, but needed by the server. */
+#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED -0x7600 /**< The own private key or pre-shared key is not set, but needed. */
+#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED -0x7680 /**< No CA Chain is set, but required to operate. */
+#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE -0x7700 /**< An unexpected message was received from our peer. */
+#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 /**< A fatal alert message was received from our peer. */
+#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED -0x7800 /**< Verification of our peer failed. */
+#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY -0x7880 /**< The peer notified us that the connection is going to be closed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO -0x7900 /**< Processing of the ClientHello handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO -0x7980 /**< Processing of the ServerHello handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE -0x7A00 /**< Processing of the Certificate handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -0x7A80 /**< Processing of the CertificateRequest handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0x7B00 /**< Processing of the ServerKeyExchange handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0x7B80 /**< Processing of the ServerHelloDone handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0x7C00 /**< Processing of the ClientKeyExchange handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -0x7C80 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -0x7D00 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0x7D80 /**< Processing of the CertificateVerify handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 /**< Processing of the ChangeCipherSpec handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED -0x7E80 /**< Processing of the Finished handshake message failed. */
+#define MBEDTLS_ERR_SSL_ALLOC_FAILED -0x7F00 /**< Memory allocation failed */
+#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -0x7F80 /**< Hardware acceleration function returned with error */
+#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 /**< Hardware acceleration function skipped / left alone data */
+#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED -0x6F00 /**< Processing of the compression / decompression failed */
+#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION -0x6E80 /**< Handshake protocol not within min/max boundaries */
+#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 /**< Processing of the NewSessionTicket handshake message failed. */
+#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 /**< Session ticket has expired. */
+#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */
+#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 /**< Unknown identity received (eg, PSK identity) */
+#define MBEDTLS_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */
+#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */
+#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */
+#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */
+#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */
+#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */
+#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 /**< No data of requested type currently available on underlying transport. */
+#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */
+#define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */
+#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */
+#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */
+#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */
+#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */
+#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */
+#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */
+#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */
+#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */
+
+/*
+ * Various constants
+ */
+#define MBEDTLS_SSL_MAJOR_VERSION_3 3
+#define MBEDTLS_SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */
+#define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */
+#define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */
+#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */
+
+#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */
+#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */
+
+#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */
+
+/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c
+ * NONE must be zero so that memset()ing structure to zero works */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_512 1 /*!< MaxFragmentLength 2^9 */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */
+
+#define MBEDTLS_SSL_IS_CLIENT 0
+#define MBEDTLS_SSL_IS_SERVER 1
+
+#define MBEDTLS_SSL_IS_NOT_FALLBACK 0
+#define MBEDTLS_SSL_IS_FALLBACK 1
+
+#define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0
+#define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1
+
+#define MBEDTLS_SSL_ETM_DISABLED 0
+#define MBEDTLS_SSL_ETM_ENABLED 1
+
+#define MBEDTLS_SSL_COMPRESS_NULL 0
+#define MBEDTLS_SSL_COMPRESS_DEFLATE 1
+
+#define MBEDTLS_SSL_VERIFY_NONE 0
+#define MBEDTLS_SSL_VERIFY_OPTIONAL 1
+#define MBEDTLS_SSL_VERIFY_REQUIRED 2
+#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */
+
+#define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0
+#define MBEDTLS_SSL_SECURE_RENEGOTIATION 1
+
+#define MBEDTLS_SSL_RENEGOTIATION_DISABLED 0
+#define MBEDTLS_SSL_RENEGOTIATION_ENABLED 1
+
+#define MBEDTLS_SSL_ANTI_REPLAY_DISABLED 0
+#define MBEDTLS_SSL_ANTI_REPLAY_ENABLED 1
+
+#define MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED -1
+#define MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT 16
+
+#define MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION 0
+#define MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION 1
+#define MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE 2
+
+#define MBEDTLS_SSL_TRUNC_HMAC_DISABLED 0
+#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED 1
+#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */
+
+#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0
+#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1
+
+#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED 0
+#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED 1
+
+#define MBEDTLS_SSL_ARC4_ENABLED 0
+#define MBEDTLS_SSL_ARC4_DISABLED 1
+
+#define MBEDTLS_SSL_PRESET_DEFAULT 0
+#define MBEDTLS_SSL_PRESET_SUITEB 2
+
+#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1
+#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0
+
+/*
+ * Default range for DTLS retransmission timer value, in milliseconds.
+ * RFC 6347 4.2.4.1 says from 1 second to 60 seconds.
+ */
+#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN 1000
+#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX 60000
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME)
+#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
+#endif
+
+/*
+ * Maximum fragment length in bytes,
+ * determines the size of each of the two internal I/O buffers.
+ *
+ * Note: the RFC defines the default size of SSL / TLS messages. If you
+ * change the value here, other clients / servers may not be able to
+ * communicate with you anymore. Only change this value if you control
+ * both sides of the connection and have it reduced at both sides, or
+ * if you're using the Max Fragment Length extension and you know all your
+ * peers are using it too!
+ */
+#if !defined(MBEDTLS_SSL_MAX_CONTENT_LEN)
+#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */
+#endif
+
+#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN)
+#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
+#endif
+
+#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN)
+#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
+#endif
+
+/*
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ */
+#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING)
+#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768
+#endif
+
+/* \} name SECTION: Module settings */
+
+/*
+ * Length of the verify data for secure renegotiation
+ */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 36
+#else
+#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 12
+#endif
+
+/*
+ * Signaling ciphersuite values (SCSV)
+ */
+#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */
+#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE 0x5600 /**< RFC 7507 section 2 */
+
+/*
+ * Supported Signature and Hash algorithms (For TLS 1.2)
+ * RFC 5246 section 7.4.1.4.1
+ */
+#define MBEDTLS_SSL_HASH_NONE 0
+#define MBEDTLS_SSL_HASH_MD5 1
+#define MBEDTLS_SSL_HASH_SHA1 2
+#define MBEDTLS_SSL_HASH_SHA224 3
+#define MBEDTLS_SSL_HASH_SHA256 4
+#define MBEDTLS_SSL_HASH_SHA384 5
+#define MBEDTLS_SSL_HASH_SHA512 6
+
+#define MBEDTLS_SSL_SIG_ANON 0
+#define MBEDTLS_SSL_SIG_RSA 1
+#define MBEDTLS_SSL_SIG_ECDSA 3
+
+/*
+ * Client Certificate Types
+ * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5
+ */
+#define MBEDTLS_SSL_CERT_TYPE_RSA_SIGN 1
+#define MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN 64
+
+/*
+ * Message, alert and handshake types
+ */
+#define MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC 20
+#define MBEDTLS_SSL_MSG_ALERT 21
+#define MBEDTLS_SSL_MSG_HANDSHAKE 22
+#define MBEDTLS_SSL_MSG_APPLICATION_DATA 23
+
+#define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1
+#define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2
+
+#define MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY 0 /* 0x00 */
+#define MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10 /* 0x0A */
+#define MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC 20 /* 0x14 */
+#define MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED 21 /* 0x15 */
+#define MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW 22 /* 0x16 */
+#define MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30 /* 0x1E */
+#define MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE 40 /* 0x28 */
+#define MBEDTLS_SSL_ALERT_MSG_NO_CERT 41 /* 0x29 */
+#define MBEDTLS_SSL_ALERT_MSG_BAD_CERT 42 /* 0x2A */
+#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT 43 /* 0x2B */
+#define MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED 44 /* 0x2C */
+#define MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED 45 /* 0x2D */
+#define MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN 46 /* 0x2E */
+#define MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER 47 /* 0x2F */
+#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA 48 /* 0x30 */
+#define MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED 49 /* 0x31 */
+#define MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR 50 /* 0x32 */
+#define MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR 51 /* 0x33 */
+#define MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION 60 /* 0x3C */
+#define MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */
+#define MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */
+#define MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */
+#define MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86 /* 0x56 */
+#define MBEDTLS_SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */
+#define MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */
+#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */
+#define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */
+#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */
+#define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */
+
+#define MBEDTLS_SSL_HS_HELLO_REQUEST 0
+#define MBEDTLS_SSL_HS_CLIENT_HELLO 1
+#define MBEDTLS_SSL_HS_SERVER_HELLO 2
+#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3
+#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4
+#define MBEDTLS_SSL_HS_CERTIFICATE 11
+#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12
+#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13
+#define MBEDTLS_SSL_HS_SERVER_HELLO_DONE 14
+#define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY 15
+#define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE 16
+#define MBEDTLS_SSL_HS_FINISHED 20
+
+/*
+ * TLS extensions
+ */
+#define MBEDTLS_TLS_EXT_SERVERNAME 0
+#define MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME 0
+
+#define MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH 1
+
+#define MBEDTLS_TLS_EXT_TRUNCATED_HMAC 4
+
+#define MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10
+#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS 11
+
+#define MBEDTLS_TLS_EXT_SIG_ALG 13
+
+#define MBEDTLS_TLS_EXT_ALPN 16
+
+#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */
+#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET 0x0017 /* 23 */
+
+#define MBEDTLS_TLS_EXT_SESSION_TICKET 35
+
+#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */
+
+#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01
+
+/*
+ * Size defines
+ */
+#if !defined(MBEDTLS_PSK_MAX_LEN)
+#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */
+#endif
+
+/* Dummy type used only for its size */
+union mbedtls_ssl_premaster_secret
+{
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+ unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+ unsigned char _pms_dhm[MBEDTLS_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+ unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]; /* RFC 4492 5.10 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+ unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 2 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+ unsigned char _pms_dhe_psk[4 + MBEDTLS_MPI_MAX_SIZE
+ + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 3 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+ unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 4 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+ unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES
+ + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */
+#endif
+};
+
+#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SSL state machine
+ */
+typedef enum
+{
+ MBEDTLS_SSL_HELLO_REQUEST,
+ MBEDTLS_SSL_CLIENT_HELLO,
+ MBEDTLS_SSL_SERVER_HELLO,
+ MBEDTLS_SSL_SERVER_CERTIFICATE,
+ MBEDTLS_SSL_SERVER_KEY_EXCHANGE,
+ MBEDTLS_SSL_CERTIFICATE_REQUEST,
+ MBEDTLS_SSL_SERVER_HELLO_DONE,
+ MBEDTLS_SSL_CLIENT_CERTIFICATE,
+ MBEDTLS_SSL_CLIENT_KEY_EXCHANGE,
+ MBEDTLS_SSL_CERTIFICATE_VERIFY,
+ MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC,
+ MBEDTLS_SSL_CLIENT_FINISHED,
+ MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC,
+ MBEDTLS_SSL_SERVER_FINISHED,
+ MBEDTLS_SSL_FLUSH_BUFFERS,
+ MBEDTLS_SSL_HANDSHAKE_WRAPUP,
+ MBEDTLS_SSL_HANDSHAKE_OVER,
+ MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET,
+ MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
+}
+mbedtls_ssl_states;
+
+/**
+ * \brief Callback type: send data on the network.
+ *
+ * \note That callback may be either blocking or non-blocking.
+ *
+ * \param ctx Context for the send callback (typically a file descriptor)
+ * \param buf Buffer holding the data to send
+ * \param len Length of the data to send
+ *
+ * \return The callback must return the number of bytes sent if any,
+ * or a non-zero error code.
+ * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE
+ * must be returned when the operation would block.
+ *
+ * \note The callback is allowed to send fewer bytes than requested.
+ * It must always return the number of bytes actually sent.
+ */
+typedef int mbedtls_ssl_send_t( void *ctx,
+ const unsigned char *buf,
+ size_t len );
+
+/**
+ * \brief Callback type: receive data from the network.
+ *
+ * \note That callback may be either blocking or non-blocking.
+ *
+ * \param ctx Context for the receive callback (typically a file
+ * descriptor)
+ * \param buf Buffer to write the received data to
+ * \param len Length of the receive buffer
+ *
+ * \return The callback must return the number of bytes received,
+ * or a non-zero error code.
+ * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ
+ * must be returned when the operation would block.
+ *
+ * \note The callback may receive fewer bytes than the length of the
+ * buffer. It must always return the number of bytes actually
+ * received and written to the buffer.
+ */
+typedef int mbedtls_ssl_recv_t( void *ctx,
+ unsigned char *buf,
+ size_t len );
+
+/**
+ * \brief Callback type: receive data from the network, with timeout
+ *
+ * \note That callback must block until data is received, or the
+ * timeout delay expires, or the operation is interrupted by a
+ * signal.
+ *
+ * \param ctx Context for the receive callback (typically a file descriptor)
+ * \param buf Buffer to write the received data to
+ * \param len Length of the receive buffer
+ * \param timeout Maximum nomber of millisecondes to wait for data
+ * 0 means no timeout (potentially waiting forever)
+ *
+ * \return The callback must return the number of bytes received,
+ * or a non-zero error code:
+ * \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ * \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *
+ * \note The callback may receive fewer bytes than the length of the
+ * buffer. It must always return the number of bytes actually
+ * received and written to the buffer.
+ */
+typedef int mbedtls_ssl_recv_timeout_t( void *ctx,
+ unsigned char *buf,
+ size_t len,
+ uint32_t timeout );
+/**
+ * \brief Callback type: set a pair of timers/delays to watch
+ *
+ * \param ctx Context pointer
+ * \param int_ms Intermediate delay in milliseconds
+ * \param fin_ms Final delay in milliseconds
+ * 0 cancels the current timer.
+ *
+ * \note This callback must at least store the necessary information
+ * for the associated \c mbedtls_ssl_get_timer_t callback to
+ * return correct information.
+ *
+ * \note If using a event-driven style of programming, an event must
+ * be generated when the final delay is passed. The event must
+ * cause a call to \c mbedtls_ssl_handshake() with the proper
+ * SSL context to be scheduled. Care must be taken to ensure
+ * that at most one such call happens at a time.
+ *
+ * \note Only one timer at a time must be running. Calling this
+ * function while a timer is running must cancel it. Cancelled
+ * timers must not generate any event.
+ */
+typedef void mbedtls_ssl_set_timer_t( void * ctx,
+ uint32_t int_ms,
+ uint32_t fin_ms );
+
+/**
+ * \brief Callback type: get status of timers/delays
+ *
+ * \param ctx Context pointer
+ *
+ * \return This callback must return:
+ * -1 if cancelled (fin_ms == 0),
+ * 0 if none of the delays have passed,
+ * 1 if only the intermediate delay has passed,
+ * 2 if the final delay has passed.
+ */
+typedef int mbedtls_ssl_get_timer_t( void * ctx );
+
+/* Defined below */
+typedef struct mbedtls_ssl_session mbedtls_ssl_session;
+typedef struct mbedtls_ssl_context mbedtls_ssl_context;
+typedef struct mbedtls_ssl_config mbedtls_ssl_config;
+
+/* Defined in ssl_internal.h */
+typedef struct mbedtls_ssl_transform mbedtls_ssl_transform;
+typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params;
+typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t;
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
+#endif
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
+#endif
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Callback type: start external signature operation.
+ *
+ * This callback is called during an SSL handshake to start
+ * a signature decryption operation using an
+ * external processor. The parameter \p cert contains
+ * the public key; it is up to the callback function to
+ * determine how to access the associated private key.
+ *
+ * This function typically sends or enqueues a request, and
+ * does not wait for the operation to complete. This allows
+ * the handshake step to be non-blocking.
+ *
+ * The parameters \p ssl and \p cert are guaranteed to remain
+ * valid throughout the handshake. On the other hand, this
+ * function must save the contents of \p hash if the value
+ * is needed for later processing, because the \p hash buffer
+ * is no longer valid after this function returns.
+ *
+ * This function may call mbedtls_ssl_set_async_operation_data()
+ * to store an operation context for later retrieval
+ * by the resume or cancel callback.
+ *
+ * \note For RSA signatures, this function must produce output
+ * that is consistent with PKCS#1 v1.5 in the same way as
+ * mbedtls_rsa_pkcs1_sign(). Before the private key operation,
+ * apply the padding steps described in RFC 8017, section 9.2
+ * "EMSA-PKCS1-v1_5" as follows.
+ * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5
+ * encoding, treating \p hash as the DigestInfo to be
+ * padded. In other words, apply EMSA-PKCS1-v1_5 starting
+ * from step 3, with `T = hash` and `tLen = hash_len`.
+ * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5
+ * encoding, treating \p hash as the hash to be encoded and
+ * padded. In other words, apply EMSA-PKCS1-v1_5 starting
+ * from step 2, with `digestAlgorithm` obtained by calling
+ * mbedtls_oid_get_oid_by_md() on \p md_alg.
+ *
+ * \note For ECDSA signatures, the output format is the DER encoding
+ * `Ecdsa-Sig-Value` defined in
+ * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4).
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified other than via
+ * mbedtls_ssl_set_async_operation_data().
+ * \param cert Certificate containing the public key.
+ * In simple cases, this is one of the pointers passed to
+ * mbedtls_ssl_conf_own_cert() when configuring the SSL
+ * connection. However, if other callbacks are used, this
+ * property may not hold. For example, if an SNI callback
+ * is registered with mbedtls_ssl_conf_sni(), then
+ * this callback determines what certificate is used.
+ * \param md_alg Hash algorithm.
+ * \param hash Buffer containing the hash. This buffer is
+ * no longer valid when the function returns.
+ * \param hash_len Size of the \c hash buffer in bytes.
+ *
+ * \return 0 if the operation was started successfully and the SSL
+ * stack should call the resume callback immediately.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ * was started successfully and the SSL stack should return
+ * immediately without calling the resume callback yet.
+ * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
+ * processor does not support this key. The SSL stack will
+ * use the private key object instead.
+ * \return Any other error indicates a fatal failure and is
+ * propagated up the call chain. The callback should
+ * use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
+ * use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ * directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *cert,
+ mbedtls_md_type_t md_alg,
+ const unsigned char *hash,
+ size_t hash_len );
+
+/**
+ * \brief Callback type: start external decryption operation.
+ *
+ * This callback is called during an SSL handshake to start
+ * an RSA decryption operation using an
+ * external processor. The parameter \p cert contains
+ * the public key; it is up to the callback function to
+ * determine how to access the associated private key.
+ *
+ * This function typically sends or enqueues a request, and
+ * does not wait for the operation to complete. This allows
+ * the handshake step to be non-blocking.
+ *
+ * The parameters \p ssl and \p cert are guaranteed to remain
+ * valid throughout the handshake. On the other hand, this
+ * function must save the contents of \p input if the value
+ * is needed for later processing, because the \p input buffer
+ * is no longer valid after this function returns.
+ *
+ * This function may call mbedtls_ssl_set_async_operation_data()
+ * to store an operation context for later retrieval
+ * by the resume or cancel callback.
+ *
+ * \warning RSA decryption as used in TLS is subject to a potential
+ * timing side channel attack first discovered by Bleichenbacher
+ * in 1998. This attack can be remotely exploitable
+ * in practice. To avoid this attack, you must ensure that
+ * if the callback performs an RSA decryption, the time it
+ * takes to execute and return the result does not depend
+ * on whether the RSA decryption succeeded or reported
+ * invalid padding.
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified other than via
+ * mbedtls_ssl_set_async_operation_data().
+ * \param cert Certificate containing the public key.
+ * In simple cases, this is one of the pointers passed to
+ * mbedtls_ssl_conf_own_cert() when configuring the SSL
+ * connection. However, if other callbacks are used, this
+ * property may not hold. For example, if an SNI callback
+ * is registered with mbedtls_ssl_conf_sni(), then
+ * this callback determines what certificate is used.
+ * \param input Buffer containing the input ciphertext. This buffer
+ * is no longer valid when the function returns.
+ * \param input_len Size of the \p input buffer in bytes.
+ *
+ * \return 0 if the operation was started successfully and the SSL
+ * stack should call the resume callback immediately.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ * was started successfully and the SSL stack should return
+ * immediately without calling the resume callback yet.
+ * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
+ * processor does not support this key. The SSL stack will
+ * use the private key object instead.
+ * \return Any other error indicates a fatal failure and is
+ * propagated up the call chain. The callback should
+ * use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
+ * use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ * directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *cert,
+ const unsigned char *input,
+ size_t input_len );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/**
+ * \brief Callback type: resume external operation.
+ *
+ * This callback is called during an SSL handshake to resume
+ * an external operation started by the
+ * ::mbedtls_ssl_async_sign_t or
+ * ::mbedtls_ssl_async_decrypt_t callback.
+ *
+ * This function typically checks the status of a pending
+ * request or causes the request queue to make progress, and
+ * does not wait for the operation to complete. This allows
+ * the handshake step to be non-blocking.
+ *
+ * This function may call mbedtls_ssl_get_async_operation_data()
+ * to retrieve an operation context set by the start callback.
+ * It may call mbedtls_ssl_set_async_operation_data() to modify
+ * this context.
+ *
+ * Note that when this function returns a status other than
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any
+ * resources associated with the operation.
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified other than via
+ * mbedtls_ssl_set_async_operation_data().
+ * \param output Buffer containing the output (signature or decrypted
+ * data) on success.
+ * \param output_len On success, number of bytes written to \p output.
+ * \param output_size Size of the \p output buffer in bytes.
+ *
+ * \return 0 if output of the operation is available in the
+ * \p output buffer.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ * is still in progress. Subsequent requests for progress
+ * on the SSL connection will call the resume callback
+ * again.
+ * \return Any other error means that the operation is aborted.
+ * The SSL handshake is aborted. The callback should
+ * use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
+ * use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ * directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl,
+ unsigned char *output,
+ size_t *output_len,
+ size_t output_size );
+
+/**
+ * \brief Callback type: cancel external operation.
+ *
+ * This callback is called if an SSL connection is closed
+ * while an asynchronous operation is in progress. Note that
+ * this callback is not called if the
+ * ::mbedtls_ssl_async_resume_t callback has run and has
+ * returned a value other than
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case
+ * the asynchronous operation has already completed.
+ *
+ * This function may call mbedtls_ssl_get_async_operation_data()
+ * to retrieve an operation context set by the start callback.
+ *
+ * \param ssl The SSL connection instance. It should not be
+ * modified.
+ */
+typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN 48
+#if defined(MBEDTLS_SHA256_C)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA256
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 32
+#elif defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA384
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 48
+#elif defined(MBEDTLS_SHA1_C)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA1
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 20
+#else
+/* This is already checked in check_config.h, but be sure. */
+#error "Bad configuration - need SHA-1, SHA-256 or SHA-512 enabled to compute digest of peer CRT."
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED &&
+ !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
+/*
+ * This structure is used for storing current session data.
+ */
+struct mbedtls_ssl_session
+{
+#if defined(MBEDTLS_HAVE_TIME)
+ mbedtls_time_t start; /*!< starting time */
+#endif
+ int ciphersuite; /*!< chosen ciphersuite */
+ int compression; /*!< chosen compression */
+ size_t id_len; /*!< session id length */
+ unsigned char id[32]; /*!< session identifier */
+ unsigned char master[48]; /*!< the master secret */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /*! The digest of the peer's end-CRT. This must be kept to detect CRT
+ * changes during renegotiation, mitigating the triple handshake attack. */
+ unsigned char *peer_cert_digest;
+ size_t peer_cert_digest_len;
+ mbedtls_md_type_t peer_cert_digest_type;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+ uint32_t verify_result; /*!< verification result */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ unsigned char *ticket; /*!< RFC 5077 session ticket */
+ size_t ticket_len; /*!< session ticket length */
+ uint32_t ticket_lifetime; /*!< ticket lifetime hint */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ int trunc_hmac; /*!< flag for truncated hmac activation */
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ int encrypt_then_mac; /*!< flag for EtM activation */
+#endif
+};
+
+/**
+ * SSL/TLS configuration to be shared between mbedtls_ssl_context structures.
+ */
+struct mbedtls_ssl_config
+{
+ /* Group items by size (largest first) to minimize padding overhead */
+
+ /*
+ * Pointers
+ */
+
+ const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version */
+
+ /** Callback for printing debug output */
+ void (*f_dbg)(void *, int, const char *, int, const char *);
+ void *p_dbg; /*!< context for the debug function */
+
+ /** Callback for getting (pseudo-)random numbers */
+ int (*f_rng)(void *, unsigned char *, size_t);
+ void *p_rng; /*!< context for the RNG function */
+
+ /** Callback to retrieve a session from the cache */
+ int (*f_get_cache)(void *, mbedtls_ssl_session *);
+ /** Callback to store a session into the cache */
+ int (*f_set_cache)(void *, const mbedtls_ssl_session *);
+ void *p_cache; /*!< context for cache callbacks */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ /** Callback for setting cert according to SNI extension */
+ int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
+ void *p_sni; /*!< context for SNI callback */
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ /** Callback to customize X.509 certificate chain verification */
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+ void *p_vrfy; /*!< context for X.509 verify calllback */
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+ /** Callback to retrieve PSK key from identity */
+ int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
+ void *p_psk; /*!< context for PSK callback */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+ /** Callback to create & write a cookie for ClientHello veirifcation */
+ int (*f_cookie_write)( void *, unsigned char **, unsigned char *,
+ const unsigned char *, size_t );
+ /** Callback to verify validity of a ClientHello cookie */
+ int (*f_cookie_check)( void *, const unsigned char *, size_t,
+ const unsigned char *, size_t );
+ void *p_cookie; /*!< context for the cookie callbacks */
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C)
+ /** Callback to create & write a session ticket */
+ int (*f_ticket_write)( void *, const mbedtls_ssl_session *,
+ unsigned char *, const unsigned char *, size_t *, uint32_t * );
+ /** Callback to parse a session ticket into a session structure */
+ int (*f_ticket_parse)( void *, mbedtls_ssl_session *, unsigned char *, size_t);
+ void *p_ticket; /*!< context for the ticket callbacks */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+ /** Callback to export key block and master secret */
+ int (*f_export_keys)( void *, const unsigned char *,
+ const unsigned char *, size_t, size_t, size_t );
+ void *p_export_keys; /*!< context for key export callback */
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */
+ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */
+ mbedtls_x509_crt *ca_chain; /*!< trusted CAs */
+ mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ mbedtls_x509_crt_ca_cb_t f_ca_cb;
+ void *p_ca_cb;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */
+ mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+ mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */
+ mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */
+ void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ const int *sig_hashes; /*!< allowed signature hashes */
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+ const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+ mbedtls_mpi dhm_P; /*!< prime modulus for DHM */
+ mbedtls_mpi dhm_G; /*!< generator for DHM */
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_key_handle_t psk_opaque; /*!< PSA key slot holding opaque PSK.
+ * This field should only be set via
+ * mbedtls_ssl_conf_psk_opaque().
+ * If either no PSK or a raw PSK have
+ * been configured, this has value \c 0. */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ unsigned char *psk; /*!< The raw pre-shared key. This field should
+ * only be set via mbedtls_ssl_conf_psk().
+ * If either no PSK or an opaque PSK
+ * have been configured, this has value NULL. */
+ size_t psk_len; /*!< The length of the raw pre-shared key.
+ * This field should only be set via
+ * mbedtls_ssl_conf_psk().
+ * Its value is non-zero if and only if
+ * \c psk is not \c NULL. */
+
+ unsigned char *psk_identity; /*!< The PSK identity for PSK negotiation.
+ * This field should only be set via
+ * mbedtls_ssl_conf_psk().
+ * This is set if and only if either
+ * \c psk or \c psk_opaque are set. */
+ size_t psk_identity_len;/*!< The length of PSK identity.
+ * This field should only be set via
+ * mbedtls_ssl_conf_psk().
+ * Its value is non-zero if and only if
+ * \c psk is not \c NULL or \c psk_opaque
+ * is not \c 0. */
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(MBEDTLS_SSL_ALPN)
+ const char **alpn_list; /*!< ordered list of protocols */
+#endif
+
+ /*
+ * Numerical settings (int then char)
+ */
+
+ uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint32_t hs_timeout_min; /*!< initial value of the handshake
+ retransmission timeout (ms) */
+ uint32_t hs_timeout_max; /*!< maximum value of the handshake
+ retransmission timeout (ms) */
+#endif
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ int renego_max_records; /*!< grace period for renegotiation */
+ unsigned char renego_period[8]; /*!< value of the record counters
+ that triggers renegotiation */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ unsigned int badmac_limit; /*!< limit of records with a bad MAC */
+#endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+ unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */
+#endif
+
+ unsigned char max_major_ver; /*!< max. major version used */
+ unsigned char max_minor_ver; /*!< max. minor version used */
+ unsigned char min_major_ver; /*!< min. major version used */
+ unsigned char min_minor_ver; /*!< min. minor version used */
+
+ /*
+ * Flags (bitfields)
+ */
+
+ unsigned int endpoint : 1; /*!< 0: client, 1: server */
+ unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */
+ unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */
+ /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */
+ unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */
+#if defined(MBEDTLS_ARC4_C)
+ unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */
+#endif
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ unsigned int mfl_code : 3; /*!< desired fragment length */
+#endif
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac? */
+#endif
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+ unsigned int extended_ms : 1; /*!< negotiate extended master secret? */
+#endif
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ unsigned int anti_replay : 1; /*!< detect and prevent replay? */
+#endif
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+ unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ unsigned int disable_renegotiation : 1; /*!< disable renegotiation? */
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ unsigned int trunc_hmac : 1; /*!< negotiate truncated hmac? */
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ unsigned int session_tickets : 1; /*!< use session tickets? */
+#endif
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+ unsigned int fallback : 1; /*!< is this a fallback? */
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+ unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in
+ Certificate Request messages? */
+#endif
+};
+
+
+struct mbedtls_ssl_context
+{
+ const mbedtls_ssl_config *conf; /*!< configuration information */
+
+ /*
+ * Miscellaneous
+ */
+ int state; /*!< SSL handshake: current state */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ int renego_status; /*!< Initial, in progress, pending? */
+ int renego_records_seen; /*!< Records since renego request, or with DTLS,
+ number of retransmissions of request if
+ renego_max_records is < 0 */
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+ int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */
+ int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ unsigned badmac_seen; /*!< records with a bad MAC received */
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ /** Callback to customize X.509 certificate chain verification */
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+ void *p_vrfy; /*!< context for X.509 verify callback */
+#endif
+
+ mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
+ mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
+ mbedtls_ssl_recv_timeout_t *f_recv_timeout;
+ /*!< Callback for network receive with timeout */
+
+ void *p_bio; /*!< context for I/O operations */
+
+ /*
+ * Session layer
+ */
+ mbedtls_ssl_session *session_in; /*!< current session data (in) */
+ mbedtls_ssl_session *session_out; /*!< current session data (out) */
+ mbedtls_ssl_session *session; /*!< negotiated session data */
+ mbedtls_ssl_session *session_negotiate; /*!< session data in negotiation */
+
+ mbedtls_ssl_handshake_params *handshake; /*!< params required only during
+ the handshake process */
+
+ /*
+ * Record layer transformations
+ */
+ mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */
+ mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */
+ mbedtls_ssl_transform *transform; /*!< negotiated transform params */
+ mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */
+
+ /*
+ * Timers
+ */
+ void *p_timer; /*!< context for the timer callbacks */
+
+ mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */
+ mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */
+
+ /*
+ * Record layer (incoming data)
+ */
+ unsigned char *in_buf; /*!< input buffer */
+ unsigned char *in_ctr; /*!< 64-bit incoming message counter
+ TLS: maintained by us
+ DTLS: read from peer */
+ unsigned char *in_hdr; /*!< start of record header */
+ unsigned char *in_len; /*!< two-bytes message length field */
+ unsigned char *in_iv; /*!< ivlen-byte IV */
+ unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */
+ unsigned char *in_offt; /*!< read offset in application data */
+
+ int in_msgtype; /*!< record header: message type */
+ size_t in_msglen; /*!< record header: message length */
+ size_t in_left; /*!< amount of data read so far */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint16_t in_epoch; /*!< DTLS epoch for incoming records */
+ size_t next_record_offset; /*!< offset of the next record in datagram
+ (equal to in_left if none) */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ uint64_t in_window_top; /*!< last validated record seq_num */
+ uint64_t in_window; /*!< bitmask for replay detection */
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+
+ size_t in_hslen; /*!< current handshake message length,
+ including the handshake header */
+ int nb_zero; /*!< # of 0-length encrypted messages */
+
+ int keep_current_message; /*!< drop or reuse current message
+ on next call to record layer? */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint8_t disable_datagram_packing; /*!< Disable packing multiple records
+ * within a single datagram. */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /*
+ * Record layer (outgoing data)
+ */
+ unsigned char *out_buf; /*!< output buffer */
+ unsigned char *out_ctr; /*!< 64-bit outgoing message counter */
+ unsigned char *out_hdr; /*!< start of record header */
+ unsigned char *out_len; /*!< two-bytes message length field */
+ unsigned char *out_iv; /*!< ivlen-byte IV */
+ unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */
+
+ int out_msgtype; /*!< record header: message type */
+ size_t out_msglen; /*!< record header: message length */
+ size_t out_left; /*!< amount of data not yet written */
+
+ unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ unsigned char *compress_buf; /*!< zlib data buffer */
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+ signed char split_done; /*!< current record already splitted? */
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+ /*
+ * PKI layer
+ */
+ int client_auth; /*!< flag for client auth. */
+
+ /*
+ * User settings
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ char *hostname; /*!< expected peer CN for verification
+ (and SNI if available) */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_ALPN)
+ const char *alpn_chosen; /*!< negotiated protocol */
+#endif /* MBEDTLS_SSL_ALPN */
+
+ /*
+ * Information for DTLS hello verify
+ */
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+ unsigned char *cli_id; /*!< transport-level ID of the client */
+ size_t cli_id_len; /*!< length of cli_id */
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
+
+ /*
+ * Secure renegotiation
+ */
+ /* needed to know when to send extension on server */
+ int secure_renegotiation; /*!< does peer support legacy or
+ secure renegotiation */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ size_t verify_data_len; /*!< length of verify data stored */
+ char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
+ char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+};
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+
+#define MBEDTLS_SSL_CHANNEL_OUTBOUND 0
+#define MBEDTLS_SSL_CHANNEL_INBOUND 1
+
+extern int (*mbedtls_ssl_hw_record_init)(mbedtls_ssl_context *ssl,
+ const unsigned char *key_enc, const unsigned char *key_dec,
+ size_t keylen,
+ const unsigned char *iv_enc, const unsigned char *iv_dec,
+ size_t ivlen,
+ const unsigned char *mac_enc, const unsigned char *mac_dec,
+ size_t maclen);
+extern int (*mbedtls_ssl_hw_record_activate)(mbedtls_ssl_context *ssl, int direction);
+extern int (*mbedtls_ssl_hw_record_reset)(mbedtls_ssl_context *ssl);
+extern int (*mbedtls_ssl_hw_record_write)(mbedtls_ssl_context *ssl);
+extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl);
+extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl);
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+/**
+ * \brief Return the name of the ciphersuite associated with the
+ * given ID
+ *
+ * \param ciphersuite_id SSL ciphersuite ID
+ *
+ * \return a string containing the ciphersuite name
+ */
+const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id );
+
+/**
+ * \brief Return the ID of the ciphersuite associated with the
+ * given name
+ *
+ * \param ciphersuite_name SSL ciphersuite name
+ *
+ * \return the ID with the ciphersuite or 0 if not found
+ */
+int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name );
+
+/**
+ * \brief Initialize an SSL context
+ * Just makes the context ready for mbedtls_ssl_setup() or
+ * mbedtls_ssl_free()
+ *
+ * \param ssl SSL context
+ */
+void mbedtls_ssl_init( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Set up an SSL context for use
+ *
+ * \note No copy of the configuration context is made, it can be
+ * shared by many mbedtls_ssl_context structures.
+ *
+ * \warning The conf structure will be accessed during the session.
+ * It must not be modified or freed as long as the session
+ * is active.
+ *
+ * \warning This function must be called exactly once per context.
+ * Calling mbedtls_ssl_setup again is not supported, even
+ * if no session is active.
+ *
+ * \param ssl SSL context
+ * \param conf SSL configuration to use
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED if
+ * memory allocation failed
+ */
+int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
+ const mbedtls_ssl_config *conf );
+
+/**
+ * \brief Reset an already initialized SSL context for re-use
+ * while retaining application-set variables, function
+ * pointers and data.
+ *
+ * \param ssl SSL context
+ * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED,
+ MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or
+ * MBEDTLS_ERR_SSL_COMPRESSION_FAILED
+ */
+int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Set the current endpoint type
+ *
+ * \param conf SSL configuration
+ * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER
+ */
+void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint );
+
+/**
+ * \brief Set the transport type (TLS or DTLS).
+ * Default: TLS
+ *
+ * \note For DTLS, you must either provide a recv callback that
+ * doesn't block, or one that handles timeouts, see
+ * \c mbedtls_ssl_set_bio(). You also need to provide timer
+ * callbacks with \c mbedtls_ssl_set_timer_cb().
+ *
+ * \param conf SSL configuration
+ * \param transport transport type:
+ * MBEDTLS_SSL_TRANSPORT_STREAM for TLS,
+ * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS.
+ */
+void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport );
+
+/**
+ * \brief Set the certificate verification mode
+ * Default: NONE on server, REQUIRED on client
+ *
+ * \param conf SSL configuration
+ * \param authmode can be:
+ *
+ * MBEDTLS_SSL_VERIFY_NONE: peer certificate is not checked
+ * (default on server)
+ * (insecure on client)
+ *
+ * MBEDTLS_SSL_VERIFY_OPTIONAL: peer certificate is checked, however the
+ * handshake continues even if verification failed;
+ * mbedtls_ssl_get_verify_result() can be called after the
+ * handshake is complete.
+ *
+ * MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate,
+ * handshake is aborted if verification failed.
+ * (default on client)
+ *
+ * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode.
+ * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at
+ * the right time(s), which may not be obvious, while REQUIRED always perform
+ * the verification as soon as possible. For example, REQUIRED was protecting
+ * against the "triple handshake" attack even before it was found.
+ */
+void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Set the verification callback (Optional).
+ *
+ * If set, the provided verify callback is called for each
+ * certificate in the peer's CRT chain, including the trusted
+ * root. For more information, please see the documentation of
+ * \c mbedtls_x509_crt_verify().
+ *
+ * \note For per context callbacks and contexts, please use
+ * mbedtls_ssl_set_verify() instead.
+ *
+ * \param conf The SSL configuration to use.
+ * \param f_vrfy The verification callback to use during CRT verification.
+ * \param p_vrfy The opaque context to be passed to the callback.
+ */
+void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/**
+ * \brief Set the random number generator callback
+ *
+ * \param conf SSL configuration
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ */
+void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief Set the debug callback
+ *
+ * The callback has the following argument:
+ * void * opaque context for the callback
+ * int debug level
+ * const char * file name
+ * int line number
+ * const char * message
+ *
+ * \param conf SSL configuration
+ * \param f_dbg debug function
+ * \param p_dbg debug parameter
+ */
+void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
+ void (*f_dbg)(void *, int, const char *, int, const char *),
+ void *p_dbg );
+
+/**
+ * \brief Set the underlying BIO callbacks for write, read and
+ * read-with-timeout.
+ *
+ * \param ssl SSL context
+ * \param p_bio parameter (context) shared by BIO callbacks
+ * \param f_send write callback
+ * \param f_recv read callback
+ * \param f_recv_timeout blocking read callback with timeout.
+ *
+ * \note One of f_recv or f_recv_timeout can be NULL, in which case
+ * the other is used. If both are non-NULL, f_recv_timeout is
+ * used and f_recv is ignored (as if it were NULL).
+ *
+ * \note The two most common use cases are:
+ * - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL
+ * - blocking I/O, f_recv == NULL, f_recv_timout != NULL
+ *
+ * \note For DTLS, you need to provide either a non-NULL
+ * f_recv_timeout callback, or a f_recv that doesn't block.
+ *
+ * \note See the documentations of \c mbedtls_ssl_sent_t,
+ * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for
+ * the conventions those callbacks must follow.
+ *
+ * \note On some platforms, net_sockets.c provides
+ * \c mbedtls_net_send(), \c mbedtls_net_recv() and
+ * \c mbedtls_net_recv_timeout() that are suitable to be used
+ * here.
+ */
+void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
+ void *p_bio,
+ mbedtls_ssl_send_t *f_send,
+ mbedtls_ssl_recv_t *f_recv,
+ mbedtls_ssl_recv_timeout_t *f_recv_timeout );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/**
+ * \brief Set the Maximum Tranport Unit (MTU).
+ * Special value: 0 means unset (no limit).
+ * This represents the maximum size of a datagram payload
+ * handled by the transport layer (usually UDP) as determined
+ * by the network link and stack. In practice, this controls
+ * the maximum size datagram the DTLS layer will pass to the
+ * \c f_send() callback set using \c mbedtls_ssl_set_bio().
+ *
+ * \note The limit on datagram size is converted to a limit on
+ * record payload by subtracting the current overhead of
+ * encapsulation and encryption/authentication if any.
+ *
+ * \note This can be called at any point during the connection, for
+ * example when a Path Maximum Transfer Unit (PMTU)
+ * estimate becomes available from other sources,
+ * such as lower (or higher) protocol layers.
+ *
+ * \note This setting only controls the size of the packets we send,
+ * and does not restrict the size of the datagrams we're
+ * willing to receive. Client-side, you can request the
+ * server to use smaller records with \c
+ * mbedtls_ssl_conf_max_frag_len().
+ *
+ * \note If both a MTU and a maximum fragment length have been
+ * configured (or negotiated with the peer), the resulting
+ * lower limit on record payload (see first note) is used.
+ *
+ * \note This can only be used to decrease the maximum size
+ * of datagrams (hence records, see first note) sent. It
+ * cannot be used to increase the maximum size of records over
+ * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN.
+ *
+ * \note Values lower than the current record layer expansion will
+ * result in an error when trying to send data.
+ *
+ * \note Using record compression together with a non-zero MTU value
+ * will result in an error when trying to send data.
+ *
+ * \param ssl SSL context
+ * \param mtu Value of the path MTU in bytes
+ */
+void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Set a connection-specific verification callback (optional).
+ *
+ * If set, the provided verify callback is called for each
+ * certificate in the peer's CRT chain, including the trusted
+ * root. For more information, please see the documentation of
+ * \c mbedtls_x509_crt_verify().
+ *
+ * \note This call is analogous to mbedtls_ssl_conf_verify() but
+ * binds the verification callback and context to an SSL context
+ * as opposed to an SSL configuration.
+ * If mbedtls_ssl_conf_verify() and mbedtls_ssl_set_verify()
+ * are both used, mbedtls_ssl_set_verify() takes precedence.
+ *
+ * \param ssl The SSL context to use.
+ * \param f_vrfy The verification callback to use during CRT verification.
+ * \param p_vrfy The opaque context to be passed to the callback.
+ */
+void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/**
+ * \brief Set the timeout period for mbedtls_ssl_read()
+ * (Default: no timeout.)
+ *
+ * \param conf SSL configuration context
+ * \param timeout Timeout value in milliseconds.
+ * Use 0 for no timeout (default).
+ *
+ * \note With blocking I/O, this will only work if a non-NULL
+ * \c f_recv_timeout was set with \c mbedtls_ssl_set_bio().
+ * With non-blocking I/O, this will only work if timer
+ * callbacks were set with \c mbedtls_ssl_set_timer_cb().
+ *
+ * \note With non-blocking I/O, you may also skip this function
+ * altogether and handle timeouts at the application layer.
+ */
+void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
+
+/**
+ * \brief Set the timer callbacks (Mandatory for DTLS.)
+ *
+ * \param ssl SSL context
+ * \param p_timer parameter (context) shared by timer callbacks
+ * \param f_set_timer set timer callback
+ * \param f_get_timer get timer callback. Must return:
+ *
+ * \note See the documentation of \c mbedtls_ssl_set_timer_t and
+ * \c mbedtls_ssl_get_timer_t for the conventions this pair of
+ * callbacks must follow.
+ *
+ * \note On some platforms, timing.c provides
+ * \c mbedtls_timing_set_delay() and
+ * \c mbedtls_timing_get_delay() that are suitable for using
+ * here, except if using an event-driven style.
+ *
+ * \note See also the "DTLS tutorial" article in our knowledge base.
+ * https://tls.mbed.org/kb/how-to/dtls-tutorial
+ */
+void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
+ void *p_timer,
+ mbedtls_ssl_set_timer_t *f_set_timer,
+ mbedtls_ssl_get_timer_t *f_get_timer );
+
+/**
+ * \brief Callback type: generate and write session ticket
+ *
+ * \note This describes what a callback implementation should do.
+ * This callback should generate an encrypted and
+ * authenticated ticket for the session and write it to the
+ * output buffer. Here, ticket means the opaque ticket part
+ * of the NewSessionTicket structure of RFC 5077.
+ *
+ * \param p_ticket Context for the callback
+ * \param session SSL session to be written in the ticket
+ * \param start Start of the output buffer
+ * \param end End of the output buffer
+ * \param tlen On exit, holds the length written
+ * \param lifetime On exit, holds the lifetime of the ticket in seconds
+ *
+ * \return 0 if successful, or
+ * a specific MBEDTLS_ERR_XXX code.
+ */
+typedef int mbedtls_ssl_ticket_write_t( void *p_ticket,
+ const mbedtls_ssl_session *session,
+ unsigned char *start,
+ const unsigned char *end,
+ size_t *tlen,
+ uint32_t *lifetime );
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+/**
+ * \brief Callback type: Export key block and master secret
+ *
+ * \note This is required for certain uses of TLS, e.g. EAP-TLS
+ * (RFC 5216) and Thread. The key pointers are ephemeral and
+ * therefore must not be stored. The master secret and keys
+ * should not be used directly except as an input to a key
+ * derivation function.
+ *
+ * \param p_expkey Context for the callback
+ * \param ms Pointer to master secret (fixed length: 48 bytes)
+ * \param kb Pointer to key block, see RFC 5246 section 6.3
+ * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
+ * \param maclen MAC length
+ * \param keylen Key length
+ * \param ivlen IV length
+ *
+ * \return 0 if successful, or
+ * a specific MBEDTLS_ERR_XXX code.
+ */
+typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
+ const unsigned char *ms,
+ const unsigned char *kb,
+ size_t maclen,
+ size_t keylen,
+ size_t ivlen );
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+
+/**
+ * \brief Callback type: parse and load session ticket
+ *
+ * \note This describes what a callback implementation should do.
+ * This callback should parse a session ticket as generated
+ * by the corresponding mbedtls_ssl_ticket_write_t function,
+ * and, if the ticket is authentic and valid, load the
+ * session.
+ *
+ * \note The implementation is allowed to modify the first len
+ * bytes of the input buffer, eg to use it as a temporary
+ * area for the decrypted ticket contents.
+ *
+ * \param p_ticket Context for the callback
+ * \param session SSL session to be loaded
+ * \param buf Start of the buffer containing the ticket
+ * \param len Length of the ticket.
+ *
+ * \return 0 if successful, or
+ * MBEDTLS_ERR_SSL_INVALID_MAC if not authentic, or
+ * MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED if expired, or
+ * any other non-zero code for other failures.
+ */
+typedef int mbedtls_ssl_ticket_parse_t( void *p_ticket,
+ mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t len );
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief Configure SSL session ticket callbacks (server only).
+ * (Default: none.)
+ *
+ * \note On server, session tickets are enabled by providing
+ * non-NULL callbacks.
+ *
+ * \note On client, use \c mbedtls_ssl_conf_session_tickets().
+ *
+ * \param conf SSL configuration context
+ * \param f_ticket_write Callback for writing a ticket
+ * \param f_ticket_parse Callback for parsing a ticket
+ * \param p_ticket Context shared by the two callbacks
+ */
+void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
+ mbedtls_ssl_ticket_write_t *f_ticket_write,
+ mbedtls_ssl_ticket_parse_t *f_ticket_parse,
+ void *p_ticket );
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+/**
+ * \brief Configure key export callback.
+ * (Default: none.)
+ *
+ * \note See \c mbedtls_ssl_export_keys_t.
+ *
+ * \param conf SSL configuration context
+ * \param f_export_keys Callback for exporting keys
+ * \param p_export_keys Context for the callback
+ */
+void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
+ mbedtls_ssl_export_keys_t *f_export_keys,
+ void *p_export_keys );
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+/**
+ * \brief Configure asynchronous private key operation callbacks.
+ *
+ * \param conf SSL configuration context
+ * \param f_async_sign Callback to start a signature operation. See
+ * the description of ::mbedtls_ssl_async_sign_t
+ * for more information. This may be \c NULL if the
+ * external processor does not support any signature
+ * operation; in this case the private key object
+ * associated with the certificate will be used.
+ * \param f_async_decrypt Callback to start a decryption operation. See
+ * the description of ::mbedtls_ssl_async_decrypt_t
+ * for more information. This may be \c NULL if the
+ * external processor does not support any decryption
+ * operation; in this case the private key object
+ * associated with the certificate will be used.
+ * \param f_async_resume Callback to resume an asynchronous operation. See
+ * the description of ::mbedtls_ssl_async_resume_t
+ * for more information. This may not be \c NULL unless
+ * \p f_async_sign and \p f_async_decrypt are both
+ * \c NULL.
+ * \param f_async_cancel Callback to cancel an asynchronous operation. See
+ * the description of ::mbedtls_ssl_async_cancel_t
+ * for more information. This may be \c NULL if
+ * no cleanup is needed.
+ * \param config_data A pointer to configuration data which can be
+ * retrieved with
+ * mbedtls_ssl_conf_get_async_config_data(). The
+ * library stores this value without dereferencing it.
+ */
+void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf,
+ mbedtls_ssl_async_sign_t *f_async_sign,
+ mbedtls_ssl_async_decrypt_t *f_async_decrypt,
+ mbedtls_ssl_async_resume_t *f_async_resume,
+ mbedtls_ssl_async_cancel_t *f_async_cancel,
+ void *config_data );
+
+/**
+ * \brief Retrieve the configuration data set by
+ * mbedtls_ssl_conf_async_private_cb().
+ *
+ * \param conf SSL configuration context
+ * \return The configuration data set by
+ * mbedtls_ssl_conf_async_private_cb().
+ */
+void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf );
+
+/**
+ * \brief Retrieve the asynchronous operation user context.
+ *
+ * \note This function may only be called while a handshake
+ * is in progress.
+ *
+ * \param ssl The SSL context to access.
+ *
+ * \return The asynchronous operation user context that was last
+ * set during the current handshake. If
+ * mbedtls_ssl_set_async_operation_data() has not yet been
+ * called during the current handshake, this function returns
+ * \c NULL.
+ */
+void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Retrieve the asynchronous operation user context.
+ *
+ * \note This function may only be called while a handshake
+ * is in progress.
+ *
+ * \param ssl The SSL context to access.
+ * \param ctx The new value of the asynchronous operation user context.
+ * Call mbedtls_ssl_get_async_operation_data() later during the
+ * same handshake to retrieve this value.
+ */
+void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
+ void *ctx );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+/**
+ * \brief Callback type: generate a cookie
+ *
+ * \param ctx Context for the callback
+ * \param p Buffer to write to,
+ * must be updated to point right after the cookie
+ * \param end Pointer to one past the end of the output buffer
+ * \param info Client ID info that was passed to
+ * \c mbedtls_ssl_set_client_transport_id()
+ * \param ilen Length of info in bytes
+ *
+ * \return The callback must return 0 on success,
+ * or a negative error code.
+ */
+typedef int mbedtls_ssl_cookie_write_t( void *ctx,
+ unsigned char **p, unsigned char *end,
+ const unsigned char *info, size_t ilen );
+
+/**
+ * \brief Callback type: verify a cookie
+ *
+ * \param ctx Context for the callback
+ * \param cookie Cookie to verify
+ * \param clen Length of cookie
+ * \param info Client ID info that was passed to
+ * \c mbedtls_ssl_set_client_transport_id()
+ * \param ilen Length of info in bytes
+ *
+ * \return The callback must return 0 if cookie is valid,
+ * or a negative error code.
+ */
+typedef int mbedtls_ssl_cookie_check_t( void *ctx,
+ const unsigned char *cookie, size_t clen,
+ const unsigned char *info, size_t ilen );
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief Register callbacks for DTLS cookies
+ * (Server only. DTLS only.)
+ *
+ * Default: dummy callbacks that fail, in order to force you to
+ * register working callbacks (and initialize their context).
+ *
+ * To disable HelloVerifyRequest, register NULL callbacks.
+ *
+ * \warning Disabling hello verification allows your server to be used
+ * for amplification in DoS attacks against other hosts.
+ * Only disable if you known this can't happen in your
+ * particular environment.
+ *
+ * \note See comments on \c mbedtls_ssl_handshake() about handling
+ * the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected
+ * on the first handshake attempt when this is enabled.
+ *
+ * \note This is also necessary to handle client reconnection from
+ * the same port as described in RFC 6347 section 4.2.8 (only
+ * the variant with cookies is supported currently). See
+ * comments on \c mbedtls_ssl_read() for details.
+ *
+ * \param conf SSL configuration
+ * \param f_cookie_write Cookie write callback
+ * \param f_cookie_check Cookie check callback
+ * \param p_cookie Context for both callbacks
+ */
+void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
+ mbedtls_ssl_cookie_write_t *f_cookie_write,
+ mbedtls_ssl_cookie_check_t *f_cookie_check,
+ void *p_cookie );
+
+/**
+ * \brief Set client's transport-level identification info.
+ * (Server only. DTLS only.)
+ *
+ * This is usually the IP address (and port), but could be
+ * anything identify the client depending on the underlying
+ * network stack. Used for HelloVerifyRequest with DTLS.
+ * This is *not* used to route the actual packets.
+ *
+ * \param ssl SSL context
+ * \param info Transport-level info identifying the client (eg IP + port)
+ * \param ilen Length of info in bytes
+ *
+ * \note An internal copy is made, so the info buffer can be reused.
+ *
+ * \return 0 on success,
+ * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used on client,
+ * MBEDTLS_ERR_SSL_ALLOC_FAILED if out of memory.
+ */
+int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl,
+ const unsigned char *info,
+ size_t ilen );
+
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+/**
+ * \brief Enable or disable anti-replay protection for DTLS.
+ * (DTLS only, no effect on TLS.)
+ * Default: enabled.
+ *
+ * \param conf SSL configuration
+ * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED.
+ *
+ * \warning Disabling this is a security risk unless the application
+ * protocol handles duplicated packets in a safe way. You
+ * should not disable this without careful consideration.
+ * However, if your application already detects duplicated
+ * packets and needs information about them to adjust its
+ * transmission strategy, then you'll want to disable this.
+ */
+void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode );
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+/**
+ * \brief Set a limit on the number of records with a bad MAC
+ * before terminating the connection.
+ * (DTLS only, no effect on TLS.)
+ * Default: 0 (disabled).
+ *
+ * \param conf SSL configuration
+ * \param limit Limit, or 0 to disable.
+ *
+ * \note If the limit is N, then the connection is terminated when
+ * the Nth non-authentic record is seen.
+ *
+ * \note Records with an invalid header are not counted, only the
+ * ones going through the authentication-decryption phase.
+ *
+ * \note This is a security trade-off related to the fact that it's
+ * often relatively easy for an active attacker ot inject UDP
+ * datagrams. On one hand, setting a low limit here makes it
+ * easier for such an attacker to forcibly terminated a
+ * connection. On the other hand, a high limit or no limit
+ * might make us waste resources checking authentication on
+ * many bogus packets.
+ */
+void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit );
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+/**
+ * \brief Allow or disallow packing of multiple handshake records
+ * within a single datagram.
+ *
+ * \param ssl The SSL context to configure.
+ * \param allow_packing This determines whether datagram packing may
+ * be used or not. A value of \c 0 means that every
+ * record will be sent in a separate datagram; a
+ * value of \c 1 means that, if space permits,
+ * multiple handshake messages (including CCS) belonging to
+ * a single flight may be packed within a single datagram.
+ *
+ * \note This is enabled by default and should only be disabled
+ * for test purposes, or if datagram packing causes
+ * interoperability issues with peers that don't support it.
+ *
+ * \note Allowing datagram packing reduces the network load since
+ * there's less overhead if multiple messages share the same
+ * datagram. Also, it increases the handshake efficiency
+ * since messages belonging to a single datagram will not
+ * be reordered in transit, and so future message buffering
+ * or flight retransmission (if no buffering is used) as
+ * means to deal with reordering are needed less frequently.
+ *
+ * \note Application records are not affected by this option and
+ * are currently always sent in separate datagrams.
+ *
+ */
+void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl,
+ unsigned allow_packing );
+
+/**
+ * \brief Set retransmit timeout values for the DTLS handshake.
+ * (DTLS only, no effect on TLS.)
+ *
+ * \param conf SSL configuration
+ * \param min Initial timeout value in milliseconds.
+ * Default: 1000 (1 second).
+ * \param max Maximum timeout value in milliseconds.
+ * Default: 60000 (60 seconds).
+ *
+ * \note Default values are from RFC 6347 section 4.2.4.1.
+ *
+ * \note The 'min' value should typically be slightly above the
+ * expected round-trip time to your peer, plus whatever time
+ * it takes for the peer to process the message. For example,
+ * if your RTT is about 600ms and you peer needs up to 1s to
+ * do the cryptographic operations in the handshake, then you
+ * should set 'min' slightly above 1600. Lower values of 'min'
+ * might cause spurious resends which waste network resources,
+ * while larger value of 'min' will increase overall latency
+ * on unreliable network links.
+ *
+ * \note The more unreliable your network connection is, the larger
+ * your max / min ratio needs to be in order to achieve
+ * reliable handshakes.
+ *
+ * \note Messages are retransmitted up to log2(ceil(max/min)) times.
+ * For example, if min = 1s and max = 5s, the retransmit plan
+ * goes: send ... 1s -> resend ... 2s -> resend ... 4s ->
+ * resend ... 5s -> give up and return a timeout error.
+ */
+void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief Set the session cache callbacks (server-side only)
+ * If not set, no session resuming is done (except if session
+ * tickets are enabled too).
+ *
+ * The session cache has the responsibility to check for stale
+ * entries based on timeout. See RFC 5246 for recommendations.
+ *
+ * Warning: session.peer_cert is cleared by the SSL/TLS layer on
+ * connection shutdown, so do not cache the pointer! Either set
+ * it to NULL or make a full copy of the certificate.
+ *
+ * The get callback is called once during the initial handshake
+ * to enable session resuming. The get function has the
+ * following parameters: (void *parameter, mbedtls_ssl_session *session)
+ * If a valid entry is found, it should fill the master of
+ * the session object with the cached values and return 0,
+ * return 1 otherwise. Optionally peer_cert can be set as well
+ * if it is properly present in cache entry.
+ *
+ * The set callback is called once during the initial handshake
+ * to enable session resuming after the entire handshake has
+ * been finished. The set function has the following parameters:
+ * (void *parameter, const mbedtls_ssl_session *session). The function
+ * should create a cache entry for future retrieval based on
+ * the data in the session structure and should keep in mind
+ * that the mbedtls_ssl_session object presented (and all its referenced
+ * data) is cleared by the SSL/TLS layer when the connection is
+ * terminated. It is recommended to add metadata to determine if
+ * an entry is still valid in the future. Return 0 if
+ * successfully cached, return 1 otherwise.
+ *
+ * \param conf SSL configuration
+ * \param p_cache parmater (context) for both callbacks
+ * \param f_get_cache session get callback
+ * \param f_set_cache session set callback
+ */
+void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
+ void *p_cache,
+ int (*f_get_cache)(void *, mbedtls_ssl_session *),
+ int (*f_set_cache)(void *, const mbedtls_ssl_session *) );
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief Request resumption of session (client-side only)
+ * Session data is copied from presented session structure.
+ *
+ * \param ssl SSL context
+ * \param session session context
+ *
+ * \return 0 if successful,
+ * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed,
+ * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or
+ * arguments are otherwise invalid
+ *
+ * \sa mbedtls_ssl_get_session()
+ */
+int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session );
+#endif /* MBEDTLS_SSL_CLI_C */
+
+/**
+ * \brief Set the list of allowed ciphersuites and the preference
+ * order. First in the list has the highest preference.
+ * (Overrides all version-specific lists)
+ *
+ * The ciphersuites array is not copied, and must remain
+ * valid for the lifetime of the ssl_config.
+ *
+ * Note: The server uses its own preferences
+ * over the preference of the client unless
+ * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined!
+ *
+ * \param conf SSL configuration
+ * \param ciphersuites 0-terminated list of allowed ciphersuites
+ */
+void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
+ const int *ciphersuites );
+
+/**
+ * \brief Set the list of allowed ciphersuites and the
+ * preference order for a specific version of the protocol.
+ * (Only useful on the server side)
+ *
+ * The ciphersuites array is not copied, and must remain
+ * valid for the lifetime of the ssl_config.
+ *
+ * \param conf SSL configuration
+ * \param ciphersuites 0-terminated list of allowed ciphersuites
+ * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3
+ * supported)
+ * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
+ * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
+ * MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ *
+ * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0
+ * and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ */
+void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
+ const int *ciphersuites,
+ int major, int minor );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Set the X.509 security profile used for verification
+ *
+ * \note The restrictions are enforced for all certificates in the
+ * chain. However, signatures in the handshake are not covered
+ * by this setting but by \b mbedtls_ssl_conf_sig_hashes().
+ *
+ * \param conf SSL configuration
+ * \param profile Profile to use
+ */
+void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
+ const mbedtls_x509_crt_profile *profile );
+
+/**
+ * \brief Set the data required to verify peer certificate
+ *
+ * \note See \c mbedtls_x509_crt_verify() for notes regarding the
+ * parameters ca_chain (maps to trust_ca for that function)
+ * and ca_crl.
+ *
+ * \param conf SSL configuration
+ * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs)
+ * \param ca_crl trusted CA CRLs
+ */
+void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
+ mbedtls_x509_crt *ca_chain,
+ mbedtls_x509_crl *ca_crl );
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+/**
+ * \brief Set the trusted certificate callback.
+ *
+ * This API allows to register the set of trusted certificates
+ * through a callback, instead of a linked list as configured
+ * by mbedtls_ssl_conf_ca_chain().
+ *
+ * This is useful for example in contexts where a large number
+ * of CAs are used, and the inefficiency of maintaining them
+ * in a linked list cannot be tolerated. It is also useful when
+ * the set of trusted CAs needs to be modified frequently.
+ *
+ * See the documentation of `mbedtls_x509_crt_ca_cb_t` for
+ * more information.
+ *
+ * \param conf The SSL configuration to register the callback with.
+ * \param f_ca_cb The trusted certificate callback to use when verifying
+ * certificate chains.
+ * \param p_ca_cb The context to be passed to \p f_ca_cb (for example,
+ * a reference to a trusted CA database).
+ *
+ * \note This API is incompatible with mbedtls_ssl_conf_ca_chain():
+ * Any call to this function overwrites the values set through
+ * earlier calls to mbedtls_ssl_conf_ca_chain() or
+ * mbedtls_ssl_conf_ca_cb().
+ *
+ * \note This API is incompatible with CA indication in
+ * CertificateRequest messages: A server-side SSL context which
+ * is bound to an SSL configuration that uses a CA callback
+ * configured via mbedtls_ssl_conf_ca_cb(), and which requires
+ * client authentication, will send an empty CA list in the
+ * corresponding CertificateRequest message.
+ *
+ * \note This API is incompatible with mbedtls_ssl_set_hs_ca_chain():
+ * If an SSL context is bound to an SSL configuration which uses
+ * CA callbacks configured via mbedtls_ssl_conf_ca_cb(), then
+ * calls to mbedtls_ssl_set_hs_ca_chain() have no effect.
+ *
+ * \note The use of this API disables the use of restartable ECC
+ * during X.509 CRT signature verification (but doesn't affect
+ * other uses).
+ *
+ * \warning This API is incompatible with the use of CRLs. Any call to
+ * mbedtls_ssl_conf_ca_cb() unsets CRLs configured through
+ * earlier calls to mbedtls_ssl_conf_ca_chain().
+ *
+ * \warning In multi-threaded environments, the callback \p f_ca_cb
+ * must be thread-safe, and it is the user's responsibility
+ * to guarantee this (for example through a mutex
+ * contained in the callback context pointed to by \p p_ca_cb).
+ */
+void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb );
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
+/**
+ * \brief Set own certificate chain and private key
+ *
+ * \note own_cert should contain in order from the bottom up your
+ * certificate chain. The top certificate (self-signed)
+ * can be omitted.
+ *
+ * \note On server, this function can be called multiple times to
+ * provision more than one cert/key pair (eg one ECDSA, one
+ * RSA with SHA-256, one RSA with SHA-1). An adequate
+ * certificate will be selected according to the client's
+ * advertised capabilities. In case multiple certificates are
+ * adequate, preference is given to the one set by the first
+ * call to this function, then second, etc.
+ *
+ * \note On client, only the first call has any effect. That is,
+ * only one client certificate can be provisioned. The
+ * server's preferences in its CertficateRequest message will
+ * be ignored and our only cert will be sent regardless of
+ * whether it matches those preferences - the server can then
+ * decide what it wants to do with it.
+ *
+ * \note The provided \p pk_key needs to match the public key in the
+ * first certificate in \p own_cert, or all handshakes using
+ * that certificate will fail. It is your responsibility
+ * to ensure that; this function will not perform any check.
+ * You may use mbedtls_pk_check_pair() in order to perform
+ * this check yourself, but be aware that this function can
+ * be computationally expensive on some key types.
+ *
+ * \param conf SSL configuration
+ * \param own_cert own public certificate chain
+ * \param pk_key own private key
+ *
+ * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ */
+int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
+ mbedtls_x509_crt *own_cert,
+ mbedtls_pk_context *pk_key );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+/**
+ * \brief Configure a pre-shared key (PSK) and identity
+ * to be used in PSK-based ciphersuites.
+ *
+ * \note This is mainly useful for clients. Servers will usually
+ * want to use \c mbedtls_ssl_conf_psk_cb() instead.
+ *
+ * \warning Currently, clients can only register a single pre-shared key.
+ * Calling this function or mbedtls_ssl_conf_psk_opaque() more
+ * than once will overwrite values configured in previous calls.
+ * Support for setting multiple PSKs on clients and selecting
+ * one based on the identity hint is not a planned feature,
+ * but feedback is welcomed.
+ *
+ * \param conf The SSL configuration to register the PSK with.
+ * \param psk The pointer to the pre-shared key to use.
+ * \param psk_len The length of the pre-shared key in bytes.
+ * \param psk_identity The pointer to the pre-shared key identity.
+ * \param psk_identity_len The length of the pre-shared key identity
+ * in bytes.
+ *
+ * \note The PSK and its identity are copied internally and
+ * hence need not be preserved by the caller for the lifetime
+ * of the SSL configuration.
+ *
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
+ */
+int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
+ const unsigned char *psk, size_t psk_len,
+ const unsigned char *psk_identity, size_t psk_identity_len );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Configure an opaque pre-shared key (PSK) and identity
+ * to be used in PSK-based ciphersuites.
+ *
+ * \note This is mainly useful for clients. Servers will usually
+ * want to use \c mbedtls_ssl_conf_psk_cb() instead.
+ *
+ * \warning Currently, clients can only register a single pre-shared key.
+ * Calling this function or mbedtls_ssl_conf_psk() more than
+ * once will overwrite values configured in previous calls.
+ * Support for setting multiple PSKs on clients and selecting
+ * one based on the identity hint is not a planned feature,
+ * but feedback is welcomed.
+ *
+ * \param conf The SSL configuration to register the PSK with.
+ * \param psk The identifier of the key slot holding the PSK.
+ * Until \p conf is destroyed or this function is successfully
+ * called again, the key slot \p psk must be populated with a
+ * key of type PSA_ALG_CATEGORY_KEY_DERIVATION whose policy
+ * allows its use for the key derivation algorithm applied
+ * in the handshake.
+ * \param psk_identity The pointer to the pre-shared key identity.
+ * \param psk_identity_len The length of the pre-shared key identity
+ * in bytes.
+ *
+ * \note The PSK identity hint is copied internally and hence need
+ * not be preserved by the caller for the lifetime of the
+ * SSL configuration.
+ *
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
+ */
+int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
+ psa_key_handle_t psk,
+ const unsigned char *psk_identity,
+ size_t psk_identity_len );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+/**
+ * \brief Set the pre-shared Key (PSK) for the current handshake.
+ *
+ * \note This should only be called inside the PSK callback,
+ * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb().
+ *
+ * \param ssl The SSL context to configure a PSK for.
+ * \param psk The pointer to the pre-shared key.
+ * \param psk_len The length of the pre-shared key in bytes.
+ *
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
+ */
+int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
+ const unsigned char *psk, size_t psk_len );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Set an opaque pre-shared Key (PSK) for the current handshake.
+ *
+ * \note This should only be called inside the PSK callback,
+ * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb().
+ *
+ * \param ssl The SSL context to configure a PSK for.
+ * \param psk The identifier of the key slot holding the PSK.
+ * For the duration of the current handshake, the key slot
+ * must be populated with a key of type
+ * PSA_ALG_CATEGORY_KEY_DERIVATION whose policy allows its
+ * use for the key derivation algorithm
+ * applied in the handshake.
+ *
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
+ */
+int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
+ psa_key_handle_t psk );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+/**
+ * \brief Set the PSK callback (server-side only).
+ *
+ * If set, the PSK callback is called for each
+ * handshake where a PSK-based ciphersuite was negotiated.
+ * The caller provides the identity received and wants to
+ * receive the actual PSK data and length.
+ *
+ * The callback has the following parameters:
+ * - \c void*: The opaque pointer \p p_psk.
+ * - \c mbedtls_ssl_context*: The SSL context to which
+ * the operation applies.
+ * - \c const unsigned char*: The PSK identity
+ * selected by the client.
+ * - \c size_t: The length of the PSK identity
+ * selected by the client.
+ *
+ * If a valid PSK identity is found, the callback should use
+ * \c mbedtls_ssl_set_hs_psk() or
+ * \c mbedtls_ssl_set_hs_psk_opaque()
+ * on the SSL context to set the correct PSK and return \c 0.
+ * Any other return value will result in a denied PSK identity.
+ *
+ * \note If you set a PSK callback using this function, then you
+ * don't need to set a PSK key and identity using
+ * \c mbedtls_ssl_conf_psk().
+ *
+ * \param conf The SSL configuration to register the callback with.
+ * \param f_psk The callback for selecting and setting the PSK based
+ * in the PSK identity chosen by the client.
+ * \param p_psk A pointer to an opaque structure to be passed to
+ * the callback, for example a PSK store.
+ */
+void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
+ int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
+ size_t),
+ void *p_psk );
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
+/**
+ * \brief Set the Diffie-Hellman public P and G values,
+ * read as hexadecimal strings (server-side only)
+ * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG])
+ *
+ * \param conf SSL configuration
+ * \param dhm_P Diffie-Hellman-Merkle modulus
+ * \param dhm_G Diffie-Hellman-Merkle generator
+ *
+ * \deprecated Superseded by \c mbedtls_ssl_conf_dh_param_bin.
+ *
+ * \return 0 if successful
+ */
+MBEDTLS_DEPRECATED int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf,
+ const char *dhm_P,
+ const char *dhm_G );
+
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief Set the Diffie-Hellman public P and G values
+ * from big-endian binary presentations.
+ * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN)
+ *
+ * \param conf SSL configuration
+ * \param dhm_P Diffie-Hellman-Merkle modulus in big-endian binary form
+ * \param P_len Length of DHM modulus
+ * \param dhm_G Diffie-Hellman-Merkle generator in big-endian binary form
+ * \param G_len Length of DHM generator
+ *
+ * \return 0 if successful
+ */
+int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
+ const unsigned char *dhm_P, size_t P_len,
+ const unsigned char *dhm_G, size_t G_len );
+
+/**
+ * \brief Set the Diffie-Hellman public P and G values,
+ * read from existing context (server-side only)
+ *
+ * \param conf SSL configuration
+ * \param dhm_ctx Diffie-Hellman-Merkle context
+ *
+ * \return 0 if successful
+ */
+int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx );
+#endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief Set the minimum length for Diffie-Hellman parameters.
+ * (Client-side only.)
+ * (Default: 1024 bits.)
+ *
+ * \param conf SSL configuration
+ * \param bitlen Minimum bit length of the DHM prime
+ */
+void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
+ unsigned int bitlen );
+#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_ECP_C)
+/**
+ * \brief Set the allowed curves in order of preference.
+ * (Default: all defined curves.)
+ *
+ * On server: this only affects selection of the ECDHE curve;
+ * the curves used for ECDH and ECDSA are determined by the
+ * list of available certificates instead.
+ *
+ * On client: this affects the list of curves offered for any
+ * use. The server can override our preference order.
+ *
+ * Both sides: limits the set of curves accepted for use in
+ * ECDHE and in the peer's end-entity certificate.
+ *
+ * \note This has no influence on which curves are allowed inside the
+ * certificate chains, see \c mbedtls_ssl_conf_cert_profile()
+ * for that. For the end-entity certificate however, the key
+ * will be accepted only if it is allowed both by this list
+ * and by the cert profile.
+ *
+ * \note This list should be ordered by decreasing preference
+ * (preferred curve first).
+ *
+ * \param conf SSL configuration
+ * \param curves Ordered list of allowed curves,
+ * terminated by MBEDTLS_ECP_DP_NONE.
+ */
+void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
+ const mbedtls_ecp_group_id *curves );
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+/**
+ * \brief Set the allowed hashes for signatures during the handshake.
+ * (Default: all available hashes except MD5.)
+ *
+ * \note This only affects which hashes are offered and can be used
+ * for signatures during the handshake. Hashes for message
+ * authentication and the TLS PRF are controlled by the
+ * ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes
+ * used for certificate signature are controlled by the
+ * verification profile, see \c mbedtls_ssl_conf_cert_profile().
+ *
+ * \note This list should be ordered by decreasing preference
+ * (preferred hash first).
+ *
+ * \param conf SSL configuration
+ * \param hashes Ordered list of allowed signature hashes,
+ * terminated by \c MBEDTLS_MD_NONE.
+ */
+void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
+ const int *hashes );
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Set or reset the hostname to check against the received
+ * server certificate. It sets the ServerName TLS extension,
+ * too, if that extension is enabled. (client-side only)
+ *
+ * \param ssl SSL context
+ * \param hostname the server hostname, may be NULL to clear hostname
+
+ * \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN.
+ *
+ * \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on
+ * allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on
+ * too long input hostname.
+ *
+ * Hostname set to the one provided on success (cleared
+ * when NULL). On allocation failure hostname is cleared.
+ * On too long input failure, old hostname is unchanged.
+ */
+int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+/**
+ * \brief Set own certificate and key for the current handshake
+ *
+ * \note Same as \c mbedtls_ssl_conf_own_cert() but for use within
+ * the SNI callback.
+ *
+ * \param ssl SSL context
+ * \param own_cert own public certificate chain
+ * \param pk_key own private key
+ *
+ * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ */
+int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *own_cert,
+ mbedtls_pk_context *pk_key );
+
+/**
+ * \brief Set the data required to verify peer certificate for the
+ * current handshake
+ *
+ * \note Same as \c mbedtls_ssl_conf_ca_chain() but for use within
+ * the SNI callback.
+ *
+ * \param ssl SSL context
+ * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs)
+ * \param ca_crl trusted CA CRLs
+ */
+void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *ca_chain,
+ mbedtls_x509_crl *ca_crl );
+
+/**
+ * \brief Set authmode for the current handshake.
+ *
+ * \note Same as \c mbedtls_ssl_conf_authmode() but for use within
+ * the SNI callback.
+ *
+ * \param ssl SSL context
+ * \param authmode MBEDTLS_SSL_VERIFY_NONE, MBEDTLS_SSL_VERIFY_OPTIONAL or
+ * MBEDTLS_SSL_VERIFY_REQUIRED
+ */
+void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
+ int authmode );
+
+/**
+ * \brief Set server side ServerName TLS extension callback
+ * (optional, server-side only).
+ *
+ * If set, the ServerName callback is called whenever the
+ * server receives a ServerName TLS extension from the client
+ * during a handshake. The ServerName callback has the
+ * following parameters: (void *parameter, mbedtls_ssl_context *ssl,
+ * const unsigned char *hostname, size_t len). If a suitable
+ * certificate is found, the callback must set the
+ * certificate(s) and key(s) to use with \c
+ * mbedtls_ssl_set_hs_own_cert() (can be called repeatedly),
+ * and may optionally adjust the CA and associated CRL with \c
+ * mbedtls_ssl_set_hs_ca_chain() as well as the client
+ * authentication mode with \c mbedtls_ssl_set_hs_authmode(),
+ * then must return 0. If no matching name is found, the
+ * callback must either set a default cert, or
+ * return non-zero to abort the handshake at this point.
+ *
+ * \param conf SSL configuration
+ * \param f_sni verification function
+ * \param p_sni verification parameter
+ */
+void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
+ int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *,
+ size_t),
+ void *p_sni );
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+/**
+ * \brief Set the EC J-PAKE password for current handshake.
+ *
+ * \note An internal copy is made, and destroyed as soon as the
+ * handshake is completed, or when the SSL context is reset or
+ * freed.
+ *
+ * \note The SSL context needs to be already set up. The right place
+ * to call this function is between \c mbedtls_ssl_setup() or
+ * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake().
+ *
+ * \param ssl SSL context
+ * \param pw EC J-PAKE password (pre-shared secret)
+ * \param pw_len length of pw in bytes
+ *
+ * \return 0 on success, or a negative error code.
+ */
+int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
+ const unsigned char *pw,
+ size_t pw_len );
+#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_ALPN)
+/**
+ * \brief Set the supported Application Layer Protocols.
+ *
+ * \param conf SSL configuration
+ * \param protos Pointer to a NULL-terminated list of supported protocols,
+ * in decreasing preference order. The pointer to the list is
+ * recorded by the library for later reference as required, so
+ * the lifetime of the table must be atleast as long as the
+ * lifetime of the SSL configuration structure.
+ *
+ * \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
+ */
+int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos );
+
+/**
+ * \brief Get the name of the negotiated Application Layer Protocol.
+ * This function should be called after the handshake is
+ * completed.
+ *
+ * \param ssl SSL context
+ *
+ * \return Protcol name, or NULL if no protocol was negotiated.
+ */
+const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_ALPN */
+
+/**
+ * \brief Set the maximum supported version sent from the client side
+ * and/or accepted at the server side
+ * (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION)
+ *
+ * \note This ignores ciphersuites from higher versions.
+ *
+ * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
+ * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ *
+ * \param conf SSL configuration
+ * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
+ * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
+ * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
+ * MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ */
+void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor );
+
+/**
+ * \brief Set the minimum accepted SSL/TLS protocol version
+ * (Default: TLS 1.0)
+ *
+ * \note Input outside of the SSL_MAX_XXXXX_VERSION and
+ * SSL_MIN_XXXXX_VERSION range is ignored.
+ *
+ * \note MBEDTLS_SSL_MINOR_VERSION_0 (SSL v3) should be avoided.
+ *
+ * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
+ * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ *
+ * \param conf SSL configuration
+ * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
+ * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
+ * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
+ * MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ */
+void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor );
+
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief Set the fallback flag (client-side only).
+ * (Default: MBEDTLS_SSL_IS_NOT_FALLBACK).
+ *
+ * \note Set to MBEDTLS_SSL_IS_FALLBACK when preparing a fallback
+ * connection, that is a connection with max_version set to a
+ * lower value than the value you're willing to use. Such
+ * fallback connections are not recommended but are sometimes
+ * necessary to interoperate with buggy (version-intolerant)
+ * servers.
+ *
+ * \warning You should NOT set this to MBEDTLS_SSL_IS_FALLBACK for
+ * non-fallback connections! This would appear to work for a
+ * while, then cause failures when the server is upgraded to
+ * support a newer TLS version.
+ *
+ * \param conf SSL configuration
+ * \param fallback MBEDTLS_SSL_IS_NOT_FALLBACK or MBEDTLS_SSL_IS_FALLBACK
+ */
+void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback );
+#endif /* MBEDTLS_SSL_FALLBACK_SCSV && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+/**
+ * \brief Enable or disable Encrypt-then-MAC
+ * (Default: MBEDTLS_SSL_ETM_ENABLED)
+ *
+ * \note This should always be enabled, it is a security
+ * improvement, and should not cause any interoperability
+ * issue (used only if the peer supports it too).
+ *
+ * \param conf SSL configuration
+ * \param etm MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED
+ */
+void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm );
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+/**
+ * \brief Enable or disable Extended Master Secret negotiation.
+ * (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED)
+ *
+ * \note This should always be enabled, it is a security fix to the
+ * protocol, and should not cause any interoperability issue
+ * (used only if the peer supports it too).
+ *
+ * \param conf SSL configuration
+ * \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED
+ */
+void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems );
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_ARC4_C)
+/**
+ * \brief Disable or enable support for RC4
+ * (Default: MBEDTLS_SSL_ARC4_DISABLED)
+ *
+ * \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465
+ * for security reasons. Use at your own risk.
+ *
+ * \note This function is deprecated and will likely be removed in
+ * a future version of the library.
+ * RC4 is disabled by default at compile time and needs to be
+ * actively enabled for use with legacy systems.
+ *
+ * \param conf SSL configuration
+ * \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED
+ */
+void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 );
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief Whether to send a list of acceptable CAs in
+ * CertificateRequest messages.
+ * (Default: do send)
+ *
+ * \param conf SSL configuration
+ * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or
+ * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED
+ */
+void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
+ char cert_req_ca_list );
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+/**
+ * \brief Set the maximum fragment length to emit and/or negotiate
+ * (Default: the smaller of MBEDTLS_SSL_IN_CONTENT_LEN and
+ * MBEDTLS_SSL_OUT_CONTENT_LEN, usually 2^14 bytes)
+ * (Server: set maximum fragment length to emit,
+ * usually negotiated by the client during handshake
+ * (Client: set maximum fragment length to emit *and*
+ * negotiate with the server during handshake)
+ *
+ * \note With TLS, this currently only affects ApplicationData (sent
+ * with \c mbedtls_ssl_read()), not handshake messages.
+ * With DTLS, this affects both ApplicationData and handshake.
+ *
+ * \note This sets the maximum length for a record's payload,
+ * excluding record overhead that will be added to it, see
+ * \c mbedtls_ssl_get_record_expansion().
+ *
+ * \note For DTLS, it is also possible to set a limit for the total
+ * size of daragrams passed to the transport layer, including
+ * record overhead, see \c mbedtls_ssl_set_mtu().
+ *
+ * \param conf SSL configuration
+ * \param mfl_code Code for maximum fragment length (allowed values:
+ * MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024,
+ * MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096)
+ *
+ * \return 0 if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+ */
+int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code );
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+/**
+ * \brief Activate negotiation of truncated HMAC
+ * (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED)
+ *
+ * \param conf SSL configuration
+ * \param truncate Enable or disable (MBEDTLS_SSL_TRUNC_HMAC_ENABLED or
+ * MBEDTLS_SSL_TRUNC_HMAC_DISABLED)
+ */
+void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate );
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+/**
+ * \brief Enable / Disable 1/n-1 record splitting
+ * (Default: MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED)
+ *
+ * \note Only affects SSLv3 and TLS 1.0, not higher versions.
+ * Does not affect non-CBC ciphersuites in any version.
+ *
+ * \param conf SSL configuration
+ * \param split MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED or
+ * MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED
+ */
+void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split );
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief Enable / Disable session tickets (client only).
+ * (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.)
+ *
+ * \note On server, use \c mbedtls_ssl_conf_session_tickets_cb().
+ *
+ * \param conf SSL configuration
+ * \param use_tickets Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or
+ * MBEDTLS_SSL_SESSION_TICKETS_DISABLED)
+ */
+void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets );
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/**
+ * \brief Enable / Disable renegotiation support for connection when
+ * initiated by peer
+ * (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED)
+ *
+ * \warning It is recommended to always disable renegotation unless you
+ * know you need it and you know what you're doing. In the
+ * past, there have been several issues associated with
+ * renegotiation or a poor understanding of its properties.
+ *
+ * \note Server-side, enabling renegotiation also makes the server
+ * susceptible to a resource DoS by a malicious client.
+ *
+ * \param conf SSL configuration
+ * \param renegotiation Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or
+ * MBEDTLS_SSL_RENEGOTIATION_DISABLED)
+ */
+void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation );
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/**
+ * \brief Prevent or allow legacy renegotiation.
+ * (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION)
+ *
+ * MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION allows connections to
+ * be established even if the peer does not support
+ * secure renegotiation, but does not allow renegotiation
+ * to take place if not secure.
+ * (Interoperable and secure option)
+ *
+ * MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations
+ * with non-upgraded peers. Allowing legacy renegotiation
+ * makes the connection vulnerable to specific man in the
+ * middle attacks. (See RFC 5746)
+ * (Most interoperable and least secure option)
+ *
+ * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE breaks off connections
+ * if peer does not support secure renegotiation. Results
+ * in interoperability issues with non-upgraded peers
+ * that do not support renegotiation altogether.
+ * (Most secure option, interoperability issues)
+ *
+ * \param conf SSL configuration
+ * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION,
+ * SSL_ALLOW_LEGACY_RENEGOTIATION or
+ * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE)
+ */
+void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/**
+ * \brief Enforce renegotiation requests.
+ * (Default: enforced, max_records = 16)
+ *
+ * When we request a renegotiation, the peer can comply or
+ * ignore the request. This function allows us to decide
+ * whether to enforce our renegotiation requests by closing
+ * the connection if the peer doesn't comply.
+ *
+ * However, records could already be in transit from the peer
+ * when the request is emitted. In order to increase
+ * reliability, we can accept a number of records before the
+ * expected handshake records.
+ *
+ * The optimal value is highly dependent on the specific usage
+ * scenario.
+ *
+ * \note With DTLS and server-initiated renegotiation, the
+ * HelloRequest is retransmited every time mbedtls_ssl_read() times
+ * out or receives Application Data, until:
+ * - max_records records have beens seen, if it is >= 0, or
+ * - the number of retransmits that would happen during an
+ * actual handshake has been reached.
+ * Please remember the request might be lost a few times
+ * if you consider setting max_records to a really low value.
+ *
+ * \warning On client, the grace period can only happen during
+ * mbedtls_ssl_read(), as opposed to mbedtls_ssl_write() and mbedtls_ssl_renegotiate()
+ * which always behave as if max_record was 0. The reason is,
+ * if we receive application data from the server, we need a
+ * place to write it, which only happens during mbedtls_ssl_read().
+ *
+ * \param conf SSL configuration
+ * \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to
+ * enforce renegotiation, or a non-negative value to enforce
+ * it but allow for a grace period of max_records records.
+ */
+void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records );
+
+/**
+ * \brief Set record counter threshold for periodic renegotiation.
+ * (Default: 2^48 - 1)
+ *
+ * Renegotiation is automatically triggered when a record
+ * counter (outgoing or ingoing) crosses the defined
+ * threshold. The default value is meant to prevent the
+ * connection from being closed when the counter is about to
+ * reached its maximal value (it is not allowed to wrap).
+ *
+ * Lower values can be used to enforce policies such as "keys
+ * must be refreshed every N packets with cipher X".
+ *
+ * The renegotiation period can be disabled by setting
+ * conf->disable_renegotiation to
+ * MBEDTLS_SSL_RENEGOTIATION_DISABLED.
+ *
+ * \note When the configured transport is
+ * MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation
+ * period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM,
+ * the maximum renegotiation period is 2^64 - 1.
+ *
+ * \param conf SSL configuration
+ * \param period The threshold value: a big-endian 64-bit number.
+ */
+void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
+ const unsigned char period[8] );
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/**
+ * \brief Check if there is data already read from the
+ * underlying transport but not yet processed.
+ *
+ * \param ssl SSL context
+ *
+ * \return 0 if nothing's pending, 1 otherwise.
+ *
+ * \note This is different in purpose and behaviour from
+ * \c mbedtls_ssl_get_bytes_avail in that it considers
+ * any kind of unprocessed data, not only unread
+ * application data. If \c mbedtls_ssl_get_bytes
+ * returns a non-zero value, this function will
+ * also signal pending data, but the converse does
+ * not hold. For example, in DTLS there might be
+ * further records waiting to be processed from
+ * the current underlying transport's datagram.
+ *
+ * \note If this function returns 1 (data pending), this
+ * does not imply that a subsequent call to
+ * \c mbedtls_ssl_read will provide any data;
+ * e.g., the unprocessed data might turn out
+ * to be an alert or a handshake message.
+ *
+ * \note This function is useful in the following situation:
+ * If the SSL/TLS module successfully returns from an
+ * operation - e.g. a handshake or an application record
+ * read - and you're awaiting incoming data next, you
+ * must not immediately idle on the underlying transport
+ * to have data ready, but you need to check the value
+ * of this function first. The reason is that the desired
+ * data might already be read but not yet processed.
+ * If, in contrast, a previous call to the SSL/TLS module
+ * returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary
+ * to call this function, as the latter error code entails
+ * that all internal data has been processed.
+ *
+ */
+int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Return the number of application data bytes
+ * remaining to be read from the current record.
+ *
+ * \param ssl SSL context
+ *
+ * \return How many bytes are available in the application
+ * data record read buffer.
+ *
+ * \note When working over a datagram transport, this is
+ * useful to detect the current datagram's boundary
+ * in case \c mbedtls_ssl_read has written the maximal
+ * amount of data fitting into the input buffer.
+ *
+ */
+size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Return the result of the certificate verification
+ *
+ * \param ssl The SSL context to use.
+ *
+ * \return \c 0 if the certificate verification was successful.
+ * \return \c -1u if the result is not available. This may happen
+ * e.g. if the handshake aborts early, or a verification
+ * callback returned a fatal error.
+ * \return A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX
+ * and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h.
+ */
+uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Return the name of the current ciphersuite
+ *
+ * \param ssl SSL context
+ *
+ * \return a string containing the ciphersuite name
+ */
+const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Return the current SSL version (SSLv3/TLSv1/etc)
+ *
+ * \param ssl SSL context
+ *
+ * \return a string containing the SSL version
+ */
+const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Return the (maximum) number of bytes added by the record
+ * layer: header + encryption/MAC overhead (inc. padding)
+ *
+ * \note This function is not available (always returns an error)
+ * when record compression is enabled.
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum record expansion in bytes, or
+ * MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if compression is
+ * enabled, which makes expansion much less predictable
+ */
+int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+/**
+ * \brief Return the maximum fragment length (payload, in bytes).
+ * This is the value negotiated with peer if any,
+ * or the locally configured value.
+ *
+ * \sa mbedtls_ssl_conf_max_frag_len()
+ * \sa mbedtls_ssl_get_max_record_payload()
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum fragment length.
+ */
+size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+/**
+ * \brief Return the current maximum outgoing record payload in bytes.
+ * This takes into account the config.h setting \c
+ * MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated
+ * max fragment length extension if used, and for DTLS the
+ * path MTU as configured and current record expansion.
+ *
+ * \note With DTLS, \c mbedtls_ssl_write() will return an error if
+ * called with a larger length value.
+ * With TLS, \c mbedtls_ssl_write() will fragment the input if
+ * necessary and return the number of bytes written; it is up
+ * to the caller to call \c mbedtls_ssl_write() again in
+ * order to send the remaining bytes if any.
+ *
+ * \note This function is not available (always returns an error)
+ * when record compression is enabled.
+ *
+ * \sa mbedtls_ssl_set_mtu()
+ * \sa mbedtls_ssl_get_max_frag_len()
+ * \sa mbedtls_ssl_get_record_expansion()
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum payload for an outgoing record,
+ * or a negative error code.
+ */
+int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Return the peer certificate from the current connection.
+ *
+ * \param ssl The SSL context to use. This must be initialized and setup.
+ *
+ * \return The current peer certificate, if available.
+ * The returned certificate is owned by the SSL context and
+ * is valid only until the next call to the SSL API.
+ * \return \c NULL if no peer certificate is available. This might
+ * be because the chosen ciphersuite doesn't use CRTs
+ * (PSK-based ciphersuites, for example), or because
+ * #MBEDTLS_SSL_KEEP_PEER_CERTIFICATE has been disabled,
+ * allowing the stack to free the peer's CRT to save memory.
+ *
+ * \note For one-time inspection of the peer's certificate during
+ * the handshake, consider registering an X.509 CRT verification
+ * callback through mbedtls_ssl_conf_verify() instead of calling
+ * this function. Using mbedtls_ssl_conf_verify() also comes at
+ * the benefit of allowing you to influence the verification
+ * process, for example by masking expected and tolerated
+ * verification failures.
+ *
+ * \warning You must not use the pointer returned by this function
+ * after any further call to the SSL API, including
+ * mbedtls_ssl_read() and mbedtls_ssl_write(); this is
+ * because the pointer might change during renegotiation,
+ * which happens transparently to the user.
+ * If you want to use the certificate across API calls,
+ * you must make a copy.
+ */
+const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief Save session in order to resume it later (client-side only)
+ * Session data is copied to presented session structure.
+ *
+ *
+ * \param ssl SSL context
+ * \param session session context
+ *
+ * \return 0 if successful,
+ * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed,
+ * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or
+ * arguments are otherwise invalid.
+ *
+ * \note Only the server certificate is copied, and not the full chain,
+ * so you should not attempt to validate the certificate again
+ * by calling \c mbedtls_x509_crt_verify() on it.
+ * Instead, you should use the results from the verification
+ * in the original handshake by calling \c mbedtls_ssl_get_verify_result()
+ * after loading the session again into a new SSL context
+ * using \c mbedtls_ssl_set_session().
+ *
+ * \note Once the session object is not needed anymore, you should
+ * free it by calling \c mbedtls_ssl_session_free().
+ *
+ * \sa mbedtls_ssl_set_session()
+ */
+int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *session );
+#endif /* MBEDTLS_SSL_CLI_C */
+
+/**
+ * \brief Perform the SSL handshake
+ *
+ * \param ssl SSL context
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
+ * if the handshake is incomplete and waiting for data to
+ * be available for reading from or writing to the underlying
+ * transport - in this case you must call this function again
+ * when the underlying transport is ready for the operation.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
+ * operation is in progress (see
+ * mbedtls_ssl_conf_async_private_cb()) - in this case you
+ * must call this function again when the operation is ready.
+ * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
+ * operation is in progress (see mbedtls_ecp_set_max_ops()) -
+ * in this case you must call this function again to complete
+ * the handshake when you're done attending other tasks.
+ * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
+ * and the client did not demonstrate reachability yet - in
+ * this case you must stop using the context (see below).
+ * \return Another SSL error code - in this case you must stop using
+ * the context (see below).
+ *
+ * \warning If this function returns something other than
+ * \c 0,
+ * #MBEDTLS_ERR_SSL_WANT_READ,
+ * #MBEDTLS_ERR_SSL_WANT_WRITE,
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
+ * you must stop using the SSL context for reading or writing,
+ * and either free it or call \c mbedtls_ssl_session_reset()
+ * on it before re-using it for a new connection; the current
+ * connection must be closed.
+ *
+ * \note If DTLS is in use, then you may choose to handle
+ * #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging
+ * purposes, as it is an expected return value rather than an
+ * actual error, but you still need to reset/free the context.
+ *
+ * \note Remarks regarding event-driven DTLS:
+ * If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram
+ * from the underlying transport layer is currently being processed,
+ * and it is safe to idle until the timer or the underlying transport
+ * signal a new event. This is not true for a successful handshake,
+ * in which case the datagram of the underlying transport that is
+ * currently being processed might or might not contain further
+ * DTLS records.
+ */
+int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Perform a single step of the SSL handshake
+ *
+ * \note The state of the context (ssl->state) will be at
+ * the next state after this function returns \c 0. Do not
+ * call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER.
+ *
+ * \param ssl SSL context
+ *
+ * \return See mbedtls_ssl_handshake().
+ *
+ * \warning If this function returns something other than \c 0,
+ * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
+ * the SSL context for reading or writing, and either free it
+ * or call \c mbedtls_ssl_session_reset() on it before
+ * re-using it for a new connection; the current connection
+ * must be closed.
+ */
+int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/**
+ * \brief Initiate an SSL renegotiation on the running connection.
+ * Client: perform the renegotiation right now.
+ * Server: request renegotiation, which will be performed
+ * during the next call to mbedtls_ssl_read() if honored by
+ * client.
+ *
+ * \param ssl SSL context
+ *
+ * \return 0 if successful, or any mbedtls_ssl_handshake() return
+ * value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't
+ * happen during a renegotiation.
+ *
+ * \warning If this function returns something other than \c 0,
+ * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
+ * the SSL context for reading or writing, and either free it
+ * or call \c mbedtls_ssl_session_reset() on it before
+ * re-using it for a new connection; the current connection
+ * must be closed.
+ *
+ */
+int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/**
+ * \brief Read at most 'len' application data bytes
+ *
+ * \param ssl SSL context
+ * \param buf buffer that will hold the data
+ * \param len maximum number of bytes to read
+ *
+ * \return The (positive) number of bytes read if successful.
+ * \return \c 0 if the read end of the underlying transport was closed
+ * - in this case you must stop using the context (see below).
+ * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
+ * if the handshake is incomplete and waiting for data to
+ * be available for reading from or writing to the underlying
+ * transport - in this case you must call this function again
+ * when the underlying transport is ready for the operation.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
+ * operation is in progress (see
+ * mbedtls_ssl_conf_async_private_cb()) - in this case you
+ * must call this function again when the operation is ready.
+ * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
+ * operation is in progress (see mbedtls_ecp_set_max_ops()) -
+ * in this case you must call this function again to complete
+ * the handshake when you're done attending other tasks.
+ * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
+ * side of a DTLS connection and the client is initiating a
+ * new connection using the same source port. See below.
+ * \return Another SSL error code - in this case you must stop using
+ * the context (see below).
+ *
+ * \warning If this function returns something other than
+ * a positive value,
+ * #MBEDTLS_ERR_SSL_WANT_READ,
+ * #MBEDTLS_ERR_SSL_WANT_WRITE,
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
+ * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
+ * you must stop using the SSL context for reading or writing,
+ * and either free it or call \c mbedtls_ssl_session_reset()
+ * on it before re-using it for a new connection; the current
+ * connection must be closed.
+ *
+ * \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT
+ * (which can only happen server-side), it means that a client
+ * is initiating a new connection using the same source port.
+ * You can either treat that as a connection close and wait
+ * for the client to resend a ClientHello, or directly
+ * continue with \c mbedtls_ssl_handshake() with the same
+ * context (as it has been reset internally). Either way, you
+ * must make sure this is seen by the application as a new
+ * connection: application state, if any, should be reset, and
+ * most importantly the identity of the client must be checked
+ * again. WARNING: not validating the identity of the client
+ * again, or not transmitting the new identity to the
+ * application layer, would allow authentication bypass!
+ *
+ * \note Remarks regarding event-driven DTLS:
+ * - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram
+ * from the underlying transport layer is currently being processed,
+ * and it is safe to idle until the timer or the underlying transport
+ * signal a new event.
+ * - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was
+ * initially available on the underlying transport, as this data may have
+ * been only e.g. duplicated messages or a renegotiation request.
+ * Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even
+ * when reacting to an incoming-data event from the underlying transport.
+ * - On success, the datagram of the underlying transport that is currently
+ * being processed may contain further DTLS records. You should call
+ * \c mbedtls_ssl_check_pending to check for remaining records.
+ *
+ */
+int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len );
+
+/**
+ * \brief Try to write exactly 'len' application data bytes
+ *
+ * \warning This function will do partial writes in some cases. If the
+ * return value is non-negative but less than length, the
+ * function must be called again with updated arguments:
+ * buf + ret, len - ret (if ret is the return value) until
+ * it returns a value equal to the last 'len' argument.
+ *
+ * \param ssl SSL context
+ * \param buf buffer holding the data
+ * \param len how many bytes must be written
+ *
+ * \return The (non-negative) number of bytes actually written if
+ * successful (may be less than \p len).
+ * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
+ * if the handshake is incomplete and waiting for data to
+ * be available for reading from or writing to the underlying
+ * transport - in this case you must call this function again
+ * when the underlying transport is ready for the operation.
+ * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
+ * operation is in progress (see
+ * mbedtls_ssl_conf_async_private_cb()) - in this case you
+ * must call this function again when the operation is ready.
+ * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
+ * operation is in progress (see mbedtls_ecp_set_max_ops()) -
+ * in this case you must call this function again to complete
+ * the handshake when you're done attending other tasks.
+ * \return Another SSL error code - in this case you must stop using
+ * the context (see below).
+ *
+ * \warning If this function returns something other than
+ * a non-negative value,
+ * #MBEDTLS_ERR_SSL_WANT_READ,
+ * #MBEDTLS_ERR_SSL_WANT_WRITE,
+ * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
+ * you must stop using the SSL context for reading or writing,
+ * and either free it or call \c mbedtls_ssl_session_reset()
+ * on it before re-using it for a new connection; the current
+ * connection must be closed.
+ *
+ * \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ,
+ * it must be called later with the *same* arguments,
+ * until it returns a value greater that or equal to 0. When
+ * the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be
+ * some partial data in the output buffer, however this is not
+ * yet sent.
+ *
+ * \note If the requested length is greater than the maximum
+ * fragment length (either the built-in limit or the one set
+ * or negotiated with the peer), then:
+ * - with TLS, less bytes than requested are written.
+ * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned.
+ * \c mbedtls_ssl_get_max_frag_len() may be used to query the
+ * active maximum fragment length.
+ *
+ * \note Attempting to write 0 bytes will result in an empty TLS
+ * application record being sent.
+ */
+int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len );
+
+/**
+ * \brief Send an alert message
+ *
+ * \param ssl SSL context
+ * \param level The alert level of the message
+ * (MBEDTLS_SSL_ALERT_LEVEL_WARNING or MBEDTLS_SSL_ALERT_LEVEL_FATAL)
+ * \param message The alert message (SSL_ALERT_MSG_*)
+ *
+ * \return 0 if successful, or a specific SSL error code.
+ *
+ * \note If this function returns something other than 0 or
+ * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ * the SSL context for reading or writing, and either free it or
+ * call \c mbedtls_ssl_session_reset() on it before re-using it
+ * for a new connection; the current connection must be closed.
+ */
+int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
+ unsigned char level,
+ unsigned char message );
+/**
+ * \brief Notify the peer that the connection is being closed
+ *
+ * \param ssl SSL context
+ *
+ * \return 0 if successful, or a specific SSL error code.
+ *
+ * \note If this function returns something other than 0 or
+ * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ * the SSL context for reading or writing, and either free it or
+ * call \c mbedtls_ssl_session_reset() on it before re-using it
+ * for a new connection; the current connection must be closed.
+ */
+int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Free referenced items in an SSL context and clear memory
+ *
+ * \param ssl SSL context
+ */
+void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Initialize an SSL configuration context
+ * Just makes the context ready for
+ * mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free().
+ *
+ * \note You need to call mbedtls_ssl_config_defaults() unless you
+ * manually set all of the relevant fields yourself.
+ *
+ * \param conf SSL configuration context
+ */
+void mbedtls_ssl_config_init( mbedtls_ssl_config *conf );
+
+/**
+ * \brief Load reasonnable default SSL configuration values.
+ * (You need to call mbedtls_ssl_config_init() first.)
+ *
+ * \param conf SSL configuration context
+ * \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER
+ * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or
+ * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS
+ * \param preset a MBEDTLS_SSL_PRESET_XXX value
+ *
+ * \note See \c mbedtls_ssl_conf_transport() for notes on DTLS.
+ *
+ * \return 0 if successful, or
+ * MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error.
+ */
+int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
+ int endpoint, int transport, int preset );
+
+/**
+ * \brief Free an SSL configuration context
+ *
+ * \param conf SSL configuration context
+ */
+void mbedtls_ssl_config_free( mbedtls_ssl_config *conf );
+
+/**
+ * \brief Initialize SSL session structure
+ *
+ * \param session SSL session
+ */
+void mbedtls_ssl_session_init( mbedtls_ssl_session *session );
+
+/**
+ * \brief Free referenced items in an SSL session including the
+ * peer certificate and clear memory
+ *
+ * \note A session object can be freed even if the SSL context
+ * that was used to retrieve the session is still in use.
+ *
+ * \param session SSL session
+ */
+void mbedtls_ssl_session_free( mbedtls_ssl_session *session );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl.h */
diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h
new file mode 100644
index 0000000..84254d3
--- /dev/null
+++ b/include/mbedtls/ssl_cache.h
@@ -0,0 +1,151 @@
+/**
+ * \file ssl_cache.h
+ *
+ * \brief SSL session cache implementation
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#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)
+#include "threading.h"
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT)
+#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */
+#endif
+
+#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES)
+#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct mbedtls_ssl_cache_context mbedtls_ssl_cache_context;
+typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry;
+
+/**
+ * \brief This structure is used for storing cache entries
+ */
+struct mbedtls_ssl_cache_entry
+{
+#if defined(MBEDTLS_HAVE_TIME)
+ mbedtls_time_t timestamp; /*!< entry timestamp */
+#endif
+ mbedtls_ssl_session session; /*!< entry session */
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_x509_buf peer_cert; /*!< entry peer_cert */
+#endif
+ mbedtls_ssl_cache_entry *next; /*!< chain pointer */
+};
+
+/**
+ * \brief Cache context
+ */
+struct mbedtls_ssl_cache_context
+{
+ mbedtls_ssl_cache_entry *chain; /*!< start of the chain */
+ int timeout; /*!< cache entry timeout */
+ int max_entries; /*!< maximum entries */
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex; /*!< mutex */
+#endif
+};
+
+/**
+ * \brief Initialize an SSL cache context
+ *
+ * \param cache SSL cache context
+ */
+void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache );
+
+/**
+ * \brief Cache get callback implementation
+ * (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param data SSL cache context
+ * \param session session to retrieve entry for
+ */
+int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session );
+
+/**
+ * \brief Cache set callback implementation
+ * (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param data SSL cache context
+ * \param session session to store entry for
+ */
+int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session );
+
+#if defined(MBEDTLS_HAVE_TIME)
+/**
+ * \brief Set the cache timeout
+ * (Default: MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT (1 day))
+ *
+ * A timeout of 0 indicates no timeout.
+ *
+ * \param cache SSL cache context
+ * \param timeout cache entry timeout in seconds
+ */
+void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout );
+#endif /* MBEDTLS_HAVE_TIME */
+
+/**
+ * \brief Set the maximum number of cache entries
+ * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50))
+ *
+ * \param cache SSL cache context
+ * \param max cache entry maximum
+ */
+void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max );
+
+/**
+ * \brief Free referenced items in a cache context and clear memory
+ *
+ * \param cache SSL cache context
+ */
+void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_cache.h */
diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
new file mode 100644
index 0000000..7126783
--- /dev/null
+++ b/include/mbedtls/ssl_ciphersuites.h
@@ -0,0 +1,558 @@
+/**
+ * \file ssl_ciphersuites.h
+ *
+ * \brief SSL Ciphersuites for mbed TLS
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Supported ciphersuites (Official IANA names)
+ */
+#define MBEDTLS_TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */
+#define MBEDTLS_TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */
+
+#define MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 0x04
+#define MBEDTLS_TLS_RSA_WITH_RC4_128_SHA 0x05
+#define MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A
+
+#define MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16
+
+#define MBEDTLS_TLS_PSK_WITH_NULL_SHA 0x2C /**< Weak! */
+#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA 0x2D /**< Weak! */
+#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA 0x2E /**< Weak! */
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA 0x2F
+
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA 0x35
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39
+
+#define MBEDTLS_TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45
+
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88
+
+#define MBEDTLS_TLS_PSK_WITH_RC4_128_SHA 0x8A
+#define MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA 0x8C
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA 0x8D
+
+#define MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA 0x8E
+#define MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91
+
+#define MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA 0x92
+#define MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95
+
+#define MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF
+#define MBEDTLS_TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */
+#define MBEDTLS_TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */
+
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3
+#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */
+#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */
+
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7
+#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */
+#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA 0xC033 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 /**< Weak! No SSL3! */
+#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! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */
+/* The last two are named with PSK_DHE in the RFC, which looks like a typo */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */
+
+#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
+ */
+typedef enum {
+ MBEDTLS_KEY_EXCHANGE_NONE = 0,
+ MBEDTLS_KEY_EXCHANGE_RSA,
+ MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+ MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+ MBEDTLS_KEY_EXCHANGE_PSK,
+ MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+ MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+ MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+ MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+ MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+ MBEDTLS_KEY_EXCHANGE_ECJPAKE,
+} mbedtls_key_exchange_type_t;
+
+/* Key exchanges using a certificate */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+#endif
+
+/* Key exchanges allowing client certificate requests */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED
+#endif
+
+/* Key exchanges involving server signature in ServerKeyExchange */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED
+#endif
+
+/* Key exchanges using ECDH */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED
+#endif
+
+/* Key exchanges that don't involve ephemeral keys */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED
+#endif
+
+/* Key exchanges that involve ephemeral keys */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED
+#endif
+
+/* Key exchanges using a PSK */
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
+#endif
+
+/* Key exchanges using DHE */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED
+#endif
+
+/* Key exchanges using ECDHE */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
+#endif
+
+typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t;
+
+#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */
+#define MBEDTLS_CIPHERSUITE_SHORT_TAG 0x02 /**< Short authentication tag,
+ eg for CCM_8 */
+#define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */
+
+/**
+ * \brief This structure is used for storing ciphersuite information
+ */
+struct mbedtls_ssl_ciphersuite_t
+{
+ int id;
+ const char * name;
+
+ mbedtls_cipher_type_t cipher;
+ mbedtls_md_type_t mac;
+ mbedtls_key_exchange_type_t key_exchange;
+
+ int min_major_ver;
+ int min_minor_ver;
+ int max_major_ver;
+ int max_minor_ver;
+
+ unsigned char flags;
+};
+
+const int *mbedtls_ssl_list_ciphersuites( void );
+
+const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name );
+const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id );
+
+#if defined(MBEDTLS_PK_C)
+mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info );
+mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info );
+#endif
+
+int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info );
+int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info );
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
+static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+ case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+ case MBEDTLS_KEY_EXCHANGE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_PSK:
+ case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
+
+static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+
+static inline int mbedtls_ssl_ciphersuite_uses_srv_cert( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+ case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_ciphersuites.h */
diff --git a/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h
new file mode 100644
index 0000000..e34760a
--- /dev/null
+++ b/include/mbedtls/ssl_cookie.h
@@ -0,0 +1,115 @@
+/**
+ * \file ssl_cookie.h
+ *
+ * \brief DTLS cookie callbacks implementation
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#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)
+#include "threading.h"
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+#ifndef MBEDTLS_SSL_COOKIE_TIMEOUT
+#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Context for the default cookie functions.
+ */
+typedef struct mbedtls_ssl_cookie_ctx
+{
+ mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */
+#if !defined(MBEDTLS_HAVE_TIME)
+ unsigned long serial; /*!< serial number for expiration */
+#endif
+ unsigned long timeout; /*!< timeout delay, in seconds if HAVE_TIME,
+ or in number of tickets issued */
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+#endif
+} mbedtls_ssl_cookie_ctx;
+
+/**
+ * \brief Initialize cookie context
+ */
+void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx );
+
+/**
+ * \brief Setup cookie context (generate keys)
+ */
+int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief Set expiration delay for cookies
+ * (Default MBEDTLS_SSL_COOKIE_TIMEOUT)
+ *
+ * \param ctx Cookie contex
+ * \param delay Delay, in seconds if HAVE_TIME, or in number of cookies
+ * issued in the meantime.
+ * 0 to disable expiration (NOT recommended)
+ */
+void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay );
+
+/**
+ * \brief Free cookie context
+ */
+void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx );
+
+/**
+ * \brief Generate cookie, see \c mbedtls_ssl_cookie_write_t
+ */
+mbedtls_ssl_cookie_write_t mbedtls_ssl_cookie_write;
+
+/**
+ * \brief Verify cookie, see \c mbedtls_ssl_cookie_write_t
+ */
+mbedtls_ssl_cookie_check_t mbedtls_ssl_cookie_check;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_cookie.h */
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
new file mode 100644
index 0000000..5dde239
--- /dev/null
+++ b/include/mbedtls/ssl_internal.h
@@ -0,0 +1,819 @@
+/**
+ * \file ssl_internal.h
+ *
+ * \brief Internal functions shared by the SSL modules
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_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"
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+#include "md5.h"
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+#include "sha1.h"
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+#include "sha256.h"
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+#include "sha512.h"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#include "ecjpake.h"
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "psa_util.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/* Determine minimum supported version */
+#define MBEDTLS_SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1 */
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1
+#define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3
+
+/* Determine maximum supported version */
+#define MBEDTLS_SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1
+#else
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1 */
+#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 */
+#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */
+
+/*
+ * DTLS retransmission states, see RFC 6347 4.2.4
+ *
+ * The SENDING state is merged in PREPARING for initial sends,
+ * but is distinct for resends.
+ *
+ * Note: initial state is wrong for server, but is not used anyway.
+ */
+#define MBEDTLS_SSL_RETRANS_PREPARING 0
+#define MBEDTLS_SSL_RETRANS_SENDING 1
+#define MBEDTLS_SSL_RETRANS_WAITING 2
+#define MBEDTLS_SSL_RETRANS_FINISHED 3
+
+/*
+ * Allow extra bytes for record, authentication and encryption overhead:
+ * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256)
+ * and allow for a maximum of 1024 of compression expansion if
+ * enabled.
+ */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+#define MBEDTLS_SSL_COMPRESSION_ADD 1024
+#else
+#define MBEDTLS_SSL_COMPRESSION_ADD 0
+#endif
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC)
+/* Ciphersuites using HMAC */
+#if defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */
+#elif defined(MBEDTLS_SHA256_C)
+#define MBEDTLS_SSL_MAC_ADD 32 /* SHA-256 used for HMAC */
+#else
+#define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */
+#endif
+#else
+/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */
+#define MBEDTLS_SSL_MAC_ADD 16
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#define MBEDTLS_SSL_PADDING_ADD 256
+#else
+#define MBEDTLS_SSL_PADDING_ADD 0
+#endif
+
+#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."
+#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_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_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
+ * that need it (e.g. for RENEGOTIATION_INFO the server already knows because
+ * of state of the renegotiation flag, so no indicator is required)
+ */
+#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0)
+#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+/*
+ * Abstraction for a grid of allowed signature-hash-algorithm pairs.
+ */
+struct mbedtls_ssl_sig_hash_set_t
+{
+ /* At the moment, we only need to remember a single suitable
+ * hash algorithm per signature algorithm. As long as that's
+ * the case - and we don't need a general lookup function -
+ * we can implement the sig-hash-set as a map from signatures
+ * to hash algorithms. */
+ mbedtls_md_type_t rsa;
+ mbedtls_md_type_t ecdsa;
+};
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+/*
+ * This structure contains the parameters only needed during handshake.
+ */
+struct mbedtls_ssl_handshake_params
+{
+ /*
+ * Handshake specific crypto variables
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */
+#endif
+#if defined(MBEDTLS_DHM_C)
+ mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */
+#endif
+#if defined(MBEDTLS_ECDH_C)
+ mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_ecc_curve_t ecdh_psa_curve;
+ psa_key_handle_t ecdh_psa_privkey;
+ unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
+ size_t ecdh_psa_peerkey_len;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#endif /* MBEDTLS_ECDH_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */
+#if defined(MBEDTLS_SSL_CLI_C)
+ unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */
+ size_t ecjpake_cache_len; /*!< Length of cached data */
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_key_handle_t psk_opaque; /*!< Opaque PSK from the callback */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ unsigned char *psk; /*!< PSK from the callback */
+ size_t psk_len; /*!< Length of PSK from callback */
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ int sni_authmode; /*!< authmode from SNI callback */
+ mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */
+ mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */
+ 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 */
+ mbedtls_x509_crt *ecrs_peer_cert; /*!< The peer's CRT chain. */
+ size_t ecrs_n; /*!< place for saving a length */
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
+ unsigned int in_msg_seq; /*!< Incoming handshake sequence number */
+
+ unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie
+ Srv: unused */
+ unsigned char verify_cookie_len; /*!< Cli: cookie length
+ Srv: flag for sending a cookie */
+
+ 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 */
+ 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 */
+
+ /*
+ * Checksum contexts
+ */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1)
+ mbedtls_md5_context fin_md5;
+ mbedtls_sha1_context fin_sha1;
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_operation_t fin_sha256_psa;
+#else
+ mbedtls_sha256_context fin_sha256;
+#endif
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_operation_t fin_sha384_psa;
+#else
+ mbedtls_sha512_context fin_sha512;
+#endif
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
+ void (*calc_verify)(mbedtls_ssl_context *, unsigned char *);
+ void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
+ int (*tls_prf)(const unsigned char *, size_t, const char *,
+ const unsigned char *, size_t,
+ unsigned char *, size_t);
+
+ size_t pmslen; /*!< premaster length */
+
+ unsigned char randbytes[64]; /*!< random bytes */
+ unsigned char premaster[MBEDTLS_PREMASTER_SIZE];
+ /*!< premaster secret */
+
+ int resume; /*!< session resume indicator*/
+ int max_major_ver; /*!< max. major version client*/
+ int max_minor_ver; /*!< max. minor version client*/
+ int cli_exts; /*!< client extension presence*/
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ int new_session_ticket; /*!< use NewSessionTicket? */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+#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.
+ */
+struct mbedtls_ssl_transform
+{
+ /*
+ * Session specific crypto layer
+ */
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+ /*!< Chosen cipersuite_info */
+ unsigned int keylen; /*!< symmetric key length (bytes) */
+ size_t minlen; /*!< min. ciphertext length */
+ size_t ivlen; /*!< IV length */
+ size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */
+ size_t maclen; /*!< MAC length */
+
+ unsigned char iv_enc[16]; /*!< IV (encryption) */
+ unsigned char iv_dec[16]; /*!< IV (decryption) */
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ /* Needed only for SSL v3.0 secret */
+ unsigned char mac_enc[20]; /*!< SSL v3.0 secret (enc) */
+ unsigned char mac_dec[20]; /*!< SSL v3.0 secret (dec) */
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+ mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */
+ mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */
+
+ mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */
+ mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */
+
+ /*
+ * Session specific compression layer
+ */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ z_stream ctx_deflate; /*!< compression context */
+ z_stream ctx_inflate; /*!< decompression context */
+#endif
+};
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/*
+ * List of certificate + private key pairs
+ */
+struct mbedtls_ssl_key_cert
+{
+ mbedtls_x509_crt *cert; /*!< cert */
+ mbedtls_pk_context *key; /*!< private key */
+ mbedtls_ssl_key_cert *next; /*!< next key/cert pair */
+};
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/*
+ * List of handshake messages kept around for resending
+ */
+struct mbedtls_ssl_flight_item
+{
+ unsigned char *p; /*!< message, including handshake headers */
+ size_t len; /*!< length of p */
+ unsigned char type; /*!< type of the message: handshake or CCS */
+ mbedtls_ssl_flight_item *next; /*!< next handshake message(s) */
+};
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+
+/* Find an entry in a signature-hash set matching a given hash algorithm. */
+mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
+ mbedtls_pk_type_t sig_alg );
+/* Add a signature-hash-pair to a signature-hash set */
+void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
+ mbedtls_pk_type_t sig_alg,
+ mbedtls_md_type_t md_alg );
+/* Allow exactly one hash algorithm for each signature. */
+void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
+ mbedtls_md_type_t md_alg );
+
+/* Setup an empty signature-hash set */
+static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set )
+{
+ mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
+ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+/**
+ * \brief Free referenced items in an SSL transform context and clear
+ * memory
+ *
+ * \param transform SSL transform context
+ */
+void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
+
+/**
+ * \brief Free referenced items in an SSL handshake context and clear
+ * memory
+ *
+ * \param ssl SSL context
+ */
+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 );
+void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
+
+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_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 );
+
+/**
+ * \brief Update record layer
+ *
+ * This function roughly separates the implementation
+ * of the logic of (D)TLS from the implementation
+ * of the secure transport.
+ *
+ * \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.
+ *
+ * \note A clarification on what is called 'record layer' here
+ * is in order, as many sensible definitions are possible:
+ *
+ * The record layer takes as input an untrusted underlying
+ * transport (stream or datagram) and transforms it into
+ * a serially multiplexed, secure transport, which
+ * conceptually provides the following:
+ *
+ * (1) Three datagram based, content-agnostic transports
+ * for handshake, alert and CCS messages.
+ * (2) One stream- or datagram-based transport
+ * for application data.
+ * (3) Functionality for changing the underlying transform
+ * securing the contents.
+ *
+ * The interface to this functionality is given as follows:
+ *
+ * a Updating
+ * [Currently implemented by mbedtls_ssl_read_record]
+ *
+ * Check if and on which of the four 'ports' data is pending:
+ * Nothing, a controlling datagram of type (1), or application
+ * data (2). In any case data is present, internal buffers
+ * provide access to the data for the user to process it.
+ * Consumption of type (1) datagrams is done automatically
+ * on the next update, invalidating that the internal buffers
+ * for previous datagrams, while consumption of application
+ * data (2) is user-controlled.
+ *
+ * b Reading of application data
+ * [Currently manual adaption of ssl->in_offt pointer]
+ *
+ * As mentioned in the last paragraph, consumption of data
+ * is different from the automatic consumption of control
+ * datagrams (1) because application data is treated as a stream.
+ *
+ * c Tracking availability of application data
+ * [Currently manually through decreasing ssl->in_msglen]
+ *
+ * For efficiency and to retain datagram semantics for
+ * application data in case of DTLS, the record layer
+ * provides functionality for checking how much application
+ * data is still available in the internal buffer.
+ *
+ * d Changing the transformation securing the communication.
+ *
+ * Given an opaque implementation of the record layer in the
+ * above sense, it should be possible to implement the logic
+ * of (D)TLS on top of it without the need to know anything
+ * about the record layer's internals. This is done e.g.
+ * in all the handshake handling functions, and in the
+ * application data reading function mbedtls_ssl_read.
+ *
+ * \note The above tries to give a conceptual picture of the
+ * record layer, but the current implementation deviates
+ * from it in some places. For example, our implementation of
+ * the update functionality through mbedtls_ssl_read_record
+ * discards datagrams depending on the current state, which
+ * wouldn't fall under the record layer's responsibility
+ * following the above definition.
+ *
+ */
+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_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 );
+int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl );
+
+void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info );
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex );
+#endif
+
+#if defined(MBEDTLS_PK_C)
+unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk );
+unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type );
+mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig );
+#endif
+
+mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash );
+unsigned char mbedtls_ssl_hash_from_md_alg( int md );
+int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md );
+
+#if defined(MBEDTLS_ECP_C)
+int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
+ mbedtls_md_type_t md );
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_key_cert *key_cert;
+
+ if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL )
+ key_cert = ssl->handshake->key_cert;
+ else
+ key_cert = ssl->conf->key_cert;
+
+ return( key_cert == NULL ? NULL : key_cert->key );
+}
+
+static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_key_cert *key_cert;
+
+ if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL )
+ key_cert = ssl->handshake->key_cert;
+ else
+ key_cert = ssl->conf->key_cert;
+
+ return( key_cert == NULL ? NULL : key_cert->cert );
+}
+
+/*
+ * Check usage of a certificate wrt extensions:
+ * keyUsage, extendedKeyUsage (later), and nSCertType (later).
+ *
+ * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we
+ * check a cert we received from them)!
+ *
+ * Return 0 if everything is OK, -1 if not.
+ */
+int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
+ const mbedtls_ssl_ciphersuite_t *ciphersuite,
+ int cert_endpoint,
+ uint32_t *flags );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+void mbedtls_ssl_write_version( int major, int minor, int transport,
+ unsigned char ver[2] );
+void mbedtls_ssl_read_version( int *major, int *minor, int transport,
+ const unsigned char ver[2] );
+
+static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ return( 13 );
+#else
+ ((void) ssl);
+#endif
+ return( 5 );
+}
+
+static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ return( 12 );
+#else
+ ((void) ssl);
+#endif
+ return( 4 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+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 */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
+#endif
+
+int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
+ const mbedtls_ssl_session *src );
+
+/* constant-time buffer comparison */
+static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n )
+{
+ size_t i;
+ volatile const unsigned char *A = (volatile const unsigned char *) a;
+ volatile const unsigned char *B = (volatile const unsigned char *) b;
+ volatile unsigned char diff = 0;
+
+ for( i = 0; i < n; i++ )
+ {
+ /* Read volatile data in order before computing diff.
+ * This avoids IAR compiler warning:
+ * 'the order of volatile accesses is undefined ..' */
+ unsigned char x = A[i], y = B[i];
+ diff |= x ^ y;
+ }
+
+ return( diff );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1)
+int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
+ unsigned char *output,
+ unsigned char *data, size_t data_len );
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+ MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+/* The hash buffer must have at least MBEDTLS_MD_MAX_SIZE bytes of length. */
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+ 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 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_internal.h */
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
new file mode 100644
index 0000000..774a007
--- /dev/null
+++ b/include/mbedtls/ssl_ticket.h
@@ -0,0 +1,142 @@
+/**
+ * \file ssl_ticket.h
+ *
+ * \brief TLS server ticket callbacks implementation
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_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
+ * secrecy, when MBEDTLS_HAVE_TIME is defined.
+ */
+
+#include "ssl.h"
+#include "cipher.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Information for session ticket protection
+ */
+typedef struct mbedtls_ssl_ticket_key
+{
+ unsigned char name[4]; /*!< random key identifier */
+ uint32_t generation_time; /*!< key generation timestamp (seconds) */
+ mbedtls_cipher_context_t ctx; /*!< context for auth enc/decryption */
+}
+mbedtls_ssl_ticket_key;
+
+/**
+ * \brief Context for session ticket handling functions
+ */
+typedef struct mbedtls_ssl_ticket_context
+{
+ mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */
+ unsigned char active; /*!< index of the currently active key */
+
+ uint32_t ticket_lifetime; /*!< lifetime of tickets in seconds */
+
+ /** Callback for getting (pseudo-)random numbers */
+ int (*f_rng)(void *, unsigned char *, size_t);
+ void *p_rng; /*!< context for the RNG function */
+
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+#endif
+}
+mbedtls_ssl_ticket_context;
+
+/**
+ * \brief Initialize a ticket context.
+ * (Just make it ready for mbedtls_ssl_ticket_setup()
+ * or mbedtls_ssl_ticket_free().)
+ *
+ * \param ctx Context to be initialized
+ */
+void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx );
+
+/**
+ * \brief Prepare context to be actually used
+ *
+ * \param ctx Context to be set up
+ * \param f_rng RNG callback function
+ * \param p_rng RNG callback context
+ * \param cipher AEAD cipher to use for ticket protection.
+ * Recommended value: MBEDTLS_CIPHER_AES_256_GCM.
+ * \param lifetime Tickets lifetime in seconds
+ * Recommended value: 86400 (one day).
+ *
+ * \note It is highly recommended to select a cipher that is at
+ * least as strong as the the strongest ciphersuite
+ * supported. Usually that means a 256-bit key.
+ *
+ * \note The lifetime of the keys is twice the lifetime of tickets.
+ * It is recommended to pick a reasonnable lifetime so as not
+ * to negate the benefits of forward secrecy.
+ *
+ * \return 0 if successful,
+ * or a specific MBEDTLS_ERR_XXX error code
+ */
+int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ mbedtls_cipher_type_t cipher,
+ uint32_t lifetime );
+
+/**
+ * \brief Implementation of the ticket write callback
+ *
+ * \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 mbedtls_ssl_ticket_parse_t for description
+ */
+mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse;
+
+/**
+ * \brief Free a context's content and zeroize it.
+ *
+ * \param ctx Context to be cleaned up
+ */
+void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_ticket.h */
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
new file mode 100644
index 0000000..b63e864
--- /dev/null
+++ b/include/mbedtls/x509.h
@@ -0,0 +1,339 @@
+/**
+ * \file x509.h
+ *
+ * \brief X.509 generic defines and structures
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_X509_H
+#define MBEDTLS_X509_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "asn1.h"
+#include "pk.h"
+
+#if defined(MBEDTLS_RSA_C)
+#include "rsa.h"
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{
+ */
+
+#if !defined(MBEDTLS_X509_MAX_INTERMEDIATE_CA)
+/**
+ * Maximum number of intermediate CAs in a verification chain.
+ * That is, maximum length of the chain, excluding the end-entity certificate
+ * and the trusted root certificate.
+ *
+ * Set this to a low value to prevent an adversary from making you waste
+ * resources verifying an overlong certificate chain.
+ */
+#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8
+#endif
+
+/**
+ * \name X509 Error codes
+ * \{
+ */
+#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */
+#define MBEDTLS_ERR_X509_UNKNOWN_OID -0x2100 /**< Requested OID is unknown. */
+#define MBEDTLS_ERR_X509_INVALID_FORMAT -0x2180 /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */
+#define MBEDTLS_ERR_X509_INVALID_VERSION -0x2200 /**< The CRT/CRL/CSR version element is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_SIGNATURE -0x2480 /**< The signature tag or value invalid. */
+#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS -0x2500 /**< The extension tag or value is invalid. */
+#define MBEDTLS_ERR_X509_UNKNOWN_VERSION -0x2580 /**< CRT/CRL/CSR has an unsupported version number. */
+#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -0x2600 /**< Signature algorithm (oid) is unsupported. */
+#define MBEDTLS_ERR_X509_SIG_MISMATCH -0x2680 /**< Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */
+#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -0x2700 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */
+#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 /**< Format not recognized as DER or PEM. */
+#define MBEDTLS_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */
+#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 occurred, eg the chain is too long or the vrfy callback failed. */
+/* \} name */
+
+/**
+ * \name X509 Verify codes
+ * \{
+ */
+/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */
+#define MBEDTLS_X509_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */
+#define MBEDTLS_X509_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */
+#define MBEDTLS_X509_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */
+#define MBEDTLS_X509_BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */
+#define MBEDTLS_X509_BADCRL_NOT_TRUSTED 0x10 /**< The CRL is not correctly signed by the trusted CA. */
+#define MBEDTLS_X509_BADCRL_EXPIRED 0x20 /**< The CRL is expired. */
+#define MBEDTLS_X509_BADCERT_MISSING 0x40 /**< Certificate was missing. */
+#define MBEDTLS_X509_BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */
+#define MBEDTLS_X509_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */
+#define MBEDTLS_X509_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */
+#define MBEDTLS_X509_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */
+#define MBEDTLS_X509_BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */
+#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */
+#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */
+#define MBEDTLS_X509_BADCERT_BAD_MD 0x4000 /**< The certificate is signed with an unacceptable hash. */
+#define MBEDTLS_X509_BADCERT_BAD_PK 0x8000 /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
+#define MBEDTLS_X509_BADCERT_BAD_KEY 0x010000 /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */
+#define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */
+#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
+#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */
+
+/* \} name */
+/* \} addtogroup x509_module */
+
+/*
+ * X.509 v3 Key Usage Extension flags
+ * Reminder: update x509_info_key_usage() when adding new flags.
+ */
+#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
+#define MBEDTLS_X509_KU_NON_REPUDIATION (0x40) /* bit 1 */
+#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */
+#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */
+#define MBEDTLS_X509_KU_KEY_AGREEMENT (0x08) /* bit 4 */
+#define MBEDTLS_X509_KU_KEY_CERT_SIGN (0x04) /* bit 5 */
+#define MBEDTLS_X509_KU_CRL_SIGN (0x02) /* bit 6 */
+#define MBEDTLS_X509_KU_ENCIPHER_ONLY (0x01) /* bit 7 */
+#define MBEDTLS_X509_KU_DECIPHER_ONLY (0x8000) /* bit 8 */
+
+/*
+ * Netscape certificate types
+ * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html)
+ */
+
+#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */
+#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */
+#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */
+#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */
+#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */
+#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */
+#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */
+#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */
+
+/*
+ * X.509 extension types
+ *
+ * Comments refer to the status for using certificates. Status can be
+ * different for writing certificates or reading CRLs or CSRs.
+ *
+ * Those are defined in oid.h as oid.c needs them in a data structure. Since
+ * these were previously defined here, let's have aliases for compatibility.
+ */
+#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER
+#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER
+#define MBEDTLS_X509_EXT_KEY_USAGE MBEDTLS_OID_X509_EXT_KEY_USAGE
+#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES
+#define MBEDTLS_X509_EXT_POLICY_MAPPINGS MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS
+#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME /* Supported (DNS) */
+#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME
+#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS
+#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS /* Supported */
+#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS
+#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS
+#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE
+#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS
+#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY
+#define MBEDTLS_X509_EXT_FRESHEST_CRL MBEDTLS_OID_X509_EXT_FRESHEST_CRL
+#define MBEDTLS_X509_EXT_NS_CERT_TYPE MBEDTLS_OID_X509_EXT_NS_CERT_TYPE
+
+/*
+ * Storage format identifiers
+ * Recognized formats: PEM and DER
+ */
+#define MBEDTLS_X509_FORMAT_DER 1
+#define MBEDTLS_X509_FORMAT_PEM 2
+
+#define MBEDTLS_X509_MAX_DN_NAME_SIZE 256 /**< Maximum value size of a DN entry */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{ */
+
+/**
+ * \name Structures for parsing X.509 certificates, CRLs and CSRs
+ * \{
+ */
+
+/**
+ * Type-length-value structure that allows for ASN1 using DER.
+ */
+typedef mbedtls_asn1_buf mbedtls_x509_buf;
+
+/**
+ * Container for ASN1 bit strings.
+ */
+typedef mbedtls_asn1_bitstring mbedtls_x509_bitstring;
+
+/**
+ * Container for ASN1 named information objects.
+ * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.).
+ */
+typedef mbedtls_asn1_named_data mbedtls_x509_name;
+
+/**
+ * Container for a sequence of ASN.1 items
+ */
+typedef mbedtls_asn1_sequence mbedtls_x509_sequence;
+
+/** Container for date and time (precision in seconds). */
+typedef struct mbedtls_x509_time
+{
+ int year, mon, day; /**< Date. */
+ int hour, min, sec; /**< Time. */
+}
+mbedtls_x509_time;
+
+/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
+/** \} addtogroup x509_module */
+
+/**
+ * \brief Store the certificate DN in printable form into buf;
+ * no more than size characters will be written.
+ *
+ * \param buf Buffer to write to
+ * \param size Maximum size of buffer
+ * \param dn The X509 name to represent
+ *
+ * \return The length of the string written (not including the
+ * terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn );
+
+/**
+ * \brief Store the certificate serial in printable form into buf;
+ * no more than size characters will be written.
+ *
+ * \param buf Buffer to write to
+ * \param size Maximum size of buffer
+ * \param serial The X509 serial to represent
+ *
+ * \return The length of the string written (not including the
+ * terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial );
+
+/**
+ * \brief Check a given mbedtls_x509_time against the system time
+ * and tell if it's in the past.
+ *
+ * \note Intended usage is "if( is_past( valid_to ) ) ERROR".
+ * Hence the return value of 1 if on internal errors.
+ *
+ * \param to mbedtls_x509_time to check
+ *
+ * \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 );
+
+/**
+ * \brief Check a given mbedtls_x509_time against the system time
+ * and tell if it's in the future.
+ *
+ * \note Intended usage is "if( is_future( valid_from ) ) ERROR".
+ * Hence the return value of 1 if on internal errors.
+ *
+ * \param from mbedtls_x509_time to check
+ *
+ * \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
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+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.
+ */
+int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
+ mbedtls_x509_name *cur );
+int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
+ mbedtls_x509_buf *alg );
+int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
+ mbedtls_x509_buf *alg, mbedtls_x509_buf *params );
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
+ mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
+ int *salt_len );
+#endif
+int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig );
+int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
+ mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
+ void **sig_opts );
+int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
+ mbedtls_x509_time *t );
+int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
+ mbedtls_x509_buf *serial );
+int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
+ mbedtls_x509_buf *ext, int tag );
+int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
+ mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
+ const void *sig_opts );
+int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name );
+int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name );
+int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
+ int critical, const unsigned char *val,
+ size_t val_len );
+int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
+ mbedtls_asn1_named_data *first );
+int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
+ mbedtls_asn1_named_data *first );
+int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
+ const char *oid, size_t oid_len,
+ unsigned char *sig, size_t size );
+
+#define MBEDTLS_X509_SAFE_SNPRINTF \
+ do { \
+ if( ret < 0 || (size_t) ret >= n ) \
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); \
+ \
+ n -= (size_t) ret; \
+ p += (size_t) ret; \
+ } while( 0 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* x509.h */
diff --git a/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h
new file mode 100644
index 0000000..fa838d6
--- /dev/null
+++ b/include/mbedtls/x509_crl.h
@@ -0,0 +1,174 @@
+/**
+ * \file x509_crl.h
+ *
+ * \brief X.509 certificate revocation list parsing
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_X509_CRL_H
+#define MBEDTLS_X509_CRL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "x509.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{ */
+
+/**
+ * \name Structures and functions for parsing CRLs
+ * \{
+ */
+
+/**
+ * Certificate revocation list entry.
+ * Contains the CA-specific serial numbers and revocation dates.
+ */
+typedef struct mbedtls_x509_crl_entry
+{
+ mbedtls_x509_buf raw;
+
+ mbedtls_x509_buf serial;
+
+ mbedtls_x509_time revocation_date;
+
+ mbedtls_x509_buf entry_ext;
+
+ struct mbedtls_x509_crl_entry *next;
+}
+mbedtls_x509_crl_entry;
+
+/**
+ * Certificate revocation list structure.
+ * Every CRL may have multiple entries.
+ */
+typedef struct mbedtls_x509_crl
+{
+ mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
+ mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
+
+ int version; /**< CRL version (1=v1, 2=v2) */
+ mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */
+
+ mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */
+
+ mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */
+
+ mbedtls_x509_time this_update;
+ mbedtls_x509_time next_update;
+
+ mbedtls_x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */
+
+ mbedtls_x509_buf crl_ext;
+
+ mbedtls_x509_buf sig_oid2;
+ mbedtls_x509_buf sig;
+ mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
+ mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
+ void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
+
+ struct mbedtls_x509_crl *next;
+}
+mbedtls_x509_crl;
+
+/**
+ * \brief Parse a DER-encoded CRL and append it to the chained list
+ *
+ * \param chain points to the start of the chain
+ * \param buf buffer holding the CRL data in DER format
+ * \param buflen size of the buffer
+ * (including the terminating null byte for PEM data)
+ *
+ * \return 0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
+ const unsigned char *buf, size_t buflen );
+/**
+ * \brief Parse one or more CRLs and append them to the chained list
+ *
+ * \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
+ * \param buflen size of the buffer
+ * (including the terminating null byte for PEM data)
+ *
+ * \return 0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief Load one or more CRLs and append them to the chained list
+ *
+ * \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)
+ *
+ * \return 0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief Returns an informational string about the CRL.
+ *
+ * \param buf Buffer to write to
+ * \param size Maximum size of buffer
+ * \param prefix A line prefix
+ * \param crl The X509 CRL to represent
+ *
+ * \return The length of the string written (not including the
+ * terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
+ const mbedtls_x509_crl *crl );
+
+/**
+ * \brief Initialize a CRL (chain)
+ *
+ * \param crl CRL chain to initialize
+ */
+void mbedtls_x509_crl_init( mbedtls_x509_crl *crl );
+
+/**
+ * \brief Unallocate all CRL data
+ *
+ * \param crl CRL chain to free
+ */
+void mbedtls_x509_crl_free( mbedtls_x509_crl *crl );
+
+/* \} name */
+/* \} addtogroup x509_module */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_x509_crl.h */
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
new file mode 100644
index 0000000..eea2632
--- /dev/null
+++ b/include/mbedtls/x509_crt.h
@@ -0,0 +1,921 @@
+/**
+ * \file x509_crt.h
+ *
+ * \brief X.509 certificate parsing and writing
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_X509_CRT_H
+#define MBEDTLS_X509_CRT_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "x509.h"
+#include "x509_crl.h"
+
+/**
+ * \addtogroup x509_module
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name Structures and functions for parsing and writing X.509 certificates
+ * \{
+ */
+
+/**
+ * Container for an X.509 certificate. The certificate may be chained.
+ */
+typedef struct mbedtls_x509_crt
+{
+ int own_buffer; /**< Indicates if \c raw is owned
+ * by the structure or not. */
+ mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
+ mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
+
+ int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
+ mbedtls_x509_buf serial; /**< Unique id for certificate issued by a specific CA. */
+ mbedtls_x509_buf sig_oid; /**< Signature algorithm, e.g. sha1RSA */
+
+ mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */
+ mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */
+
+ mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */
+ mbedtls_x509_name subject; /**< The parsed subject data (named information object). */
+
+ mbedtls_x509_time valid_from; /**< Start time of certificate validity. */
+ mbedtls_x509_time valid_to; /**< End time of certificate validity. */
+
+ mbedtls_x509_buf pk_raw;
+ mbedtls_pk_context pk; /**< Container for the public key context. */
+
+ mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
+ mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
+ mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */
+ mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */
+
+ int ext_types; /**< Bit string containing detected and parsed extensions */
+ int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
+ int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */
+
+ unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */
+
+ mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
+
+ unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */
+
+ mbedtls_x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */
+ mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
+ mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
+ void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
+
+ struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */
+}
+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 ) )
+
+/**
+ * Security profile for certificate verification.
+ *
+ * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG().
+ */
+typedef struct mbedtls_x509_crt_profile
+{
+ uint32_t allowed_mds; /**< MDs for signatures */
+ uint32_t allowed_pks; /**< PK algs for signatures */
+ uint32_t allowed_curves; /**< Elliptic curves for ECDSA */
+ uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */
+}
+mbedtls_x509_crt_profile;
+
+#define MBEDTLS_X509_CRT_VERSION_1 0
+#define MBEDTLS_X509_CRT_VERSION_2 1
+#define MBEDTLS_X509_CRT_VERSION_3 2
+
+#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32
+#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15
+
+#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN )
+#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512
+#endif
+
+/**
+ * Container for writing a certificate (CRT)
+ */
+typedef struct mbedtls_x509write_cert
+{
+ int version;
+ mbedtls_mpi serial;
+ mbedtls_pk_context *subject_key;
+ mbedtls_pk_context *issuer_key;
+ mbedtls_asn1_named_data *subject;
+ mbedtls_asn1_named_data *issuer;
+ mbedtls_md_type_t md_alg;
+ char not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1];
+ char not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1];
+ mbedtls_asn1_named_data *extensions;
+}
+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;
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ /* This stores the list of potential trusted signers obtained from
+ * the CA callback used for the CRT verification, if configured.
+ * We must track it somewhere because the callback passes its
+ * ownership to the caller. */
+ mbedtls_x509_crt *trust_ca_cb_result;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+} 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
+ * and compatibility with current deployments.
+ */
+extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default;
+
+/**
+ * Expected next default profile. Recommended for new deployments.
+ * Currently targets a 128-bit security level, except for RSA-2048.
+ */
+extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next;
+
+/**
+ * NSA Suite B profile.
+ */
+extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb;
+
+/**
+ * \brief Parse a single DER formatted certificate and add it
+ * to the end of the provided chained list.
+ *
+ * \param chain The pointer to the start of the CRT chain to attach to.
+ * When parsing the first CRT in a chain, this should point
+ * to an instance of ::mbedtls_x509_crt initialized through
+ * mbedtls_x509_crt_init().
+ * \param buf The buffer holding the DER encoded certificate.
+ * \param buflen The size in Bytes of \p buf.
+ *
+ * \note This function makes an internal copy of the CRT buffer
+ * \p buf. In particular, \p buf may be destroyed or reused
+ * after this call returns. To avoid duplicating the CRT
+ * buffer (at the cost of stricter lifetime constraints),
+ * use mbedtls_x509_crt_parse_der_nocopy() instead.
+ *
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
+ */
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen );
+
+/**
+ * \brief Parse a single DER formatted certificate and add it
+ * to the end of the provided chained list. This is a
+ * variant of mbedtls_x509_crt_parse_der() which takes
+ * temporary ownership of the CRT buffer until the CRT
+ * is destroyed.
+ *
+ * \param chain The pointer to the start of the CRT chain to attach to.
+ * When parsing the first CRT in a chain, this should point
+ * to an instance of ::mbedtls_x509_crt initialized through
+ * mbedtls_x509_crt_init().
+ * \param buf The address of the readable buffer holding the DER encoded
+ * certificate to use. On success, this buffer must be
+ * retained and not be changed for the liftetime of the
+ * CRT chain \p chain, that is, until \p chain is destroyed
+ * through a call to mbedtls_x509_crt_free().
+ * \param buflen The size in Bytes of \p buf.
+ *
+ * \note This call is functionally equivalent to
+ * mbedtls_x509_crt_parse_der(), but it avoids creating a
+ * copy of the input buffer at the cost of stronger lifetime
+ * constraints. This is useful in constrained environments
+ * where duplication of the CRT cannot be tolerated.
+ *
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
+ */
+int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen );
+
+/**
+ * \brief Parse one DER-encoded or one or more concatenated PEM-encoded
+ * certificates and add them to the chained list.
+ *
+ * For CRTs in PEM encoding, the function parses permissively:
+ * if at least one certificate can be parsed, the function
+ * returns the number of certificates for which parsing failed
+ * (hence \c 0 if all certificates were parsed successfully).
+ * If no certificate could be parsed, the function returns
+ * the first (negative) error encountered during parsing.
+ *
+ * PEM encoded certificates may be interleaved by other data
+ * such as human readable descriptions of their content, as
+ * long as the certificates are enclosed in the PEM specific
+ * '-----{BEGIN/END} CERTIFICATE-----' delimiters.
+ *
+ * \param chain The chain to which to add the parsed certificates.
+ * \param buf The buffer holding the certificate data in PEM or DER format.
+ * For certificates in PEM encoding, this may be a concatenation
+ * of multiple certificates; for DER encoding, the buffer must
+ * comprise exactly one certificate.
+ * \param buflen The size of \p buf, including the terminating \c NULL byte
+ * in case of PEM encoded data.
+ *
+ * \return \c 0 if all certificates were parsed successfully.
+ * \return The (positive) number of certificates that couldn't
+ * be parsed if parsing was partly successful (see above).
+ * \return A negative X509 or PEM error code otherwise.
+ *
+ */
+int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief Load one or more certificates and add them
+ * to the chained list. Parses permissively. If some
+ * certificates can be parsed, the result is the number
+ * of failed certificates it encountered. If none complete
+ * correctly, the first error is returned.
+ *
+ * \param chain points to the start of the chain
+ * \param path filename to read the certificates from
+ *
+ * \return 0 if all certificates parsed successfully, a positive number
+ * if partly successful or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path );
+
+/**
+ * \brief Load one or more certificate files from a path and add them
+ * to the chained list. Parses permissively. If some
+ * certificates can be parsed, the result is the number
+ * of failed certificates it encountered. If none complete
+ * correctly, the first error is returned.
+ *
+ * \param chain points to the start of the chain
+ * \param path directory / folder to read the certificate files from
+ *
+ * \return 0 if all certificates parsed successfully, a positive number
+ * if partly successful or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief Returns an informational string about the
+ * certificate.
+ *
+ * \param buf Buffer to write to
+ * \param size Maximum size of buffer
+ * \param prefix A line prefix
+ * \param crt The X509 certificate to represent
+ *
+ * \return The length of the string written (not including the
+ * terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
+ const mbedtls_x509_crt *crt );
+
+/**
+ * \brief Returns an informational string about the
+ * verification status of a certificate.
+ *
+ * \param buf Buffer to write to
+ * \param size Maximum size of buffer
+ * \param prefix A line prefix
+ * \param flags Verification flags created by mbedtls_x509_crt_verify()
+ *
+ * \return The length of the string written (not including the
+ * terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
+ uint32_t flags );
+
+/**
+ * \brief Verify a chain of certificates.
+ *
+ * The verify callback is a user-supplied callback that
+ * can clear / modify / add flags for a certificate. If set,
+ * the verification callback is called for each
+ * certificate in the chain (from the trust-ca down to the
+ * presented crt). The parameters for the callback are:
+ * (void *parameter, mbedtls_x509_crt *crt, int certificate_depth,
+ * int *flags). With the flags representing current flags for
+ * that specific certificate and the certificate depth from
+ * the bottom (Peer cert depth = 0).
+ *
+ * All flags left after returning from the callback
+ * are also returned to the application. The function should
+ * return 0 for anything (including invalid certificates)
+ * other than fatal error, as a non-zero return code
+ * immediately aborts the verification process. For fatal
+ * errors, a specific error code should be used (different
+ * from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not
+ * be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR
+ * can be used if no better code is available.
+ *
+ * \note In case verification failed, the results can be displayed
+ * using \c mbedtls_x509_crt_verify_info()
+ *
+ * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the
+ * default security profile.
+ *
+ * \note It is your responsibility to provide up-to-date CRLs for
+ * all trusted CAs. If no CRL is provided for the CA that was
+ * used to sign the certificate, CRL verification is skipped
+ * silently, that is *without* setting any flag.
+ *
+ * \note The \c trust_ca list can contain two types of certificates:
+ * (1) those of trusted root CAs, so that certificates
+ * chaining up to those CAs will be trusted, and (2)
+ * self-signed end-entity certificates to be trusted (for
+ * specific peers you know) - in that case, the self-signed
+ * certificate doesn't need to have the CA bit set.
+ *
+ * \param crt The certificate chain to be verified.
+ * \param trust_ca The list of trusted CAs.
+ * \param ca_crl The list of CRLs for trusted CAs.
+ * \param cn The expected Common Name. This may be \c NULL if the
+ * CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ *
+ * \return \c 0 if the chain is valid with respect to the
+ * passed CN, CAs, CRLs and security profile.
+ * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the
+ * certificate chain verification failed. In this case,
+ * \c *flags will have one or more
+ * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX
+ * flags set.
+ * \return Another negative error code in case of a fatal error
+ * encountered during the verification process.
+ */
+int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt *trust_ca,
+ mbedtls_x509_crl *ca_crl,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy );
+
+/**
+ * \brief Verify a chain of certificates with respect to
+ * a configurable security profile.
+ *
+ * \note Same as \c mbedtls_x509_crt_verify(), but with explicit
+ * security profile.
+ *
+ * \note The restrictions on keys (RSA minimum size, allowed curves
+ * for ECDSA) apply to all certificates: trusted root,
+ * intermediate CAs if any, and end entity certificate.
+ *
+ * \param crt The 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 The security profile to use for the verification.
+ * \param cn The expected Common Name. This may be \c NULL if the
+ * CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ *
+ * \return \c 0 if the chain is valid with respect to the
+ * passed CN, CAs, CRLs and security profile.
+ * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the
+ * certificate chain verification failed. In this case,
+ * \c *flags will have one or more
+ * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX
+ * flags set.
+ * \return Another negative error code in case of a fatal error
+ * encountered during the verification process.
+ */
+int mbedtls_x509_crt_verify_with_profile( 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 );
+
+/**
+ * \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 The 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 The security profile to use for the verification.
+ * \param cn The expected Common Name. This may be \c NULL if the
+ * CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ * \param rs_ctx The restart context to use. This may be set to \c NULL
+ * to disable restartable ECC.
+ *
+ * \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 );
+
+/**
+ * \brief The type of trusted certificate callbacks.
+ *
+ * Callbacks of this type are passed to and used by the CRT
+ * verification routine mbedtls_x509_crt_verify_with_ca_cb()
+ * when looking for trusted signers of a given certificate.
+ *
+ * On success, the callback returns a list of trusted
+ * certificates to be considered as potential signers
+ * for the input certificate.
+ *
+ * \param p_ctx An opaque context passed to the callback.
+ * \param child The certificate for which to search a potential signer.
+ * This will point to a readable certificate.
+ * \param candidate_cas The address at which to store the address of the first
+ * entry in the generated linked list of candidate signers.
+ * This will not be \c NULL.
+ *
+ * \note The callback must only return a non-zero value on a
+ * fatal error. If, in contrast, the search for a potential
+ * signer completes without a single candidate, the
+ * callback must return \c 0 and set \c *candidate_cas
+ * to \c NULL.
+ *
+ * \return \c 0 on success. In this case, \c *candidate_cas points
+ * to a heap-allocated linked list of instances of
+ * ::mbedtls_x509_crt, and ownership of this list is passed
+ * to the caller.
+ * \return A negative error code on failure.
+ */
+typedef int (*mbedtls_x509_crt_ca_cb_t)( void *p_ctx,
+ mbedtls_x509_crt const *child,
+ mbedtls_x509_crt **candidate_cas );
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+/**
+ * \brief Version of \c mbedtls_x509_crt_verify_with_profile() which
+ * uses a callback to acquire the list of trusted CA
+ * certificates.
+ *
+ * \param crt The certificate chain to be verified.
+ * \param f_ca_cb The callback to be used to query for potential signers
+ * of a given child certificate. See the documentation of
+ * ::mbedtls_x509_crt_ca_cb_t for more information.
+ * \param p_ca_cb The opaque context to be passed to \p f_ca_cb.
+ * \param profile The security profile for the verification.
+ * \param cn The expected Common Name. This may be \c NULL if the
+ * CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ *
+ * \return See \c mbedtls_crt_verify_with_profile().
+ */
+int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
+ 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 );
+
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+/**
+ * \brief Check usage of certificate against keyUsage extension.
+ *
+ * \param crt Leaf certificate used.
+ * \param usage Intended usage(s) (eg MBEDTLS_X509_KU_KEY_ENCIPHERMENT
+ * before using the certificate to perform an RSA key
+ * exchange).
+ *
+ * \note Except for decipherOnly and encipherOnly, a bit set in the
+ * usage argument means this bit MUST be set in the
+ * certificate. For decipherOnly and encipherOnly, it means
+ * that bit MAY be set.
+ *
+ * \return 0 is these uses of the certificate are allowed,
+ * MBEDTLS_ERR_X509_BAD_INPUT_DATA if the keyUsage extension
+ * is present but does not match the usage argument.
+ *
+ * \note You should only call this function on leaf certificates, on
+ * (intermediate) CAs the keyUsage extension is automatically
+ * checked by \c mbedtls_x509_crt_verify().
+ */
+int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
+ unsigned int usage );
+#endif /* MBEDTLS_X509_CHECK_KEY_USAGE) */
+
+#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+/**
+ * \brief Check usage of certificate against extendedKeyUsage.
+ *
+ * \param crt Leaf certificate used.
+ * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or
+ * MBEDTLS_OID_CLIENT_AUTH).
+ * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()).
+ *
+ * \return 0 if this use of the certificate is allowed,
+ * MBEDTLS_ERR_X509_BAD_INPUT_DATA if not.
+ *
+ * \note Usually only makes sense on leaf certificates.
+ */
+int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
+ const char *usage_oid,
+ size_t usage_len );
+#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+/**
+ * \brief Verify the certificate revocation status
+ *
+ * \param crt a certificate to be verified
+ * \param crl the CRL to verify against
+ *
+ * \return 1 if the certificate is revoked, 0 otherwise
+ *
+ */
+int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl );
+#endif /* MBEDTLS_X509_CRL_PARSE_C */
+
+/**
+ * \brief Initialize a certificate (chain)
+ *
+ * \param crt Certificate chain to initialize
+ */
+void mbedtls_x509_crt_init( mbedtls_x509_crt *crt );
+
+/**
+ * \brief Unallocate all certificate data
+ *
+ * \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 */
+/* \} addtogroup x509_module */
+
+#if defined(MBEDTLS_X509_CRT_WRITE_C)
+/**
+ * \brief Initialize a CRT writing context
+ *
+ * \param ctx CRT context to initialize
+ */
+void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx );
+
+/**
+ * \brief Set the verion for a Certificate
+ * Default: MBEDTLS_X509_CRT_VERSION_3
+ *
+ * \param ctx CRT context to use
+ * \param version version to set (MBEDTLS_X509_CRT_VERSION_1, MBEDTLS_X509_CRT_VERSION_2 or
+ * MBEDTLS_X509_CRT_VERSION_3)
+ */
+void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version );
+
+/**
+ * \brief Set the serial number for a Certificate.
+ *
+ * \param ctx CRT context to use
+ * \param serial serial number to set
+ *
+ * \return 0 if successful
+ */
+int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial );
+
+/**
+ * \brief Set the validity period for a Certificate
+ * Timestamps should be in string format for UTC timezone
+ * i.e. "YYYYMMDDhhmmss"
+ * e.g. "20131231235959" for December 31st 2013
+ * at 23:59:59
+ *
+ * \param ctx CRT context to use
+ * \param not_before not_before timestamp
+ * \param not_after not_after timestamp
+ *
+ * \return 0 if timestamp was parsed successfully, or
+ * a specific error code
+ */
+int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before,
+ const char *not_after );
+
+/**
+ * \brief Set the issuer name for a Certificate
+ * Issuer names should contain a comma-separated list
+ * of OID types and values:
+ * e.g. "C=UK,O=ARM,CN=mbed TLS CA"
+ *
+ * \param ctx CRT context to use
+ * \param issuer_name issuer name to set
+ *
+ * \return 0 if issuer name was parsed successfully, or
+ * a specific error code
+ */
+int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
+ const char *issuer_name );
+
+/**
+ * \brief Set the subject name for a Certificate
+ * Subject names should contain a comma-separated list
+ * of OID types and values:
+ * e.g. "C=UK,O=ARM,CN=mbed TLS Server 1"
+ *
+ * \param ctx CRT context to use
+ * \param subject_name subject name to set
+ *
+ * \return 0 if subject name was parsed successfully, or
+ * a specific error code
+ */
+int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx,
+ const char *subject_name );
+
+/**
+ * \brief Set the subject public key for the certificate
+ *
+ * \param ctx CRT context to use
+ * \param key public key to include
+ */
+void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key );
+
+/**
+ * \brief Set the issuer key used for signing the certificate
+ *
+ * \param ctx CRT context to use
+ * \param key private key to sign with
+ */
+void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key );
+
+/**
+ * \brief Set the MD algorithm to use for the signature
+ * (e.g. MBEDTLS_MD_SHA1)
+ *
+ * \param ctx CRT context to use
+ * \param md_alg MD algorithm to use
+ */
+void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg );
+
+/**
+ * \brief Generic function to add to or replace an extension in the
+ * CRT
+ *
+ * \param ctx CRT context to use
+ * \param oid OID of the extension
+ * \param oid_len length of the OID
+ * \param critical if the extension is critical (per the RFC's definition)
+ * \param val value of the extension OCTET STRING
+ * \param val_len length of the value data
+ *
+ * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
+ const char *oid, size_t oid_len,
+ int critical,
+ const unsigned char *val, size_t val_len );
+
+/**
+ * \brief Set the basicConstraints extension for a CRT
+ *
+ * \param ctx CRT context to use
+ * \param is_ca is this a CA certificate
+ * \param max_pathlen maximum length of certificate chains below this
+ * certificate (only for CA certificates, -1 is
+ * inlimited)
+ *
+ * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
+ int is_ca, int max_pathlen );
+
+#if defined(MBEDTLS_SHA1_C)
+/**
+ * \brief Set the subjectKeyIdentifier extension for a CRT
+ * Requires that mbedtls_x509write_crt_set_subject_key() has been
+ * called before
+ *
+ * \param ctx CRT context to use
+ *
+ * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx );
+
+/**
+ * \brief Set the authorityKeyIdentifier extension for a CRT
+ * Requires that mbedtls_x509write_crt_set_issuer_key() has been
+ * called before
+ *
+ * \param ctx CRT context to use
+ *
+ * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx );
+#endif /* MBEDTLS_SHA1_C */
+
+/**
+ * \brief Set the Key Usage Extension flags
+ * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN)
+ *
+ * \param ctx CRT context to use
+ * \param key_usage key usage flags to set
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
+ unsigned int key_usage );
+
+/**
+ * \brief Set the Netscape Cert Type flags
+ * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL)
+ *
+ * \param ctx CRT context to use
+ * \param ns_cert_type Netscape Cert Type flags to set
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
+ unsigned char ns_cert_type );
+
+/**
+ * \brief Free the contents of a CRT write context
+ *
+ * \param ctx CRT context to free
+ */
+void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx );
+
+/**
+ * \brief Write a built up certificate to a X509 DER structure
+ * Note: data is written at the end of the buffer! Use the
+ * return value to determine where you should start
+ * using the buffer
+ *
+ * \param ctx certificate to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ * \param f_rng RNG function (for signature, see note)
+ * \param p_rng RNG parameter
+ *
+ * \return length of data written if successful, or a specific
+ * error code
+ *
+ * \note f_rng may be NULL if RSA is used for signature and the
+ * signature is made offline (otherwise f_rng is desirable
+ * for countermeasures against timing attacks).
+ * ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+/**
+ * \brief Write a built up certificate to a X509 PEM string
+ *
+ * \param ctx certificate to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ * \param f_rng RNG function (for signature, see note)
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful, or a specific error code
+ *
+ * \note f_rng may be NULL if RSA is used for signature and the
+ * signature is made offline (otherwise f_rng is desirable
+ * for countermeasures against timing attacks).
+ * ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+#endif /* MBEDTLS_PEM_WRITE_C */
+#endif /* MBEDTLS_X509_CRT_WRITE_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_x509_crt.h */
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
new file mode 100644
index 0000000..a3c2804
--- /dev/null
+++ b/include/mbedtls/x509_csr.h
@@ -0,0 +1,307 @@
+/**
+ * \file x509_csr.h
+ *
+ * \brief X.509 certificate signing request parsing and writing
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_X509_CSR_H
+#define MBEDTLS_X509_CSR_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "x509.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{ */
+
+/**
+ * \name Structures and functions for X.509 Certificate Signing Requests (CSR)
+ * \{
+ */
+
+/**
+ * Certificate Signing Request (CSR) structure.
+ */
+typedef struct mbedtls_x509_csr
+{
+ mbedtls_x509_buf raw; /**< The raw CSR data (DER). */
+ mbedtls_x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */
+
+ int version; /**< CSR version (1=v1). */
+
+ mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). */
+ mbedtls_x509_name subject; /**< The parsed subject data (named information object). */
+
+ mbedtls_pk_context pk; /**< Container for the public key context. */
+
+ mbedtls_x509_buf sig_oid;
+ mbedtls_x509_buf sig;
+ mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
+ mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
+ void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
+}
+mbedtls_x509_csr;
+
+/**
+ * Container for writing a CSR
+ */
+typedef struct mbedtls_x509write_csr
+{
+ mbedtls_pk_context *key;
+ mbedtls_asn1_named_data *subject;
+ mbedtls_md_type_t md_alg;
+ mbedtls_asn1_named_data *extensions;
+}
+mbedtls_x509write_csr;
+
+#if defined(MBEDTLS_X509_CSR_PARSE_C)
+/**
+ * \brief Load a Certificate Signing Request (CSR) in DER format
+ *
+ * \note CSR attributes (if any) are currently silently ignored.
+ *
+ * \param csr CSR context to fill
+ * \param buf buffer holding the CRL data
+ * \param buflen size of the buffer
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
+ const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief Load a Certificate Signing Request (CSR), DER or PEM format
+ *
+ * \note See notes for \c mbedtls_x509_csr_parse_der()
+ *
+ * \param csr CSR context to fill
+ * \param buf buffer holding the CRL data
+ * \param buflen size of the buffer
+ * (including the terminating null byte for PEM data)
+ *
+ * \return 0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief Load a Certificate Signing Request (CSR)
+ *
+ * \note See notes for \c mbedtls_x509_csr_parse()
+ *
+ * \param csr CSR context to fill
+ * \param path filename to read the CSR from
+ *
+ * \return 0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief Returns an informational string about the
+ * CSR.
+ *
+ * \param buf Buffer to write to
+ * \param size Maximum size of buffer
+ * \param prefix A line prefix
+ * \param csr The X509 CSR to represent
+ *
+ * \return The length of the string written (not including the
+ * terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
+ const mbedtls_x509_csr *csr );
+
+/**
+ * \brief Initialize a CSR
+ *
+ * \param csr CSR to initialize
+ */
+void mbedtls_x509_csr_init( mbedtls_x509_csr *csr );
+
+/**
+ * \brief Unallocate all CSR data
+ *
+ * \param csr CSR to free
+ */
+void mbedtls_x509_csr_free( mbedtls_x509_csr *csr );
+#endif /* MBEDTLS_X509_CSR_PARSE_C */
+
+/* \} name */
+/* \} addtogroup x509_module */
+
+#if defined(MBEDTLS_X509_CSR_WRITE_C)
+/**
+ * \brief Initialize a CSR context
+ *
+ * \param ctx CSR context to initialize
+ */
+void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx );
+
+/**
+ * \brief Set the subject name for a CSR
+ * Subject names should contain a comma-separated list
+ * of OID types and values:
+ * e.g. "C=UK,O=ARM,CN=mbed TLS Server 1"
+ *
+ * \param ctx CSR context to use
+ * \param subject_name subject name to set
+ *
+ * \return 0 if subject name was parsed successfully, or
+ * a specific error code
+ */
+int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
+ const char *subject_name );
+
+/**
+ * \brief Set the key for a CSR (public key will be included,
+ * private key used to sign the CSR when writing it)
+ *
+ * \param ctx CSR context to use
+ * \param key Asymetric key to include
+ */
+void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key );
+
+/**
+ * \brief Set the MD algorithm to use for the signature
+ * (e.g. MBEDTLS_MD_SHA1)
+ *
+ * \param ctx CSR context to use
+ * \param md_alg MD algorithm to use
+ */
+void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg );
+
+/**
+ * \brief Set the Key Usage Extension flags
+ * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN)
+ *
+ * \param ctx CSR context to use
+ * \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 );
+
+/**
+ * \brief Set the Netscape Cert Type flags
+ * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL)
+ *
+ * \param ctx CSR context to use
+ * \param ns_cert_type Netscape Cert Type flags to set
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
+ unsigned char ns_cert_type );
+
+/**
+ * \brief Generic function to add to or replace an extension in the
+ * CSR
+ *
+ * \param ctx CSR context to use
+ * \param oid OID of the extension
+ * \param oid_len length of the OID
+ * \param val value of the extension OCTET STRING
+ * \param val_len length of the value data
+ *
+ * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
+ const char *oid, size_t oid_len,
+ const unsigned char *val, size_t val_len );
+
+/**
+ * \brief Free the contents of a CSR context
+ *
+ * \param ctx CSR context to free
+ */
+void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx );
+
+/**
+ * \brief Write a CSR (Certificate Signing Request) to a
+ * DER structure
+ * Note: data is written at the end of the buffer! Use the
+ * return value to determine where you should start
+ * using the buffer
+ *
+ * \param ctx CSR to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ * \param f_rng RNG function (for signature, see note)
+ * \param p_rng RNG parameter
+ *
+ * \return length of data written if successful, or a specific
+ * error code
+ *
+ * \note f_rng may be NULL if RSA is used for signature and the
+ * signature is made offline (otherwise f_rng is desirable
+ * for countermeasures against timing attacks).
+ * ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+/**
+ * \brief Write a CSR (Certificate Signing Request) to a
+ * PEM string
+ *
+ * \param ctx CSR to write away
+ * \param buf buffer to write to
+ * \param size size of the buffer
+ * \param f_rng RNG function (for signature, see note)
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful, or a specific error code
+ *
+ * \note f_rng may be NULL if RSA is used for signature and the
+ * signature is made offline (otherwise f_rng is desirable
+ * for countermeasures against timing attacks).
+ * ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+#endif /* MBEDTLS_PEM_WRITE_C */
+#endif /* MBEDTLS_X509_CSR_WRITE_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_x509_csr.h */