My mbedtls client has been working for 2 years. It did what I required and has been stable.
However, I now need to force a new server to use my preferred cipher suite.
I found the helper function to force the cipher suite here:
https://github.com/Mbed-TLS/mbedtls/blob/de4d5b78558666d2e258d95e6c5875f9c72...
I added mbedtls_ssl_conf_preference_order(conf, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) to the end of the function to force the server to choose my ciphersuite.
Prior to this change I called the mbedtls functions in this chronological order:
mbedtls_ssl_init(&_ssl); mbedtls_ssl_config_init(&_conf); mbedtls_ctr_drbg_init(&_ctr_drbg); mbedtls_entropy_init(&_entropy); mbedtls_x509_crt_init(&_cacert); mbedtls_pk_init(&_pkey); mbedtls_ctr_drbg_seed mbedtls_ssl_config_defaults mbedtls_ssl_conf_rng mbedtls_ssl_conf_authmode mbedtls_x509_crt_parse_file mbedtls_ssl_conf_ca_chain mbedtls_ssl_setup mbedtls_ssl_set_hostname
and then proceed to call:
mbedtls_ssl_set_bio mbedtls_ssl_handshake
Now:
If I call mbedtls_ssl_conf_ciphersuites BEFORE mbedtls_ssl_config_defaults, the ciphersuite list is ignored/seems to get overriden.
If I call mbedtls_ssl_conf_ciphersuites AFTER mbedtls_ssl_config_defaults, my ciphersuite list changes are accepted and transmitted (I can see in Wireshark). The server then responds agreeing to use my chosen cipher suite.
However, mbedtls_ssl_handshake returns with value -26112, which I have looked up to be MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER.
Unfortunately I have no clue what is causing this.
Could somebody please advise how this should be done? I can see Client2 example but there are functions I have which are not in there. Client1 seems too simple for me but Client2 seems beyond what I require.
On 14/09/2024 04:03, Mbed TLS via mbed-tls wrote:
My mbedtls client has been working for 2 years. It did what I required and has been stable.
However, I now need to force a new server to use my preferred cipher suite.
I found the helper function to force the cipher suite here:
https://github.com/Mbed-TLS/mbedtls/blob/de4d5b78558666d2e258d95e6c5875f9c72...
I added mbedtls_ssl_conf_preference_order(conf, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) to the end of the function to force the server to choose my ciphersuite.
Note that this is a server-side function, it has no effect on clients. The way the TLS protocol works is, the client sends a list of cipher suites that it supports, then the server picks one of them. With Mbed TLS (and I think that's typical of TLS server implementations), there are two ways this can go:
1. The server goes through its list of cipher suites in order of preference, and picks the first one that the client supports. (ORDER_SERVER) 2. The server goes through the list of cipher suites sent by the client, and picks the first one that the server supports. (ORDER_CLIENT)
If you want to force a server to use your preferred cipher suite, don't send other cipher suites. Call mbedtls_ssl_conf_ciphersuites with a list that only includes cipher suites that you're happy with.
(…)
However, mbedtls_ssl_handshake returns with value -26112, which I have looked up to be MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER.
This error indicates that your client received something that it thinks is not valid according to the TLS protocol. So either the server is sending something wrong, or it's hitting some limitation in the client.
To find out more, make sure you compile Mbed TLS with MBEDTLS_DEBUG_C enabled, call mbedtls_ssl_conf_dbg() to set up a debug callback (typically printing its arguments, see examples in e.g. ssl_client1.c), and call mbedtls_debug_set_threshold(4). You'll get a detailed trace that tells you exactly where the error was detected and what happened before.
Best regards,
Hi Gilles, sorry I realised that after posting I could add debug logging but I couldn't reply to this thread until you had replied.
Before adding the logging I think I can spot a/the problem.
This is part of my initialisation code:
forced_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id("TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"); forced_ciphersuite[1] = 0;
if (conf->max_tls_version > ciphersuite_info->max_tls_version) { conf->max_tls_version = (mbedtls_ssl_protocol_version) ciphersuite_info->max_tls_version; }
if (conf->min_tls_version < ciphersuite_info->min_tls_version) { conf->min_tls_version = (mbedtls_ssl_protocol_version) ciphersuite_info->min_tls_version; }
mbedtls_ssl_conf_ciphersuites(conf, &forced_ciphersuite[0]);
// If I print conf.ciphersuite_list here, it contains my cipher
if (0 != mbedtls_ssl_setup(&_ssl, &_conf))
// If I print _ssl.conf.ciphersuite_list here, it does NOT contain my cipher
So the call to mbedtls_ssl_setup() seems to be losing my ciphersuite?
On Sat, 14 Sept 2024 at 09:56, Gilles Peskine gilles.peskine@arm.com wrote:
On 14/09/2024 04:03, Mbed TLS via mbed-tls wrote:
My mbedtls client has been working for 2 years. It did what I required and has been stable.
However, I now need to force a new server to use my preferred cipher suite.
I found the helper function to force the cipher suite here:
https://github.com/Mbed-TLS/mbedtls/blob/de4d5b78558666d2e258d95e6c5875f9c72...
I added mbedtls_ssl_conf_preference_order(conf, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) to the end of the function to force the server to choose my ciphersuite.
Note that this is a server-side function, it has no effect on clients. The way the TLS protocol works is, the client sends a list of cipher suites that it supports, then the server picks one of them. With Mbed TLS (and I think that's typical of TLS server implementations), there are two ways this can go:
- The server goes through its list of cipher suites in order of
preference, and picks the first one that the client supports. (ORDER_SERVER) 2. The server goes through the list of cipher suites sent by the client, and picks the first one that the server supports. (ORDER_CLIENT)
If you want to force a server to use your preferred cipher suite, don't send other cipher suites. Call mbedtls_ssl_conf_ciphersuites with a list that only includes cipher suites that you're happy with.
(…)
However, mbedtls_ssl_handshake returns with value -26112, which I have looked up to be MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER.
This error indicates that your client received something that it thinks is not valid according to the TLS protocol. So either the server is sending something wrong, or it's hitting some limitation in the client.
To find out more, make sure you compile Mbed TLS with MBEDTLS_DEBUG_C enabled, call mbedtls_ssl_conf_dbg() to set up a debug callback (typically printing its arguments, see examples in e.g. ssl_client1.c), and call mbedtls_debug_set_threshold(4). You'll get a detailed trace that tells you exactly where the error was detected and what happened before.
Best regards,
-- Gilles Peskine Mbed TLS developer
Please ignore conf vs _conf, it's the same variable I'm just having to type the code manually.
On Sat, 14 Sept 2024 at 19:45, Mbed TLS mbedtls77@gmail.com wrote:
Hi Gilles, sorry I realised that after posting I could add debug logging but I couldn't reply to this thread until you had replied.
Before adding the logging I think I can spot a/the problem.
This is part of my initialisation code:
forced_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id("TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"); forced_ciphersuite[1] = 0;
if (conf->max_tls_version > ciphersuite_info->max_tls_version) { conf->max_tls_version = (mbedtls_ssl_protocol_version) ciphersuite_info->max_tls_version; }
if (conf->min_tls_version < ciphersuite_info->min_tls_version) { conf->min_tls_version = (mbedtls_ssl_protocol_version) ciphersuite_info->min_tls_version; }
mbedtls_ssl_conf_ciphersuites(conf, &forced_ciphersuite[0]);
// If I print conf.ciphersuite_list here, it contains my cipher
if (0 != mbedtls_ssl_setup(&_ssl, &_conf))
// If I print _ssl.conf.ciphersuite_list here, it does NOT contain my cipher
So the call to mbedtls_ssl_setup() seems to be losing my ciphersuite?
On Sat, 14 Sept 2024 at 09:56, Gilles Peskine gilles.peskine@arm.com wrote:
On 14/09/2024 04:03, Mbed TLS via mbed-tls wrote:
My mbedtls client has been working for 2 years. It did what I required and has been stable.
However, I now need to force a new server to use my preferred cipher suite.
I found the helper function to force the cipher suite here:
https://github.com/Mbed-TLS/mbedtls/blob/de4d5b78558666d2e258d95e6c5875f9c72...
I added mbedtls_ssl_conf_preference_order(conf, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) to the end of the function to force the server to choose my ciphersuite.
Note that this is a server-side function, it has no effect on clients. The way the TLS protocol works is, the client sends a list of cipher suites that it supports, then the server picks one of them. With Mbed TLS (and I think that's typical of TLS server implementations), there are two ways this can go:
- The server goes through its list of cipher suites in order of
preference, and picks the first one that the client supports. (ORDER_SERVER) 2. The server goes through the list of cipher suites sent by the client, and picks the first one that the server supports. (ORDER_CLIENT)
If you want to force a server to use your preferred cipher suite, don't send other cipher suites. Call mbedtls_ssl_conf_ciphersuites with a list that only includes cipher suites that you're happy with.
(…)
However, mbedtls_ssl_handshake returns with value -26112, which I have looked up to be MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER.
This error indicates that your client received something that it thinks is not valid according to the TLS protocol. So either the server is sending something wrong, or it's hitting some limitation in the client.
To find out more, make sure you compile Mbed TLS with MBEDTLS_DEBUG_C enabled, call mbedtls_ssl_conf_dbg() to set up a debug callback (typically printing its arguments, see examples in e.g. ssl_client1.c), and call mbedtls_debug_set_threshold(4). You'll get a detailed trace that tells you exactly where the error was detected and what happened before.
Best regards,
-- Gilles Peskine Mbed TLS developer
So, I add my preferred ciphersuite "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"
I check my conf object ciphersuite_list and it is still present
I then call mbedtls_ssl_setup.
The debugging logging only says "ssl_tls.c:1234: The SSL configuration is tls12 only"
Now when I query ssl->conf->ciphersuite_list instead of my preferred ciphersuite, instead it just has ID number 4.
I then call the handshake and in Wireshark I can see:
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
So for some reason mbedtls_ssl_setup is replacing my preferred ciphersuite with the empty. I'm looking at the source code but not seeing an obvious reason for this
On Sat, 14 Sept 2024 at 19:46, Mbed TLS mbedtls77@gmail.com wrote:
Please ignore conf vs _conf, it's the same variable I'm just having to type the code manually.
On Sat, 14 Sept 2024 at 19:45, Mbed TLS mbedtls77@gmail.com wrote:
Hi Gilles, sorry I realised that after posting I could add debug logging but I couldn't reply to this thread until you had replied.
Before adding the logging I think I can spot a/the problem.
This is part of my initialisation code:
forced_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id("TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"); forced_ciphersuite[1] = 0;
if (conf->max_tls_version > ciphersuite_info->max_tls_version) { conf->max_tls_version = (mbedtls_ssl_protocol_version) ciphersuite_info->max_tls_version; }
if (conf->min_tls_version < ciphersuite_info->min_tls_version) { conf->min_tls_version = (mbedtls_ssl_protocol_version) ciphersuite_info->min_tls_version; }
mbedtls_ssl_conf_ciphersuites(conf, &forced_ciphersuite[0]);
// If I print conf.ciphersuite_list here, it contains my cipher
if (0 != mbedtls_ssl_setup(&_ssl, &_conf))
// If I print _ssl.conf.ciphersuite_list here, it does NOT contain my cipher
So the call to mbedtls_ssl_setup() seems to be losing my ciphersuite?
On Sat, 14 Sept 2024 at 09:56, Gilles Peskine gilles.peskine@arm.com wrote:
On 14/09/2024 04:03, Mbed TLS via mbed-tls wrote:
My mbedtls client has been working for 2 years. It did what I required and has been stable.
However, I now need to force a new server to use my preferred cipher suite.
I found the helper function to force the cipher suite here:
https://github.com/Mbed-TLS/mbedtls/blob/de4d5b78558666d2e258d95e6c5875f9c72...
I added mbedtls_ssl_conf_preference_order(conf, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) to the end of the function to force the server to choose my ciphersuite.
Note that this is a server-side function, it has no effect on clients. The way the TLS protocol works is, the client sends a list of cipher suites that it supports, then the server picks one of them. With Mbed TLS (and I think that's typical of TLS server implementations), there are two ways this can go:
- The server goes through its list of cipher suites in order of
preference, and picks the first one that the client supports. (ORDER_SERVER) 2. The server goes through the list of cipher suites sent by the client, and picks the first one that the server supports. (ORDER_CLIENT)
If you want to force a server to use your preferred cipher suite, don't send other cipher suites. Call mbedtls_ssl_conf_ciphersuites with a list that only includes cipher suites that you're happy with.
(…)
However, mbedtls_ssl_handshake returns with value -26112, which I have looked up to be MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER.
This error indicates that your client received something that it thinks is not valid according to the TLS protocol. So either the server is sending something wrong, or it's hitting some limitation in the client.
To find out more, make sure you compile Mbed TLS with MBEDTLS_DEBUG_C enabled, call mbedtls_ssl_conf_dbg() to set up a debug callback (typically printing its arguments, see examples in e.g. ssl_client1.c), and call mbedtls_debug_set_threshold(4). You'll get a detailed trace that tells you exactly where the error was detected and what happened before.
Best regards,
-- Gilles Peskine Mbed TLS developer
Is forced_ciphersuites a local variable? Note that the memory pointed to by forced_ciphersuites must remain valid as long as conf is valid, and conf must remain valid for the whole session. If forced_ciphersuites is a local variable and goes out of scope after the call to mbedtls_ssl_conf_ciphersuites(), its memory has probably been reused by the time the SSL session starts. The memory may even be reused by the time mbedtls_ssl_setup() is called due to a compiler optimization.
Best regards,
mbed-tls@lists.trustedfirmware.org