One of my goal of the past months was to use an STM32 Nucleo board to get a webpage through HTTPS, using an Ethernet shield for TCP/IP stack. I was close last time, but I discovered that my Nucleo-F103RB did not have enough RAM. Now I have my hands on a Nucleo-F411RE that has 128KiB of RAM and 512KiB of Flash, and I was finally able to do it.
The hardware is composed of:
- STM32F411RE microcontroller
- SPI master to communicate with other chips
- USART serial port with STLink USB connection for standard I/O
- JTAG with STLink USB connection to flash program
- Ethernet shield
- Wiznet W5100 that implements the TCP/IP and UDP/IP stacks.
- SPI connection to the board below.
The software that I uploaded on board is composed of:
- Low-level drivers provided by libopencm3
- W5100 SPI driver to expose the chip registers and memories.
- Socket API: POSIX socket library developed by me on top of W5100 functionality.
- USART minimal driver to write/read from serial port through the STLink USB connection on the Nucleo.
- DNS: I developed a minimal implementation of getaddrinfo() to retrieve the IP address of a website from its name.
- TLS: I used mbedTLS 2.2.0 for the Transport Layer Security 1.2
- The certificate of the CA, that is embedded statically as a binary blob into the program (I used Chrome to download it beforehand).
- The application is simply an HTTP GET request.
The tools I used to build the software are:
- GCC ARM Embedded toolchain (version 4.9 2015q1) to compile and link the code,
- OpenOCD (version 0.9.0) to write the software image into the STM32 embedded flash,
- Chrome to download the CA certificate,
- minicom to connect with the serial port
- All on my Debian (Stretch) Linux box
To build and run:
gitcheckout my nucleo_tests repo (now at commit eb2cc1942618f745286028c3cc591012b92d56bc).
- Go in
libopencm3directory and run “
make” to compile the low-level drivers.
- Download mbedTLS 2.2.0 and unpack it in nucleo_tests directory.
- Open “
nucleo_tests/tests/test.mk“, comment the stm32f103rb line and uncomment the stm32f411re line.
- Go in “
nucleo_tests/tests/mbedtls” directory and run “
make” to build both the mbedTLS library and the application.
- Connect the Nucleo board + Ethernet shield to the PC with USB, and connect the Ethernet cable.
- In another terminal run “
minicom -b 57600 -D /dev/ttyACM0” to connect to the serial port.
- Run “
make flash” to write the program into the STM32 embedded flash (uses
- Wait for the Link LED on the Ethernet shield to turn on.
- Go in the minicom terminal, and you should see a prompt; press a key to continue.
- The terminal should print the page that has been retrieved through HTTPS.
This is the output I get from the serial port:
Press any key to continue... Certificate: cert. version : 3 serial number : 02:0B:70:F4:68:67:1E:47:13:96:63:3D:99:2C:E5:CD issuer name : C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA subject name : C=US, ST=Cali HTTP/1.1 200 OK Server: nginx Date: Thu, 04 Feb 2016 20:41:12 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Last-Modified: Mon, 09 Nov 2015 23:59:43 GMT ETag: "687f8a-bd-52424631079c0" Cache-Control: max-age=1209600 Expires: Wed, 10 Feb 2016 15:34:38 GMT Vary: Accept-Encoding X-Varnish: 324309826 304737767 Age: 709594 Via: 1.1 varnish Strict-Transport-Security: max-age=31536000; includeSubdomains X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN bd <html> <head> <title>Site Under Maintenance</title> </head> <body> <h1>This site is currently under maintenance. Please try back later.</h1> </body> </html> 0
To conclude, this proof of concept shows a very small platform that can be used to build IoT applications with a layer of security. Instead of having an application processor running Linux, we have a microcontroller running at a frequency as low as 16MHz, the base software is around 90KiB of code running in flash, and needs around 50KiB of RAM, between static and dynamic memory. We are using a security layer that doesn’t invent anything new: it’s an implementation of the widely used TLS.