You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/10/27 12:57:19 UTC

(nuttx-apps) 02/07: openssl_mbedtls_wrapper: add ssl wrapper from libwebsockets

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit f7582e34e51c43dcebd78e3c011ac37124d1d6ae
Author: makejian <ma...@xiaomi.com>
AuthorDate: Wed Sep 13 20:50:07 2023 +0800

    openssl_mbedtls_wrapper: add ssl wrapper from libwebsockets
    
    Signed-off-by: makejian <ma...@xiaomi.com>
---
 .../openssl_mbedtls_wrapper/include/openssl/base.h |    5 +-
 .../openssl_mbedtls_wrapper/include/openssl/err.h  |    2 +
 .../openssl_mbedtls_wrapper/include/openssl/evp.h  |   11 +
 .../openssl_mbedtls_wrapper/include/openssl/ssl.h  |  305 ++++++
 .../openssl_mbedtls_wrapper/include/openssl/ssl3.h |   49 +
 .../include/openssl/ssl_dbg.h                      |  211 ++++
 .../include/openssl/ssl_local.h                    |  148 +++
 .../include/openssl/stack.h                        |   25 +-
 .../include/openssl/{err.h => statem.h}            |   57 +-
 .../openssl_mbedtls_wrapper/include/openssl/tls1.h |   63 ++
 .../include/openssl/types.h                        |   72 ++
 .../openssl_mbedtls_wrapper/include/openssl/x509.h |   34 +
 .../include/openssl/x509_local.h                   |   36 +
 .../include/openssl/x509_vfy.h                     |  120 +++
 crypto/openssl_mbedtls_wrapper/mbedtls/evp.c       |   52 +-
 crypto/openssl_mbedtls_wrapper/mbedtls/ssl_cert.c  |  139 +++
 crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c   | 1015 ++++++++++++++++++
 .../openssl_mbedtls_wrapper/mbedtls/ssl_methods.c  |  105 ++
 .../openssl_mbedtls_wrapper/mbedtls/ssl_methods.h  |  141 +++
 crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c    | 1076 ++++++++++++++++++++
 crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h    |   70 ++
 crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.c  |   39 +
 crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.h  |   55 +
 crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c   |  242 +++++
 crypto/openssl_mbedtls_wrapper/mbedtls/stack.c     |   79 ++
 crypto/openssl_mbedtls_wrapper/mbedtls/statem.c    |   39 +
 crypto/openssl_mbedtls_wrapper/mbedtls/x509.c      |   85 ++
 crypto/openssl_mbedtls_wrapper/mbedtls/x509_vpm.c  |   39 +
 28 files changed, 4290 insertions(+), 24 deletions(-)

diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/base.h b/crypto/openssl_mbedtls_wrapper/include/openssl/base.h
index e3a3b3b68..b621aabe8 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/base.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/base.h
@@ -57,11 +57,9 @@ typedef struct BN_CTX BN_CTX;
 typedef struct EC_GROUP EC_GROUP;
 typedef struct EC_KEY EC_KEY;
 typedef struct EC_POINT EC_POINT;
-typedef struct EVP_PKEY EVP_PKEY;
+typedef struct evp_pkey_st EVP_PKEY;
 typedef struct EVP_PKEY_CTX EVP_PKEY_CTX;
 typedef struct PKCS8_PRIV_KEY_INFO PKCS8_PRIV_KEY_INFO;
-typedef struct RSA RSA;
-typedef struct X509 X509;
 typedef struct X509_ALGOR X509_ALGOR;
 typedef struct X509_EXTENSION X509_EXTENSION;
 typedef struct X509_NAME X509_NAME;
@@ -74,6 +72,7 @@ typedef struct sha256_state_st SHA256_CTX;
 typedef struct sha_state_st SHA_CTX;
 typedef struct cbb_st CBB;
 typedef struct ecdsa_sig_st ECDSA_SIG;
+typedef void RSA;
 
 #ifdef __cplusplus
 }
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/err.h b/crypto/openssl_mbedtls_wrapper/include/openssl/err.h
index 6012e3c9a..e406d1364 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/err.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/err.h
@@ -45,6 +45,8 @@ extern "C"
 
 unsigned long ERR_peek_last_error(void);
 void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+void ERR_free_strings(void);
+char *ERR_error_string(unsigned long e, char *buf);
 
 #ifdef __cplusplus
 }
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h b/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h
index b9333b73d..ae5fae9cf 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h
@@ -30,6 +30,7 @@
 #include <openssl/ec_key.h>
 #include <openssl/mem.h>
 #include <openssl/nid.h>
+#include <openssl/types.h>
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -41,6 +42,12 @@
 
 #define EVP_PKEY_X25519 NID_X25519
 
+struct evp_pkey_st
+{
+  void *pkey_pm;
+  const PKEY_METHOD *method;
+};
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -56,6 +63,8 @@ RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey);
 
 int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key);
 
+EVP_PKEY *__EVP_PKEY_new(EVP_PKEY *ipk);
+
 EVP_PKEY *EVP_PKEY_new(void);
 
 void EVP_PKEY_free(EVP_PKEY *pkey);
@@ -153,6 +162,8 @@ int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,
                       unsigned iterations, const EVP_MD *digest,
                       size_t key_len, uint8_t *out_key);
 
+const PKEY_METHOD *EVP_PKEY_method(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h
new file mode 100644
index 000000000..c8d29788e
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_SSL_H
+#define OPENSSL_MBEDTLS_WRAPPER_SSL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stddef.h>
+#include <openssl/types.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/tls1.h>
+
+/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+#define SSL_SENT_SHUTDOWN       1
+#define SSL_RECEIVED_SHUTDOWN   2
+
+#define SSL_VERIFY_NONE                 0x00
+#define SSL_VERIFY_PEER                 0x01
+#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
+#define SSL_VERIFY_CLIENT_ONCE          0x04
+
+/* The following 3 states are kept in ssl->rlayer.rstate when reads fail, you
+ * should not need these
+ */
+#define SSL_ST_READ_HEADER              0xF0
+#define SSL_ST_READ_BODY                0xF1
+#define SSL_ST_READ_DONE                0xF2
+
+#define SSL_NOTHING                     1
+#define SSL_WRITING                     2
+#define SSL_READING                     3
+#define SSL_X509_LOOKUP                 4
+#define SSL_ASYNC_PAUSED                5
+#define SSL_ASYNC_NO_JOBS               6
+
+#define SSL_ERROR_NONE                  0
+#define SSL_ERROR_SSL                   1
+#define SSL_ERROR_WANT_READ             2
+#define SSL_ERROR_WANT_WRITE            3
+#define SSL_ERROR_WANT_X509_LOOKUP      4
+#define SSL_ERROR_SYSCALL               5/* look at error stack/return value/errno */
+#define SSL_ERROR_ZERO_RETURN           6
+#define SSL_ERROR_WANT_CONNECT          7
+#define SSL_ERROR_WANT_ACCEPT           8
+#define SSL_ERROR_WANT_ASYNC            9
+#define SSL_ERROR_WANT_ASYNC_JOB       10
+
+typedef enum
+{
+    TLS_ST_BEFORE,
+    TLS_ST_OK,
+    DTLS_ST_CR_HELLO_VERIFY_REQUEST,
+    TLS_ST_CR_SRVR_HELLO,
+    TLS_ST_CR_CERT,
+    TLS_ST_CR_CERT_STATUS,
+    TLS_ST_CR_KEY_EXCH,
+    TLS_ST_CR_CERT_REQ,
+    TLS_ST_CR_SRVR_DONE,
+    TLS_ST_CR_SESSION_TICKET,
+    TLS_ST_CR_CHANGE,
+    TLS_ST_CR_FINISHED,
+    TLS_ST_CW_CLNT_HELLO,
+    TLS_ST_CW_CERT,
+    TLS_ST_CW_KEY_EXCH,
+    TLS_ST_CW_CERT_VRFY,
+    TLS_ST_CW_CHANGE,
+    TLS_ST_CW_NEXT_PROTO,
+    TLS_ST_CW_FINISHED,
+    TLS_ST_SW_HELLO_REQ,
+    TLS_ST_SR_CLNT_HELLO,
+    DTLS_ST_SW_HELLO_VERIFY_REQUEST,
+    TLS_ST_SW_SRVR_HELLO,
+    TLS_ST_SW_CERT,
+    TLS_ST_SW_KEY_EXCH,
+    TLS_ST_SW_CERT_REQ,
+    TLS_ST_SW_SRVR_DONE,
+    TLS_ST_SR_CERT,
+    TLS_ST_SR_KEY_EXCH,
+    TLS_ST_SR_CERT_VRFY,
+    TLS_ST_SR_NEXT_PROTO,
+    TLS_ST_SR_CHANGE,
+    TLS_ST_SR_FINISHED,
+    TLS_ST_SW_SESSION_TICKET,
+    TLS_ST_SW_CERT_STATUS,
+    TLS_ST_SW_CHANGE,
+    TLS_ST_SW_FINISHED
+}
+OSSL_HANDSHAKE_STATE;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
+
+int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+                                    unsigned long flags);
+
+int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param,
+                                      unsigned long flags);
+
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
+
+int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ssl, int len,
+                               const unsigned char *d);
+
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+
+int SSL_use_certificate(SSL *ssl, X509 *x);
+
+X509 *SSL_get_certificate(const SSL *ssl);
+
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
+                                 const unsigned char *d);
+
+int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+
+X509 *SSL_get_peer_certificate(const SSL *ssl);
+
+int SSL_want(const SSL *ssl);
+
+int SSL_want_nothing(const SSL *ssl);
+
+int SSL_want_read(const SSL *ssl);
+
+int SSL_want_write(const SSL *ssl);
+
+int SSL_want_x509_lookup(const SSL *ssl);
+
+void _ssl_set_alpn_list(const SSL *ssl);
+
+int SSL_get_error(const SSL *ssl, int ret_code);
+
+OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl);
+
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, void *rngctx);
+
+void SSL_CTX_free(SSL_CTX *ctx);
+
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
+
+const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
+
+SSL *SSL_new(SSL_CTX *ctx);
+
+void SSL_free(SSL *ssl);
+
+int SSL_do_handshake(SSL *ssl);
+
+int SSL_connect(SSL *ssl);
+
+int SSL_accept(SSL *ssl);
+
+int SSL_shutdown(SSL *ssl);
+
+int SSL_clear(SSL *ssl);
+
+int SSL_read(SSL *ssl, void *buffer, int len);
+
+int SSL_write(SSL *ssl, const void *buffer, int len);
+
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+
+const SSL_METHOD *SSL_get_ssl_method(SSL *ssl);
+
+int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method);
+
+int SSL_get_shutdown(const SSL *ssl);
+
+void SSL_set_shutdown(SSL *ssl, int mode);
+
+int SSL_pending(const SSL *ssl);
+
+int SSL_has_pending(const SSL *ssl);
+
+unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op);
+
+unsigned long SSL_CTX_get_options(SSL_CTX *ctx);
+
+unsigned long SSL_clear_options(SSL *ssl, unsigned long op);
+
+unsigned long SSL_get_options(SSL *ssl);
+
+unsigned long SSL_set_options(SSL *ssl, unsigned long op);
+
+int SSL_get_fd(const SSL *ssl);
+
+int SSL_get_rfd(const SSL *ssl);
+
+int SSL_get_wfd(const SSL *ssl);
+
+int SSL_set_fd(SSL *ssl, int fd);
+
+int SSL_set_rfd(SSL *ssl, int fd);
+
+int SSL_set_wfd(SSL *ssl, int fd);
+
+int SSL_version(const SSL *ssl);
+
+const char *SSL_alert_type_string(int value);
+
+void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len);
+
+void SSL_set_default_read_buffer_len(SSL *ssl, size_t len);
+
+void SSL_set_info_callback(SSL *ssl,
+                           void (*cb) (const SSL *ssl, int type, int val));
+
+int SSL_CTX_up_ref(SSL_CTX *ctx);
+
+void SSL_set_security_level(SSL *ssl, int level);
+
+int SSL_get_security_level(const SSL *ssl);
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+
+long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
+
+long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+
+void SSL_set_read_ahead(SSL *ssl, int yes);
+
+void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
+
+int SSL_get_read_ahead(const SSL *ssl);
+
+long SSL_CTX_get_read_ahead(SSL_CTX *ctx);
+
+long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx);
+
+long SSL_set_time(SSL *ssl, long t);
+
+long SSL_set_timeout(SSL *ssl, long t);
+
+long SSL_get_verify_result(const SSL *ssl);
+
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
+
+int SSL_get_verify_depth(const SSL *ssl);
+
+void SSL_set_verify_depth(SSL *ssl, int depth);
+
+void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
+                        int (*verify_callback)(int, X509_STORE_CTX *));
+
+void SSL_set_verify(SSL *ssl, int mode,
+                    int (*verify_callback)(int, X509_STORE_CTX *));
+
+void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx);
+
+void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, next_proto_cb cb, void *arg);
+
+void SSL_set_alpn_select_cb(SSL *ssl, void *arg);
+
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+
+int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+
+int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
+                                const unsigned char *d, long len);
+
+int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
+                            const unsigned char *d, long len);
+
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+
+int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
+                                   long len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_SSL_H */
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl3.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl3.h
new file mode 100644
index 000000000..43a809a3b
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl3.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/ssl3.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_SSL_SSL3_H
+#define OPENSSL_MBEDTLS_WRAPPER_SSL_SSL3_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SSL3_AD_CLOSE_NOTIFY             0
+#define SSL3_AD_UNEXPECTED_MESSAGE      10/* fatal */
+#define SSL3_AD_BAD_RECORD_MAC          20/* fatal */
+#define SSL3_AD_DECOMPRESSION_FAILURE   30/* fatal */
+#define SSL3_AD_HANDSHAKE_FAILURE       40/* fatal */
+#define SSL3_AD_NO_CERTIFICATE          41
+#define SSL3_AD_BAD_CERTIFICATE         42
+#define SSL3_AD_UNSUPPORTED_CERTIFICATE 43
+#define SSL3_AD_CERTIFICATE_REVOKED     44
+#define SSL3_AD_CERTIFICATE_EXPIRED     45
+#define SSL3_AD_CERTIFICATE_UNKNOWN     46
+#define SSL3_AD_ILLEGAL_PARAMETER       47/* fatal */
+
+#define SSL3_AL_WARNING                  1
+#define SSL3_AL_FATAL                    2
+
+#define SSL3_VERSION                 0x0300
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_SSL_SSL3_H */
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_dbg.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_dbg.h
new file mode 100644
index 000000000..1d433e44a
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_dbg.h
@@ -0,0 +1,211 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_dbg.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_SSL_DBG_H
+#define OPENSSL_MBEDTLS_WRAPPER_SSL_DBG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef CONFIG_OPENSSL_DEBUG_LEVEL
+#  define SSL_DEBUG_LEVEL CONFIG_OPENSSL_DEBUG_LEVEL
+#else
+#  define SSL_DEBUG_LEVEL 0
+#endif
+
+#define SSL_DEBUG_ON  (SSL_DEBUG_LEVEL + 1)
+#define SSL_DEBUG_OFF (SSL_DEBUG_LEVEL - 1)
+
+#ifdef CONFIG_OPENSSL_DEBUG
+#  ifndef SSL_DEBUG_LOG
+#    error "SSL_DEBUG_LOG is not defined"
+#  endif
+
+#  ifndef SSL_DEBUG_FL
+#    define SSL_DEBUG_FL "\n"
+#  endif
+
+#  define SSL_SHOW_LOCATION()                         \
+    SSL_DEBUG_LOG("SSL assert : %s %d\n",             \
+      __FILE__, __LINE__)
+
+#  define SSL_DEBUG(level, fmt, ...)                  \
+{                                                     \
+  if (level > SSL_DEBUG_LEVEL)                        \
+    {                                                 \
+      SSL_DEBUG_LOG(fmt SSL_DEBUG_FL, ##__VA_ARGS__); \
+    }                                                 \
+}
+#else /* CONFIG_OPENSSL_DEBUG */
+#  define SSL_SHOW_LOCATION()
+
+#  define SSL_DEBUG(level, fmt, ...)
+#endif /* CONFIG_OPENSSL_DEBUG */
+
+/* OpenSSL assert function
+ *
+ * if select "CONFIG_OPENSSL_ASSERT_DEBUG", SSL_ASSERT* will show error
+ * file name and line
+ * if select "CONFIG_OPENSSL_ASSERT_EXIT", SSL_ASSERT* will just return
+ * error code.
+ * if select "CONFIG_OPENSSL_ASSERT_DEBUG_EXIT" SSL_ASSERT* will show error
+ * file name and line, then return error code.
+ * if select "CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK", SSL_ASSERT* will show error
+ * file name and line, then block here with "while (1)"
+ *
+ * SSL_ASSERT1 may will return "-1", so function's return argument is
+ * integer.
+ * SSL_ASSERT2 may will return "NULL", so function's return argument is a
+ * point.
+ * SSL_ASSERT2 may will return nothing, so function's return argument is
+ * "void".
+ */
+
+#if defined(CONFIG_OPENSSL_ASSERT_DEBUG)
+#  define SSL_ASSERT1(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+    }                                                 \
+}
+
+#  define SSL_ASSERT2(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+    }                                                 \
+}
+
+#  define SSL_ASSERT3(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+    }                                                 \
+}
+#elif defined(CONFIG_OPENSSL_ASSERT_EXIT)
+#  define SSL_ASSERT1(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      return -1;                                      \
+    }                                                 \
+}
+
+#  define SSL_ASSERT2(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      return NULL;                                    \
+    }                                                 \
+}
+
+#  define SSL_ASSERT3(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      return ;                                        \
+    }                                                 \
+}
+#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_EXIT)
+#  define SSL_ASSERT1(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+      return -1;                                      \
+    }                                                 \
+}
+
+#  define SSL_ASSERT2(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+      return NULL;                                    \
+    }                                                 \
+}
+
+#  define SSL_ASSERT3(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+      return ;                                        \
+    }                                                 \
+}
+#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK)
+#  define SSL_ASSERT1(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+      while (1);                                      \
+    }                                                 \
+}
+
+#  define SSL_ASSERT2(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+      while (1);                                      \
+    }                                                 \
+}
+
+#  define SSL_ASSERT3(s)                              \
+{                                                     \
+  if (!(s))                                           \
+    {                                                 \
+      SSL_SHOW_LOCATION();                            \
+      while (1);                                      \
+    }                                                 \
+}
+#else
+#  define SSL_ASSERT1(s)
+#  define SSL_ASSERT2(s)
+#  define SSL_ASSERT3(s)
+#endif
+
+#define SSL_PLATFORM_DEBUG_LEVEL SSL_DEBUG_OFF
+#define SSL_PLATFORM_ERROR_LEVEL SSL_DEBUG_ON
+
+#define SSL_CERT_DEBUG_LEVEL     SSL_DEBUG_OFF
+#define SSL_CERT_ERROR_LEVEL     SSL_DEBUG_ON
+
+#define SSL_PKEY_DEBUG_LEVEL     SSL_DEBUG_OFF
+#define SSL_PKEY_ERROR_LEVEL     SSL_DEBUG_ON
+
+#define SSL_X509_DEBUG_LEVEL     SSL_DEBUG_OFF
+#define SSL_X509_ERROR_LEVEL     SSL_DEBUG_ON
+
+#define SSL_LIB_DEBUG_LEVEL      SSL_DEBUG_OFF
+#define SSL_LIB_ERROR_LEVEL      SSL_DEBUG_ON
+
+#define SSL_STACK_DEBUG_LEVEL    SSL_DEBUG_OFF
+#define SSL_STACK_ERROR_LEVEL    SSL_DEBUG_ON
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_SSL_DBG_H */
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h
new file mode 100644
index 000000000..082be2bcc
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_SSL_LOCAL_H
+#define OPENSSL_MBEDTLS_WRAPPER_SSL_LOCAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <openssl/ssl.h>
+#include <openssl/statem.h>
+#include <openssl/x509.h>
+#include <openssl/x509_local.h>
+#include <openssl/x509_vfy.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct record_layer_st
+{
+  int rstate;
+  int read_ahead;
+};
+
+struct ssl_ctx_st
+{
+  int version;
+  int references;
+  unsigned long options;
+  const SSL_METHOD *method;
+  CERT *cert;
+  X509 *client_CA;
+  const char **alpn_protos;
+  next_proto_cb alpn_cb;
+  int verify_mode;
+  int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx);
+  long session_timeout;
+  int read_ahead;
+  int read_buffer_len;
+  X509_VERIFY_PARAM param;
+};
+
+struct ssl_method_func_st
+{
+  int (*ssl_new)(SSL *ssl);
+  void (*ssl_free)(SSL *ssl);
+  int (*ssl_handshake)(SSL *ssl);
+  int (*ssl_shutdown)(SSL *ssl);
+  int (*ssl_clear)(SSL *ssl);
+  int (*ssl_read)(SSL *ssl, void *buffer, int len);
+  int (*ssl_send)(SSL *ssl, const void *buffer, int len);
+  int (*ssl_pending)(const SSL *ssl);
+  void (*ssl_set_fd)(SSL *ssl, int fd, int mode);
+  int (*ssl_get_fd)(const SSL *ssl, int mode);
+  void (*ssl_set_bufflen)(SSL *ssl, int len);
+  long (*ssl_get_verify_result)(const SSL *ssl);
+  OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl);
+};
+
+struct ssl_method_st
+{
+  /* protocol version(one of SSL3.0, TLS1.0, etc.) */
+
+  int version;
+
+  /* SSL mode(client(0) , server(1), not known(-1)) */
+
+  int endpoint;
+  const SSL_METHOD_FUNC *func;
+};
+
+struct ssl_session_st
+{
+  long timeout;
+  long time;
+  X509 *peer;
+};
+
+struct ssl_st
+{
+/* protocol version(one of SSL3.0, TLS1.0, etc.) */
+
+  int version;
+  unsigned long options;
+
+/* shut things down(0x01 : sent, 0x02 : received) */
+
+  int shutdown;
+  CERT *cert;
+  X509 *client_CA;
+  SSL_CTX  *ctx;
+  const SSL_METHOD *method;
+  const char **alpn_protos;
+  RECORD_LAYER rlayer;
+
+/* where we are */
+
+  OSSL_STATEM statem;
+  SSL_SESSION *session;
+  int verify_mode;
+  int (*verify_callback) (int ok, X509_STORE_CTX *ctx);
+  int rwstate;
+  int interrupted_remaining_write;
+  long verify_result;
+  X509_VERIFY_PARAM param;
+  int err;
+  void (*info_callback) (const SSL *ssl, int type, int val);
+
+/* SSL low-level system arch point */
+
+  void *ssl_pm;
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+CERT *__ssl_cert_new(CERT *ic);
+CERT *ssl_cert_new(void);
+void ssl_cert_free(CERT *cert);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_SSL_LOCAL_H */
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/stack.h b/crypto/openssl_mbedtls_wrapper/include/openssl/stack.h
index f49c00e09..9419b22db 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/stack.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/stack.h
@@ -24,17 +24,32 @@
  * Included Files
  ****************************************************************************/
 
-#include <openssl/base.h>
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
+#include <openssl/types.h>
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct stack_st
+{
+    char **data;
+    int num_alloc;
+    OPENSSL_sk_compfunc c;
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c);
+OPENSSL_STACK *OPENSSL_sk_new_null(void);
+void OPENSSL_sk_free(OPENSSL_STACK *stack);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/err.h b/crypto/openssl_mbedtls_wrapper/include/openssl/statem.h
similarity index 68%
copy from crypto/openssl_mbedtls_wrapper/include/openssl/err.h
copy to crypto/openssl_mbedtls_wrapper/include/openssl/statem.h
index 6012e3c9a..bdd6dd281 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/err.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/statem.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * apps/crypto/openssl_mbedtls_wrapper/include/openssl/err.h
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/statem.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -17,37 +17,66 @@
  * under the License.
  ****************************************************************************/
 
-#ifndef OPENSSL_MBEDTLS_WRAPPER_ERR_H
-#define OPENSSL_MBEDTLS_WRAPPER_ERR_H
+#ifndef OPENSSL_MBEDTLS_WRAPPER_STATEM_H
+#define OPENSSL_MBEDTLS_WRAPPER_STATEM_H
 
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-#include <stddef.h>
+#include <openssl/types.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
 
 /****************************************************************************
- * Pre-processor Definitions
+ * Public Types
  ****************************************************************************/
 
-#define ERR_GET_LIB(l) (int)(((l) >> 24L) & 0x0FFL)
-#define ERR_GET_REASON(l) (int)((l)&0xFFFL)
-#define ERR_LIB_CIPHER 30
+typedef enum
+{
+/* No handshake in progress */
 
-#ifdef __cplusplus
-extern "C"
+  MSG_FLOW_UNINITED,
+
+/* A permanent error with this connection */
+
+  MSG_FLOW_ERROR,
+
+/* We are about to renegotiate */
+
+  MSG_FLOW_RENEGOTIATE,
+
+/* We are reading messages */
+
+  MSG_FLOW_READING,
+
+/* We are writing messages */
+
+  MSG_FLOW_WRITING,
+
+/* Handshake has finished */
+
+  MSG_FLOW_FINISHED
+}
+MSG_FLOW_STATE;
+
+struct ossl_statem_st
 {
-#endif
+  MSG_FLOW_STATE state;
+  int hand_state;
+};
 
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
 
-unsigned long ERR_peek_last_error(void);
-void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+int ossl_statem_in_error(const SSL *ssl);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* OPENSSL_MBEDTLS_WRAPPER_ERR_H */
+#endif /* OPENSSL_MBEDTLS_WRAPPER_STACK_H */
\ No newline at end of file
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h b/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h
new file mode 100644
index 000000000..3b0468221
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_TLS1_H
+#define OPENSSL_MBEDTLS_WRAPPER_TLS1_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define TLS1_AD_DECRYPTION_FAILED       21
+#define TLS1_AD_RECORD_OVERFLOW         22
+#define TLS1_AD_UNKNOWN_CA              48/* fatal */
+#define TLS1_AD_ACCESS_DENIED           49/* fatal */
+#define TLS1_AD_DECODE_ERROR            50/* fatal */
+#define TLS1_AD_DECRYPT_ERROR           51
+#define TLS1_AD_EXPORT_RESTRICTION      60/* fatal */
+#define TLS1_AD_PROTOCOL_VERSION        70/* fatal */
+#define TLS1_AD_INSUFFICIENT_SECURITY   71/* fatal */
+#define TLS1_AD_INTERNAL_ERROR          80/* fatal */
+#define TLS1_AD_INAPPROPRIATE_FALLBACK  86/* fatal */
+#define TLS1_AD_USER_CANCELLED          90
+#define TLS1_AD_NO_RENEGOTIATION        100
+/* codes 110-114 are from RFC3546 */
+#define TLS1_AD_UNSUPPORTED_EXTENSION   110
+#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
+#define TLS1_AD_UNRECOGNIZED_NAME       112
+#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
+#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
+#define TLS1_AD_UNKNOWN_PSK_IDENTITY    115/* fatal */
+#define TLS1_AD_NO_APPLICATION_PROTOCOL 120/* fatal */
+
+/* Special value for method supporting multiple versions */
+#define TLS_ANY_VERSION                 0x10000
+
+#define TLS1_VERSION                    0x0301
+#define TLS1_1_VERSION                  0x0302
+#define TLS1_2_VERSION                  0x0303
+
+#define SSL_TLSEXT_ERR_OK 0
+#define SSL_TLSEXT_ERR_NOACK 3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_TLS1_H */
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/types.h b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h
new file mode 100644
index 000000000..b66b2c6b7
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/types.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_TYPES_H
+#define OPENSSL_MBEDTLS_WRAPPER_TYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef void SSL_CIPHER;
+typedef void X509_STORE;
+
+typedef void RSA;
+typedef void BIO;
+
+typedef int (*OPENSSL_sk_compfunc)(const void *, const void *);
+
+typedef struct stack_st OPENSSL_STACK;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_method_func_st SSL_METHOD_FUNC;
+typedef struct record_layer_st RECORD_LAYER;
+typedef struct ossl_statem_st OSSL_STATEM;
+typedef struct ssl_session_st SSL_SESSION;
+typedef struct ssl_ctx_st SSL_CTX;
+typedef struct ssl_st SSL;
+typedef struct cert_st CERT;
+typedef struct x509_st X509;
+typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM;
+typedef struct evp_pkey_st EVP_PKEY;
+typedef struct x509_method_st X509_METHOD;
+typedef struct pkey_method_st PKEY_METHOD;
+
+#define ossl_inline inline
+#define OPENSSL_NPN_NEGOTIATED 1
+
+#define SSL_METHOD_CALL(f, s, ...)        s->method->func->ssl_##f(s, ##__VA_ARGS__)
+#define X509_METHOD_CALL(f, x, ...)       x->method->x509_##f(x, ##__VA_ARGS__)
+#define EVP_PKEY_METHOD_CALL(f, k, ...)   k->method->pkey_##f(k, ##__VA_ARGS__)
+
+typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out,
+                             unsigned char *outlen, const unsigned char *in,
+                             unsigned int inlen, void *arg);
+
+struct pkey_method_st
+{
+  int (*pkey_new)(EVP_PKEY *pkey, EVP_PKEY *m_pkey);
+  void (*pkey_free)(EVP_PKEY *pkey);
+  int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_TYPES_H */
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h b/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h
index f2261ff43..d7d83847e 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h
@@ -24,16 +24,46 @@
  * Included Files
  ****************************************************************************/
 
+#include <stdint.h>
+
 #include <openssl/base.h>
 #include <openssl/bytestring.h>
 #include <openssl/ecdsa.h>
 #include <openssl/obj.h>
+#include <openssl/types.h>
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct x509_st
+{
+/* X509 certification platform private point */
+
+  void *x509_pm;
+  const X509_METHOD *method;
+};
+
+struct x509_method_st
+{
+  int (*x509_new)(X509 *x, X509 *m_x);
+  void (*x509_free)(X509 *x);
+  int (*x509_load)(X509 *x, const unsigned char *buf, int len);
+  int (*x509_show_info)(X509 *x);
+};
+
+struct cert_st
+{
+  int sec_level;
+  X509 *x509;
+  EVP_PKEY *pkey;
+};
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -103,6 +133,10 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *info,
 
 X509 *d2i_X509(X509 **out, const uint8_t **inp, long len);
 
+const char *X509_verify_cert_error_string(long n);
+
+X509 *__X509_new(X509 *ix);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/x509_local.h b/crypto/openssl_mbedtls_wrapper/include/openssl/x509_local.h
new file mode 100644
index 000000000..ddecc6209
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/x509_local.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/x509_local.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_X509_LOCAL_H
+#define OPENSSL_MBEDTLS_WRAPPER_X509_LOCAL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct X509_VERIFY_PARAM_st
+{
+  int depth;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_X509_LOCAL_H */
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/x509_vfy.h b/crypto/openssl_mbedtls_wrapper/include/openssl/x509_vfy.h
new file mode 100644
index 000000000..1cda9abd7
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/x509_vfy.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/include/openssl/x509_vfy.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_X509_VFY_H
+#define OPENSSL_MBEDTLS_WRAPPER_X509_VFY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define         X509_V_OK                                       0
+#define         X509_V_ERR_UNSPECIFIED                          1
+#define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
+#define         X509_V_ERR_UNABLE_TO_GET_CRL                    3
+#define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
+#define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
+#define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
+#define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7
+#define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8
+#define         X509_V_ERR_CERT_NOT_YET_VALID                   9
+#define         X509_V_ERR_CERT_HAS_EXPIRED                     10
+#define         X509_V_ERR_CRL_NOT_YET_VALID                    11
+#define         X509_V_ERR_CRL_HAS_EXPIRED                      12
+#define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
+#define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
+#define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
+#define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
+#define         X509_V_ERR_OUT_OF_MEM                           17
+#define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
+#define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
+#define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
+#define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
+#define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
+#define         X509_V_ERR_CERT_REVOKED                         23
+#define         X509_V_ERR_INVALID_CA                           24
+#define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
+#define         X509_V_ERR_INVALID_PURPOSE                      26
+#define         X509_V_ERR_CERT_UNTRUSTED                       27
+#define         X509_V_ERR_CERT_REJECTED                        28
+/* These are 'informational' when looking for issuer cert */
+#define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
+#define         X509_V_ERR_AKID_SKID_MISMATCH                   30
+#define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
+#define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32
+#define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
+#define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
+#define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
+#define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
+#define         X509_V_ERR_INVALID_NON_CA                       37
+#define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
+#define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
+#define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
+#define         X509_V_ERR_INVALID_EXTENSION                    41
+#define         X509_V_ERR_INVALID_POLICY_EXTENSION             42
+#define         X509_V_ERR_NO_EXPLICIT_POLICY                   43
+#define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
+#define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45
+#define         X509_V_ERR_UNNESTED_RESOURCE                    46
+#define         X509_V_ERR_PERMITTED_VIOLATION                  47
+#define         X509_V_ERR_EXCLUDED_VIOLATION                   48
+#define         X509_V_ERR_SUBTREE_MINMAX                       49
+/* The application is not happy */
+#define         X509_V_ERR_APPLICATION_VERIFICATION             50
+#define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
+#define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
+#define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
+#define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54
+/* Another issuer check debug option */
+#define         X509_V_ERR_PATH_LOOP                            55
+/* Suite B mode algorithm violation */
+#define         X509_V_ERR_SUITE_B_INVALID_VERSION              56
+#define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
+#define         X509_V_ERR_SUITE_B_INVALID_CURVE                58
+#define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
+#define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
+#define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+/* Host, email and IP check errors */
+#define         X509_V_ERR_HOSTNAME_MISMATCH                    62
+#define         X509_V_ERR_EMAIL_MISMATCH                       63
+#define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64
+/* DANE TLSA errors */
+#define         X509_V_ERR_DANE_NO_MATCH                        65
+/* security level errors */
+#define         X509_V_ERR_EE_KEY_TOO_SMALL                     66
+#define         X509_V_ERR_CA_KEY_TOO_SMALL                     67
+#define         X509_V_ERR_CA_MD_TOO_WEAK                       68
+/* Caller error */
+#define         X509_V_ERR_INVALID_CALL                         69
+/* Issuer lookup error */
+#define         X509_V_ERR_STORE_LOOKUP                         70
+/* Certificate transparency */
+#define         X509_V_ERR_NO_VALID_SCTS                        71
+
+#define         X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         72
+
+typedef void X509_STORE_CTX;
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_X509_VFY_H */
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c b/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c
index 37b708440..1f2b8af6c 100644
--- a/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c
@@ -15,7 +15,6 @@
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
  * License for the specific language governing permissions and limitations
  * under the License.
- *
  ****************************************************************************/
 
 /****************************************************************************
@@ -24,13 +23,57 @@
 
 #include <openssl/bn.h>
 #include <openssl/cipher.h>
+#include <openssl/ssl_dbg.h>
 #include <openssl/ec.h>
 #include <openssl/evp.h>
+#include <openssl/types.h>
+#include "ssl_port.h"
 
 #include <mbedtls/md.h>
 #include <mbedtls/pk.h>
 #include <mbedtls/rsa.h>
 
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+EVP_PKEY *__EVP_PKEY_new(EVP_PKEY *ipk)
+{
+  int ret;
+  EVP_PKEY *pkey;
+
+  pkey = ssl_mem_zalloc(sizeof(EVP_PKEY));
+  if (!pkey)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "no enough memory > (pkey)");
+      goto no_mem;
+    }
+
+  if (ipk)
+    {
+      pkey->method = ipk->method;
+    }
+  else
+    {
+      pkey->method = EVP_PKEY_method();
+    }
+
+  ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL,
+                "EVP_PKEY_METHOD_CALL(new) return %d", ret);
+      goto failed;
+    }
+
+  return pkey;
+
+failed:
+  ssl_mem_free(pkey);
+no_mem:
+  return NULL;
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -55,6 +98,11 @@ RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey)
 
 void EVP_PKEY_free(EVP_PKEY *pkey)
 {
+    SSL_ASSERT3(pkey);
+
+    EVP_PKEY_METHOD_CALL(free, pkey);
+
+    ssl_mem_free(pkey);
 }
 
 int EVP_PKEY_type(int nid)
@@ -69,7 +117,7 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey)
 
 EVP_PKEY *EVP_PKEY_new(void)
 {
-  return NULL;
+  return __EVP_PKEY_new(NULL);
 }
 
 int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_cert.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_cert.c
new file mode 100644
index 000000000..49f05b5da
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_cert.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_cert.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <openssl/ssl_dbg.h>
+#include <openssl/evp.h>
+#include <openssl/ssl_local.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include "ssl_port.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+CERT *__ssl_cert_new(CERT *ic)
+{
+  CERT *cert;
+
+  X509 *ix;
+  EVP_PKEY *ipk;
+
+  cert = ssl_mem_zalloc(sizeof(CERT));
+  if (!cert)
+    {
+      SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "no enough memory > (cert)");
+      goto no_mem;
+    }
+
+  if (ic)
+    {
+      ipk = ic->pkey;
+      ix = ic->x509;
+    }
+  else
+    {
+      ipk = NULL;
+      ix = NULL;
+    }
+
+  cert->pkey = __EVP_PKEY_new(ipk);
+  if (!cert->pkey)
+    {
+      SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__EVP_PKEY_new() return NULL");
+      goto pkey_err;
+    }
+
+  cert->x509 = __X509_new(ix);
+  if (!cert->x509)
+    {
+      SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__X509_new() return NULL");
+      goto x509_err;
+    }
+
+  return cert;
+
+x509_err:
+  EVP_PKEY_free(cert->pkey);
+pkey_err:
+  ssl_mem_free(cert);
+no_mem:
+  return NULL;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
+{
+  SSL_ASSERT1(ctx);
+  SSL_ASSERT1(x);
+  assert(ctx);
+  if (ctx->client_CA == x)
+    {
+      return 1;
+    }
+
+  X509_free(ctx->client_CA);
+  ctx->client_CA = x;
+  return 1;
+}
+
+int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ctx, int len,
+                               const unsigned char *d)
+{
+  X509 *x;
+
+  x = d2i_X509(NULL, &d, len);
+  if (!x)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL");
+      return 0;
+    }
+
+  SSL_ASSERT1(ctx);
+  X509_free(ctx->client_CA);
+  ctx->client_CA = x;
+
+  return 1;
+}
+
+CERT *ssl_cert_new(void)
+{
+  return __ssl_cert_new(NULL);
+}
+
+void ssl_cert_free(CERT *cert)
+{
+  SSL_ASSERT3(cert);
+
+  X509_free(cert->x509);
+
+  EVP_PKEY_free(cert->pkey);
+
+  ssl_mem_free(cert);
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c
new file mode 100644
index 000000000..7f289247d
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c
@@ -0,0 +1,1015 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <openssl/ssl_dbg.h>
+#include <openssl/ssl3.h>
+#include <openssl/ssl_local.h>
+#include "ssl_port.h"
+
+#define SSL_SEND_DATA_MAX_LENGTH 1460
+
+struct alpn_ctx
+{
+  unsigned char data[23];
+  unsigned char len;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static SSL_SESSION *SSL_SESSION_new(void)
+{
+  SSL_SESSION *session;
+
+  session = ssl_mem_zalloc(sizeof(SSL_SESSION));
+  if (!session)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (session)");
+      goto failed1;
+    }
+
+  session->peer = X509_new();
+  if (!session->peer)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL");
+      goto failed2;
+    }
+
+  return session;
+
+failed2:
+  ssl_mem_free(session);
+failed1:
+  return NULL;
+}
+
+static void SSL_SESSION_free(SSL_SESSION *session)
+{
+  X509_free(session->peer);
+  ssl_mem_free(session);
+}
+
+static void
+_openssl_alpn_to_mbedtls(struct alpn_ctx *ac, char ***palpn_protos)
+{
+  unsigned char *p = ac->data;
+  unsigned char *q;
+  unsigned char len;
+  char **alpn_protos;
+  int count = 0;
+
+  /* find out how many entries he gave us */
+
+  len = *p++;
+  while (p - ac->data < ac->len)
+    {
+      if (len--)
+        {
+          p++;
+          continue;
+        }
+
+      count++;
+      len = *p++;
+      if (!len)
+        {
+          break;
+        }
+    }
+
+  if (!len)
+    {
+      count++;
+    }
+
+  if (!count)
+    {
+      return;
+    }
+
+  /* allocate space for count + 1 pointers and the data afterwards */
+
+  alpn_protos = ssl_mem_zalloc((count + 1) * sizeof(char *) + ac->len + 1);
+  if (!alpn_protos)
+    {
+      return;
+    }
+
+  *palpn_protos = alpn_protos;
+
+  /* convert to mbedtls format */
+
+  q = (unsigned char *)alpn_protos + (count + 1) * sizeof(char *);
+  p = ac->data;
+  count = 0;
+
+  len = *p++;
+  alpn_protos[count] = (char *)q;
+  while (p - ac->data < ac->len)
+    {
+      if (len--)
+        {
+          *q++ = *p++;
+          continue;
+        }
+
+      *q++ = '\0';
+      count++;
+      len = *p++;
+      alpn_protos[count] = (char *)q;
+      if (!len)
+        {
+          break;
+        }
+    }
+
+  if (!len)
+    {
+      *q++ = '\0';
+      count++;
+      len = *p++;
+      alpn_protos[count] = (char *)q;
+    }
+
+  alpn_protos[count] = NULL; /* last pointer ends list with NULL */
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl)
+{
+  return &ssl->param;
+}
+
+X509 *SSL_get_certificate(const SSL *ssl)
+{
+  SSL_ASSERT2(ssl);
+
+  return ssl->cert->x509;
+}
+
+X509 *SSL_get_peer_certificate(const SSL *ssl)
+{
+  SSL_ASSERT2(ssl);
+
+  return ssl->session->peer;
+}
+
+int SSL_want(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->rwstate;
+}
+
+int SSL_want_nothing(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  if (ssl->err)
+    {
+      return 1;
+    }
+
+  return (SSL_want(ssl) == SSL_NOTHING);
+}
+
+int SSL_want_read(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  if (ssl->err)
+    {
+      return 0;
+    }
+
+  return (SSL_want(ssl) == SSL_READING);
+}
+
+int SSL_want_x509_lookup(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return (SSL_want(ssl) == SSL_WRITING);
+}
+
+int SSL_get_error(const SSL *ssl, int ret_code)
+{
+  int ret = SSL_ERROR_SYSCALL;
+
+  SSL_ASSERT1(ssl);
+
+  if (ret_code > 0)
+    {
+      ret = SSL_ERROR_NONE;
+    }
+  else if (ret_code < 0)
+    {
+      if (ssl->err == SSL_ERROR_WANT_READ || SSL_want_read(ssl))
+        {
+          ret = SSL_ERROR_WANT_READ;
+        }
+      else if (ssl->err == SSL_ERROR_WANT_WRITE || SSL_want_write(ssl))
+        {
+          ret = SSL_ERROR_WANT_WRITE;
+        }
+      else
+        {
+          ret = SSL_ERROR_SYSCALL;
+        }
+    }
+  else
+    {
+      if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN)
+        {
+          ret = SSL_ERROR_ZERO_RETURN;
+        }
+      else
+        {
+          ret = SSL_ERROR_SYSCALL;
+        }
+    }
+
+  return ret;
+}
+
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, void *rngctx)
+{
+  SSL_CTX *ctx;
+  CERT *cert;
+  X509 *client_ca;
+
+  if (!method)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no no_method");
+      return NULL;
+    }
+
+  client_ca = X509_new();
+  if (!client_ca)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL");
+      goto failed1;
+    }
+
+  cert = ssl_cert_new();
+  if (!cert)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "ssl_cert_new() return NULL");
+      goto failed2;
+    }
+
+  ctx = (SSL_CTX *)ssl_mem_zalloc(sizeof(SSL_CTX));
+  if (!ctx)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ctx)");
+      goto failed3;
+    }
+
+  ctx->method = method;
+  ctx->client_CA = client_ca;
+  ctx->cert = cert;
+  ctx->version = method->version;
+  return ctx;
+
+failed3:
+  ssl_cert_free(cert);
+failed2:
+  X509_free(client_ca);
+failed1:
+  return NULL;
+}
+
+void SSL_CTX_free(SSL_CTX *ctx)
+{
+  SSL_ASSERT3(ctx);
+
+  ssl_cert_free(ctx->cert);
+
+  X509_free(ctx->client_CA);
+
+  if (ctx->alpn_protos)
+    {
+      ssl_mem_free(ctx->alpn_protos);
+    }
+
+  ssl_mem_free(ctx);
+}
+
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)
+{
+  SSL_ASSERT1(ctx);
+  SSL_ASSERT1(meth);
+
+  ctx->method = meth;
+
+  ctx->version = meth->version;
+
+  return 1;
+}
+
+const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx)
+{
+  SSL_ASSERT2(ctx);
+
+  return ctx->method;
+}
+
+SSL *SSL_new(SSL_CTX *ctx)
+{
+  int ret = 0;
+  SSL *ssl;
+
+  if (!ctx)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no ctx");
+      return NULL;
+    }
+
+  ssl = (SSL *)ssl_mem_zalloc(sizeof(SSL));
+  if (!ssl)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ssl)");
+      goto failed1;
+    }
+
+  ssl->session = SSL_SESSION_new();
+  if (!ssl->session)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_SESSION_new() return NULL");
+      goto failed2;
+    }
+
+  ssl->cert = __ssl_cert_new(ctx->cert);
+  if (!ssl->cert)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__ssl_cert_new() return NULL");
+      goto failed3;
+    }
+
+  ssl->client_CA = __X509_new(ctx->client_CA);
+  if (!ssl->client_CA)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__X509_new() return NULL");
+      goto failed4;
+    }
+
+  ssl->ctx = ctx;
+  ssl->method = ctx->method;
+
+  ssl->version = ctx->version;
+  ssl->options = ctx->options;
+
+  ssl->verify_mode = ctx->verify_mode;
+
+  ret = SSL_METHOD_CALL(new, ssl);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret);
+      goto failed5;
+    }
+
+  _ssl_set_alpn_list(ssl);
+
+  ssl->rwstate = SSL_NOTHING;
+
+  return ssl;
+
+failed5:
+  X509_free(ssl->client_CA);
+failed4:
+  ssl_cert_free(ssl->cert);
+failed3:
+  SSL_SESSION_free(ssl->session);
+failed2:
+  ssl_mem_free(ssl);
+failed1:
+  return NULL;
+}
+
+void SSL_free(SSL *ssl)
+{
+  SSL_ASSERT3(ssl);
+
+  SSL_METHOD_CALL(free, ssl);
+
+  X509_free(ssl->client_CA);
+
+  ssl_cert_free(ssl->cert);
+
+  SSL_SESSION_free(ssl->session);
+
+  if (ssl->alpn_protos)
+    {
+      ssl_mem_free(ssl->alpn_protos);
+    }
+
+  ssl_mem_free(ssl);
+}
+
+int SSL_do_handshake(SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  ret = SSL_METHOD_CALL(handshake, ssl);
+
+  return ret;
+}
+
+int SSL_connect(SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return SSL_do_handshake(ssl);
+}
+
+int SSL_accept(SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return SSL_do_handshake(ssl);
+}
+
+int SSL_shutdown(SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  if (SSL_get_state(ssl) != TLS_ST_OK)
+    {
+      return 1;
+    }
+
+  ret = SSL_METHOD_CALL(shutdown, ssl);
+
+  return ret;
+}
+
+int SSL_clear(SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  ret = SSL_shutdown(ssl);
+  if (1 != ret)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret);
+      goto failed1;
+    }
+
+  SSL_METHOD_CALL(free, ssl);
+
+  ret = SSL_METHOD_CALL(new, ssl);
+  if (!ret)
+    {
+      SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret);
+      goto failed1;
+    }
+
+  return 1;
+
+failed1:
+  return ret;
+}
+
+int SSL_read(SSL *ssl, void *buffer, int len)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(buffer);
+  SSL_ASSERT1(len);
+
+  ssl->rwstate = SSL_READING;
+
+  ret = SSL_METHOD_CALL(read, ssl, buffer, len);
+
+  if (ret == len)
+    {
+      ssl->rwstate = SSL_NOTHING;
+    }
+
+  return ret;
+}
+
+int SSL_write(SSL *ssl, const void *buffer, int len)
+{
+  int ret;
+  int send_bytes;
+  int bytes;
+  const unsigned char *pbuf;
+
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(buffer);
+  SSL_ASSERT1(len);
+
+  ssl->rwstate = SSL_WRITING;
+
+  send_bytes = len;
+  pbuf = (const unsigned char *)buffer;
+
+  do
+    {
+      if (send_bytes > SSL_SEND_DATA_MAX_LENGTH)
+        {
+          bytes = SSL_SEND_DATA_MAX_LENGTH;
+        }
+      else
+        {
+          bytes = send_bytes;
+        }
+
+      if (ssl->interrupted_remaining_write)
+        {
+          bytes = ssl->interrupted_remaining_write;
+          ssl->interrupted_remaining_write = 0;
+        }
+
+      ret = SSL_METHOD_CALL(send, ssl, pbuf, bytes);
+
+      /* the return is a NEGATIVE OpenSSL error code, or the length sent */
+
+      if (ret > 0)
+        {
+          pbuf += ret;
+          send_bytes -= ret;
+        }
+      else
+        {
+          ssl->interrupted_remaining_write = bytes;
+        }
+    }
+  while (ret > 0 && send_bytes && ret == bytes);
+
+  if (ret >= 0)
+    {
+      ret = len - send_bytes;
+      if (!ret)
+        {
+          ssl->rwstate = SSL_NOTHING;
+        }
+    }
+  else
+    {
+      if (send_bytes == len)
+        {
+          ret = -1;
+        }
+      else
+        {
+          ret = len - send_bytes;
+        }
+    }
+
+  return ret;
+}
+
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
+{
+  SSL_ASSERT2(ssl);
+
+  return ssl->ctx;
+}
+
+const SSL_METHOD *SSL_get_ssl_method(SSL *ssl)
+{
+  SSL_ASSERT2(ssl);
+
+  return ssl->method;
+}
+
+int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(method);
+
+  if (ssl->version != method->version)
+    {
+      ret = SSL_shutdown(ssl);
+      if (1 != ret)
+        {
+          SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret);
+          goto failed1;
+        }
+
+      SSL_METHOD_CALL(free, ssl);
+
+      ssl->method = method;
+
+      ret = SSL_METHOD_CALL(new, ssl);
+      if (!ret)
+        {
+          SSL_DEBUG(SSL_LIB_ERROR_LEVEL,
+                    "SSL_METHOD_CALL(new) return %d", ret);
+          goto failed1;
+        }
+    }
+  else
+    {
+      ssl->method = method;
+    }
+
+  return 1;
+
+failed1:
+  return ret;
+}
+
+int SSL_get_shutdown(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->shutdown;
+}
+
+void SSL_set_shutdown(SSL *ssl, int mode)
+{
+  SSL_ASSERT3(ssl);
+
+  ssl->shutdown = mode;
+}
+
+int SSL_pending(const SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  ret = SSL_METHOD_CALL(pending, ssl);
+
+  return ret;
+}
+
+int SSL_has_pending(const SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  if (SSL_pending(ssl))
+    {
+      ret = 1;
+    }
+  else
+    {
+      ret = 0;
+    }
+
+  return ret;
+}
+
+unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op)
+{
+  SSL_ASSERT1(ctx);
+
+  return ctx->options &= ~op;
+}
+
+unsigned long SSL_CTX_get_options(SSL_CTX *ctx)
+{
+  SSL_ASSERT1(ctx);
+
+  return ctx->options;
+}
+
+unsigned long SSL_clear_options(SSL *ssl, unsigned long op)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->options & ~op;
+}
+
+unsigned long SSL_get_options(SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->options;
+}
+
+unsigned long SSL_set_options(SSL *ssl, unsigned long op)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->options |= op;
+}
+
+int SSL_get_fd(const SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  ret = SSL_METHOD_CALL(get_fd, ssl, 0);
+
+  return ret;
+}
+
+int SSL_get_rfd(const SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  ret = SSL_METHOD_CALL(get_fd, ssl, 0);
+
+  return ret;
+}
+
+int SSL_get_wfd(const SSL *ssl)
+{
+  int ret;
+
+  SSL_ASSERT1(ssl);
+
+  ret = SSL_METHOD_CALL(get_fd, ssl, 0);
+
+  return ret;
+}
+
+int SSL_set_fd(SSL *ssl, int fd)
+{
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(fd >= 0);
+
+  SSL_METHOD_CALL(set_fd, ssl, fd, 0);
+
+  return 1;
+}
+
+int SSL_set_rfd(SSL *ssl, int fd)
+{
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(fd >= 0);
+
+  SSL_METHOD_CALL(set_fd, ssl, fd, 0);
+
+  return 1;
+}
+
+int SSL_set_wfd(SSL *ssl, int fd)
+{
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(fd >= 0);
+
+  SSL_METHOD_CALL(set_fd, ssl, fd, 0);
+
+  return 1;
+}
+
+int SSL_version(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->version;
+}
+
+const char *SSL_alert_type_string(int value)
+{
+  const char *str;
+
+  switch (value >> 8)
+    {
+      case SSL3_AL_WARNING:
+        str = "W";
+        break;
+      case SSL3_AL_FATAL:
+        str = "F";
+        break;
+      default:
+        str = "U";
+        break;
+    }
+
+  return str;
+}
+
+void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len)
+{
+  SSL_ASSERT3(ctx);
+
+  ctx->read_buffer_len = (int)len;
+}
+
+void SSL_set_default_read_buffer_len(SSL *ssl, size_t len)
+{
+  SSL_ASSERT3(ssl);
+  SSL_ASSERT3(len);
+
+  SSL_METHOD_CALL(set_bufflen, ssl, (int)len);
+}
+
+void SSL_set_info_callback(SSL *ssl,
+                           void (*cb) (const SSL *ssl, int type, int val))
+{
+  SSL_ASSERT3(ssl);
+
+  ssl->info_callback = cb;
+}
+
+int SSL_CTX_up_ref(SSL_CTX *ctx)
+{
+  SSL_ASSERT1(ctx);
+
+  /* no support multi-thread SSL here */
+
+  ctx->references++;
+
+  return 1;
+}
+
+void SSL_set_security_level(SSL *ssl, int level)
+{
+  SSL_ASSERT3(ssl);
+
+  ssl->cert->sec_level = level;
+}
+
+int SSL_get_security_level(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->cert->sec_level;
+}
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
+{
+  SSL_ASSERT1(ctx);
+
+  return ctx->verify_mode;
+}
+
+long SSL_CTX_set_timeout(SSL_CTX *ctx, long t)
+{
+  long l;
+
+  SSL_ASSERT1(ctx);
+
+  l = ctx->session_timeout;
+  ctx->session_timeout = t;
+
+  return l;
+}
+
+long SSL_CTX_get_timeout(const SSL_CTX *ctx)
+{
+  SSL_ASSERT1(ctx);
+
+  return ctx->session_timeout;
+}
+
+void SSL_set_read_ahead(SSL *ssl, int yes)
+{
+  SSL_ASSERT3(ssl);
+
+  ssl->rlayer.read_ahead = yes;
+}
+
+void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes)
+{
+  SSL_ASSERT3(ctx);
+
+  ctx->read_ahead = yes;
+}
+
+int SSL_get_read_ahead(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->rlayer.read_ahead;
+}
+
+long SSL_CTX_get_read_ahead(SSL_CTX *ctx)
+{
+  SSL_ASSERT1(ctx);
+
+  return ctx->read_ahead;
+}
+
+long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx)
+{
+  SSL_ASSERT1(ctx);
+
+  return ctx->read_ahead;
+}
+
+long SSL_set_time(SSL *ssl, long t)
+{
+  SSL_ASSERT1(ssl);
+
+  ssl->session->time = t;
+
+  return t;
+}
+
+long SSL_set_timeout(SSL *ssl, long t)
+{
+  SSL_ASSERT1(ssl);
+
+  ssl->session->timeout = t;
+
+  return t;
+}
+
+long SSL_get_verify_result(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return SSL_METHOD_CALL(get_verify_result, ssl);
+}
+
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
+{
+  SSL_ASSERT1(ctx);
+
+  return ctx->param.depth;
+}
+
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth)
+{
+  SSL_ASSERT3(ctx);
+
+  ctx->param.depth = depth;
+}
+
+int SSL_get_verify_depth(const SSL *ssl)
+{
+  SSL_ASSERT1(ssl);
+
+  return ssl->param.depth;
+}
+
+void SSL_set_verify_depth(SSL *ssl, int depth)
+{
+  SSL_ASSERT3(ssl);
+
+  ssl->param.depth = depth;
+}
+
+void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
+                        int (*verify_callback)(int, X509_STORE_CTX *))
+{
+  SSL_ASSERT3(ctx);
+
+  ctx->verify_mode = mode;
+  ctx->default_verify_callback = verify_callback;
+}
+
+void SSL_set_verify(SSL *ssl, int mode,
+                    int (*verify_callback)(int, X509_STORE_CTX *))
+{
+  SSL_ASSERT3(ssl);
+
+  ssl->verify_mode = mode;
+  ssl->verify_callback = verify_callback;
+}
+
+void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx)
+{
+  return NULL;
+}
+
+void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, next_proto_cb cb, void *arg)
+{
+  struct alpn_ctx *ac = arg;
+
+  ctx->alpn_cb = cb;
+
+  _openssl_alpn_to_mbedtls(ac, (char * **)&ctx->alpn_protos);
+}
+
+void SSL_set_alpn_select_cb(SSL *ssl, void *arg)
+{
+  struct alpn_ctx *ac = arg;
+
+  _openssl_alpn_to_mbedtls(ac, (char * **)&ssl->alpn_protos);
+
+  _ssl_set_alpn_list(ssl);
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c
new file mode 100644
index 000000000..981a20535
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <openssl/tls1.h>
+#include <openssl/ssl_local.h>
+#include <openssl/ssl3.h>
+#include "ssl_methods.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/**
+ * TLS method function collection
+ */
+
+IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func,
+        ssl_pm_new, ssl_pm_free,
+        ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear,
+        ssl_pm_read, ssl_pm_send, ssl_pm_pending,
+        ssl_pm_set_fd, ssl_pm_get_fd,
+        ssl_pm_set_bufflen,
+        ssl_pm_get_verify_result,
+        ssl_pm_get_state);
+
+/**
+ * TLS or SSL client method collection
+ */
+
+IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0,
+                     TLS_method_func, TLSv1_2_client_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 0,
+                     TLS_method_func, TLSv1_1_client_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method);
+
+IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method);
+
+/**
+ * TLS or SSL server method collection
+ */
+
+IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1,
+                     TLS_method_func, TLSv1_1_server_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 1,
+                     TLS_method_func, TLSv1_2_server_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method);
+
+IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method);
+
+/**
+ * TLS or SSL method collection
+ */
+
+IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method);
+
+IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method);
+
+IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method);
+
+IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method);
+
+IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method);
+
+/**
+ * @brief get X509 object method
+ */
+
+IMPLEMENT_X509_METHOD(X509_method,
+            x509_pm_new, x509_pm_free,
+            x509_pm_load, x509_pm_show_info);
+
+/**
+ * @brief get private key object method
+ */
+
+IMPLEMENT_PKEY_METHOD(EVP_PKEY_method,
+            pkey_pm_new, pkey_pm_free,
+            pkey_pm_load);
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h
new file mode 100644
index 000000000..4b090f509
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_SSL_METHODS_H
+#define OPENSSL_MBEDTLS_WRAPPER_SSL_METHODS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <openssl/ssl.h>
+#include "ssl_pm.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* TLS method function implement */
+
+#define IMPLEMENT_TLS_METHOD_FUNC(func_name, \
+                                  new, free, \
+                                  handshake, shutdown, clear, \
+                                  read, send, pending, \
+                                  set_fd, get_fd, \
+                                  set_bufflen, \
+                                  get_verify_result, \
+                                  get_state) \
+    static const SSL_METHOD_FUNC func_name LOCAL_ATRR = \
+      { \
+        new, \
+        free, \
+        handshake, \
+        shutdown, \
+        clear, \
+        read, \
+        send, \
+        pending, \
+        set_fd, \
+        get_fd, \
+        set_bufflen, \
+        get_verify_result, \
+        get_state \
+      };
+
+#define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \
+    const SSL_METHOD* func_name(void) \
+      { \
+        static const SSL_METHOD func_name##_data LOCAL_ATRR = \
+          { \
+            ver, \
+            mode, \
+            &(fun), \
+          }; \
+        return &func_name##_data; \
+      }
+
+#define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \
+    const SSL_METHOD* func_name(void) \
+      { \
+        static const SSL_METHOD func_name##_data LOCAL_ATRR = \
+          { \
+            ver, \
+            mode, \
+            &(fun), \
+          }; \
+        return &func_name##_data; \
+      }
+
+#define IMPLEMENT_X509_METHOD(func_name, \
+                new, \
+                free, \
+                load, \
+                show_info) \
+    const X509_METHOD* func_name(void) \
+      { \
+        static const X509_METHOD func_name##_data LOCAL_ATRR = \
+          { \
+            new, \
+            free, \
+            load, \
+            show_info \
+          }; \
+        return &func_name##_data; \
+      }
+
+#define IMPLEMENT_PKEY_METHOD(func_name, \
+                new, \
+                free, \
+                load) \
+    const PKEY_METHOD* func_name(void) \
+      { \
+        static const PKEY_METHOD func_name##_data LOCAL_ATRR = \
+          { \
+            new, \
+            free, \
+            load \
+          }; \
+        return &func_name##_data; \
+    }
+
+/**
+ * @brief get X509 object method
+ *
+ * @param none
+ *
+ * @return X509 object method point
+ */
+
+const X509_METHOD *X509_method(void);
+
+/**
+ * @brief get private key object method
+ *
+ * @param none
+ *
+ * @return private key object method point
+ */
+
+const PKEY_METHOD *EVP_PKEY_method(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_SSL_METHODS_H */
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c
new file mode 100644
index 000000000..39cdabb12
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c
@@ -0,0 +1,1076 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+
+#include "ssl_pm.h"
+#include "ssl_port.h"
+#include <openssl/ssl_dbg.h>
+#include <openssl/ssl_local.h>
+#include <openssl/tls1.h>
+#include <openssl/evp.h>
+
+/* mbedtls include */
+#include "mbedtls/platform.h"
+#include "mbedtls/net_sockets.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+
+#define X509_INFO_STRING_LENGTH 8192
+
+struct ssl_pm
+{
+  /* local socket file description */
+
+  mbedtls_net_context fd;
+
+  /* remote client socket file description */
+
+  mbedtls_net_context cl_fd;
+  mbedtls_ssl_config conf;
+  mbedtls_ctr_drbg_context ctr_drbg;
+  mbedtls_ssl_context ssl;
+  mbedtls_entropy_context entropy;
+  SSL *owner;
+};
+
+struct x509_pm
+{
+  mbedtls_x509_crt *x509_crt;
+  mbedtls_x509_crt *ex_crt;
+};
+
+struct pkey_pm
+{
+  mbedtls_pk_context *pkey;
+  mbedtls_pk_context *ex_pkey;
+};
+
+unsigned int max_content_len;
+
+/* mbedtls debug level */
+#define MBEDTLS_DEBUG_LEVEL 4
+
+/**
+ * @brief mbedtls debug function
+ */
+
+static void ssl_platform_debug(void *ctx, int level,
+                               const char *file, int line,
+                               const char *str)
+{
+  /* Shorten 'file' from the whole file path to just the filename
+
+   * This is a bit wasteful because the macros are compiled in with
+   * the full _FILE_ path in each case.
+   */
+
+  printf("%s:%d %s", file, line, str);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/**
+ * @brief create SSL low-level object
+ */
+
+int ssl_pm_new(SSL *ssl)
+{
+  struct ssl_pm *ssl_pm;
+  int ret;
+
+  const unsigned char pers[] = "OpenSSL PM";
+  size_t pers_len = sizeof(pers);
+
+  int endpoint;
+  int version;
+
+  const SSL_METHOD *method = ssl->method;
+
+  ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm));
+  if (!ssl_pm)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (ssl_pm)");
+      goto no_mem;
+    }
+
+  ssl_pm->owner = ssl;
+
+  if (!ssl->ctx->read_buffer_len)
+    {
+      ssl->ctx->read_buffer_len = 2048;
+    }
+
+  max_content_len = ssl->ctx->read_buffer_len;
+
+  mbedtls_net_init(&ssl_pm->fd);
+  mbedtls_net_init(&ssl_pm->cl_fd);
+
+  mbedtls_ssl_config_init(&ssl_pm->conf);
+  mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg);
+  mbedtls_entropy_init(&ssl_pm->entropy);
+  mbedtls_ssl_init(&ssl_pm->ssl);
+
+  ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func,
+                              &ssl_pm->entropy, pers, pers_len);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ctr_drbg_seed() return -0x%x", -ret);
+      goto mbedtls_err1;
+    }
+
+  if (method->endpoint)
+    {
+      endpoint = MBEDTLS_SSL_IS_SERVER;
+    }
+  else
+    {
+      endpoint = MBEDTLS_SSL_IS_CLIENT;
+    }
+
+  ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint,
+                                    MBEDTLS_SSL_TRANSPORT_STREAM,
+                                    MBEDTLS_SSL_PRESET_DEFAULT);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ssl_config_defaults() return -0x%x", -ret);
+      goto mbedtls_err2;
+    }
+
+  if (TLS_ANY_VERSION != ssl->version)
+    {
+      if (TLS1_2_VERSION == ssl->version)
+        {
+          version = MBEDTLS_SSL_MINOR_VERSION_3;
+        }
+      else if (TLS1_1_VERSION == ssl->version)
+        {
+          version = MBEDTLS_SSL_MINOR_VERSION_2;
+        }
+      else if (TLS1_VERSION == ssl->version)
+        {
+          version = MBEDTLS_SSL_MINOR_VERSION_1;
+        }
+      else
+        {
+          version = MBEDTLS_SSL_MINOR_VERSION_0;
+        }
+
+      mbedtls_ssl_conf_max_version(&ssl_pm->conf,
+                                   MBEDTLS_SSL_MAJOR_VERSION_3, version);
+      mbedtls_ssl_conf_min_version(&ssl_pm->conf,
+                                   MBEDTLS_SSL_MAJOR_VERSION_3, version);
+    }
+  else
+    {
+      mbedtls_ssl_conf_max_version(&ssl_pm->conf,
+                                   MBEDTLS_SSL_MAJOR_VERSION_3,
+                                   MBEDTLS_SSL_MINOR_VERSION_3);
+      mbedtls_ssl_conf_min_version(&ssl_pm->conf,
+                                   MBEDTLS_SSL_MAJOR_VERSION_3,
+                                   MBEDTLS_SSL_MINOR_VERSION_0);
+    }
+
+  mbedtls_ssl_conf_rng(&ssl_pm->conf,
+                 mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg);
+  mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL);
+
+  ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ssl_setup() return -0x%x", -ret);
+      goto mbedtls_err2;
+    }
+
+  mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd,
+                      mbedtls_net_send, mbedtls_net_recv, NULL);
+
+  ssl->ssl_pm = ssl_pm;
+
+  return 0;
+
+mbedtls_err2:
+  mbedtls_ssl_config_free(&ssl_pm->conf);
+  mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg);
+mbedtls_err1:
+  mbedtls_entropy_free(&ssl_pm->entropy);
+  ssl_mem_free(ssl_pm);
+no_mem:
+  return -1;
+}
+
+/**
+ * @brief free SSL low-level object
+ */
+
+void ssl_pm_free(SSL *ssl)
+{
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg);
+  mbedtls_entropy_free(&ssl_pm->entropy);
+  mbedtls_ssl_config_free(&ssl_pm->conf);
+  mbedtls_ssl_free(&ssl_pm->ssl);
+
+  ssl_mem_free(ssl_pm);
+  ssl->ssl_pm = NULL;
+}
+
+/**
+ * @brief reload SSL low-level certification object
+ */
+
+static int ssl_pm_reload_crt(SSL *ssl)
+{
+  int ret;
+  int mode;
+  struct ssl_pm *ssl_pm = ssl->ssl_pm;
+  struct x509_pm *ca_pm = (struct x509_pm *)ssl->client_CA->x509_pm;
+
+  struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm;
+  struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm;
+
+  if (ssl->verify_mode == SSL_VERIFY_PEER)
+    {
+      mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
+    }
+  else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+    {
+      mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
+    }
+  else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE)
+    {
+      mode = MBEDTLS_SSL_VERIFY_UNSET;
+    }
+  else
+    {
+      mode = MBEDTLS_SSL_VERIFY_NONE;
+    }
+
+  mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode);
+
+  if (ca_pm->x509_crt)
+    {
+      mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL);
+    }
+  else if (ca_pm->ex_crt)
+    {
+      mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->ex_crt, NULL);
+    }
+
+  if (crt_pm->x509_crt && pkey_pm->pkey)
+    {
+      ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf,
+                                      crt_pm->x509_crt, pkey_pm->pkey);
+    }
+  else if (crt_pm->ex_crt && pkey_pm->ex_pkey)
+    {
+      ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf,
+                                      crt_pm->ex_crt, pkey_pm->ex_pkey);
+    }
+  else
+    {
+      ret = 0;
+    }
+
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ssl_conf_own_cert() return -0x%x", -ret);
+      ret = -1;
+    }
+
+  return ret;
+}
+
+/* Perform the mbedtls SSL handshake instead of mbedtls_ssl_handshake.
+ * We can add debug here.
+ */
+
+static int mbedtls_handshake(mbedtls_ssl_context *ssl)
+{
+  int ret = 0;
+
+  while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER)
+    {
+      ret = mbedtls_ssl_handshake_step(ssl);
+
+      if (ret != 0)
+        {
+          break;
+        }
+    }
+
+  return ret;
+}
+
+int ssl_pm_handshake(SSL *ssl)
+{
+  int ret;
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  ssl->err = 0;
+  errno = 0;
+
+  ret = ssl_pm_reload_crt(ssl);
+  if (ret)
+    {
+      printf("%s: cert reload failed\n", __func__);
+      return 0;
+    }
+
+  if (ssl_pm->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
+    {
+      ssl_speed_up_enter();
+
+      /* mbedtls return codes
+       * 0 = successful, or MBEDTLS_ERR_SSL_WANT_READ/WRITE
+       * anything else = death
+       */
+
+      ret = mbedtls_handshake(&ssl_pm->ssl);
+      ssl_speed_up_exit();
+    }
+  else
+    {
+      ret = 0;
+    }
+
+  /* OpenSSL return codes:
+   *   0 = did not complete, but may be retried
+   *   1 = successfully completed
+   *   <0 = death
+   */
+
+  if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)
+    {
+      ssl->err = ret;
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ssl_handshake() return -0x%x", -ret);
+      return 0; /* OpenSSL: did not complete but may be retried */
+    }
+
+  if (ret == 0)
+    {
+      /* successful */
+
+      struct x509_pm *x509_pm =
+                     (struct x509_pm *)ssl->session->peer->x509_pm;
+
+      x509_pm->ex_crt = (mbedtls_x509_crt *)
+                        mbedtls_ssl_get_peer_cert(&ssl_pm->ssl);
+      return 1; /* openssl successful */
+    }
+
+  if (errno == 11)
+    {
+      ssl->err = ret == MBEDTLS_ERR_SSL_WANT_READ;
+
+      return 0;
+    }
+
+  printf("%s: mbedtls_ssl_handshake() returned -0x%x\n", __func__, -ret);
+
+  /* it's had it */
+
+  ssl->err = SSL_ERROR_SYSCALL;
+
+  return -1; /* openssl death */
+}
+
+mbedtls_x509_crt *
+ssl_ctx_get_mbedtls_x509_crt(SSL_CTX *ssl_ctx)
+{
+  struct x509_pm *x509_pm = (struct x509_pm *)ssl_ctx->cert->x509->x509_pm;
+
+  if (!x509_pm)
+    {
+      return NULL;
+    }
+
+  return x509_pm->x509_crt;
+}
+
+mbedtls_x509_crt *
+ssl_get_peer_mbedtls_x509_crt(SSL *ssl)
+{
+  struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm;
+
+  if (!x509_pm)
+    {
+      return NULL;
+    }
+
+  return x509_pm->ex_crt;
+}
+
+int ssl_pm_shutdown(SSL *ssl)
+{
+  int ret;
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  ret = mbedtls_ssl_close_notify(&ssl_pm->ssl);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ssl_close_notify() return -0x%x", -ret);
+      if (ret == MBEDTLS_ERR_NET_CONN_RESET)
+        {
+          ssl->err = SSL_ERROR_SYSCALL;
+        }
+
+      ret = -1; /* OpenSSL: "Call SSL_get_error with the return value to find the reason */
+    }
+  else
+    {
+      struct x509_pm *x509_pm =
+                     (struct x509_pm *)ssl->session->peer->x509_pm;
+
+      x509_pm->ex_crt = NULL;
+      ret = 1; /* OpenSSL: "The shutdown was successfully completed"
+                * ...0 means retry */
+    }
+
+  return ret;
+}
+
+int ssl_pm_clear(SSL *ssl)
+{
+  return ssl_pm_shutdown(ssl);
+}
+
+int ssl_pm_read(SSL *ssl, void *buffer, int len)
+{
+  int ret;
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len);
+  if (ret < 0)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ssl_read() return -0x%x", -ret);
+      if (ret == MBEDTLS_ERR_NET_CONN_RESET ||
+          ret <= MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) /* fatal errors */
+        {
+          ssl->err = SSL_ERROR_SYSCALL;
+        }
+
+      ret = -1;
+    }
+
+  return ret;
+}
+
+/* This returns -1, or the length sent.
+ * If -1, then you need to find out if the error was
+ * fatal or recoverable using SSL_get_error()
+ */
+
+int ssl_pm_send(SSL *ssl, const void *buffer, int len)
+{
+  int ret;
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len);
+  /* We can get a positive number, which may be less than len... that
+   * much was sent successfully and you can call again to send more.
+   *
+   * We can get a negative mbedtls error code... if WANT_WRITE or WANT_READ,
+   * it's nonfatal and means it should be retried as-is.  If something else,
+   * it's fatal actually.
+   *
+   * If this function returns something other than a positive value or
+   * MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context becomes unusable, and
+   * you should either free it or call mbedtls_ssl_session_reset() on it
+   * before re-using it for a new connection; the current connection must
+   * be closed.
+   *
+   * When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, it must be
+   * called later with the same arguments, until it returns a positive value.
+   */
+
+  if (ret < 0)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_ssl_write() return -0x%x", -ret);
+      switch (ret)
+        {
+          case MBEDTLS_ERR_NET_SEND_FAILED:
+          case MBEDTLS_ERR_NET_CONN_RESET:
+            ssl->err = SSL_ERROR_SYSCALL;
+            break;
+          case MBEDTLS_ERR_SSL_WANT_WRITE:
+            ssl->err = SSL_ERROR_WANT_WRITE;
+            break;
+          case MBEDTLS_ERR_SSL_WANT_READ:
+            ssl->err = SSL_ERROR_WANT_READ;
+            break;
+          default:
+            break;
+          }
+
+      ret = -1;
+    }
+
+  return ret;
+}
+
+int ssl_pm_pending(const SSL *ssl)
+{
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  return (int)mbedtls_ssl_get_bytes_avail(&ssl_pm->ssl);
+}
+
+void ssl_pm_set_fd(SSL *ssl, int fd, int mode)
+{
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  ssl_pm->fd.fd = fd;
+}
+
+int ssl_pm_get_fd(const SSL *ssl, int mode)
+{
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  return ssl_pm->fd.fd;
+}
+
+OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl)
+{
+  OSSL_HANDSHAKE_STATE state;
+
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  switch (ssl_pm->ssl.state)
+    {
+      case MBEDTLS_SSL_CLIENT_HELLO:
+        state = TLS_ST_CW_CLNT_HELLO;
+        break;
+      case MBEDTLS_SSL_SERVER_HELLO:
+        state = TLS_ST_SW_SRVR_HELLO;
+        break;
+      case MBEDTLS_SSL_SERVER_CERTIFICATE:
+        state = TLS_ST_SW_CERT;
+        break;
+      case MBEDTLS_SSL_SERVER_HELLO_DONE:
+        state = TLS_ST_SW_SRVR_DONE;
+        break;
+      case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
+        state = TLS_ST_CW_KEY_EXCH;
+        break;
+      case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
+        state = TLS_ST_CW_CHANGE;
+        break;
+      case MBEDTLS_SSL_CLIENT_FINISHED:
+        state = TLS_ST_CW_FINISHED;
+        break;
+      case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
+        state = TLS_ST_SW_CHANGE;
+        break;
+      case MBEDTLS_SSL_SERVER_FINISHED:
+        state = TLS_ST_SW_FINISHED;
+        break;
+      case MBEDTLS_SSL_CLIENT_CERTIFICATE:
+        state = TLS_ST_CW_CERT;
+        break;
+      case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
+        state = TLS_ST_SR_KEY_EXCH;
+        break;
+      case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
+        state = TLS_ST_SW_SESSION_TICKET;
+        break;
+      case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
+        state = TLS_ST_SW_CERT_REQ;
+        break;
+      case MBEDTLS_SSL_HANDSHAKE_OVER:
+        state = TLS_ST_OK;
+        break;
+      default :
+        state = TLS_ST_BEFORE;
+        break;
+    }
+
+  return state;
+}
+
+int x509_pm_show_info(X509 *x)
+{
+  int ret;
+  char *buf;
+  mbedtls_x509_crt *x509_crt;
+  struct x509_pm *x509_pm = x->x509_pm;
+
+  if (x509_pm->x509_crt)
+    {
+      x509_crt = x509_pm->x509_crt;
+    }
+  else if (x509_pm->ex_crt)
+    {
+      x509_crt = x509_pm->ex_crt;
+    }
+  else
+    {
+      x509_crt = NULL;
+    }
+
+  if (!x509_crt)
+    {
+      return -1;
+    }
+
+  buf = ssl_mem_malloc(X509_INFO_STRING_LENGTH);
+  if (!buf)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (buf)");
+      goto no_mem;
+    }
+
+  ret = mbedtls_x509_crt_info(buf, X509_INFO_STRING_LENGTH - 1,
+                              "", x509_crt);
+  if (ret <= 0)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_x509_crt_info() return -0x%x", -ret);
+      goto mbedtls_err1;
+    }
+
+  buf[ret] = 0;
+
+  ssl_mem_free(buf);
+
+  SSL_DEBUG(SSL_DEBUG_ON, "%s", buf);
+
+  return 0;
+
+mbedtls_err1:
+  ssl_mem_free(buf);
+no_mem:
+  return -1;
+}
+
+int x509_pm_new(X509 *x, X509 *m_x)
+{
+  struct x509_pm *x509_pm;
+
+  x509_pm = ssl_mem_zalloc(sizeof(struct x509_pm));
+  if (!x509_pm)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (x509_pm)");
+      goto failed1;
+    }
+
+  x->x509_pm = x509_pm;
+
+  if (m_x)
+    {
+      struct x509_pm *m_x509_pm = (struct x509_pm *)m_x->x509_pm;
+
+      x509_pm->ex_crt = m_x509_pm->x509_crt;
+    }
+
+  return 0;
+
+failed1:
+  return -1;
+}
+
+void x509_pm_free(X509 *x)
+{
+  struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm;
+
+  if (x509_pm->x509_crt)
+    {
+      mbedtls_x509_crt_free(x509_pm->x509_crt);
+
+      ssl_mem_free(x509_pm->x509_crt);
+      x509_pm->x509_crt = NULL;
+    }
+
+  ssl_mem_free(x->x509_pm);
+  x->x509_pm = NULL;
+}
+
+int x509_pm_load(X509 *x, const unsigned char *buffer, int len)
+{
+  int ret;
+  unsigned char *load_buf;
+  struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm;
+
+  if (x509_pm->x509_crt)
+    {
+      mbedtls_x509_crt_free(x509_pm->x509_crt);
+    }
+
+  if (!x509_pm->x509_crt)
+    {
+      x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt));
+      if (!x509_pm->x509_crt)
+        {
+          SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                    "no enough memory > (x509_pm->x509_crt)");
+          goto no_mem;
+        }
+    }
+
+  mbedtls_x509_crt_init(x509_pm->x509_crt);
+  if (buffer[0] != 0x30)
+    {
+      load_buf = ssl_mem_malloc(len + 1);
+      if (!load_buf)
+        {
+          SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                    "no enough memory > (load_buf)");
+          goto failed;
+        }
+
+      ssl_memcpy(load_buf, buffer, len);
+      load_buf[len] = '\0';
+
+      ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1);
+      ssl_mem_free(load_buf);
+    }
+  else
+    {
+      printf("parsing as der\n");
+
+      ret = mbedtls_x509_crt_parse_der(x509_pm->x509_crt, buffer, len);
+    }
+
+  if (ret)
+    {
+      printf("mbedtls_x509_crt_parse return -0x%x", -ret);
+      goto failed;
+    }
+
+  return 0;
+
+failed:
+  mbedtls_x509_crt_free(x509_pm->x509_crt);
+  ssl_mem_free(x509_pm->x509_crt);
+  x509_pm->x509_crt = NULL;
+no_mem:
+  return -1;
+}
+
+int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey)
+{
+  struct pkey_pm *pkey_pm;
+
+  pkey_pm = ssl_mem_zalloc(sizeof(struct pkey_pm));
+  if (!pkey_pm)
+    {
+      return -1;
+    }
+
+  pk->pkey_pm = pkey_pm;
+
+  if (m_pkey)
+    {
+      struct pkey_pm *m_pkey_pm = (struct pkey_pm *)m_pkey->pkey_pm;
+
+      pkey_pm->ex_pkey = m_pkey_pm->pkey;
+    }
+
+  return 0;
+}
+
+void pkey_pm_free(EVP_PKEY *pk)
+{
+  struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm;
+
+  if (pkey_pm->pkey)
+    {
+      mbedtls_pk_free(pkey_pm->pkey);
+
+      ssl_mem_free(pkey_pm->pkey);
+      pkey_pm->pkey = NULL;
+    }
+
+  ssl_mem_free(pk->pkey_pm);
+  pk->pkey_pm = NULL;
+}
+
+int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len)
+{
+  int ret;
+  unsigned char *load_buf;
+  struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm;
+  mbedtls_ctr_drbg_context ctr_drbg;
+
+  if (pkey_pm->pkey)
+    {
+      mbedtls_pk_free(pkey_pm->pkey);
+    }
+
+  if (!pkey_pm->pkey)
+    {
+      pkey_pm->pkey = ssl_mem_malloc(sizeof(mbedtls_pk_context));
+      if (!pkey_pm->pkey)
+        {
+          SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                    "no enough memory > (pkey_pm->pkey)");
+          goto no_mem;
+        }
+    }
+
+  load_buf = ssl_mem_malloc(len + 1);
+  if (!load_buf)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (load_buf)");
+      goto failed;
+    }
+
+  ssl_memcpy(load_buf, buffer, len);
+  load_buf[len] = '\0';
+
+  mbedtls_pk_init(pkey_pm->pkey);
+  mbedtls_ctr_drbg_init(&ctr_drbg);
+
+  ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1,
+                             NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg);
+  ssl_mem_free(load_buf);
+
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+                "mbedtls_pk_parse_key return -0x%x", -ret);
+      goto failed;
+    }
+
+  mbedtls_ctr_drbg_free(&ctr_drbg);
+
+  return 0;
+
+failed:
+  mbedtls_ctr_drbg_free(&ctr_drbg);
+  mbedtls_pk_free(pkey_pm->pkey);
+  ssl_mem_free(pkey_pm->pkey);
+  pkey_pm->pkey = NULL;
+no_mem:
+  return -1;
+}
+
+void ssl_pm_set_bufflen(SSL *ssl, int len)
+{
+  max_content_len = len;
+}
+
+long ssl_pm_get_verify_result(const SSL *ssl)
+{
+  uint32_t ret;
+  long verify_result;
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl);
+  if (!ret)
+    {
+      return X509_V_OK;
+    }
+
+  if (ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED ||
+      (ret & MBEDTLS_X509_BADCRL_NOT_TRUSTED))
+    {
+      verify_result = X509_V_ERR_INVALID_CA;
+    }
+  else if (ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
+    {
+      verify_result = X509_V_ERR_HOSTNAME_MISMATCH;
+    }
+  else if ((ret & MBEDTLS_X509_BADCERT_BAD_KEY) ||
+           (ret & MBEDTLS_X509_BADCRL_BAD_KEY))
+    {
+      verify_result = X509_V_ERR_CA_KEY_TOO_SMALL;
+    }
+  else if ((ret & MBEDTLS_X509_BADCERT_BAD_MD) ||
+           (ret & MBEDTLS_X509_BADCRL_BAD_MD))
+    {
+      verify_result = X509_V_ERR_CA_MD_TOO_WEAK;
+    }
+  else if ((ret & MBEDTLS_X509_BADCERT_FUTURE) ||
+           (ret & MBEDTLS_X509_BADCRL_FUTURE))
+    {
+      verify_result = X509_V_ERR_CERT_NOT_YET_VALID;
+    }
+  else if ((ret & MBEDTLS_X509_BADCERT_EXPIRED) ||
+           (ret & MBEDTLS_X509_BADCRL_EXPIRED))
+    {
+      verify_result = X509_V_ERR_CERT_HAS_EXPIRED;
+    }
+  else
+    {
+      verify_result = X509_V_ERR_UNSPECIFIED;
+    }
+
+  SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL,
+            "mbedtls_ssl_get_verify_result() return 0x%x", ret);
+
+  return verify_result;
+}
+
+/**
+ * @brief set expected hostname on peer cert CN
+ */
+
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen)
+{
+  SSL *ssl = (SSL *)((char *)param - offsetof(SSL, param));
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+  char *name_cstr = NULL;
+
+  if (namelen)
+    {
+      name_cstr = malloc(namelen + 1);
+      if (!name_cstr)
+        {
+          return 0;
+        }
+
+      memcpy(name_cstr, name, namelen);
+      name_cstr[namelen] = '\0';
+      name = name_cstr;
+    }
+
+  mbedtls_ssl_set_hostname(&ssl_pm->ssl, name);
+
+  if (namelen)
+    {
+      free(name_cstr);
+    }
+
+  return 1;
+}
+
+void _ssl_set_alpn_list(const SSL *ssl)
+{
+  if (ssl->alpn_protos)
+    {
+      if (mbedtls_ssl_conf_alpn_protocols(
+          &((struct ssl_pm *)(ssl->ssl_pm))->conf,
+        ssl->alpn_protos))
+        {
+          fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n");
+        }
+
+      return;
+    }
+
+  if (!ssl->ctx->alpn_protos)
+    {
+      return;
+    }
+
+  if (mbedtls_ssl_conf_alpn_protocols(
+      &((struct ssl_pm *)(ssl->ssl_pm))->conf,
+      ssl->ctx->alpn_protos))
+    {
+      fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n");
+    }
+}
+
+void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+                            unsigned int *len)
+{
+  const char *alp = mbedtls_ssl_get_alpn_protocol(
+                &((struct ssl_pm *)(ssl->ssl_pm))->ssl);
+
+  *data = (const unsigned char *)alp;
+  if (alp)
+    {
+      *len = (int)strlen(alp);
+    }
+  else
+    {
+      *len = 0;
+    }
+}
+
+int SSL_set_sni_callback(SSL *ssl,
+                         int(*cb)(void *, mbedtls_ssl_context *,
+                         const unsigned char *, size_t), void *param)
+{
+  struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+  mbedtls_ssl_conf_sni(&ssl_pm->conf, cb, param);
+
+  return 0;
+}
+
+SSL *SSL_SSL_from_mbedtls_ssl_context(mbedtls_ssl_context *msc)
+{
+  struct ssl_pm *ssl_pm =
+        (struct ssl_pm *)((char *)msc - offsetof(struct ssl_pm, ssl));
+
+  return ssl_pm->owner;
+}
+
+void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
+{
+  struct ssl_pm *ssl_pm = ssl->ssl_pm;
+  struct x509_pm *x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm;
+  struct x509_pm *x509_pm_ca = (struct x509_pm *)ctx->client_CA->x509_pm;
+
+  struct pkey_pm *pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm;
+  int mode;
+
+  if (ssl->cert)
+    {
+      ssl_cert_free(ssl->cert);
+    }
+
+  ssl->ctx = ctx;
+  ssl->cert = __ssl_cert_new(ctx->cert);
+
+  if (ctx->verify_mode == SSL_VERIFY_PEER)
+    {
+      mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
+    }
+  else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+    {
+      mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
+    }
+  else if (ctx->verify_mode == SSL_VERIFY_CLIENT_ONCE)
+    {
+      mode = MBEDTLS_SSL_VERIFY_UNSET;
+    }
+  else
+    {
+      mode = MBEDTLS_SSL_VERIFY_NONE;
+    }
+
+  /* apply new ctx cert to ssl */
+
+  ssl->verify_mode = ctx->verify_mode;
+
+  mbedtls_ssl_set_hs_ca_chain(&ssl_pm->ssl, x509_pm_ca->x509_crt, NULL);
+  mbedtls_ssl_set_hs_own_cert(&ssl_pm->ssl, x509_pm->x509_crt,
+                              pkey_pm->pkey);
+  mbedtls_ssl_set_hs_authmode(&ssl_pm->ssl, mode);
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h
new file mode 100644
index 000000000..6d1b0f629
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_SSL_PM_H
+#define OPENSSL_MBEDTLS_WRAPPER_SSL_PM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <string.h>
+#include <openssl/ssl.h>
+#include "ssl_port.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define LOCAL_ATRR
+
+int ssl_pm_new(SSL *ssl);
+void ssl_pm_free(SSL *ssl);
+
+int ssl_pm_handshake(SSL *ssl);
+int ssl_pm_shutdown(SSL *ssl);
+int ssl_pm_clear(SSL *ssl);
+
+int ssl_pm_read(SSL *ssl, void *buffer, int len);
+int ssl_pm_send(SSL *ssl, const void *buffer, int len);
+int ssl_pm_pending(const SSL *ssl);
+
+void ssl_pm_set_fd(SSL *ssl, int fd, int mode);
+int ssl_pm_get_fd(const SSL *ssl, int mode);
+
+OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl);
+
+void ssl_pm_set_bufflen(SSL *ssl, int len);
+
+int x509_pm_show_info(X509 *x);
+int x509_pm_new(X509 *x, X509 *m_x);
+void x509_pm_free(X509 *x);
+int x509_pm_load(X509 *x, const unsigned char *buffer, int len);
+
+int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk);
+void pkey_pm_free(EVP_PKEY *pk);
+int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len);
+
+long ssl_pm_get_verify_result(const SSL *ssl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_SSL_PM_H */
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.c
new file mode 100644
index 000000000..b1ff4ee8b
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.c
@@ -0,0 +1,39 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "ssl_port.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void *ssl_mem_zalloc(size_t size)
+{
+  void *p = malloc(size);
+
+  if (p)
+    {
+      memset(p, 0, size);
+    }
+
+  return p;
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.h b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.h
new file mode 100644
index 000000000..2ff053253
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_port.h
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+#ifndef OPENSSL_MBEDTLS_WRAPPER_SSL_PORT_H
+#define OPENSSL_MBEDTLS_WRAPPER_SSL_PORT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "string.h"
+#include "stdlib.h"
+#if defined(LWS_HAVE_MALLOC_H)
+#include "malloc.h"
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void *ssl_mem_zalloc(size_t size);
+
+#define ssl_mem_malloc malloc
+#define ssl_mem_free   free
+
+#define ssl_memcpy     memcpy
+#define ssl_strlen     strlen
+
+#define ssl_speed_up_enter()
+#define ssl_speed_up_exit()
+
+#define SSL_DEBUG_FL
+#define SSL_DEBUG_LOG(fmt, ...) ESP_LOGI("openssl", fmt, ##__VA_ARGS__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENSSL_MBEDTLS_WRAPPER_SSL_PORT_H */
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c
new file mode 100644
index 000000000..8c0e584cd
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c
@@ -0,0 +1,242 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+#include <openssl/ssl_dbg.h>
+#include <openssl/evp.h>
+#include <openssl/ssl_local.h>
+#include <openssl/x509.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
+{
+  SSL_ASSERT1(ctx);
+  SSL_ASSERT1(x);
+
+  if (ctx->cert->x509 == x)
+    {
+      return 1;
+    }
+
+  X509_free(ctx->cert->x509);
+  ctx->cert->x509 = x;
+  return 1;
+}
+
+int SSL_use_certificate(SSL *ssl, X509 *x)
+{
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(x);
+
+  if (ssl->cert->x509 == x)
+    {
+      return 1;
+    }
+
+  X509_free(ssl->cert->x509);
+  ssl->cert->x509 = x;
+  return 1;
+}
+
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
+                                 const unsigned char *d)
+{
+  int ret;
+  X509 *x;
+
+  x = d2i_X509(NULL, &d, len);
+  if (!x)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL");
+      goto failed1;
+    }
+
+  ret = SSL_CTX_use_certificate(ctx, x);
+  if (!ret)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL,
+                "SSL_CTX_use_certificate() return %d", ret);
+      goto failed2;
+    }
+
+  return 1;
+
+failed2:
+  X509_free(x);
+failed1:
+  return 0;
+}
+
+int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
+{
+  int ret;
+  X509 *x;
+
+  x = d2i_X509(NULL, &d, len);
+  if (!x)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL");
+      goto failed1;
+    }
+
+  ret = SSL_use_certificate(ssl, x);
+  if (!ret)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL,
+                "SSL_use_certificate() return %d", ret);
+      goto failed2;
+    }
+
+  return 1;
+
+failed2:
+  X509_free(x);
+failed1:
+  return 0;
+}
+
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
+{
+  return 0;
+}
+
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
+{
+  return 0;
+}
+
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
+{
+  SSL_ASSERT1(ctx);
+  SSL_ASSERT1(pkey);
+
+  if (ctx->cert->pkey == pkey)
+    {
+      return 1;
+    }
+
+  if (ctx->cert->pkey)
+    {
+      EVP_PKEY_free(ctx->cert->pkey);
+    }
+
+  ctx->cert->pkey = pkey;
+
+  return 1;
+}
+
+int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
+{
+  SSL_ASSERT1(ssl);
+  SSL_ASSERT1(pkey);
+
+  if (ssl->cert->pkey == pkey)
+    {
+      return 1;
+    }
+
+  if (ssl->cert->pkey)
+    {
+      EVP_PKEY_free(ssl->cert->pkey);
+    }
+
+  ssl->cert->pkey = pkey;
+
+  return 1;
+}
+
+int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
+                                const unsigned char *d, long len)
+{
+  int ret;
+  EVP_PKEY *pk;
+
+  pk = d2i_PrivateKey(0, NULL, &d, len);
+  if (!pk)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL");
+      goto failed1;
+    }
+
+  ret = SSL_CTX_use_PrivateKey(ctx, pk);
+  if (!ret)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL,
+                "SSL_CTX_use_PrivateKey() return %d", ret);
+      goto failed2;
+    }
+
+  return 1;
+
+failed2:
+  EVP_PKEY_free(pk);
+failed1:
+  return 0;
+}
+
+int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
+                            const unsigned char *d, long len)
+{
+  int ret;
+  EVP_PKEY *pk;
+
+  pk = d2i_PrivateKey(0, NULL, &d, len);
+  if (!pk)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL");
+      goto failed1;
+    }
+
+  ret = SSL_use_PrivateKey(ssl, pk);
+  if (!ret)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_PrivateKey() return %d", ret);
+      goto failed2;
+    }
+
+  return 1;
+
+failed2:
+  EVP_PKEY_free(pk);
+failed1:
+  return 0;
+}
+
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+{
+  return 0;
+}
+
+int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+{
+  return 0;
+}
+
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
+                                   long len)
+{
+  return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len);
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/stack.c b/crypto/openssl_mbedtls_wrapper/mbedtls/stack.c
new file mode 100644
index 000000000..0ab5e2956
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/stack.c
@@ -0,0 +1,79 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/stack.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <openssl/stack.h>
+#include <openssl/ssl_dbg.h>
+#include "ssl_port.h"
+
+#ifndef CONFIG_MIN_NODES
+    #define MIN_NODES 4
+#else
+    #define MIN_NODES CONFIG_MIN_NODES
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c)
+{
+  OPENSSL_STACK *stack;
+  char **data;
+
+  stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK));
+  if (!stack)
+    {
+      SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (stack)");
+      goto no_mem1;
+    }
+
+  data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES);
+  if (!data)
+    {
+      SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (data)");
+      goto no_mem2;
+    }
+
+  stack->data = data;
+  stack->num_alloc = MIN_NODES;
+  stack->c = c;
+
+  return stack;
+
+no_mem2:
+  ssl_mem_free(stack);
+no_mem1:
+  return NULL;
+}
+
+OPENSSL_STACK *OPENSSL_sk_new_null(void)
+{
+  return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL);
+}
+
+void OPENSSL_sk_free(OPENSSL_STACK *stack)
+{
+  SSL_ASSERT3(stack);
+
+  ssl_mem_free(stack->data);
+  ssl_mem_free(stack);
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/statem.c b/crypto/openssl_mbedtls_wrapper/mbedtls/statem.c
new file mode 100644
index 000000000..d7b13b2e4
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/statem.c
@@ -0,0 +1,39 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/statem.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <openssl/ssl_dbg.h>
+#include <openssl/ssl_local.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl)
+{
+  OSSL_HANDSHAKE_STATE state;
+
+  SSL_ASSERT1(ssl);
+
+  state = SSL_METHOD_CALL(get_state, ssl);
+
+  return state;
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/x509.c b/crypto/openssl_mbedtls_wrapper/mbedtls/x509.c
index a648e87a9..ab0b17366 100644
--- a/crypto/openssl_mbedtls_wrapper/mbedtls/x509.c
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/x509.c
@@ -22,7 +22,10 @@
  * Included Files
  ****************************************************************************/
 
+#include <openssl/ssl_dbg.h>
 #include <openssl/x509.h>
+#include "ssl_port.h"
+#include "ssl_methods.h"
 
 /****************************************************************************
  * Public Functions
@@ -161,3 +164,85 @@ EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
 {
   return NULL;
 }
+
+X509 *d2i_X509(X509 **out, const unsigned char **inp, long len)
+{
+  int m = 0;
+  int ret;
+  X509 *x;
+
+  SSL_ASSERT2(inp);
+  SSL_ASSERT2(len);
+
+  if (out && *out)
+    {
+      x = *out;
+    }
+  else
+    {
+      x = X509_new();
+      if (!x)
+        {
+          SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL");
+          goto failed1;
+        }
+
+      m = 1;
+    }
+
+  ret = X509_METHOD_CALL(load, x, *inp, (int)len);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL,
+                "X509_METHOD_CALL(load) return %d", ret);
+      goto failed2;
+    }
+
+  return x;
+
+failed2:
+  if (m)
+    {
+      X509_free(x);
+    }
+
+failed1:
+  return NULL;
+}
+
+X509 *__X509_new(X509 *ix)
+{
+  int ret;
+  X509 *x;
+
+  x = ssl_mem_zalloc(sizeof(X509));
+  if (!x)
+    {
+      SSL_DEBUG(SSL_X509_ERROR_LEVEL, "no enough memory > (x)");
+      goto no_mem;
+    }
+
+  if (ix)
+    {
+      x->method = ix->method;
+    }
+  else
+    {
+      x->method = X509_method();
+    }
+
+  ret = X509_METHOD_CALL(new, x, ix);
+  if (ret)
+    {
+      SSL_DEBUG(SSL_PKEY_ERROR_LEVEL,
+                "X509_METHOD_CALL(new) return %d", ret);
+      goto failed;
+    }
+
+  return x;
+
+failed:
+  ssl_mem_free(x);
+no_mem:
+  return NULL;
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/x509_vpm.c b/crypto/openssl_mbedtls_wrapper/mbedtls/x509_vpm.c
new file mode 100644
index 000000000..dfe9e7fab
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/x509_vpm.c
@@ -0,0 +1,39 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/x509_vpm.c
+ *
+ * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+ *
+ * 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <openssl/types.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+                                    unsigned long flags)
+{
+  return 0;
+}
+
+int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param,
+                                      unsigned long flags)
+{
+  return 0;
+}