Browse Source

feat: ECDSA peripheral while performing http connection with mutual auth

Harshit Malpani 2 năm trước cách đây
mục cha
commit
692e1a9e61

+ 9 - 1
components/esp-tls/esp_tls.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -151,6 +151,10 @@ typedef struct esp_tls_cfg {
     unsigned int clientkey_password_len;    /*!< String length of the password pointed to by
                                                  clientkey_password */
 
+    bool use_ecdsa_peripheral;              /*!< Use the ECDSA peripheral for the private key operations */
+
+    uint8_t ecdsa_key_efuse_blk;            /*!< The efuse block where the ECDSA key is stored */
+
     bool non_block;                         /*!< Configure non-blocking mode. If set to true the
                                                  underneath socket will be configured in non
                                                  blocking mode after tls session is established */
@@ -276,6 +280,10 @@ typedef struct esp_tls_cfg_server {
     unsigned int serverkey_password_len;        /*!< String length of the password pointed to by
                                                      serverkey_password */
 
+    bool use_ecdsa_peripheral;                  /*!< Use ECDSA peripheral to use private key */
+
+    uint8_t ecdsa_key_efuse_blk;                /*!< The efuse block where ECDSA key is stored */
+
     bool use_secure_element;                    /*!< Enable this option to use secure element or
                                                  atecc608a chip ( Integrated with ESP32-WROOM-32SE ) */
 

+ 73 - 0
components/esp-tls/esp_tls_mbedtls.c

@@ -20,6 +20,10 @@
 #include "esp_log.h"
 #include "esp_check.h"
 
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+#include "ecdsa/ecdsa_alt.h"
+#endif
+
 #ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
 #include "esp_crt_bundle.h"
 #endif
@@ -404,6 +408,19 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki)
                 return ret;
             }
         } else
+#endif
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+        if (tls->use_ecdsa_peripheral) {
+            esp_ecdsa_pk_conf_t conf = {
+                .grp_id = MBEDTLS_ECP_DP_SECP256R1,
+                .efuse_block = tls->ecdsa_efuse_blk,
+            };
+            ret = esp_ecdsa_set_pk_context(pki->pk_key, &conf);
+            if (ret != ESP_OK) {
+                ESP_LOGE(TAG, "Failed to initialize pk context for ecdsa peripheral with the key stored in efuse block %d", tls->ecdsa_efuse_blk);
+                return ret;
+            }
+        } else
 #endif
         if (pki->privkey_pem_buf != NULL) {
             ret = mbedtls_pk_parse_key(pki->pk_key, pki->privkey_pem_buf, pki->privkey_pem_bytes,
@@ -580,6 +597,29 @@ esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
         ESP_LOGE(TAG, "Please enable secure element support for ESP-TLS in menuconfig");
         return ESP_FAIL;
 #endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
+    }  else if (cfg->use_ecdsa_peripheral) {
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+        tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral;
+        tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk;
+        esp_tls_pki_t pki = {
+            .public_cert = &tls->servercert,
+            .pk_key = &tls->serverkey,
+            .publiccert_pem_buf = cfg->servercert_buf,
+            .publiccert_pem_bytes = cfg->servercert_bytes,
+            .privkey_pem_buf = NULL,
+            .privkey_pem_bytes = 0,
+            .privkey_password = NULL,
+            .privkey_password_len = 0,
+        };
+        esp_err_t esp_ret = set_pki_context(tls, &pki);
+        if (esp_ret != ESP_OK) {
+            ESP_LOGE(TAG, "Failed to set client pki context");
+            return esp_ret;
+        }
+#else
+        ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig.");
+        return ESP_FAIL;
+#endif
     } else if (cfg->servercert_buf != NULL && cfg->serverkey_buf != NULL) {
         esp_tls_pki_t pki = {
             .public_cert = &tls->servercert,
@@ -786,6 +826,39 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
 #else
         ESP_LOGE(TAG, "Please enable the DS peripheral support for the ESP-TLS in menuconfig. (only supported for the ESP32-S2 chip)");
         return ESP_FAIL;
+#endif
+    } else if (cfg->use_ecdsa_peripheral) {
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+        tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral;
+        tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk;
+        esp_tls_pki_t pki = {
+            .public_cert = &tls->clientcert,
+            .pk_key = &tls->clientkey,
+            .publiccert_pem_buf = cfg->clientcert_buf,
+            .publiccert_pem_bytes = cfg->clientcert_bytes,
+            .privkey_pem_buf = NULL,
+            .privkey_pem_bytes = 0,
+            .privkey_password = NULL,
+            .privkey_password_len = 0,
+        };
+        esp_err_t esp_ret = set_pki_context(tls, &pki);
+        if (esp_ret != ESP_OK) {
+            ESP_LOGE(TAG, "Failed to set client pki context");
+            return esp_ret;
+        }
+        static const int ecdsa_peripheral_supported_ciphersuites[] = {
+            MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
+            MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
+#endif
+            0
+        };
+
+        ESP_LOGD(TAG, "Set the ciphersuites list");
+        mbedtls_ssl_conf_ciphersuites(&tls->conf, ecdsa_peripheral_supported_ciphersuites);
+#else
+        ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig.");
+        return ESP_FAIL;
 #endif
     } else if (cfg->clientcert_pem_buf != NULL && cfg->clientkey_pem_buf != NULL) {
         esp_tls_pki_t pki = {

+ 4 - 0
components/esp-tls/private_include/esp_tls_private.h

@@ -58,6 +58,10 @@ struct esp_tls {
 
     mbedtls_pk_context clientkey;                                               /*!< Container for the private key of the client
                                                                                      certificate */
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+    bool use_ecdsa_peripheral;                                                  /*!< Use the ECDSA peripheral for the private key operations. */
+    uint8_t ecdsa_efuse_blk;                                                    /*!< The efuse block number where the ECDSA key is stored. */
+#endif
 #ifdef CONFIG_ESP_TLS_SERVER
     mbedtls_x509_crt servercert;                                                /*!< Container for the X.509 server certificate */
 

+ 6 - 2
components/esp_http_client/esp_http_client.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -729,7 +729,11 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
             esp_transport_ssl_set_client_key_data_der(ssl, config->client_key_pem, config->client_key_len);
         }
     }
-
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+    if (config->use_ecdsa_peripheral) {
+        esp_transport_ssl_set_client_key_ecdsa_peripheral(ssl, config->ecdsa_key_efuse_blk);
+    }
+#endif
     if (config->client_key_password && config->client_key_password_len > 0) {
         esp_transport_ssl_set_client_key_password(ssl, config->client_key_password, config->client_key_password_len);
     }

+ 4 - 0
components/esp_http_client/include/esp_http_client.h

@@ -133,6 +133,10 @@ typedef struct {
     size_t                      client_key_len;      /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */
     const char                  *client_key_password;      /*!< Client key decryption password string */
     size_t                      client_key_password_len;   /*!< String length of the password pointed to by client_key_password */
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+    bool                        use_ecdsa_peripheral;       /*!< Use ECDSA peripheral to use private key. */
+    uint8_t                     ecdsa_key_efuse_blk;        /*!< The efuse block where ECDSA key is stored. */
+#endif
     const char                  *user_agent;         /*!< The User Agent string to send with HTTP requests */
     esp_http_client_method_t    method;                   /*!< HTTP Method */
     int                         timeout_ms;               /*!< Network timeout in milliseconds */

+ 1 - 1
components/esp_http_server/include/esp_http_server.h

@@ -313,7 +313,7 @@ typedef struct httpd_config {
  *  - ESP_ERR_HTTPD_ALLOC_MEM  : Failed to allocate memory for instance
  *  - ESP_ERR_HTTPD_TASK       : Failed to launch server task
  */
-esp_err_t  httpd_start(httpd_handle_t *handle, const httpd_config_t *config);
+esp_err_t httpd_start(httpd_handle_t *handle, const httpd_config_t *config);
 
 /**
  * @brief Stops the web server

+ 9 - 1
components/esp_https_server/include/esp_https_server.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -79,6 +79,12 @@ struct httpd_ssl_config {
     /** Private key byte length */
     size_t prvtkey_len;
 
+    /** Use ECDSA peripheral to use private key */
+    bool use_ecdsa_peripheral;
+
+    /** The efuse block where ECDSA key is stored */
+    uint8_t ecdsa_key_efuse_blk;
+
     /** Transport Mode (default secure) */
     httpd_ssl_transport_mode_t transport_mode;
 
@@ -150,6 +156,8 @@ typedef struct httpd_ssl_config httpd_ssl_config_t;
     .cacert_len = 0,                              \
     .prvtkey_pem = NULL,                          \
     .prvtkey_len = 0,                             \
+    .use_ecdsa_peripheral = false,                \
+    .ecdsa_key_efuse_blk = 0,                     \
     .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \
     .port_secure = 443,                           \
     .port_insecure = 80,                          \

+ 10 - 2
components/esp_https_server/src/https_server.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -262,7 +262,15 @@ static httpd_ssl_ctx_t *create_secure_context(const struct httpd_ssl_config *con
     /* Pass on secure element boolean */
     cfg->use_secure_element = config->use_secure_element;
     if (!cfg->use_secure_element) {
-        if (config->prvtkey_pem != NULL && config->prvtkey_len > 0) {
+        if (config->use_ecdsa_peripheral) {
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+            ssl_ctx->tls_cfg->use_ecdsa_peripheral = config->use_ecdsa_peripheral;
+            ssl_ctx->tls_cfg->ecdsa_key_efuse_blk = config->ecdsa_key_efuse_blk;
+#else
+            ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig.");
+            goto exit;
+#endif
+        } else if (config->prvtkey_pem != NULL && config->prvtkey_len > 0) {
             cfg->serverkey_buf = malloc(config->prvtkey_len);
 
             if (cfg->serverkey_buf) {

+ 3 - 0
components/mbedtls/CMakeLists.txt

@@ -245,6 +245,9 @@ if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
 
     if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN)
         target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign")
+        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_restartable")
+        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature")
+        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature_restartable")
     endif()
 
     if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)

+ 133 - 0
components/mbedtls/port/ecdsa/ecdsa_alt.c

@@ -6,7 +6,9 @@
 #include <string.h>
 #include "hal/ecdsa_hal.h"
 #include "esp_efuse.h"
+#include "mbedtls/error.h"
 #include "mbedtls/ecdsa.h"
+#include "mbedtls/asn1write.h"
 #include "mbedtls/platform_util.h"
 #include "esp_private/periph_ctrl.h"
 #include "ecdsa/ecdsa_alt.h"
@@ -279,6 +281,137 @@ int __wrap_mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mp
         return __real_mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, f_rng, p_rng);
     }
 }
+
+extern int __real_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                                          const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                                          int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind,
+                                          mbedtls_ecdsa_restart_ctx *rs_ctx);
+
+int __wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                                          const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                                          int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind,
+                                          mbedtls_ecdsa_restart_ctx *rs_ctx);
+
+int __wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                                          const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                                          int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind,
+                                          mbedtls_ecdsa_restart_ctx *rs_ctx)
+{
+    /*
+     * Check `d` whether it contains the hardware key
+     */
+    if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
+        // Use hardware ECDSA peripheral
+        return esp_ecdsa_sign(grp, r, s, d, buf, blen);
+    } else {
+        return __real_mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, f_rng, p_rng, f_rng_blind, p_rng_blind, rs_ctx);
+    }
+}
+
+int __real_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
+                                              mbedtls_md_type_t md_alg,
+                                              const unsigned char *hash, size_t hlen,
+                                              unsigned char *sig, size_t sig_size, size_t *slen,
+                                              int (*f_rng)(void *, unsigned char *, size_t),
+                                              void *p_rng,
+                                              mbedtls_ecdsa_restart_ctx *rs_ctx);
+
+int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
+                                              mbedtls_md_type_t md_alg,
+                                              const unsigned char *hash, size_t hlen,
+                                              unsigned char *sig, size_t sig_size, size_t *slen,
+                                              int (*f_rng)(void *, unsigned char *, size_t),
+                                              void *p_rng,
+                                              mbedtls_ecdsa_restart_ctx *rs_ctx);
+
+/*
+ * Convert a signature (given by context) to ASN.1
+ */
+static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s,
+                                   unsigned char *sig, size_t sig_size,
+                                   size_t *slen)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 };
+    // Setting the pointer p to the end of the buffer as the functions used afterwards write in backwards manner in the given buffer.
+    unsigned char *p = buf + sizeof(buf);
+    size_t len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s));
+    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r));
+
+    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
+    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf,
+                                                     MBEDTLS_ASN1_CONSTRUCTED |
+                                                     MBEDTLS_ASN1_SEQUENCE));
+
+    if (len > sig_size) {
+        return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+    }
+
+    memcpy(sig, p, len);
+    *slen = len;
+
+    return 0;
+}
+
+int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
+                                              mbedtls_md_type_t md_alg,
+                                              const unsigned char *hash, size_t hlen,
+                                              unsigned char *sig, size_t sig_size, size_t *slen,
+                                              int (*f_rng)(void *, unsigned char *, size_t),
+                                              void *p_rng,
+                                              mbedtls_ecdsa_restart_ctx *rs_ctx)
+{
+    if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) != ECDSA_KEY_MAGIC) {
+        return __real_mbedtls_ecdsa_write_signature_restartable(ctx, md_alg, hash, hlen, sig, sig_size, slen, f_rng, p_rng, rs_ctx);
+    }
+
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_mpi r, s;
+
+    mbedtls_mpi_init(&r);
+    mbedtls_mpi_init(&s);
+
+    /*
+     * Check `d` whether it contains the hardware key
+     */
+    if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
+        // Use hardware ECDSA peripheral
+
+        MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen));
+    }
+
+    MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen));
+
+cleanup:
+    mbedtls_mpi_free(&r);
+    mbedtls_mpi_free(&s);
+
+    return ret;
+}
+
+int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
+                                  mbedtls_md_type_t md_alg,
+                                  const unsigned char *hash, size_t hlen,
+                                  unsigned char *sig, size_t sig_size, size_t *slen,
+                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  void *p_rng);
+
+int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
+                                  mbedtls_md_type_t md_alg,
+                                  const unsigned char *hash, size_t hlen,
+                                  unsigned char *sig, size_t sig_size, size_t *slen,
+                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  void *p_rng)
+{
+    return __wrap_mbedtls_ecdsa_write_signature_restartable(
+        ctx, md_alg, hash, hlen, sig, sig_size, slen,
+        f_rng, p_rng, NULL);
+}
 #endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */
 
 #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY

+ 11 - 1
components/tcp_transport/include/esp_transport_ssl.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -72,6 +72,16 @@ void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t);
  */
 void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char *data, int len);
 
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+/**
+ * @brief      Set SSL client key data for mutual authentication when using ECDSA peripheral.
+ *
+ * @param      t            ssl transport
+ * @param[in]  efuse_blk    Efuse block where ECDSA private key is stored
+ */
+void esp_transport_ssl_set_client_key_ecdsa_peripheral(esp_transport_handle_t t, uint8_t ecdsa_efuse_blk);
+#endif
+
 /**
  * @brief      Set SSL client certificate data for mutual authentication (as DER format).
  *             Note that, this function stores the pointer to data, rather than making a copy.

+ 10 - 1
components/tcp_transport/transport_ssl.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -370,6 +370,15 @@ void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char
     ssl->cfg.clientcert_pem_bytes = len + 1;
 }
 
+#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
+void esp_transport_ssl_set_client_key_ecdsa_peripheral(esp_transport_handle_t t, uint8_t ecdsa_efuse_blk)
+{
+    GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
+    ssl->cfg.use_ecdsa_peripheral = true;
+    ssl->cfg.ecdsa_key_efuse_blk = ecdsa_efuse_blk;
+}
+#endif
+
 void esp_transport_ssl_set_client_cert_data_der(esp_transport_handle_t t, const char *data, int len)
 {
     GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);