Skip to content
Client library for Teserakt's E4 solution, in C89
C Objective-C Other
Branch: develop
Clone or download
odeke-em and diagprov all: fix sizeof, spurious spaces before/after brackets
Automated find and replace in-place with:

* perl -pi -e 's/ \)/\)/' *
* perl -pi -e 's/\( /\(/' *

to make for more consistent code to improve

Also made consistent of invoking

instead of

    sizeof expr

Fixes #12
Latest commit 679372c Jan 8, 2020
Type Name Latest commit message Commit time
Failed to load latest commit information.
.githooks Githooks and very early readme. Mar 8, 2019
.github/workflows Quality assurance: enable github actions + sanitizers. Jan 7, 2020
scripts Quality assurance: enable github actions + sanitizers. Jan 7, 2020
src all: fix sizeof, spurious spaces before/after brackets Jan 9, 2020
test all: fix sizeof, spurious spaces before/after brackets Jan 9, 2020
.clang E4_ERROR_OK->E4_RESULT_OK Jul 11, 2019
.gitignore Remove KAT tools for the time being. Jan 7, 2020 Lowercase contributing .md Jan 6, 2020
LICENSE Fix license. Jan 7, 2020
Makefile Makefile to allow multiple configurations, inspired by BearSSL. Aug 15, 2019 Make debug prints truly debug-only Jan 8, 2020 Lowercase extensions. Jan 6, 2020
logo.png This commit tidies up a few issues: Jan 6, 2020

Teserakt AG



This repository provides the libe4 C library, a client library for Teserakt's E4, and end-to-end encryption and key management framework for MQTT and other publish-subscribe protocols.

libe4 defines a simple interface for encryption and decryption of messages.

  • int e4c_protect_message(uint8_t *ciphertext, size_t ciphertext_max_len, size_t *ciphertext_len, const uint8_t *message, size_t message_len, const char *topic_name, e4storage *storage, const uint32_t proto_opts); - this function takes a message to be protected and a "topic" for which it should be protected and returns ciphertext that can be sent using your messaging layer.
  • int e4c_unprotect_message(uint8_t *message, size_t message_max_len, size_t *message_len, const uint8_t *ciphertext, size_t ciphertext_len, const char *topic_name, e4storage *storage, const uint32_t proto_opts); This function performs the reverse of the protect function.

We talk of message protection instead of just encryption because the protection operation includes also authentication and replay defense.

E4's server (C2) is necessary to send control messages and manage a fleet of clients through GUIs, APIs, and automation components. The server can for example deploy key rotation policies, grant and revoke rights, and enable forward secrecy.

Please contact us to request access to a private instance of the server, or test the limited public version. Without the C2 server, the E4 client library can be used to protect messages using static keys, manually managed.

When to use

This code implements the same protocol as e4go. If you are using a system that can support projects written in Golang, you may prefer to benefit from the security and reliability of the language instead of using C code.

This project is aimed at cases that have very small memory footprints, cannot tolerate stop-the-world garbage collection (i.e. realtime applications) or cannot run Golang code.


libe4 is designed only to include those components that are necessary for a given mode to run. In particular, for low end devices using only symmetric encryption, public key variants of the code should not be used.

libe4 can be compiled as follows:

CONF=symkey make

This will output, into the build/symkey folder, a directory structure as follows:

├── include
│   └── e4
│       ├── crypto
│       │   ├── aes256enc.h
│       │   ├── aes_siv.h
│       │   ├── curve25519.h
│       │   ├── ed25519.h
│       │   ├── fixedint.h
│       │   ├── selftest.h
│       │   ├── sha3.h
│       │   ├── sha512.h
│       │   └── xed25519.h
│       ├── e4.h
│       ├── inline.h
│       ├── internal
│       │   ├── e4c_pk_store_file.h
│       │   └── e4c_store_file.h
│       ├── pstdint.h
│       ├── stdint.h
│       ├── strlcpy.h
│       └── util.h
├── lib
│   └── libe4.a

Tests can be built with the following command:

CONF=symkey make testbuild

and the following command will build and execute tests in one pass

CONF=symkey make test

Users who wish to build the pubkey variant should run:

CONF=pubkey make

and where needed make test. Output in this case will be in build/pubkey.



Once compiled, libe4 can be integrated into your application as follows:

  • You should add build/mode/include to your include path, e.g. -I$(E4DIR)/build/symkey/include.
  • You should link with the static library.

You may then use e4 in your code with the include:

#include "e4/e4.h"


libe4 is designed to be used in environments that may not include any kind of runtime or kernel. As a consequence, implementing persistent storage will depend entirely on the capabilities of the hardware environment.

To overcome this, libe4 provides a e4storage struct and corresponding set of functions that are forward-declared in e4.h. It also provides a demonstration "file store" for both variants, and a "memory store" that is not persistent.

The file store is enabled by default. To configure it explicitly, run:

CONF=symkey STORE=file make

To select memory storage, run

CONF=pubkey STORE=mem make

(this is also using public keys).

Alternatively, you may implement the storage APIs yourself. These are described in e4.h. If you do this, be sure to pass

CONF=... STORE=none make


libe4 currently makes zero effort to be thread-safe and function calls are not reentrant. This is because we wish to have zero dependencies on APIs that provide this functionality and we have no knowledge of the target CPU architecture.


libe4 respects environment variables such as CC. You may therefore, for example, cross compile for arm using something like:

CC=clang LD=clang \
E4_CFLAGS="--target=armv7m-linux-eabi" \
E4_LDFLAGS="--target=armv7m-linux-eabi" CSTD=c89 \
CC=clang LD=clang CONF=pubkey make

Or an appropriate way to target your cross compiler.

For the moment, Arduino and Android cross compile makefiles are in beta, but will be published publicly as soon as they are ready (they require a more complicated and specific use of make).


Before contributing, please read our CONTRIBUTING guide.


To report a security vulnerability (or potential vulnerability where private discussion is preferred) see SECURITY.

Intellectual Property

libe4 is copyright (c) Teserakt AG 2018-2020, and released under Apache 2.0 License, (see LICENSE). Portions are copyright other authors and licensed differently, please see OPENSOURCE.

You can’t perform that action at this time.