mbedtls_ssl_read reading all 0x0F
I'm using a component https://github.com/tuanpmt/espmqtt which in turn uses mbedtls to open a TLS connection to an MQTT service (mosquito).
The TLS connection is successfully established and the client sends a 26 byte message (CONNECT) to the server which successfully decrypted. The server then sends a 4 byte reply (CONNACK). In Wireshark, this all looks okay and I can see the 4 byte CONNACK.
However, the problem is that on the client when it goes to read the reply using mbedtls_ssl_read https://github.com/tuanpmt/espmqtt/blob/master/lib/transport_ssl.c#L192
it's getting a return value of 16 and the bytes in the buffer are all 0x0F.
The only "odd" thing I can see is that the reply packet from the server has two Application Data records.
No. Time Source Destination Protocol Length Info 18 2018-04-06 11:13:44.851085687 192.168.0.2 192.168.0.105 TLSv1 136 Application Data, Application Data Frame 18: 136 bytes on wire (1088 bits), 136 bytes captured (1088 bits) on interface 0 Ethernet II, Src: Raspberr_cc:77:14 (b8:27:eb:cc:77:14), Dst: 30:ae:a4:28:88:98 (30:ae:a4:28:88:98) Internet Protocol Version 4, Src: 192.168.0.2 (192.168.0.2), Dst: 192.168.0.105 (192.168.0.105) Transmission Control Protocol, Src Port: 8883 (8883), Dst Port: 51201 (51201), Seq: 2041, Ack: 631, Len: 82 Secure Sockets Layer TLSv1 Record Layer: Application Data Protocol: Application Data Content Type: Application Data (23) Version: TLS 1.0 (0x0301) Length: 36 Encrypted Application Data: 521ad97c6c298f68a1834adfe20ad96a9315b169c3e5e59f... TLSv1 Record Layer: Application Data Protocol: Application Data Content Type: Application Data (23) Version: TLS 1.0 (0x0301) Length: 36 Encrypted Application Data: efa6f8b7d1495587dcfebcb39855e7d1aacff5b10c0ef333...
Any pointers on where to start looking for the cause of the problem?
mbedtls_ssl_read() returns "he (positive) number of bytes read". On the wireshark capture you showed, it says that every application data is 36 bytes. Unless it includes some SHA1 20 bytes HASH, it doesn't correspond to the 16 bytes you read.
You should check what the ciphersuite that was negotiated first.
In addition, enabled debug logs for the Mbed TLS, and check for any other error.
Please also check your bio callback implementation.
Mbed TLS Team member
this might be an instance of a known bug of Mbed TLS when handling ApplicationData records with empty Plaintext. In case such a record is received in a connection using a CBC-base cipher suite, Mbed TLS will currently incorrectly return 16 0xf bytes.
This would also explain why two AD records are sent, but Wireshark displays only one - Wireshark might be configured to drop empty AD records. Note also that any AD record of plaintext size < 16 bytes will lead to ciphertext length 36 bytes, consisting of 16 padded + encrypted bytes + 20 bytes of SHA-1 authentication (assuming that's what your ciphersuite uses for HMAC).
Could you confirm that you're using a CBC-based cipher suite? Does the problem persist of you switch to a non-CBC based suite? Finally, do you have a way of checking whether the server sends an empty AD record?
Hanno, Mbed TLS team member
From the Server Hello Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f) So it looks like your description matches what I'm seeing.
I changed to server to use ECDHE-RSA-AES256-GCM-SHA384 and now there is a single Application Data record in the reply and the mbedtls_ssl_read is returning 4 with the buffer containing the correct data,
Thanks for your help, Conor
that's good news, thanks for confirming!
Hanno, Mbed TLS team member