<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[wolfSSL - Embedded SSL Library — Issue with a bare metal LWIP/WolfSSL setup on a STM32 device]]></title>
		<link>https://www.wolfssl.com/forums/topic2445-issue-with-a-bare-metal-lwipwolfssl-setup-on-a-stm32-device.html</link>
		<atom:link href="https://www.wolfssl.com/forums/feed-rss-topic2445.xml" rel="self" type="application/rss+xml" />
		<description><![CDATA[The most recent posts in Issue with a bare metal LWIP/WolfSSL setup on a STM32 device.]]></description>
		<lastBuildDate>Thu, 18 Dec 2025 04:32:15 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Issue with a bare metal LWIP/WolfSSL setup on a STM32 device]]></title>
			<link>https://www.wolfssl.com/forums/post8655.html#p8655</link>
			<description><![CDATA[<p>Thank your for your reply, but do I not have to use the IO callbacks, because I have no os?</p>]]></description>
			<author><![CDATA[null@example.com (mika)]]></author>
			<pubDate>Thu, 18 Dec 2025 04:32:15 +0000</pubDate>
			<guid>https://www.wolfssl.com/forums/post8655.html#p8655</guid>
		</item>
		<item>
			<title><![CDATA[Re: Issue with a bare metal LWIP/WolfSSL setup on a STM32 device]]></title>
			<link>https://www.wolfssl.com/forums/post8654.html#p8654</link>
			<description><![CDATA[<p>Hello Mika,</p><p>Welcome to the wolfSSL Forums.</p><p>wolfSSL has native support for LwIP, so you do not need to set up the IO callbacks. I think that is where your issue is coming from. We actually have an excellent LwIP example that you&#039;ll find useful:<br /><a href="https://github.com/wolfSSL/wolfssl-examples/tree/master/lwip">https://github.com/wolfSSL/wolfssl-exam … aster/lwip</a></p><p>For LwIP native tcp sockets, define `WOLFSSL_LWIP_NATIVE`<br />For LwIP sockets API, just use `WOLFSSL_LWIP`</p><p>Could you tell us a bit about your project using wolfSSL and where you are from for our support records?</p><p>Kind regards,<br />Eric - wolfSSL Support</p>]]></description>
			<author><![CDATA[null@example.com (embhorn)]]></author>
			<pubDate>Wed, 17 Dec 2025 14:12:56 +0000</pubDate>
			<guid>https://www.wolfssl.com/forums/post8654.html#p8654</guid>
		</item>
		<item>
			<title><![CDATA[Re: Issue with a bare metal LWIP/WolfSSL setup on a STM32 device]]></title>
			<link>https://www.wolfssl.com/forums/post8653.html#p8653</link>
			<description><![CDATA[<div class="codebox"><pre><code>#ifndef MIDDLEWARES_WOLFSSL_WOLFSSL_WOLFCRYPT_USER_SETTINGS_H_
#define MIDDLEWARES_WOLFSSL_WOLFSSL_WOLFCRYPT_USER_SETTINGS_H_

#define WOLFSSL_SHA256
#define WOLFSSL_SHA384
#define OPENSSL_EXTRA
#define CUSTOM_RAND_GENERATE_BLOCK
#define DEBUG_WOLFSSL
#define NO_OLD_TLS
#define HAVE_ECC
#define WOLFSSL_SHA512
#define WOLFSSL_NO_SOCK
#define WOLFSSL_USER_IO
#define NO_RSA
#define HAVE_AEAD
#define HAVE_HKDF
#define HAVE_TLS_EXTENSIONS
#define NO_DH
#define HAVE_ED25519
#define HAVE_CURVE25519
#define WOLFSSL_TLS13
#define WOLFSSL_NO_TLS12
#define NO_FILESYSTEM
#define NO_STDIO
#define NO_DIR
#define SINGLE_THREADED
#define NO_WRITEV
#define NO_READV
#define NO_IOVEC
#define WOLFSSL_NO_ASM
#define HAVE_ERRNO_H
#include &lt;errno.h&gt;


#ifdef WOLFSSL_NO_MALLOC
  #undef WOLFSSL_NO_MALLOC
#endif




#endif /* MIDDLEWARES_WOLFSSL_WOLFSSL_WOLFCRYPT_USER_SETTINGS_H_ */</code></pre></div><br /><p>and the user settings.</p>]]></description>
			<author><![CDATA[null@example.com (mika)]]></author>
			<pubDate>Wed, 17 Dec 2025 11:19:43 +0000</pubDate>
			<guid>https://www.wolfssl.com/forums/post8653.html#p8653</guid>
		</item>
		<item>
			<title><![CDATA[Re: Issue with a bare metal LWIP/WolfSSL setup on a STM32 device]]></title>
			<link>https://www.wolfssl.com/forums/post8652.html#p8652</link>
			<description><![CDATA[<div class="codebox"><pre><code>#include &quot;wolfssl/ssl.h&quot;
#include &quot;certs.h&quot;
#include &quot;lwip/tcp.h&quot;
#include &quot;tls_client.h&quot;
#include &lt;stdlib.h&gt;


static WOLFSSL_CTX *g_ctx = NULL;


#define TLS_RX_BUF_SIZE   4096

typedef enum {
    TLS_STATE_IDLE = 0,
    TLS_STATE_TCP_CONNECTING,
    TLS_STATE_TCP_CONNECTED,
    TLS_STATE_TLS_HANDSHAKE,
    TLS_STATE_TLS_ESTABLISHED,
    TLS_STATE_ERROR
} tls_state_t;

typedef struct {
    struct tcp_pcb* pcb;
    WOLFSSL*        ssl;
    tls_state_t     state;

    uint8_t         rxBuf[TLS_RX_BUF_SIZE];
    uint32_t        rxHead;
    uint32_t        rxTail;

    int             lastErr;      // debug
} tls_conn_t;

static tls_conn_t g_tls;


//
//static void* myMalloc(size_t n) { return malloc(n); }
//static void  myFree(void* p)    { free(p); }
//static void* myRealloc(void* p, size_t n) { return realloc(p, n); }


static uint32_t tls_rx_available(tls_conn_t* c) {
    if (c-&gt;rxHead &gt;= c-&gt;rxTail)
        return c-&gt;rxHead - c-&gt;rxTail;
    else
        return TLS_RX_BUF_SIZE - (c-&gt;rxTail - c-&gt;rxHead);
}

static uint32_t tls_rx_space(tls_conn_t* c) {
    return TLS_RX_BUF_SIZE - 1 - tls_rx_available(c);
}

static void tls_rx_push(tls_conn_t* c, const uint8_t* data, uint32_t len) {
    while (len--) {
        c-&gt;rxBuf[c-&gt;rxHead] = *data++;
        c-&gt;rxHead = (c-&gt;rxHead + 1) % TLS_RX_BUF_SIZE;
    }
}

static uint32_t tls_rx_pop(tls_conn_t* c, uint8_t* dst, uint32_t maxLen) {
    uint32_t avail = tls_rx_available(c);
    if (avail == 0) return 0;

    if (maxLen &gt; avail) maxLen = avail;
    for (uint32_t i = 0; i &lt; maxLen; i++) {
        dst[i] = c-&gt;rxBuf[c-&gt;rxTail];
        c-&gt;rxTail = (c-&gt;rxTail + 1) % TLS_RX_BUF_SIZE;
    }
    return maxLen;
}

static err_t tls_tcp_connected_cb(void *arg, struct tcp_pcb *tpcb, err_t err)
{
    tls_conn_t* c = (tls_conn_t*)arg;
    printf(&quot;connected_cb err=%d\r\n&quot;, (int)err);

    if (err != ERR_OK) {
        c-&gt;state = TLS_STATE_ERROR;
        return err;
    }

    c-&gt;state = TLS_STATE_TCP_CONNECTED;

    return ERR_OK;
}

static err_t tls_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
                             struct pbuf *p, err_t err)
{
    tls_conn_t* c = (tls_conn_t*)arg;

    if (p == NULL) {
        c-&gt;state = TLS_STATE_ERROR;
        return ERR_OK;
    }

    if (tls_rx_space(c) &lt; p-&gt;tot_len) {
        printf(&quot;RX overflow -&gt; abort TLS\n&quot;);
        pbuf_free(p);
//        tcp_abort(tpcb);
        c-&gt;state = TLS_STATE_ERROR;
        c-&gt;lastErr = ERR_MEM;
        return ERR_ABRT;
    }

    struct pbuf* q = p;
    while (q) {
        tls_rx_push(c, (uint8_t*)q-&gt;payload, q-&gt;len);
        q = q-&gt;next;
    }

    tcp_recved(tpcb, p-&gt;tot_len);
    pbuf_free(p);
    return ERR_OK;
}





static void tls_tcp_err_cb(void *arg, err_t err)
{
    tls_conn_t* c = (tls_conn_t*)arg;
    printf(&quot;tcp_err_cb err=%d\r\n&quot;, (int)err);
    c-&gt;state   = TLS_STATE_ERROR;
    c-&gt;lastErr = err;
}


/* wird via WOLFSSL_USER_IO verwendet */
static int my_IORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx)
{
    tls_conn_t* c = (tls_conn_t*)ctx;
    uint32_t n = tls_rx_pop(c, (uint8_t*)buff, (uint32_t)sz);

    if (n == 0) {
        // keine Daten gerade → nicht blocken
        return WOLFSSL_CBIO_ERR_WANT_READ;
    }

    return (int)n;
}

static int my_IOSend(WOLFSSL* ssl, char* buff, int sz, void* ctx)
{
    static int cnt = 0;
    cnt++;
    printf(&quot;IOSend #%d sz=%d\r\n&quot;, cnt, sz);


    tls_conn_t* c = (tls_conn_t*)ctx;
    if (c-&gt;pcb == NULL) return WOLFSSL_CBIO_ERR_CONN_CLOSE;

    err_t err = tcp_write(c-&gt;pcb, buff, sz, TCP_WRITE_FLAG_COPY);
    if (err == ERR_MEM) {
        return WOLFSSL_CBIO_ERR_WANT_WRITE;
    } else if (err != ERR_OK) {
        return WOLFSSL_CBIO_ERR_GENERAL;
    }

    tcp_output(c-&gt;pcb);
    return sz;
}




static void wolfssl_dump_errors(void)
{
    unsigned long e;
    char buf[WOLFSSL_MAX_ERROR_SZ];

    while ((e = wolfSSL_ERR_get_error()) != 0) {
        wolfSSL_ERR_error_string_n(e, buf, sizeof(buf));
        printf(&quot;wolfSSL: %s\n&quot;, buf);
    }
}

void test_rng(void) {
    WC_RNG rng;
    int ret = wc_InitRng(&amp;rng);
    if (ret != 0) {
        char msg[WOLFSSL_MAX_ERROR_SZ];
        wc_ErrorString(ret, msg);
        printf(&quot;wc_InitRng failed: %d (%s)\r\n&quot;, ret, msg);
        return;
    }
    wc_FreeRng(&amp;rng);
    printf(&quot;wc_InitRng OK\r\n&quot;);
}




void TLS_GlobalInit(void)
{
    test_rng();
    wolfSSL_Init();
    int i = 0;
    int ret;

//    wolfSSL_SetAllocators(myMalloc, myFree, myRealloc);
    g_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
    wolfSSL_SetIORecv(g_ctx, my_IORecv);
    wolfSSL_SetIOSend(g_ctx, my_IOSend);
    if (g_ctx == NULL)
    {
        /* fatal – keine TLS-Konfiguration */
        while (1)
        {
            if (i == 0)
            {
        printf(&quot;leider falsch\n&quot;);
                i += 1;
            }

        }
    }

    ret = wolfSSL_CTX_load_verify_buffer(g_ctx, ca_ed25519_der,
            ca_ed25519_der_len, WOLFSSL_FILETYPE_ASN1);

//    wolfSSL_CTX_set_verify(g_ctx, WOLFSSL_VERIFY_NONE, 0);


    if (ret != WOLFSSL_SUCCESS) {
        char errBuf[80];
        /* Bei ctx-Funktionen einfach direkt den Code in einen String umwandeln: */
        wolfSSL_ERR_error_string_n((unsigned long)ret, errBuf, sizeof(errBuf));
        printf(&quot;load_verify_buffer failed: %d (%s)\n&quot;, ret, errBuf);
    }

    printf(&quot;hallihallo\n&quot;);
}




void TLS_ClientStart(const ip_addr_t* ip, u16_t port)
{
    memset(&amp;g_tls, 0, sizeof(g_tls));

    g_tls.pcb = tcp_new();
    if (g_tls.pcb == NULL) {
        g_tls.state = TLS_STATE_ERROR;
        return;
    }

    g_tls.state = TLS_STATE_TCP_CONNECTING;

    tcp_arg(g_tls.pcb, &amp;g_tls);      // our connection struct as arg
    tcp_err(g_tls.pcb, tls_tcp_err_cb);
    tcp_recv(g_tls.pcb, tls_tcp_recv_cb);

    err_t e = tcp_connect(g_tls.pcb, ip, port, tls_tcp_connected_cb);
    printf(&quot;tcp_connect()=%d\r\n&quot;, (int)e);
    if (e != ERR_OK) { g_tls.state = TLS_STATE_ERROR; g_tls.lastErr = e; }
}





void TLS_ClientProcess(void)
{
    int ret;

    switch (g_tls.state) {

    case TLS_STATE_TCP_CONNECTED:

        printf(&quot;g_ctx=%p\r\n&quot;, (void*)g_ctx);
        g_tls.ssl = wolfSSL_new(g_ctx);
        if (g_tls.ssl == NULL) {
            g_tls.state = TLS_STATE_ERROR;
            break;
        }

//        wolfSSL_SSLSetIORecv(g_tls.ssl, my_IORecv); //extra
//        wolfSSL_SSLSetIOSend(g_tls.ssl, my_IOSend); //etxra

        wolfSSL_SetIOReadCtx(g_tls.ssl,  &amp;g_tls);
        wolfSSL_SetIOWriteCtx(g_tls.ssl, &amp;g_tls);

        wolfSSL_set_using_nonblock(g_tls.ssl, 1);

        g_tls.state = TLS_STATE_TLS_HANDSHAKE;
        break;

    case TLS_STATE_TLS_HANDSHAKE:

//        const char dummy[] = &quot;X&quot;;
//        ret = wolfSSL_write(g_tls.ssl, dummy, sizeof(dummy));
//        int err = wolfSSL_get_error(g_tls.ssl, ret);
//        printf(&quot;wolfSSL_write ret=%d err=%d\r\n&quot;, ret, err);

        ret = wolfSSL_connect(g_tls.ssl);
        if (ret == WOLFSSL_SUCCESS) {
            printf(&quot;TLS handshake OK\r\n&quot;);
            g_tls.state = TLS_STATE_TLS_ESTABLISHED;
        } else
        {
            int err = wolfSSL_get_error(g_tls.ssl, ret);
            if (err == WOLFSSL_ERROR_WANT_READ ||
                err == WOLFSSL_ERROR_WANT_WRITE) {
            } else {
                printf(&quot;TLS handshake failed: %d\r\n&quot;, err);
                g_tls.state = TLS_STATE_ERROR;



                    wolfssl_dump_errors();   // &lt;-- zeigt den echten Grund
            }
        }
        break;

    case TLS_STATE_TLS_ESTABLISHED:
        /* hier könntest du z.B. einmalig etwas senden: */
        // const char* msg = &quot;HELLO FROM STM32\r\n&quot;;
        // wolfSSL_write(g_tls.ssl, msg, strlen(msg));
        // g_tls.state = TLS_STATE_IDLE; // oder weitere Logik
        break;

    case TLS_STATE_ERROR:
        printf(&quot;tcp_err_cb: err=%d\r\n&quot;, g_tls.lastErr);
//        printf(&quot;TCP connect failed, err=%d\r\n&quot;, g_tls.lastErr);
        // ggf. pcb/ssl freigeben etc.
        g_tls.state = TLS_STATE_TLS_HANDSHAKE;

        break;

    default:
//        printf(&quot;TCP connect failed, err=%d\r\n&quot;, g_tls.state);
        break;
    }
}</code></pre></div><p>here is the most important code</p>]]></description>
			<author><![CDATA[null@example.com (mika)]]></author>
			<pubDate>Wed, 17 Dec 2025 11:17:19 +0000</pubDate>
			<guid>https://www.wolfssl.com/forums/post8652.html#p8652</guid>
		</item>
		<item>
			<title><![CDATA[Issue with a bare metal LWIP/WolfSSL setup on a STM32 device]]></title>
			<link>https://www.wolfssl.com/forums/post8651.html#p8651</link>
			<description><![CDATA[<p>Hello There,</p><p>I have issues with achieving a Handshake, while the stm32n6570-dk acting as a Client and a Debian System as the corresponding Server.</p><p>After the TLS Handshake and initializing WolfSSL plus providing him the Root Certificate, it gives me errors at wolfssl_connect:</p><p>It returns -1.</p><p>wolfSSL_ERR_get_error says something like &quot;unknown error&quot;.</p><p>wolfSSL_get_error just returns 32.</p><p>I am actually quite stuck at this point.</p>]]></description>
			<author><![CDATA[null@example.com (mika)]]></author>
			<pubDate>Wed, 17 Dec 2025 11:12:27 +0000</pubDate>
			<guid>https://www.wolfssl.com/forums/post8651.html#p8651</guid>
		</item>
	</channel>
</rss>
