In order to apply bearSSL in the project, the first thing I need to do is to include the bearSSL library object. The source code is available as a git repository, simply type “git clone https://www.bearssl.org/git/BearSSL” in a terminal to download the newest version of bearSSL. Apart from this, the git will keep track of the released version of bearSSL so that you can stay updated with the latest release easily, I am again amazed by how powerful the git is.
The author of bearSSL — Thomas Pornin has provided the tools to compile the source code into library project for general environment like Unix, Mac, Windows, etc. But since our project is on PIC32, I will need to configure the makefile to use the appropriate compiler so that it can run in PIC32. Hence I create a library project in MPLAB-X_IDE, choose the correct device (PIC32MZ2048EFG064) and compiler, then include the bearSSL source code and build the project. A “*.a” library file will be generated, add the library file into the board project and include the header file that contains the functions declarations (provided in BearSSL/inc) then there you have it. If I want to edit the source code I can just do so in the library project and build it again, nothing needs to be changed in the board project. Most of the bearSSL function is written in an independent .c file and each is compiled into a .o object file so that in the linking process, only the required function will be linked and leave the others aside. This is the advantage of using a library, you don’t need to worry about the memory space it takes to include a huge library just for a fraction of its functionalities as the unused part of the code won’t be programmed into the device.
After studying the sample provided by bearSSL in server_basic.c , there are a few things I need to get it work:
i) The server certificate and key. BearSSL has provided the tools to generate the C code of the certificate and key in the arrangement it needs. Type ./brssl chain “OPTION” “FILE” and ./brssl skey “OPTION” “FILE” to generate them respectively, both certificate file and key file need to be in .pem format. Copy the C code, paste it in a header file and include it in the project.
ii) A server context with type “br_ssl_server_context” that contains the certificate and key. Set up the server context with br_ssl_server_init_”method” depends on the supported encryption method.
iii) The I/O buffer large enough for bearSSL to process a full 16kbyte SSL and the overhead alongside (maximum 325byte) records since we could not negotiate the record size from the server side. The total size is 16709 bytes for a half-duplex mode (Input and output share the same buffer) or 33178 bytes for full-duplex mode.
iv) The low level read and write function of tcp/ip stack module to interface with bearSSL so that bearSSL can interact with the tcp transportation layer to receive and send the packages. I need a wrapper to get the recv() and send() function of Berkeley module to suit the structure of the callback function that bearSSL needs. The call back function is set through a call of function br_sslio_init(&ioc, &sc.eng, low_read, &cfd, low_write, &cfd);
On the Berkeley socket side, before starting the SSL handshake there are a few things to set up:
i) Create a new socket: socket();
ii) Bind the socket with the IP address: bind();
iii) Get to socket to listen on a certain port: listen();
iv) Create a new socket after receiving a client request associated with that client: accept();
v) Pass the accepted socket to bearSSL by br_sslio_init();
After these are done, I tried to run the project, it fails (not surprisingly), the server would not reply a client hello. After looking into the source code, br_ssl_server_reset() return failure because the entropy, which is needed by bearSSL to achieve cryptographic resistance, is not provided by the operating system, yet bearSSL assume it would. Thus, I include the crypto library of harmony to generate the entropy with Random Number Generator by function CRYPT_RNG_BlockGenerate();. Then, inject the entropy into bearSSL engine by function br_ssl_engine_inject_entropy();. Now, the project gets into a compilation error “undefined reference to `_CP0_GET_COUNT'”. After searching online, I found that other people have this problem as well, it is a bug started on Harmony v2.02 and not yet resolved (we are now on Harmony v2.05). Fortunate enough it is not a huge issue, it is just the Harmony generated code did not include the necessary header file at the right place, hence I get into the Harmony generated code and fix that problem.
Running the project again, br_ssl_server_reset() return success, it worked. Yet, the server still does not respond to the client hello. To be honest, it is very difficult to debug a project that had very few documentation available for a newbie like me, since bearSSL is still in its alpha stage yet I want to apply it in another platform. But as Dr. Shawn said, “If you want to work on embedded computing, this is what you will face, one platform or another”. Surely I have underestimated the difficulties of embedded computing, but yeah, challenge accepted.