During my research about the TrustZone® security extension over the last weeks I’ve had the HeartBleed exploit from 2014 in my mind. How would TrustZone® help us manage that type of ‘no bounds check’ exploit? Of course, TrustZone® was first widely available when NXP introduced the Cortex® M33 family LPC55S69 in 1Q2019 and wasn’t available back in 2014, but I wanted to put it to the test.
HeartBleed was a very-widely publicised security vulnerability in the Heart-beat extension to the TLS and DTLS protocol that affected OpenSSL. Disclosed in April 2014, the bug allowed data to leak from any server or client running TLS/DTLS, potentially disclosing valuable security information. Since OpenSSL had such a large installed user-base in many internet applications, the vulnerability had a potential global impact. I remember the extensive coverage of the exploit on tech blogs, forums and even the mainstream media such as (here in UK) the BBC.
You’ll find many articles on HeartBleed published online, for example here and here (it is ironic that the website http://www.heartbleed.com does not support https). I provide a 2-minute overview in my video on the YouTube embeddedpro channel, but let me give a quick synopsis here.
A client and a server can establish a secure communication channel over an IP connection using the TLS or DTLS protocols. The channel is guarded with timeouts, and so if the server takes too long to respond, or the human client goes off to brew coffee whilst in an online banking session, the channel will time out. That is a very good thing. However some of the computation required in the D/TLS protocols can be challenging for the client and so a HeartBeat extension was introduced in 2012 as RFC6520. This permitted either the server or the client to send a simple message over the link as a ‘keep alive’ signal. Sent at regular intervals, the extension was known as the D/TLS Heart-beat.
Technically, the Heart-beat message is formatted as an ascii string, and the string-length. It would typically be sent by the client to the server. Then the message is echoed by the server.
The Heartbleed vulnerability works by exploiting the bad programming in OpenSSL 1.0.1. The message contains both the string, and a 16-bit integer of the string length. We can argue about why the message needs to contain the string length (it is very easy to the server to calculate the string length…. strlen() ??? … ) but the important topic is that the server did not actually test the bounds for the integer. In the diagram above, the message contains the string ‘hello’ and the input parameter 255. Heart-beat extension in OpenSSL 1.0.1 would reply, not with the string ‘hello’ but with the string hello and the 250 bytes after the string. That’s just a programming error, but of course in a security application, it has the potential to leak valuable security information back to the client: ‘B4dP455w0rd‘ in this example.
In this week’s video I demonstrate a HeartBleed simulator that I wrote in MCUXpresso IDE and ran on LPC55S69-EVK. I needed to write some bad software that received an input string (asdfghjkl) and the incorrect string length 64. The example performs a conversion to upper case, and then returns the requested number of characters. The software does not do any bounds checks (just like Heartbleed) and responds with 64 bytes off the stack. As you can see, the function reveals the text from the previous heartbeat, and also other, non-ascii data.
OK, TrustZone® to the rescue.
No. Sorry to deliver the bad news but TrustZone® does NOT help with this type of missing bounds-check. In fact, it is possible for TrustZone® to make the problem worse. Yes, really. If you consider the problem, you’d want to put all of the security library into Secure memory, and execute it with the M33 core in the secure state. The secure state has its own stack and this is not accessible in the non-secure state. But of course that secure stack is going to contain – by definition – secure information. Heartbleed – with the code running in the secure state – is more likely to return valuable information in this situation because the stack contains security material.
TrustZone® could help us… but only if we were smart enough to put the Heartbeat extension into non-secure memory and execute it in the non-secure state. That way, our bad programming would leak bytes from the non-secure stack and not from the secure stack.
There are two problems with this:
- I don’t believe that anyone would think sufficiently and place the heartbeat code in non-secure memory. “Oh, it’s SSL and goes into the secure world“…
- And secondly, the scenario still allows us to write bad software.
It is not the job of TrustZone® to compensate for our bad programming.
TrustZone® brings us many features to support a security use-case. For example, ARM introduced the Test Target (TT) instruction. This takes an address and converts it into the region number assigned in the Security Attribution Unit (SAU) and so programmatically we can test an input pointer and determine if it is in secure, non-secure or non-secure callable memory. But don’t forget to test the end of the address range and confirm that this is in the same region, otherwise the pointer may actually cross from non-secure memory into secure memory. By including the header arm_cmse.h in the project, we can then use the intrinsic cmse_TT(void *p).
And the CMSE standard defines that the internal core registers are zeroed out at the return from a secure function. This prevents any information leakage from the secure to the non-secure world. But if we write bad software (for example forget to test input pointers, assume that strings are null-terminated, don’t perform bounds check on input parameters etc etc) then our code is vulnerable to attack.
I feel so passionately about TrustZone® vs our bad programming practice that I added a ‘Head-shot’ to this weeks video – so I speak to camera for the first time in these videos. So if you’ve wondered what I look like, then watch the video!
I should close with the comments that the HeartBleed exploit was fixed in April 2014 (the day that the exploit was published) in version OpenSSL 1.0.1g and that MCUXpresso SDK contains the optional component mbedTLS. mbedTLS does not support the D/TLS Heartbeat extension and was not, and is not susceptible to the HeartBleed exploit.
Next week I’ll move away from TrustZone® and get back to details about the LPC55S69. I’m going to investigate the ROM APIs in LPC55S69 and in particular, the In-System Programming (ISP) functionality with blhost.exe.
See you next time!