pbTLS  1.1
pbTLS Documentation

This document describes the pbTLS API that has been carefully designed and implemented.
In our Demo "S" (STMicro) and Demo "A" (Atmel) we use the WIZnet W5500 chip for the hardware TCP Socket functions and Ethernet I/F.
Other Network layer or field bus systems can be used and TLS enabled with pbTLS as well, but here TCP/IP and Ethernet is used in the Demo.


Due to the overall complexity of the TLS protocol on the one hand and fairly limited resources of the ARM Cortex M0 to M7 platform on the other hand, this implementation is as efficient and specialized as possible while still fulfilling minimum requirements of the TLS specification.

This library currently implements version 1.2 of TLS as proposed in RFC 5246. http://tools.ietf.org/html/rfc5246
Please note that for security and efficiency reasons backward compatibility with former versions of TLS or SSL have not been implemented. This however can be done upon request if need be.
The software module only use the required cryptographic primitives such as AES, SHA256, ECC or RSA to keep the code size to a minimum. Since there are known vulnerabilities of the underlying cryptographic primitives, special care has been taken to devise appropriate countermeasures, some of them unique to the implementation in question, i.e. specifically designed with a trade-off between security and efficiency.
RFC 5246 states that a TLS-compliant application must implement at least the cipher suite TLS_RSA_WITH_AES_128_CBC_SHA. For security reasons it has been decided to have TLS_RSA_WITH_AES_256_CBC_SHA256 as the default cipher suite of choice for the implementation in question, whose flexible design however allow future modifications with respect to integration of further cipher suites.
In order to keep the code size to a minimum as well as to increase the overall security the implementation shall support TLS version 1.2 only.
For the sake of simplicity and efficiency, the software module include the necessary X509v3 server certificate, i.e. binary representation thereof in its code as opposed to storing and reading such data from file. This design aspect in particular or any other aspects in general (including reasonable extensions) are subject to change in future releases if so demanded by WIZnet or its customers.
Since this library has been thoroughly tested against a well-known SSL/TLS implementation PolarSSL v1.2.0 - v1.2.5, this version of the TLS library ships with test certificates used by PolarSSL for testing purposes only! Real-life applications require real certificates that every customer can order when buying pbTLS enabled devices or module. For more information see Certificate.

Technical Challenge

Implementing TLS on or for embedded devices turned out to be quite challenging due to its complexity and requirements with respect to system resources. For example, RFC 5246 states that the TLS layer fragments information blocks into records carrying data in chunks of up to 214 bytes. Consequently, the implementation must have access to sufficient memory resources in order to support this requirement which is the case when working on regular PC platforms. Thus, our reference implementation is currently capable of processing records with the maximum size. Therefore, special care had to be taken during porting this code to the ARM Cortex M platform. In practice such sizes are however rarely used, which means that a possible compromise solution would eventually lead to a certain reduction of the maximum record size on the target platform in order to accommodate limited RAM resources. In fact, our current reference implementation already contains highly specialized routines for dynamic memory allocation. These functions ensure that the module starts operating with internal buffers set to their minimum sizes. During the following tasks that implement the TLS state machine for both the handshake part and the application data layer, memory may be requested on demand. In other words, if a peer decides to send larger TLS records, such behavior is recognized with the help of look-ahead reading logic resulting in increasing the size of the internal record buffer. Once a subsequent read or write operation has been successfully carried out, dynamic memory allocation routines release any additional memory reconfiguring the buffer to its default (minimum) size. The application logic described above is limited by available memory only. As a matter of fact, a connection may terminate if internal memory allocation routines detect a shortage of system resources.
Note on dynamic memory allocation
Since the library carries all corresponding certificates as pre-coded binary arrays, stack usage is fairly high. Heap is used for dynamic memory mostly to hold the TLS record buffer.
More info will follow.
Another technical challenge was introduced by parts of TLS that rely on asymmetric cryptography such as the key exchange during handshake. Current version of TLSLib implements this part with the help of RSA encryption, 2048 bits. As a matter of fact, symmetric algorithms are roughly 1000 times faster than traditional asymmetric ones, including RSA. On our limited ARM Cortex M3 or M4 reference platform the most demanding is RSA decryption. This algorithm need 350ms on the 168 MHz Cortex M3/M4.

Certificate Handling

For the sake of simplicity and efficiency all certificates required to operate TLS are stored by the users application and referred to by pointers. e.g. can be placed inside files of the application or written into the MCUs Flash memory by ISP or programming tool. The pbTLS engine is called with pointers to the certficates. Following certificates will be generally used throughout any TLS session.

  • server_cert RSA 2048 bits (or ECC) server certificate that will be presented as a part of the certificate chain sent to every client to initiate a TLS handshake.
  • ca_cert RSA 2048 bits (or ECC) root CA certificate that will also be presented to all clients to prove the authenticity of the server certificate. The server certificate has been issued and digitally signed by this certificate, i.e. by the corresponding secret key of the root CA.
  • client_cert RSA 2048 bits (or ECC) client certificate used in client mode only. Generally, TLS servers may or may not request client verification which in client mode is automatically detected. Should a server ask the client to prove its identity the client may or may not decide to oblige by sending his own certificate to the server. It is up to the server then to decide, what to do if the client refused to present his certificate. Since most implementations would certainly terminate connection at this point, TLSLib automatically sends the pre-coded client certificate to satisfy the server's request. This behaviour has been tested with both PolarSSL TLS v1.2 server and TLS 1.2 Testing , the latter being one of the few publicly available implementations of TLS v1.2 for testing purposes.


Certificates are normally BASE64 encoded. Therefore, in order to retrieve the byte array (HEX) representation, you can manually BASE64 decode the input
For conversion of BASE64 to HEX you can use this online tool: BASE64-to-HEX

HOWTO: In order to retrieve a C-style array from a binary file, open it in Notepad++ (this will usually be a CRT file containing both the text representation of the certificate in question and its binary counterpart which is also BASE64 encoded), select the portion between the BEGIN and END CERTIFICATE tags and copy it to a new temporary file or buffer.
use openssl command line like this:
$ openssl x509 -in server_rsa_cert.cert -text
copy the BASE64part here.
Now decode the BASE64 encoded block e.g. with BASE64-to-HEX and open the result in HEX or TXT editor. Finally run replace (Ctrl H) on the block and replace all space by ",0x" so the result look like:
0x30,0x82,0x03,0x37,0x30,0x82, ....
This can be used as a C Array of Bytes.


Retrieving RSA parameters such as the private key, i.e. private exponent and public modulus are more tricky than handling certificates as described above.

The key is normally stored in a base64 coded PEM file. Reading its values is best done with openssl:
openssl rsa -in mykey.pem -noout -modulus
openssl rsa -in mykey.pem -noout -text
shows all parameters of the private key, such as modus, privateExponent, publicExponent, prime1 .. exponent1 .. for instance.

Here is how the corresponding ASN.1 syntax has to be interpreted:
read & write RSA keys

software crypto
the TLSEngine() parameter for the private key expect a string (e.g. RSA2048 is 640 Byte long) as an array of Byte concatenated prime1 + prime2 + exponent1 + exponent2 + coefficient (without the leading 0x00).
Sometimes the modulus can be one byte longer than it is actually supposed to be.
Here is why:
Be careful that your MPIs all have the first bit set to 0, though! OpenSSH appears to treat the MPIs as a two's-complement signed representation, so if your first bit is a 1, ssh will think you're trying to provide a negative value. If your calculations produce a number with the high bit set to 1, just increase the length by another byte and pad the beginning with 0x00 to keep it positive.
(this is why the modulus above is 257 bytes starting with 0x00,0xC4 instead of 256 starting with 0xc4,0x68).
=> In such a case simply skip the leading zero when storing the modulus in a byte array!
for eWBM hardware crypto - new in 1.1
For using the hardware crypto RSA provided in the MS500 the private key (RSA2048) is expected as a string (array) of 256 Bytes.
Here only the 256 bytes from privateExponent (without the leading 0x00) is needed and used.

crypto Key Sizes / Cryptographic Parameters

When it comes to working with what is called cryptographic primitives, TLSLib relies on another very efficient library which in turn implements algorithms such as RSA for instance. Because there is always a trade-off between efficiency and functionality, this library makes use of conditional compilation which on the one hand is rather static because parts of the code are simply omitted or replaced by different parts based on how conditional variables have been set. On the other hand however, conditional compilation saves quite a considerable amount of unused and thus unnecessary portions of source code which allows for producing lean and highly specialised binary applications. That is why current version of TLSLib can only be used with cipher suites based on RSA 2048 bits on the asymmetric part as well as AES 256 bits on the symmetric front. This modular structure of the library allows for future implementations of additional cipher suites based on different cryptographic primitives, if need be. Customers may then consider acquiring new functionality by simply buying corresponding binary modules.

Instructions for Use

The entire library consists of only four consecutive functions, which makes it even easier to handle it from high level applications. The following graph demonstrates a typical TLSLib state machine.

State nodes bearing function names are clickable and therefore reference the respective function.

For detailed instructions for use see TLSLIB.h

echo engine example = https Demo

In our https demo "echo machine" we answer a client (browser) request with a small static web page hard encoded in our demo firmware source code. The structure of that demo is very simple because of the fully encapsulated TLS handshake within the pbTLS library.



For testing purposes this version of TLSLib has been compiled with activated debugging output which is based on printf() implemented by the Standard Library. This output is sent to the COM port of STM32 or ATSAM MCU which can be read on the serial console with the help of third-party applications such as PuTTY for instance.

Since this version of the library generates a lot of data, consider specifying a log file name when using PuTTY to create an offline copy of the session.
Witali Bartsch & Joachim Wuelbeck, Steen Harbach AG


2016-9: version 1.0 with software library only
2017-6: version 1.1 with support for eWBM hardware crypto, and one additional feature + parameter for TLSEngine.