Hello Kaleb,

thanks for your response.

Can you tell us a bit about what is driving this effort?

I am working on a research project on Post-quantum TLS. I already integrated a bunch of PQ algorithms into wolfSSL, but I am struggling with the ones with bigger signatures because of the fragmentation.

WHERE in the second fragment are the garbage values? Are they at the head or the tail of the message?

There is garbage at the beginning of the second fragment (it overwrites the part of the signature data) and also after the end of the signature.

, let me know if you have any followup questions.

I am not sure, if I calculated the overall size correctly; it is also not quite clear, how the fragments should look like.

So the first fragment is:
    | RECORD_HEADER | HANDSHAKE_HEADER | DATA_1 |
   
The second (and the remaining ones) are: 
    | RECORD_HEADER | HANDSHAKE_HEADER | DATA_2 |
   
The data which hast to be send is
        DATA = | DATA_1 | DATA_2 | = | HASH_SIG_SIZE | VERIFY_HEADER | SIGNATURE |
        (divided into 2 or more parts).


Does it make sense so far? Is my understanding correct?

Hi everyone,

I am using custom signature algorithms for TLS 1.3 authentication.
The sizes of the signatures are huge, so the CertificateVerify message is bigger than the max. size allowed by standard (i.e. MAX_RECORD_SIZE = 16384 and  MAX_PLAINTEXT_SZ   = (1 << 14)), so the extra fragmentation of CertificateVerify message has to be added.

I am trying to implement the fragmentation, but my code does not work correctly and I am not sure how to fix it. I tried to reuse the fragmentation code from the SendTls13Certificate() function as much as possible. For now, the first fragment seems to be correct, but the second fragment contains some garbage value (partially from the previous fragment of the Server Certificate message).

static int SendTls13CertificateVerify(WOLFSSL* ssl)
{
   
    /* 
            ...        
    */
          
          

    switch(ssl->options.asyncState)
    {
        /*  
            ...   
            
        */
        
        case TLS_ASYNC_FINALIZE:
        {
            /* Put the record and handshake headers on. */
            word32 length = args->length + HASH_SIG_SIZE + VERIFY_HEADER;
            word32 payloadSz = length;
            word32 maxFragment = wolfSSL_GetMaxRecordSize(ssl, MAX_RECORD_SIZE);

            while (length > 0 && ret == 0) {
                word32 fragSz = 0;
                args->sendSz = RECORD_HEADER_SZ;

                if (ssl->fragOffset == 0)  {
                    if (length <= maxFragment - HANDSHAKE_HEADER_SZ) {
                        fragSz = length;
                    }
                    else
                        fragSz = maxFragment - HANDSHAKE_HEADER_SZ;

                    args->sendSz += fragSz + HANDSHAKE_HEADER_SZ;
                }
                else {
                    fragSz = min(length, maxFragment);
                    args->sendSz += fragSz;
                }

                args->sendSz += MAX_MSG_EXTRA;

                /* Check buffers are big enough and grow if needed. */
                if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0)
                    return ret;

                /* Get position in output buffer to write new message to. */
                args->output = ssl->buffers.outputBuffer.buffer +
                        ssl->buffers.outputBuffer.length;

                if (ssl->fragOffset == 0) {
                    AddTls13RecordHeader(args->output, fragSz + HANDSHAKE_HEADER_SZ, handshake, ssl);
                    AddTls13HandShakeHeader(args->output + RECORD_HEADER_SZ, payloadSz, 0, fragSz, certificate_verify, ssl);
                    args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ +
                                   fragSz;
                }
                else
                    AddTls13RecordHeader(args->output, fragSz, handshake, ssl);

                ssl->fragOffset += fragSz;
                length -= fragSz;

                /* This message is always encrypted. */
                args->sendSz = BuildTls13Message(ssl, args->output,
                                    MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA,
                                    args->output + RECORD_HEADER_SZ,
                                    args->sendSz - RECORD_HEADER_SZ, handshake, 1, 0, 0);
                if (args->sendSz < 0)
                    return args->sendSz;

                ssl->buffers.outputBuffer.length += args->sendSz;
                if (!ssl->options.groupMessages)
                    ret = SendBuffered(ssl);
            }

            /* Advance state and proceed */
            ssl->options.asyncState = TLS_ASYNC_END;
        } /* case TLS_ASYNC_FINALIZE */
        FALL_THROUGH;

        case TLS_ASYNC_END:
        {
            /* Clean up the fragment offset */
            ssl->fragOffset = 0;

            if (ret < 0) {
                goto exit_scv;
            }
            else {
                args->sendSz = ret;
                ret = 0;
            }

        #ifdef WOLFSSL_CALLBACKS
            if (ssl->hsInfoOn)
                AddPacketName(ssl, "CertificateVerify");
            if (ssl->toInfoOn) {
                AddPacketInfo(ssl, "CertificateVerify", handshake,
                            args->output, args->sendSz, WRITE_PROTO, ssl->heap);
            }
        #endif

            ssl->buffers.outputBuffer.length += args->sendSz;

            if (!ssl->options.groupMessages)
                ret = SendBuffered(ssl);
            break;
        }
        default:
            ret = INPUT_CASE_ERROR;
    } /* switch(ssl->options.asyncState) */

exit_scv:

    WOLFSSL_LEAVE("SendTls13CertificateVerify", ret);
    WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND);

#ifdef WOLFSSL_ASYNC_CRYPT
    /* Handle async operation */
    if (ret == WC_PENDING_E) {
        return ret;
    }
#endif /* WOLFSSL_ASYNC_CRYPT */

    /* Final cleanup */
    FreeScv13Args(ssl, args);
    FreeKeyExchange(ssl);

    return ret;
}

Please give me some clues how to fix this. Thanks in advance!

Regards,
Yulia

tmael wrote:

2.
I believe --enable-debug configure option is all you need to display debug info of the server/client example application.

Hope this helps.

Hi tmael,

Thanks!

Hello everyone,

1. I am using TLS 1.3 only (without older versions) and would like to negotiate shared secret using one specific group (for example, ECC_X448). Is there any way to do it?


2. And also I would like to enable full debug logs.
For instance, if I use client and server programs (./examples/client/client and ./examples/server/server respectively) and configure build using

./configure --enable-tls13 --disable-tlsv12 --disable-oldtls --enable-debug

and also define WOLFSSL_DEBUG_TLS in the client and server, then only function names will be printed in the stderr, without printing the full keys (using WOLFSSL_BUFFER) and other secrets.


It would be really useful if, for example, he public keys could be printed when calling TLSX_KeyShare_GenKey() function.
Is it possible and how can I enable it?


Thank you very much for your help!


Regards,
Julia

Hi David,

Thanks for you response, I added WOLFSSL_API to the header definitions, but unfortunately it did not help.
I then checked if my functions are built in the library by running

nm -g /usr/local/lib/libwolfssl.so | grep PQ

and it turned out, they are not.

In the output of readelf the functions are LOCAL instead of GLOBAL, so maybe that's why they cannot be seen by the linker?

 readelf -sW /usr/local/lib/libwolfssl.so | grep PQ
   414: 0000000000029b90    59 FUNC    LOCAL  DEFAULT   14 wc_FreePQKey
   453: 0000000000029bd0    30 FUNC    LOCAL  DEFAULT   14 wc_GeneratePQKeyPair
   715: 0000000000029b30    88 FUNC    LOCAL  DEFAULT   14 wc_InitPQKey

The library object src_libwolfssl_la-PQ.lo is present in the /wolfssl/wolfcrypt/src directory.

Could you give me an advice how to fix it? Thanks!

Hello everyone,
I am trying to add custom crypto algorithms in wolfssl for my project, however I have a couple problems and I am not sure why.

The setup is as follows:

1. In the wolfssl/wolfcrypt/src directory I added a new file, PQ.c, where new functions wc_InitPQKey(),
wc_FreePQKey(), wc_GeneratePQKeyPair() etc. are implemented. The corresponding header is in wolfssl/wolfssl/wolfcrypt/PQ.h.

2. I defined a new WolfSSL configuration: --enable-pq.
- For that, I added the following into wolfssl/configure.ac:

    ...
    enable_pq=yes
    ...
    # PQ
    AC_ARG_ENABLE([pq],
        [AS_HELP_STRING([--enable-pq],[Enable wolfSSL PQ support (default: disabled)])],
        [ ENABLED_PQ=$enableval ],
        [ ENABLED_PQ=no ]
        )

    if test "$ENABLED_PQ" = "yes"
    then
        AM_CFLAGS="$AM_CFLAGS -DHAVE_PQ"
    fi
    ...
    AM_CONDITIONAL([BUILD_PQ],[test "x$ENABLED_PQ" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
    ...
    echo "   * PQ:                      $ENABLED_PQ"
    ...

- in the wolfssl/src/include.am I added:

    ...
    if BUILD_PQ
    src_libwolfssl_la_SOURCES += wolfcrypt/src/PQ.c
    endif
    ...

- in the wolfssl/wolfssl/wolfcrypt/include.am:

    ...
    nobase_include_HEADERS+= \
                         wolfssl/wolfcrypt/aes.h \
                         ...
                         wolfssl/wolfcrypt/PQ.h \
                         ...
    ...
    if BUILD_PQ
    nobase_include_HEADERS+= wolfssl/wolfcrypt/PQ.h
    endif

3. To build the library, I do:

    ./configure --enable-pq
    make
    sudo make install

4. In my test project file I include <wolfssl/options.h>, <wolfssl/wolfcrypt/PQ.h>, <wolfssl/wolfcrypt/settings.h> etc. and call my functions
wc_InitPQKey(), wc_FreePQKey(), wc_GeneratePQKeyPair().


However, when I am trying to compile the project I get the following:

make
gcc -Wall   -c -o main.o main.c
gcc -o myprog main.o -lwolfssl
/usr/bin/ld: main.o: in function `main':
main.c:(.text+0x12d): undefined reference to `wc_InitPQKey'
/usr/bin/ld: main.c:(.text+0x14a): undefined reference to `wc_InitPQKey'
/usr/bin/ld: main.c:(.text+0x1ce): undefined reference to `wc_GeneratePQKeyPair'
...

Am I missing something?
Thank your very much for your help!