stm32F777NIHx + libwebsockets + lwip + mbedtls handshake failed

I am using libwebsockets ,lwip, and mbedtls on stm32F777NIHx.But mbedtls_handshake failed.The phenomenon is very strange.
In altcp_mbedtls_bio_recv function( in this file:altcp_tls_mbedtls.c),the “struct pbuf *p” is 0xc032, 0xc032 is an illegal address, its address value is too low. I think 0xc032 means MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384.
In mbedtls/ssl_cphersuites.h, I can see this definition.
#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */.


The privkey and cert is as following:
const u8_t privkey = "-----BEGIN RSA PRIVATE KEY-----\r\n\

MIIEogIBAAKCAQEAqJPUXePfMvL7JDPw/Nrbx4jXnnaZd39g2FHOJIqXqZi6rJq7\r\n\

WLNa9Ice1VGvGHMgG7l3xNulMtNE2s2wdR5YrK13FWwKeVCj3oSd5h6RNon2SJuf\r\n\

vJb/4LzCBxcYn1XNHM3z3KZnXFdRFYPH6Je+GlEhhN3+GX9wym6rWymQnSJwE2q7\r\n\

rkCKFAaP6OJnHJ6D/ad2/E7bRZqOkA1p/DlfxqHVmwpFDn5Js6sSJlgG1JOoRUzl\r\n\

UDltbC8sqX9S5rZFCEWCPt3PdEXm3NmXWmbg0+415wXStangIr+O/Bq8h6dUvL5J\r\n\

jRnDBQ0yWYbodJhMDkCLB5E7jmGI/ebkjmWEyQIDAQABAoIBABmryV8y4D5l+hCd\r\n\

SEl5GpbcI9mhveUQpLLMYlP2NvpAo8y9E2KCjYtHOE7LzZovjegq6i40NIf03Dtl\r\n\

r0VmhaJmGAhPF5k5ynqMP29XoE1p3PNZn42cgQK8O9/QiJNbAY0tX8FuJbdOJK7e\r\n\

DodA9FYVnMEa/SLs4UQybi3Hupny8VEL+yZGFKxgNfFAWe//+QWU0FtfQ1rTfaqU\r\n\

sBlc8Kzkjex7dfedLqlJPX8Hxn5kScPW+m+0ozBCdZ3TZDhDWdVSzzfx7LYvxkiT\r\n\

YlFXJ2K4FykKGlHrP7DEqF7ddliC2qcSffFaecWxt6NAdkfOKQJqjpwl/M3o7XGO\r\n\

rdcGuAECgYEAz+J+JcV5ts60EPZdcJ7yI+Sep8SlosGH1yo32ufs2lYDhLj8EC5M\r\n\

1KOGnpl8bsm3Rh8D2lnW8tHGIznoO9nInsDcG7FM28k9iYZAxAPxlHx3l7+twixS\r\n\

edc0jlTgpmjl4ruzZA3Yqqd+Br/Ga5BwHaftruCvMc2WXijW5TM6RIkCgYEAz5hR\r\n\

Ijcirxc61lRYjjwphwxDp7Wrgr+dHkH28IBrC5m7R+4GWIDlD4Xvic8Baohg17ta\r\n\

BFOtNDFnJE+ndFPW64Up38L+hHDyFlOUIlM9XBhFoHwQQeOX/+UIDJFTMZFVuzb7\r\n\

yZep4KV/pIwaVKnDZuuedCS2glEdXuRY9xqdrkECgYA3gQehWhpnPsVBCiZknWuV\r\n\

PcNGk/CNhhKY1kLXhbjtiq2h0Cosv8/vrkGRMvXQNrdiV4GV2QrVBkFawmlJIZq5\r\n\

GFEsa6hTvmVZxKiiLVNhC+J6d8kS4PacZWM45Vyd0cAfS3JYMoI4/kNd1fJKYeQt\r\n\

ZtrFKGRebb/KIClQRN830QKBgGRkB5BhU2+S70wo2+5k37xETQ90hm2jVksEoXOq\r\n\

1pl0jaH6VK1GH//CyJU/OzMWoqaRHrYK9S7RWUyxDIzv4nZhHl/sf4Lyz8/GOVPk\r\n\

Jz87KaizdnU2qBIC40KYoL/OxcPUkizqICfYQQMFEdKxiiJifW0zN+OLcIWsLe3J\r\n\

vElBAoGAGmFqRlswYnkGJigDI5g2LA7l92AXMSl2AKI9KI2z4BhQW4bFaVkBVNL5\r\n\

eO/eB0gia2XEfetPq5NJkl8tYSaxD43ktb5NChrCqHfTPjmo3oqvtAo28z7ZkPEX\r\n\

C2lY6WsD19SiiRJbUpeUzCLf3a1Tw/BSD4AZhOgzUP7dEl9D8n0=\r\n\

-----END RSA PRIVATE KEY-----\r\n\0\0";

const u8_t cert = "-----BEGIN CERTIFICATE-----\r\n\

MIIElTCCAn2gAwIBAgIJAI5nRyUnY3sYMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD\r\n\

VQQGEwJRRDEQMA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEPMA0G\r\n\

A1UECgwGbXlob21lMQ8wDQYDVQQLDAZteWhvbWUxGDAWBgNVBAMMD3F1ZG9uZ3No\r\n\

ZW5nLmNvbTEjMCEGCSqGSIb3DQEJARYUc2VsZkBxdWRvbmdzaGVuZy5jb20wHhcN\r\n\

MjAwNzA1MjMwNTMzWhcNMjExMTE3MjMwNTMzWjBhMQswCQYDVQQGEwJDTjEQMA4G\r\n\

A1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEUMBIGA1UECgwLc2llbWVu\r\n\

cy5jb20xGDAWBgNVBAMMD2xhYi5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB\r\n\

BQADggEPADCCAQoCggEBAKiT1F3j3zLy+yQz8Pza28eI1552mXd/YNhRziSKl6mY\r\n\

uqyau1izWvSHHtVRrxhzIBu5d8TbpTLTRNrNsHUeWKytdxVsCnlQo96EneYekTaJ\r\n\

9kibn7yW/+C8wgcXGJ9VzRzN89ymZ1xXURWDx+iXvhpRIYTd/hl/cMpuq1spkJ0i\r\n\

cBNqu65AihQGj+jiZxyeg/2ndvxO20WajpANafw5X8ah1ZsKRQ5+SbOrEiZYBtST\r\n\

qEVM5VA5bWwvLKl/Uua2RQhFgj7dz3RF5tzZl1pm4NPuNecF0rWp4CK/jvwavIen\r\n\

VLy+SY0ZwwUNMlmG6HSYTA5AiweRO45hiP3m5I5lhMkCAwEAAaMeMBwwGgYDVR0R\r\n\

BBMwEYIPbGFiLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQCszdJ0EXbv\r\n\

FGmG7/DxppO22bEJsQ7MK6XNmHTAN31x3KDyg+0x5RcVC5chvPv3+6rSeykIeA1E\r\n\

L3vSTmTrOqHsjZaQb+zY9CgC+IBLJKvM75Eifk0mZOZdMH72GezGAaH+WSSoRuME\r\n\

8S+3gyOauOJ9H6yDVS2j5WxfUWo1Nt6DlZgkDYxGO1cXtsWW6t3/ntC0jN6OdcKB\r\n\

JsZaSuvs/NgI+OgKUP7HefM/mJBrw0JNQNpCfpBW6hJbfzE+jGl4KFFhFMEQqUG2\r\n\

GkaoLe9B+66HyRnkEqNWinDSTXYvOjV4hMAEfljsOf7sjCzrKHpLN0a9snmpPCur\r\n\

a70aqgr08jtzzTdU3zr49oMMvPO9MqQvRmd5DYIhibZMGRByyUEZaorGCFlYbVP+\r\n\

IrcOp63yZS/tjUJgiFMDWD1UBKkyV4QR6d7JManA3KNwdML/G9eEWNzlZ3p8ebkT\r\n\

BZlHB0YW57TeRBDsB6vHuillYsLgv2hgj5JIiHDSYMjqfwmPZ9i1+pOnf/kbq8/P\r\n\

iUMQdUn/ViSv+wUebu07MaujmAC9h0nlLnhFGgPSSCqzKYPIC1v7CfJ2Jwop7sY+\r\n\

ZDvWah/enUB8L4TNlkzFR/Aq6lAAA875vGKdjrhPa7bjLy0M08b1glzgYBT5AGaj\r\n\

nVGxmpbGngECdOA2o/Cf1QeLTEnXuCTH6w==\r\n\

-----END CERTIFICATE-----\r\n\0\0";

The libwebsocktes code is as following:
int lwsDemo(void)

{

// server url will be http://localhost:9000

int                              port = 60002;

struct lws_context *             context;

struct lws_context_creation_info context_info = { .port                     = port,

                                                  .iface                    = NULL,

                                                  .protocols                = protocols_ws,

                                                  .extensions               = NULL,

                                                  .ssl_cert_filepath        = NULL,

                                                  .ssl_private_key_filepath = NULL,

                                                  .ssl_ca_filepath          = NULL,

                                                  .server_ssl_cert_mem      = cert,

                                                  .server_ssl_cert_mem_len      =  sizeof(cert),

                                                  .server_ssl_private_key_mem       = privkey,

                                                  .server_ssl_private_key_mem_len   = sizeof(privkey),

                                                  .gid                      = -1,

                                                  .uid                      = -1,

                                                  .options                  = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT,

                                                  .ka_time     = 0,

                                                  .ka_probes   = 0,

                                                  .ka_interval = 0 };

// create lws context representing this server

context = lws_create_context(&context_info);

TraceInit(websocket_send);

if (context == NULL)

{

    LWIP_info(stderr, "lws init failed\n");

    return -1;

}

LWIP_info("starting server...\n");

// infinite loop, to end this server send SIGTERM. (CTRL+C)

while (1)

{

    lws_service(context, 50);

    // lws_service will process all waiting events with their

    // callback functions and then wait 50 ms.

    // (this is a single threaded webserver and this will keep our server

    // from generating load while there are not requests to process)

}

lws_context_destroy(context);

return 0;

}

The ssl_pm_new function(which is in libwebsockets,ssl_pm.c) is as following:
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 = (unsigned int)ssl->ctx->read_buffer_len;

// printf("ssl->ctx->read_buffer_len = %d ++++++++++++++++++++\n", ssl->ctx->read_buffer_len);

//mbedtls_net_init(NULL);

//mbedtls_net_init(NULL);

//ssl_pm->fd.fd = -1;

//ssl_pm->cl_fd.fd = -1;

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) {

    lwsl_notice("%s: mbedtls_ctr_drbg_seed() return -0x%x", __func__, -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) {

    lwsl_err("%s: mbedtls_ssl_config_defaults() return -0x%x", __func__, -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);

//#ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG

// mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL);

// mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL);

//#else

mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL);

//#endif

ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf);

if (ret) {

    lwsl_err("%s: mbedtls_ssl_setup() return -0x%x", __func__, -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);

mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, altcp_mbedtls_bio_send, altcp_mbedtls_bio_recv, NULL);

//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;

}

The altcp_mbedtls_bio_recv function(which is in lwip,altcp_tls_mbedtls.c) is as following:
int altcp_mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len)

{

struct altcp_pcb *conn = (struct altcp_pcb *)ctx;

altcp_mbedtls_state_t *state;

struct pbuf *p;

u16_t ret;

u16_t copy_len;

err_t err;

LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */

if ((conn == NULL) || (conn->state == NULL)) {

return MBEDTLS_ERR_NET_INVALID_CONTEXT;

}

state = (altcp_mbedtls_state_t *)conn->state;

p = state->rx;

/* @todo: return MBEDTLS_ERR_NET_CONN_RESET/MBEDTLS_ERR_NET_RECV_FAILED? */

if ((p == NULL) || ((p->len == 0) && (p->next == NULL))) {

if (p) {

  pbuf_free(p);

}

state->rx = NULL;

if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==

    ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {

  /* close queued but not passed up yet */

  return 0;

}

return MBEDTLS_ERR_SSL_WANT_READ;

}

/* limit number of bytes again to copy from first pbuf in a chain only */

copy_len = (u16_t)LWIP_MIN(len, p->len);

/* copy the data */

ret = pbuf_copy_partial(p, buf, copy_len, 0);

LWIP_ASSERT(“ret == copy_len”, ret == copy_len);

/* hide the copied bytes from the pbuf */

err = pbuf_remove_header(p, ret);

LWIP_ASSERT(“error”, err == ERR_OK);

if (p->len == 0) {

/* the first pbuf has been fully read, free it */

state->rx = p->next;

p->next = NULL;

pbuf_free(p);

}

state->bio_bytes_read += (int)ret;

return ret;

}