Getting mbedTLS to work with your Keil project
This is post 6 of the series/tutorial. In case you have not gone through the other posts, you can do so now.
In the previous post (post #5), we added mbedTLS to the project and agreed that we would follow the sample that comes with the mbedTLS pack. If you followed everything correctly you should see an output such as the one below. There are several additional steps but I discuss them below the dump.
You realize we are having secure communication because the HTTP request was served on HTTPS (port 443). You can try with as many other sites as you like. Unfortunately, some will fail because of memory requirements enforced by the servers. Such as google.com (in my case). Such issues I will leave for you to sort out. In this post let us look at a few elements of code that if you fail to set up correctly, will result in failure. In case I do not get to handle one of interest to you, feel free to reach me in the comments section or via email.
Memory Allocations
The TLS protocol involves negotiation between the server and the client. We cannot decide the algorithms used for secure communication in advance, because we do not know which ones the server support and if they will be supported forever. As such, mbedTLS (and similar libraries) do a lot of runtime memory allocations. The malloc
, calloc
and free
functions are used. This memory required will not show up when you build. In fact, when I build I get Program Size: Code=226812 RO-data=68688 RW-data=352 ZI-data=108764 but the real used RAM is more. The processors I have been using for this tutorial (LPC4337) has three memory regions for RAM as per the datasheet.
Add these sections in your project configuration dialog in Keil as shown below and in commit 4d07dfa
These memory allocations done at runtime are drawn from a heap that needs to be configured in the assembler or linker file. By default, Keil adds a heap size of the size 0x400 (1kB). For the TLS client to work, I increased the heap to 0x0001 0000 (64kB). See commit 40cd137. If the memory configuration is not done, you will probably see an error message saying “Not enough memory …” for each symbol that could not fit in the allocated memory.
Note: If you are using an STM32F2/3/4 micro-controller, the RAM is normally in one place and you need not make any changes in the project configuration dialog but only in the startup file (assembly).
STACK CONFIGURATION
The TLS library makes most of its decision at runtime meaning that you cannot determine the specific size of the stack. If we were not running an RTOS, we’d need to change the stack size in the startup file from the default 0x200. In the repo we are using, we had already setup Keil RTX which is an RTOS. I created a separate thread to handle the TLS sample. I could have used the existing communication thread but I wanted to separate them for anyone looking specifically for the PPP communication in the previous posts. The TLS thread, as shown in commit 38d6897, has a 6kB stack size. I decided this out of trial and error and observing the OS Support window in Keil that would show you stack usage and when there is an overflow.
TESTING TLS CLIENT OR LIBRARY
To do the testing of TLS I switched from accessing the internet via PPP as per previous posts to using Ethernet because it is way faster. (I explained why in post #5). At the same time, the initialization of the network stack needs to be done once and as such you will see the use of compiler directives (commit 6619b07). The network stack is initialized by mbedTLS in a file named net.c yet the stack does not allow calling the initialize function more than once.
At this point, your output should be the same as the one dumped at the beginning of this post.
NOTES
- Take caution of the pins used for ethernet in case you are using a different board from the one I am using. I used the RMII interface whose pins are configured in RTE_Device.h
- The X.509 issue in the log will be solved in the next post here