Cifra

Cifra is a collection of cryptographic primitives targeted at embedded use.

Build Status

Documentation

Analysis Status

Coverage Status

Aims

In order of descending emphasis, cifra aims for:

  • Clarity and simplicity.
  • Countermeasures for side channel leaks inherent in some algorithms.
  • Suitability for embedded use. Particularly: cifra uses an absolute minimum of the standard C library and is reasonably efficient with respect to code and data space.

Features

  • AES in the GCM, CCM, EAX and OCB authenticated encryption modes.
  • NORX authenticated encryption system.
  • SHA224, SHA256, SHA384 and SHA512 hash functions (including HMAC and PBKDF2).
  • SHA3-224, SHA3-256, SHA3-384, SHA3-512 hash functions (FIPS 202 compatible).
  • ChaCha20 and Salsa20 stream ciphers.
  • Poly1305 one time MAC.
  • 100% code coverage by line, zero static analysis defects, valgrind-clean.

Additionally cifra imports curve25519 from elsewhere (μNaCl, NaCl, tweetNaCl, Adam Langley's curve25519-donna) for comparison between various implementations on embedded targets.

Documentation

Available at Read the Docs.

Testing

There is quite a lot of testing available:

  • Host builds: run make test in the src directory. This builds and runs assorted test programs.
  • Emulated embedded builds: run make test in the src/arm directory. This expects to find qemu-system-gnuarmeclipse on the path. These tests assume a Cortex-M3 target.
  • Cortex-M0 on-target tests: run make test.stm32f0 in the src/arm directory. This expects to find openocd on the path, with an STM32F0xx attached via stlinkv2. It uses ARM semihosting to report results.
  • Cortex-M3/4 on-target tests: run make test.stm32f1 or make test.stm32f3 as above.

Additionally all embedded targets expect to find the arm-none-eabi toolchain to be on the path.

Measurements

All measurements performed at -Os (optimise for space), on the following MCUs:

CorePart numberPrice (1s)Max clockFlashSRAM
Cortex-M0STM32F030F4P61.17EUR48MHz16KB4KB
Cortex-M3STM32F103C8T62.87EUR72MHz64KB20KB
Cortex-M4FSTM32F303K6T64.53EUR72MHz32KB12KB

More measurements are available for AEAD modes on my blog post: Benchmarking Modern Authenticated Encryption on €1 devices.

AES

This test does a key schedule, then encrypts one block.

128-bit key

CoreCycles (key schedule + block)Cycles (key schedule)Cycles (block)StackCode size
Cortex-M0715621475009312B1020B
Cortex-M3469215913101300B960B
Cortex-M4F459115713020300B960B

256-bit key

CoreCycles (key schedule + block)Cycles (key schedule)Cycles (block)StackCode size
Cortex-M01061136506961396B1100B
Cortex-M3673524504285380B1048B
Cortex-M4F658824164172380B1048B

AES128-GCM

This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data. It includes the initial key schedule.

CoreCyclesStackCode size
Cortex-M057022796B2600B
Cortex-M344306812B2644B
Cortex-M4F43657812B2644B

AES128-EAX

This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data. It includes the initial key schedule.

CoreCyclesStackCode size
Cortex-M050564932B2836B
Cortex-M332855932B2780B
Cortex-M4F32159932B2780B

AES128-CCM

This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data. It includes the initial key schedule.

CoreCyclesStackCode size
Cortex-M037677772B2280B
Cortex-M324462780B2256B
Cortex-M4F23949780B2256B

NORX32

This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data.

CoreCyclesStackCode size
Cortex-M010692320B1636B
Cortex-M36909320B1820B
Cortex-M4F6855320B1820B

ChaCha20

This test encrypts a 64 byte message.

CoreCyclesStackCode size
Cortex-M05981564B1416B
Cortex-M33487544B1328B
Cortex-M4F3468544B1328B

(For comparison with AES, add an AES256 key schedule plus 4 blocks. That's about 33K cycles.)

Salsa20

This test encrypts a 64 byte message.

CoreCyclesStackCode size
Cortex-M06173560B1412B
Cortex-M33320552B1272B
Cortex-M4F3311552B1272B

SHA256

This test hashes the empty string (one compression function invocation).

CoreCyclesStackCode size
Cortex-M011561312B1760B
Cortex-M36530300B1708B
Cortex-M4F6278300B1708B

SHA512

This test hashes the empty string (one compression function invocation).

CoreCyclesStackCode size
Cortex-M038447796B2888B
Cortex-M328771836B2988B
Cortex-M4F28777836B2980B

SHA3-256

This test hashes the empty string (one sponge permutation).

CoreCyclesStackCode size
Cortex-M093648848B2212B
Cortex-M374321856B2164B
Cortex-M4F72215856B2140B

SHA3-512

This test hashes the empty string (one sponge permutation).

CoreCyclesStackCode size
Cortex-M092565880B2212B
Cortex-M373509888B2164B
Cortex-M4F71419888B2140B

HMAC-SHA256

This test computes a MAC with a 32 byte key over the message “hello world”.

CoreCyclesStackCode size
Cortex-M0489241328B2200B
Cortex-M3283331324B2132B
Cortex-M4F273371324B2132B

Poly1305-AES

This test computes a MAC with a 32 byte key over the message “hello world”. It includes the AES nonce processing.

CoreCyclesStackCode size
Cortex-M015719704B1920B
Cortex-M311328696B1964B
Cortex-M4F10706696B1932B

Curve25519

This test is one point multiplication.

This uses the implementation from μNaCl by Düll, Haase, Hinterwälder, Hutter, Paar, Sánchez and Schwabe.

CoreCyclesStackCode size
Cortex-M04070271464B5596B
Cortex-M33720363448B5536B
Cortex-M4F3720105448B5536B

See curve25519-shootout for comparitive measurements for other curve25519 implementations.

C library requirements

Cifra requires memcpy, memset, and abort.

Future

  • Keccak hash function (aka SHA3).
  • Poly1305 one-time MAC.
  • Constant time curve25519 for Cortex-M4F using the FPU.
  • Constant time curve25519 for Cortex-M3 (avoiding the variable-time multiplier).

Notable past bugs/advisories

  • Issue #2: in all versions before commit d62aa26e (September 16th 2015) too much padding was added when hashing messages of certain lengths. Specifically, messages whose length satisfied len % 64 = 55 for SHA1/SHA224/SHA256 or len % 128 = 119 for SHA384/SHA512. SHA3 was not affected. Better testing is now in place.
  • Issue #3: in all versions before commit 82d77cd8 (April 16th 2016) EAX would produce wrong tags for empty AADs or messages. The underlying CMAC is now more resistant to this case.

License

CC0.

Please attribute the author. This is a request only, and not a license term.

Author

Joseph Birr-Pixton jpixton@gmail.com