Topic: ML-KEM in Post-quantum DTLS1.3

Hello,

I'm working on a DTLS 1.3 server using the wolfSSL library. I'm trying to implement a post-quantum connection using ML-KEM and Dilithium.

I've modified the C code for the server (https://github.com/wolfSSL/wolfssl-exam … r-dtls13.c) and client (https://github.com/wolfSSL/wolfssl-exam … t-dtls13.c) .I've added the following for it to use ML-KEM 1024 in both client and server implementations.

    /* Create the WOLFSSL Object */
    if ((ssl = wolfSSL_new(ctx)) == NULL) {
      fprintf(stderr, "wolfSSL_new error.\n");
      goto cleanup;
    }
    /* new code */
    ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ML_KEM_1024);
    if (ret < 0) {
      fprintf(stderr, "ERROR: failed to set the requested group to "
                      "WOLFSSL_ML_KEM_1024.\n");
      ret = -1;
      goto cleanup;
    }

When I run the client and connect to the server, the server successfully establishes a connection, and the output shows:

New connection established using DTLSv1.3 TLS_AES_256_GCM_SHA384

I'm confused because this output only specifies the symmetric cipher suite. It doesn't explicitly confirm that ML-KEM was used.

Is there a way to verify through the wolfSSL logs or API that ML-KEM 1024 was used? Thanks in advance for any insight and sorry if this is out of place.

Share

2 (edited by Sunnysunday 2025-09-07 05:19:59)

Re: ML-KEM in Post-quantum DTLS1.3

In DTLS1.3 the key exchange (key share) is no longer specified in the Cipher Suite but it's negotiated separately via the Supported Groups and KeyShare extensions in the ClientHello and ServerHello.

I don't know right now if the key share is shown in the logs, I would have to check, but I always check with a Wireshark packet capture anyway and there you can see which key share was actually used.

Share

Re: ML-KEM in Post-quantum DTLS1.3

Hello SunnySunday and matemagico13,

my name is Anthony and I am a member of the wolfSSL team.

I built wolfSSL with the following configure line:

./configure --enable-dtls --enable-dtls13 --enable-mlkem --enable-dtls-frag-ch

Then I ran the example server and client as shown and got the output as shown:

 $ ./examples/server/server -u -v 4 --pqc ML_KEM_1024
Using Post-Quantum KEM: ML_KEM_1024
SSL version is DTLSv1.3
SSL cipher suite is TLS_AES_256_GCM_SHA384
SSL curve name is ML_KEM_1024
Client message: hello wolfssl

 $ ./examples/client/client -u -v 4
SSL version is DTLSv1.3
SSL cipher suite is TLS_AES_256_GCM_SHA384
SSL curve name is ML_KEM_1024
I hear you fa shizzle!

Note that the use of ML-KEM is clearly shown.  I made no modifications to the code. Please let me know if you have further questions.

Warm regards, Anthony .

Share

Re: ML-KEM in Post-quantum DTLS1.3

matemagico13 wrote:

Hello,

I'm working on a DTLS 1.3 server using the wolfSSL library. I'm trying to implement a post-quantum connection using ML-KEM and Dilithium.

I've modified the C code for the server (https://github.com/wolfSSL/wolfssl-exam … r-dtls13.c ball orbit) and client (https://github.com/wolfSSL/wolfssl-exam … t-dtls13.c) .I've added the following for it to use ML-KEM 1024 in both client and server implementations.

    /* Create the WOLFSSL Object */
    if ((ssl = wolfSSL_new(ctx)) == NULL) {
      fprintf(stderr, "wolfSSL_new error.\n");
      goto cleanup;
    }
    /* new code */
    ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ML_KEM_1024);
    if (ret < 0) {
      fprintf(stderr, "ERROR: failed to set the requested group to "
                      "WOLFSSL_ML_KEM_1024.\n");
      ret = -1;
      goto cleanup;
    }

When I run the client and connect to the server, the server successfully establishes a connection, and the output shows:

New connection established using DTLSv1.3 TLS_AES_256_GCM_SHA384

I'm confused because this output only specifies the symmetric cipher suite. It doesn't explicitly confirm that ML-KEM was used.

Is there a way to verify through the wolfSSL logs or API that ML-KEM 1024 was used? Thanks in advance for any insight and sorry if this is out of place.

You’re right — the cipher suite string you’re seeing (TLS_AES_256_GCM_SHA384) only describes the negotiated symmetric cipher, not the key exchange mechanism. In TLS 1.3/DTLS 1.3, the KEM or key exchange group is negotiated separately and doesn’t show up in the cipher suite line.

With wolfSSL, there are a couple of ways you can confirm that ML-KEM 1024 is actually being used:

Enable verbose debugging logs
Call:

wolfSSL_Debugging_ON();


before creating the context. This will dump detailed handshake logs to stderr, including the “key_share” extension negotiation. If ML-KEM 1024 is chosen, you’ll see it logged during the ClientHello/ServerHello exchange.

Query the group in use via the API
After the handshake, you can call:

int group = wolfSSL_GetNegotiatedGroup(ssl);
printf("Negotiated group: %d\n", group);


For post-quantum groups, this should return WOLFSSL_ML_KEM_1024 (or the corresponding enum value). That way, you can explicitly check what group was used.

Check the handshake trace with Wireshark
If you capture the DTLS handshake, you should see the key_share extension containing ML-KEM 1024 parameters in the ClientHello and ServerHello. That gives you external confirmation independent of wolfSSL.

So in short: the “AES_256_GCM_SHA384” part is normal, and you’ll need either wolfSSL debug logs, wolfSSL_GetNegotiatedGroup(), or a packet trace to verify that the ML-KEM 1024 group was negotiated.

Share

Re: ML-KEM in Post-quantum DTLS1.3

I concur. You can use our APIs to output what algorithms are used. But the gold standard is to have a packet sniffer (wireshark for example) confirm that you are actually doing a quantum-safe connection.

Share