cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 NetXDuo not properly working when using ECDSA or TLS 1.3

amos3
Associate III

Hello,

I have been trying to connect my STM32H573I-DK to our web server for some time now, unsuccessfully.
I am basing my secure application on the X-CUBE-AZURE-H5 Expansion Package project.
I can successfully run the example and connect (and publish) to Azure DPS.

The main issue I am facing is that there seem to be something wrong when using any cipher suite that isn't TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, despite them being defined and supported throughout the NetXDuo stack. This also happens to be the one cipher suite used to establish the connection with Azure in the example.

This cipher suite is considered to be weak and unsecure, hence our preference in using a different one.
We tried the following cipher suites, with no luck:

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Use GCM instead of CBC. This errors during the TLS handshake with "bad record MAC" (Authentication tag check failed)

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Use ECDSA and GCM (preferred TLS 1.2 method). This fails the TLS handshake with "client's Finished message is incorrect" (Invalid Finished verify data)

TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Use ECDSA instead of RSA, keep CBC. This fails the TLS handshake with "client's Finished message is incorrect" (Invalid Finished verify data)

We finally tried enabling TLS 1.3:
TLS_AES_128_GCM_SHA256
Use TLS 1.3 instead of TLS 1.2. This fails the handshake with "bad record MAC" (Message authentication failed)

From the above there appear to be two separate issues:

  1. Using ECDSA causes the client finished message to be built incorrectly
  2. Using GCM causes the authentication to fail

I now wonder whether there is a known issue with supporting the cipher suites above? Could it be somewhere that different algorithms are actually uses within the Secure Manager?
Was the choice of using an obsolete cipher suite in the Azure example deliberate for this reason?
It seems odd that we can't use any of the cipher suites deemed secure, can anyone help us solve this problem?

Many thanks,
Alex

6 REPLIES 6
Guillaume K
ST Employee

Hello

The X-Cube-Azure-H5 is designed to connect specifically to Microsoft's Azure IoT Cloud MQTT (with TLS) servers with their own (reduced) set of ciphers.

In particular, there are custom crypto methods to use STM32H5's secure manager PSA crypto functions . They are used in place of netxduo "standard" crypto functions.

In particular for ECDSA , the crypto_method_ecdsa_psa_crypto structure allows to use STM32H5 internal User key.

Not every crypto algorithm is supported in the adaptation layer.

If you want to connect to other TLS servers (for example your HTTPS server) then you have to adapt the application to the kind of ciphers supported by your server.

Do you want to support both Azure IoT Cloud server connection and separate HTTPS server connection ? or are you targeting only HTTPS server connection ? If the latter:

- A first option is to not define ENABLE_PSA_CRYPTO_CIPHERSUITES C define. comment it in app_azure_iot_config.h. Thus the Nx_Azure_IoT application should use standard netxduo crypto functions and support more crypto algorithms.

if you do that, in nx_secure_user.h comment the #define NX_SECURE_HASH_METADATA_CLONE nx_crypto_hash_clone_psa

when using "standard" netxduo crypto, NX_SECURE_HASH_METADATA_CLONE should be the "standard" one as defined in nx_secure_tls.h

- another option if you don't plan to connect to Azure IoT cloud DPS/IoT hub is to not use Nx_Azure_IoT and start from STM32 Cube H5 MQTT_Client (Projects\STM32H573I-DK\Applications\NetXDuo\Nx_MQTT_Client) or see Microsoft example Middlewares\ST\netxduo\samples\demo_netxduo_https.c

 

the key point is what set of ciphers is passed by the application to netxduo TLS layer in nx_secure_tls_session_create().

the standard list nx_crypto_tls_ciphers is defined in Middlewares\ST\netxduo\crypto_libraries\src\nx_crypto_generic_ciphersuites.c

for Nx_Azure_Iot application it's _nx_azure_iot_tls_supported_crypto defined in Projects\STM32H573I-DK\Applications\ROT\Nx_Azure_IoT\NetXDuo\App\nx_azure_iot_ciphersuites.c

 

 

 

 

 

Hi Guillaume,

Thank you for the prompt reply.

We do indeed want to connect to both our HTTPS server and Azure IoT.

I did try to go down both ways of using the generic and the azure_iot ciphersuites, where I also noticed that the initialisation of the secure tls is done using a different API in the Azure example.

What I tried so far:

1. Use the `nx_secure_tls_session_create()` API with the TLS configuration from Projects\STM32H573I-DK\Applications\ROT\Nx_Azure_IoT\NetXDuo\psa_crypto_ciphersuites\nx_crypto_psa_crypto_ciphersuites.c

status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers_ecc_psa_crypto, crypto_metadata_client, sizeof(crypto_metadata_client));
if (status != NX_SUCCESS) {
    return status;
}

/* Initialise ecc parameters */
status = nx_secure_tls_ecc_initialize(tls_session, &nx_crypto_ecc_supported_groups_psa_crypto, nx_crypto_ecc_supported_groups_size_psa_crypto, &nx_crypto_ecc_curves_psa_crypto);
if (status != NX_SUCCESS) {
    return status;
}

 

2. Use the `nx_secure_tls_session_create()` API with the TLS configuration from Middlewares\ST\netxduo\crypto_libraries\src\nx_crypto_generic_ciphersuites.c

status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers_ecc, crypto_metadata_client, sizeof(crypto_metadata_client));
if (status != NX_SUCCESS) {
    return status;
}

/* Initialise ecc parameters */
status = nx_secure_tls_ecc_initialize(tls_session, &nx_crypto_ecc_supported_groups, nx_crypto_ecc_supported_groups_size, &nx_crypto_ecc_curves);
if (status != NX_SUCCESS) {
    return status;
}

 

3. Use directly the `_nx_secure_tls_session_create_ext()` API with the TLS configuration from Projects\STM32H573I-DK\Applications\ROT\Nx_Azure_IoT\NetXDuo\App\nx_azure_iot_ciphersuites.c

status = _nx_secure_tls_session_create_ext(tls_session,
								_nx_azure_iot_tls_supported_crypto,
								_nx_azure_iot_tls_supported_crypto_size,
								_nx_azure_iot_tls_ciphersuite_map,
								_nx_azure_iot_tls_ciphersuite_map_size,
								crypto_metadata_client,
								sizeof(crypto_metadata_client));
if (status != NX_SUCCESS) {
    return status;
}

 All three cases have been tested with the following flags on and off:
NX_SECURE_ENABLE_AEAD_CIPHER
NX_SECURE_TLS_ENABLE_TLS_1_3

Additionally, I modified _nx_azure_iot_tls_supported_crypto[] and _nx_azure_iot_tls_ciphersuite_map[] to include GCM encryption methods.

 

Is the issue here that there is no psa implementation for the GCM case?
By looking at the _nx_crypto_ciphersuite_lookup_table_ecc_psa_crypto[] table in nx_crypto_psa_crypto_ciphersuites.c it appears that all the GCM methods (e.g.crypto_method_aes_128_gcm_16)  listed are those from the "standard NetXDuo" (nx_crypto_methods.c).

amos3_0-1706698095787.png

If so, is there any way we could add this?

Thanks,

Alex

If you want a PSA implementation of AES GCM instead of CBC it is needed to create a NX_CRYPTO_METHOD structure for it: "crypto_method_aes_gcm_psa" which points to _nx_crypto_method_aes_psa_operation (and *_init, *_cleanup).

And modify _nx_crypto_method_aes_psa_operation() in nx_crypto_aes_psa.c to handle the case of GCM:

    /* Determine our algorithm type for setting the key policy. */
    if (method -> nx_crypto_algorithm == NX_CRYPTO_ENCRYPTION_AES_CBC)
    {
        /* Set the algorithm - we are using AES-CBC with PKCS7 padding. */
        ctx -> nx_crypto_aes_psa_algorithm = PSA_ALG_CBC_NO_PADDING; //PSA_ALG_CBC_PKCS7;
    }
// insert case AES GCM here
    else
    {
        psa_destroy_key(ctx -> nx_crypto_aes_key_handle);
        return(NX_CRYPTO_INVALID_ALGORITHM);
    }

 

Currently it does only CBC.

it should call PSA API with correct parameters for GCM. 

I have not tested it.

Thanks! Am I right to think that I'd also need to implement a psa variant of

NX_CRYPTO_KEEP UINT  _nx_crypto_method_aes_psa_gcm_operation(...)

similarly to what has been done with _nx_crypto_method_aes_psa_cbc_operation(...) ?

yes

Cool, thank you. Do you perhaps have any pointers or any useful resources we could use?