Modifying the TLS library to encrypt over BLE

I am looking for resources to help adjust the sockets used in the mbedtls library to communicate over Bluetooth Low Energy. I haven’t been able to find any posts on the knowledge base addressing this topic, but there was one glimmer of hope on Stack Overflow hinting that it might be possible. Does anyone have any experience with this, or some other recommendations?

To preemptively answer the questions about “why not just do this using BLE standard protocols”: I have a use case where bonding is going to be prohibited, thus also prohibiting standard BLE encryption. I would also be open to other solutions that work with this limitation, assuming it does not require building my own crypto library.

Thanks in advance for any advice!

@mheida17 If I understand your requirement, you want to use TLS over BLE transport. Am I right?
TLS stands for Transport Layer Security, and can be used for any Transport Layer. This can be done with Mbed TLS! You only need to implement your own bio callbacks, and set them using mbedtls_ssl_set_bio().

Note that Mbed OS already has BLE enabled, and integrated, and has support for many platforms. Have you considered using Mbed OS?

I suggest you read the following articles:

There are other articles in the knowledge base that may interest you as well.
I hope this answers your question.

Regards,
Mbed TLS Team member
Ron

Hi Ron,

Thanks for the info. I still want to use the GATT as intended to write to meaningful attributes and avoid creating a “virtual serial port” over BLE.

If I am understanding the suggestion correctly, we would either need to (1) change the bio callbacks after the handshake has occurred to read/write to different attributes or (2) use an external means to modify the internal parameters of the mbedtls_ssl_send_t and mbedtls_ssl_recv_t callbacks to read/write to different attributes.

Is it recommended to call mbedtls_ssl_set_bio() after the handshake, or to modify the parameters of the mbedtls_ssl_send_t and mbedtls_ssl_recv_t callbacks with our own implementation?

Best Regards,
Matt

Hi Matt,

I am suggesting you set the bio prior to the handshake. The TLS negotiation and data transfer should be on the same transport. that is, if you wish to protect your data using TLS, and not the BLE defined cryptographic protocols.
I am not sure what you mean by `virtual serial port" over BLE. I am suggestion you write a wrapper code that will implement the callbacks, calling your BLE API and sockets.

Why do you wish to change the attributes of your callbacks after the handshake?
I may be missing something in your use case, but once you implement your callbacks using BLE, all TLS encrypted communication will be over those callbacks, using the Mbed TLS API.

Hi Ron,

I think I know what @mheida17 meant, because I am considering a similar solution. Normally TLS works over TCP stream and it requires TCP socket. In case of BLE we do not have such a stream and socket. We could implement a stream in a serial connection fashion, a custom and simple implementation of Serial Port Profile for BLE that would use one GATT characteristic to exchange data between server and client, server would send data to client via notification and client would just write to that characteristic (check this example). However that solution means that we cannot make use of structure provided by GATT and expose some individual values as separate characteristics, i.e. one characteristic for CPU temperature, one for fan speed etc.

Alternative solution to the virtual serial (custom SPP) with TLS would be to encrypt each characteristic separately (whenever client wants to read it or write it). So first we would need to do TLS handshake using some special GATT characteristic and then encrypt values of other characteristics. Can Mbed TLS be used for that? Check how this application layer security example uses Mbed TLS, unfortunately there is no handshake with authentication.

Second question - do you see any problem with that approach of TLS over SPP as described in the linked example? Note that they do not use application layer (GATT) acknowledgments, instead they rely on lower BT layers to guarantee delivery.

Regards
Marcin

Hi @mass85

I wouldn’t say normally. the better term is Usually. Once of the reasons TLS was changed from SSL, is because it is not used only as Secure Socket Layer, but it is intended as Transport Layer Security. This means, it can be used to protect any Transport Layer, including BLE. You will just need to replace the bio callbacks as described here.

Regards

Hi @mheida17. I am looking for the similar solution. I wanted to introduce DTLS handshake between two BLE devices. I also wanted to use the GATT server as a DTLS tunnel for BLE. I am stuck at setting up the mbedtls_set_bio() call backs. I don’t know exactly how can I set up the read and write call backs. Have you figured out any solution, it will be a great help.

Thanks in advance.

Regards,
Prasanna

In order to do that, you need to handle the bio functions. These functions has to read or write into some buffers which are sent or updated with received data from BLE. Is not an easy task, but I managed to do it, with DTLS.

Think about how the sockets works in a OS. mbledtls expect data to be written and received from sockets. If you implemented the sockets over BLE, you’d be able to make it work.

For TLS (not DTLS) you need reliability. If you assure the data is received by endpoints and it’s received in order, TLS can be implemented as well. But, I’d go with DTLS as it handles retransmissions, packet order and so on. It’s easier to implement.