AzureMXChip/MXCHIPAZ3166/core/lib/netxduo/nx_secure/src/nx_secure_tls_send_clienthello_extensions.c
UINT _nx_secure_tls_send_clienthello_extensions(NX_SECURE_TLS_SESSION *tls_session,
                                                UCHAR *packet_buffer, ULONG *packet_offset,
                                                ULONG *extensions_length, ULONG available_size)
{
ULONG  length = *packet_offset;
USHORT extension_length = 0, total_extensions_length;
UINT   status;

    total_extensions_length = 0;


#ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
    status = _nx_secure_tls_send_clienthello_sec_spf_extensions(tls_session,
                                                                packet_buffer,
                                                                &length,
                                                                &extension_length,
                                                                available_size);
    total_extensions_length = (USHORT)(total_extensions_length + extension_length);
#endif

#ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
    /* We have to add renegotiation extensions in both initial sessions and renegotiating sessions. */
    if (tls_session -> nx_secure_tls_renegotation_enabled == NX_TRUE)
    {
        status = _nx_secure_tls_send_clienthello_sec_reneg_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if(status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
    }
#endif

/* We can't do TLS 1.3 without ECC. */
#if (NX_SECURE_TLS_TLS_1_3_ENABLED)
    if(tls_session->nx_secure_tls_1_3)
    {
        /* Send supported TLS versions extensions (for TLS 1.3). */
        status = _nx_secure_tls_send_clienthello_supported_versions_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if(status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);

        /* Send KeyShare extension (for TLS 1.3). */
        _nx_secure_tls_send_clienthello_key_share_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if(status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);

        /* Including a "cookie" extension if one was provided in the HelloRetryRequest. */
        if ((tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY) && 
            (tls_session -> nx_secure_tls_cookie_length != 0))
        {

            /* Add Extension Type. */
            packet_buffer[length] = (UCHAR)((NX_SECURE_TLS_EXTENSION_COOKIE) >> 8);
            packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_EXTENSION_COOKIE);
            length += 2;

            /* Add Extension Length. */
            extension_length = (USHORT)(tls_session -> nx_secure_tls_cookie_length + 2);
            packet_buffer[length] = (UCHAR)(extension_length >> 8);
            packet_buffer[length + 1] = (UCHAR)(extension_length);
            length += 2;

            /* Add Cookie Length. */
            packet_buffer[length] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length >> 8);
            packet_buffer[length + 1] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length);
            length += 2;

            /* Add Cookie. */
            NX_SECURE_MEMCPY(&packet_buffer[length], tls_session -> nx_secure_tls_cookie, tls_session -> nx_secure_tls_cookie_length); /* Use case of memcpy is verified. */
            length += (tls_session -> nx_secure_tls_cookie_length);

            /* Update total extensions length and reset the stored cookie length. */
            total_extensions_length = (USHORT)(total_extensions_length + extension_length + 4);
            tls_session -> nx_secure_tls_cookie_length = 0;
        }
    }
#endif

    /* RFC 5246 7.4.1.4.1 Signature Algorithm:
       Note: this extension is not meaningful for TLS versions prior to 1.2.
       Clients MUST NOT offer it if they are offering prior versions. */
    if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
    {

        /* Send the available signature algorithms extension. */
        status = _nx_secure_tls_send_clienthello_sig_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if (status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
    }

#ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
    /* Send the server name indication extension. */
    status = _nx_secure_tls_send_clienthello_sni_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
    if(status != NX_SUCCESS)
    {
        return(status);
    }
    total_extensions_length = (USHORT)(total_extensions_length + extension_length);
#endif

#if (NX_SECURE_TLS_TLS_1_3_ENABLED)
    if(tls_session->nx_secure_tls_1_3 && tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_count > 0)
    {
        status = _nx_secure_tls_send_clienthello_psk_kem_extension(tls_session, packet_buffer, &length, &extension_length);
        if (status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
    }
#endif

    *extensions_length = total_extensions_length;
    *packet_offset = length;


    return(NX_SUCCESS);
}
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_secure_tls_send_clienthello_extensions          PORTABLE C      */
/*                                                           6.1          */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Timothy Stapko, Microsoft Corporation                               */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function populates an NX_PACKET with ClientHello extensions,   */
/*    which provide additional information to the remote host for the     */
/*    initial handshake negotiations.                                     */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    tls_session                           TLS control block             */
/*    packet_buffer                         Outgoing TLS packet           */
/*    packet_offset                         Offset into packet buffer     */
/*    extensions_length                     Return total extension length */
/*    available_size                        Available size of buffer      */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    status                                Completion status             */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    _nx_secure_tls_send_clienthello_sec_reneg_extension                 */
/*                                          Send ClientHello Renegotiation*/
/*                                            extension                   */
/*    _nx_secure_tls_send_clienthello_sig_extension                       */
/*                                          Send ClientHello Signature    */
/*                                            extension                   */
/*    _nx_secure_tls_send_clienthello_sni_extension                       */
/*                                          Send ClientHello SNI extension*/
/*    _nx_secure_tls_send_clienthello_ec_extension                        */
/*                                          Send ClientHello EC extension */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    _nx_secure_tls_send_clienthello       Send TLS ClientHello          */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
/*  09-30-2020     Timothy Stapko           Modified comment(s),          */
/*                                            verified memcpy use cases,  */
/*                                            fixed renegotiation bug,    */
/*                                            resulting in version 6.1    */
/*                                                                        */
/**************************************************************************/
FUNCTION                                               RELEASE

_nx_secure_tls_send_clienthello_extensions          PORTABLE C
6.1
AUTHOR

Timothy Stapko, Microsoft Corporation

DESCRIPTION

This function populates an NX_PACKET with ClientHello extensions,
which provide additional information to the remote host for the
initial handshake negotiations.

INPUT

tls_session                           TLS control block
packet_buffer                         Outgoing TLS packet
packet_offset                         Offset into packet buffer
extensions_length                     Return total extension length
available_size                        Available size of buffer

OUTPUT

status                                Completion status

CALLS



CALLED BY



RELEASE HISTORY

DATE              NAME                      DESCRIPTION

05-19-2020     Timothy Stapko           Initial Version 6.0
09-30-2020     Timothy Stapko           Modified comment(s),
verified memcpy use cases,
fixed renegotiation bug,
resulting in version 6.1
FUNCTION RELEASE _nx_secure_tls_send_clienthello_extensions PORTABLE C 6 . 1 AUTHOR Timothy Stapko Microsoft Corporation DESCRIPTION This function populates an NX_PACKET with ClientHello extensions which provide additional information to the remote host for the initial handshake negotiations . INPUT tls_session TLS control block packet_buffer Outgoing TLS packet packet_offset Offset into packet buffer extensions_length Return total extension length available_size Available size of buffer OUTPUT status Completion status CALLS CALLED BY RELEASE HISTORY DATE NAME DESCRIPTION 05 - 19 - 2020 Timothy Stapko Initial Version 6 . 0 09 - 30 - 2020 Timothy Stapko Modified comment ( s ) verified memcpy use cases fixed renegotiation bug resulting in version 6 . 1
UINT _nx_secure_tls_send_clienthello_extensions(NX_SECURE_TLS_SESSION *tls_session,
                                                UCHAR *packet_buffer, ULONG *packet_offset,
                                                ULONG *extensions_length, ULONG available_size)
{
ULONG  length = *packet_offset;
USHORT extension_length = 0, total_extensions_length;
UINT   status;
    total_extensions_length = 0;
#ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
    status = _nx_secure_tls_send_clienthello_sec_spf_extensions(tls_session,
                                                                packet_buffer,
                                                                &length,
                                                                &extension_length,
                                                                available_size);
    total_extensions_length = (USHORT)(total_extensions_length + extension_length);
#endif
#ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
    if (tls_session -> nx_secure_tls_renegotation_enabled == NX_TRUE)
    {
        status = _nx_secure_tls_send_clienthello_sec_reneg_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if(status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
    }
#endif
#if (NX_SECURE_TLS_TLS_1_3_ENABLED)
    if(tls_session->nx_secure_tls_1_3)
    {
        status = _nx_secure_tls_send_clienthello_supported_versions_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if(status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
        _nx_secure_tls_send_clienthello_key_share_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if(status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
        if ((tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY) && 
            (tls_session -> nx_secure_tls_cookie_length != 0))
        {
            packet_buffer[length] = (UCHAR)((NX_SECURE_TLS_EXTENSION_COOKIE) >> 8);
            packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_EXTENSION_COOKIE);
            length += 2;
            extension_length = (USHORT)(tls_session -> nx_secure_tls_cookie_length + 2);
            packet_buffer[length] = (UCHAR)(extension_length >> 8);
            packet_buffer[length + 1] = (UCHAR)(extension_length);
            length += 2;
            packet_buffer[length] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length >> 8);
            packet_buffer[length + 1] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length);
            length += 2;
            NX_SECURE_MEMCPY(&packet_buffer[length], tls_session -> nx_secure_tls_cookie, tls_session -> nx_secure_tls_cookie_length); 
            length += (tls_session -> nx_secure_tls_cookie_length);
            total_extensions_length = (USHORT)(total_extensions_length + extension_length + 4);
            tls_session -> nx_secure_tls_cookie_length = 0;
        }
    }
#endif
    if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
    {
        status = _nx_secure_tls_send_clienthello_sig_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
        if (status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
    }
#ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
    status = _nx_secure_tls_send_clienthello_sni_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
    if(status != NX_SUCCESS)
    {
        return(status);
    }
    total_extensions_length = (USHORT)(total_extensions_length + extension_length);
#endif
#if (NX_SECURE_TLS_TLS_1_3_ENABLED)
    if(tls_session->nx_secure_tls_1_3 && tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_count > 0)
    {
        status = _nx_secure_tls_send_clienthello_psk_kem_extension(tls_session, packet_buffer, &length, &extension_length);
        if (status != NX_SUCCESS)
        {
            return(status);
        }
        total_extensions_length = (USHORT)(total_extensions_length + extension_length);
    }
#endif
    *extensions_length = total_extensions_length;
    *packet_offset = length;
    return(NX_SUCCESS);
}
UINT _nx_secure_tls_send_clienthello_extensions ( NX_SECURE_TLS_SESSION * tls_session , UCHAR * packet_buffer , ULONG * packet_offset , ULONG * extensions_length , ULONG available_size ) { ULONG length = * packet_offset ; USHORT extension_length = 0 , total_extensions_length ; UINT status ; total_extensions_length = 0 ; #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE status = _nx_secure_tls_send_clienthello_sec_spf_extensions ( tls_session , packet_buffer , & length , & extension_length , available_size ) ; total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length ) ; #endif #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION if ( tls_session -> nx_secure_tls_renegotation_enabled == NX_TRUE ) { status = _nx_secure_tls_send_clienthello_sec_reneg_extension ( tls_session , packet_buffer , & length , & extension_length , available_size ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length ) ; } #endif #if ( NX_SECURE_TLS_TLS_1_3_ENABLED ) if ( tls_session -> nx_secure_tls_1_3 ) { status = _nx_secure_tls_send_clienthello_supported_versions_extension ( tls_session , packet_buffer , & length , & extension_length , available_size ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length ) ; _nx_secure_tls_send_clienthello_key_share_extension ( tls_session , packet_buffer , & length , & extension_length , available_size ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length ) ; if ( ( tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY ) && ( tls_session -> nx_secure_tls_cookie_length != 0 ) ) { packet_buffer [ length ] = ( UCHAR ) ( ( NX_SECURE_TLS_EXTENSION_COOKIE ) >> 8 ) ; packet_buffer [ length + 1 ] = ( UCHAR ) ( NX_SECURE_TLS_EXTENSION_COOKIE ) ; length += 2 ; extension_length = ( USHORT ) ( tls_session -> nx_secure_tls_cookie_length + 2 ) ; packet_buffer [ length ] = ( UCHAR ) ( extension_length >> 8 ) ; packet_buffer [ length + 1 ] = ( UCHAR ) ( extension_length ) ; length += 2 ; packet_buffer [ length ] = ( UCHAR ) ( tls_session -> nx_secure_tls_cookie_length >> 8 ) ; packet_buffer [ length + 1 ] = ( UCHAR ) ( tls_session -> nx_secure_tls_cookie_length ) ; length += 2 ; NX_SECURE_MEMCPY ( & packet_buffer [ length ] , tls_session -> nx_secure_tls_cookie , tls_session -> nx_secure_tls_cookie_length ) ; length += ( tls_session -> nx_secure_tls_cookie_length ) ; total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length + 4 ) ; tls_session -> nx_secure_tls_cookie_length = 0 ; } } #endif if ( tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ) { status = _nx_secure_tls_send_clienthello_sig_extension ( tls_session , packet_buffer , & length , & extension_length , available_size ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length ) ; } #ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED status = _nx_secure_tls_send_clienthello_sni_extension ( tls_session , packet_buffer , & length , & extension_length , available_size ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length ) ; #endif #if ( NX_SECURE_TLS_TLS_1_3_ENABLED ) if ( tls_session -> nx_secure_tls_1_3 && tls_session -> nx_secure_tls_credentials . nx_secure_tls_psk_count > 0 ) { status = _nx_secure_tls_send_clienthello_psk_kem_extension ( tls_session , packet_buffer , & length , & extension_length ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } total_extensions_length = ( USHORT ) ( total_extensions_length + extension_length ) ; } #endif * extensions_length = total_extensions_length ; * packet_offset = length ; return ( NX_SUCCESS ) ; }
FUNCTION                                               RELEASE
FUNCTION RELEASE
/* We have to add renegotiation extensions in both initial sessions and renegotiating sessions. */ /* We can't do TLS 1.3 without ECC. */ /* Send supported TLS versions extensions (for TLS 1.3). */ /* Send KeyShare extension (for TLS 1.3). */ /* Including a "cookie" extension if one was provided in the HelloRetryRequest. */ /* Add Extension Type. */ /* Add Extension Length. */ /* Add Cookie Length. */ /* Add Cookie. */ /* Use case of memcpy is verified. */ /* Update total extensions length and reset the stored cookie length. */ /* RFC 5246 7.4.1.4.1 Signature Algorithm:
       Note: this extension is not meaningful for TLS versions prior to 1.2.
       Clients MUST NOT offer it if they are offering prior versions. */ /* Send the available signature algorithms extension. */ /* Send the server name indication extension. */