wolfMQTT icon indicating copy to clipboard operation
wolfMQTT copied to clipboard

Cannot configure PQC for wolfMQTT example

Open sandevins opened this issue 7 months ago • 2 comments

I am trying to get my wolfmqtt client on ESP-32 to use PQC. I am using a modified version of examples/mqttexample.c.

The process I followed was to define the following in the user_settings.h.

#define HAVE_PQC
#define WOLFSSL_EXPERIMENTAL_SETTINGS
#define WOLFSSL_KYBER_ORIGINAL

Then I build again after a clean with:

idf.py clean
idf.py build

But I receive the following error.

managed_components/wolfssl__wolfssl/wolfssl/wolfcrypt/settings.h:4109:2: error: #error Please do not define HAVE_PQC yourself.
 4109 | #error Please do not define HAVE_PQC yourself.

Is there any example on how to configure PQC for ESP-32?

sandevins avatar May 19 '25 14:05 sandevins

Hi @sandevins ,

As the error states, you shouldn't define HAVE_PQC yourself. Instead you should either define WOLFSSL_HAVE_MLKEM, or if you are using liboqs you should instead define HAVE_LIBOQS.

kareem-wolfssl avatar May 19 '25 18:05 kareem-wolfssl

Hi @kareem-wolfssl ,

Thanks for your quick response. Now I have defined these variables in user_settings.h.

#define WOLFSSL_EXPERIMENTAL_SETTINGS
#define HAVE_LIBOQS
#define WOLFSSL_HAVE_KYBER
#define WOLFSSL_KYBER_ORIGINAL

I also defined the Algorithm the following way.

#ifdef HAVE_PQC
    static const char* mTlsPQAlg = "P256_KYBER_LEVEL1";
#endif

Now I have another error at this lines.

#ifdef HAVE_PQC
        if ((rc == WOLFSSL_SUCCESS) && (mTlsPQAlg != NULL)) {
            int group = 0;
            if (XSTRCMP(mTlsPQAlg, "KYBER_LEVEL1") == 0) {
                group = WOLFSSL_KYBER_LEVEL1;
            } else if (XSTRCMP(mTlsPQAlg, "P256_KYBER_LEVEL1") == 0) {
                group = WOLFSSL_P256_KYBER_LEVEL1;
            } else {
                PRINTF("Invalid post-quantum KEM specified");
            }

            if (group != 0) {
                client->tls.ssl = wolfSSL_new(client->tls.ctx);
                if (client->tls.ssl == NULL) {
                    rc = WOLFSSL_FAILURE;
                }

                if (rc == WOLFSSL_SUCCESS) {
                    rc = wolfSSL_UseKeyShare(client->tls.ssl, group);
                    if (rc != WOLFSSL_SUCCESS) {
                        const char* tls_version = wolfSSL_get_version(client->tls.ssl);
                        PRINTF("TLS version: %s", tls_version);
                        char err_buf[80];
                        wolfSSL_ERR_error_string_n(rc, err_buf, sizeof(err_buf));
                        PRINTF("Use key share failed: %d (%s)", rc, err_buf);
                    }
                }
            }
        }
#endif /* HAVE_PQC */

The output for those lines is the following.

TLS version: TLSv1.3
Use key share failed: -173 (Bad function argument)

The code that gives this error is the following.

int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
{
    int ret;

    if (ssl == NULL)
        return BAD_FUNC_ARG;

#ifdef WOLFSSL_ASYNC_CRYPT
    ret = wolfSSL_AsyncPop(ssl, NULL);
    if (ret != WC_NO_ERR_TRACE(WC_NO_PENDING_E)) {
        /* Check for error */
        if (ret < 0)
            return ret;
    }
#endif

#if defined(WOLFSSL_HAVE_KYBER)
    if (WOLFSSL_NAMED_GROUP_IS_PQC(group)) {

        if (ssl->ctx != NULL && ssl->ctx->method != NULL &&
            !IsAtLeastTLSv1_3(ssl->version)) {
            return BAD_FUNC_ARG;            <----------------------- This line gives the error
        }

        if (ssl->options.side == WOLFSSL_SERVER_END) {
            /* If I am the server of a KEM connection, do not do keygen because
             * I'm going to encapsulate with the client's public key. Note that
             * I might be the client and ssl->option.side has not been properly
             * set yet. In that case the KeyGen operation will be deferred to
             * connection time. */
            return WOLFSSL_SUCCESS;
        }
    }
#endif
#if defined(NO_TLS)
    (void)ret;
    (void)group;
#else
    ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL, &ssl->extensions);
    if (ret != 0)
        return ret;
#endif /* NO_TLS */
    return WOLFSSL_SUCCESS;
}

Must be the line I marked as the ssl struct is allocated (as I could get the version).

Before that I specify the TLS version in this lines.

    client->tls.ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
    if (client->tls.ctx) {
        wolfSSL_CTX_set_verify(client->tls.ctx, WOLFSSL_VERIFY_PEER,
                mqtt_tls_verify_cb);

        /* default to success */
        rc = WOLFSSL_SUCCESS;

Do you have any idea of what could be happening?

Thanks in advance.

sandevins avatar May 20 '25 08:05 sandevins

Resolved by #432

embhorn avatar Jul 25 '25 12:07 embhorn