Hazelnet 3.0.0
Reference implementation of the CAN Bus Security (CBS) protocol
|
Hazelnet implements the Client and Server roles of the CAN Bus Security (CBS) protocol, which secures the CAN FD traffic providing encryption, authenticity, and freshness of the messages.
The user of the library must handle the physical transmission and reception manually as this library only handles the building of messages to transmit and processing of received messages. This is done to guarantee better portability across systems. The internal library state keeps track of ongoing handshakes, timeouts and other events per each Group.
The library uses standard C11 code and is hardware-independent. The compile targets for a desktop OS add some features like heap memory allocation and use the time and TRNG functionality the OS provides. The any-platform version uses user-provided structs to operate on and requires the user to provide function pointers to custom timestamping and random-number-generators of the used platform; recommended for embedded systems.
Hazelnet depends on other projects from the same author:
The dependencies are included in this project as Git Submodules, so be sure to clone this repository with the --recurse-submodules
option.
You only need the C99/C11 standard library to compile the library for any platform, including embedded. No heap-allocation required (malloc).
stdint.h
stdbool.h
stddef.h
string.h
On the other hand, when compiling for a desktop OS, additional features are enabled. In particular configurations can be loaded from files, the library context is heap-allocated, and the OS provides the current time and true randomness.
stdlib.h
for heap-allocation (calloc)stdio.h
to access configuration filessysinfoapi.h
to get the current time in millisecondsbcrypt.h
to get random numberssys/time.h
to get the current time in millisecondsThe library is not thread safe. All API calls on the same context should be performed within the same thread (or RTOS task) or mutual exclusion locks should be placed by the library user around said API calls to protect the library from race conditions. For the time being, no thread-safe protections have been implemented as they are not easily portable.
inc
folder contains the public headers of the library.hzl.h
is a common header for both the Client and Server. You always need this.hzl_Client.h
and hzl_Server.h
are the API header of the Client and Server libraries (respectively) when compiled for any platform. Pick one of the two roles.hzl_ClientOs.h
and hzl_ServerOs.h
are extensions of the API for the Client and Server libraries (respectively) when compiled for desktop operating systems (assuming a file system and heap-memory allocation).src
folder contains the library sources:src/common
is code shared between Client and Serversrc/client
and src/server
folder contain sources for the respective Parties.c
files are generally named after the user-facing API function they implement.To use the client library, the following headers are required:
The usage is the same except compared to the desktop OS case, except for the Context init and deinit as it cannot necessarily happen on the heap or be loaded from a file. The user must prepare it manually:
The Server library has an analogous API to the Client, with the same interface when it comes to processing of the messages. The main difference is that the Server requires an additional configuration field in its context, namely the array of per-Client configurations.
To use the Server library, the following headers are required:
There are multiple valid ways of doing so. The project is CMake-enabled, so this should be the easiest way. For embedded systems where CMake is not an option, the project may be also compiled using any custom build system.
The dependencies are included in this project as Git Submodules, so be sure to clone this repository with the --recurse-submodules
option.
If you have already cloned the repo, but not the submodules, then run
In the project root folder, run the following to create an out-of-source build:
By default, an optimised-for-size release build is performed. To change it, append the -DCMAKE_BUILD_TYPE=Release
or Debug
to the cmake ..
command and build again.
You may already know this, which makes this section mostly a note for my future self. When compiling from the Windows command line using the MSVC toolchain:
"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe"
but yours may be different, especially for different VS versions. This is required if you already installed CMake through MSYS.hzl_client_any
, hzl_server_any
: Client- and Server-side static libraries for any platform, including embedded. No assumptions about the system, no heap memory, no files.hzl_client_desktop
, hzl_server_desktop
: Client- and Server-side static libraries for desktop operating systems, assuming malloc, a file system and using the OS-provided TRNG.hzl_client_desktop_shared
, hzl_server_desktop_shared
: like hzl_client_desktop
and hzl_server_desktop
but shared (dynamic) libraries.All other targets are internal dependencies or test targets: the user should not worry about them.
Include the following directories in the search path for header files (-Iinc
compiler option for GCC):
For the test suite, also add
Include the following directories in the search path for source files:
For the test suite, also add
tst/(client|server|interop)/hzl(Client|Server|Interop)Test_Main.c
file runs all tests, depending which set of tests you are compiling.You can run the test suite with ctest
:
or by directly executing the test runner executables:
To run the unit tests in an embedded environment, rename the main()
function of the test runners tst/(client|server)/hzl(Client|Server)Test_Main.c
into something else (e.g. runAllHazelnetTests()
), integrate it into your embedded firware and call it from your embedded project. The Atto framework assumes you have printf
available for the reports, but you can search-and-replace its instances with another function, if you prefer.
The interop
tests are meant for desktops only, because it does not make a lot of sense for an embedded device to make an interoperability test with itself.
Doxygen is build separately (not part of make all
) to avoid running it every time the library is recompiled during development: