balena / chacha20-whitebox

Whitebox Cryptography built over ChaCha20
BSD 2-Clause "Simplified" License
4 stars 2 forks source link

ChaCha20 whitebox cryptography

This code contains a simple implementation of the ChaCha20 stream cipher, designed by Daniel J Bernstein and a part of the eSTREAM stream cipher portfolio, RFC 7539 variant (nonce = 96 bits, counter = 32 bits). It is a simple non-optimized version of the specification with focus on testability.

It requires a minimal set of C and no special external libraries.

The whitebox output supports encrypting of a single 64-bytes block.

How it works

The gen_tables.c precalculates tables based on the result of the ChaCha20 computation varying the nonce up to a given limit (13-bits is provided as example) and maintaining same key and counter. The output function chacha20_core_table contained in the output file chacha20_tables.c does a single lookup based on the input nonce, returning the final mask (16 32-bit words) to be applied to the input.

Building

A simple make performs a complete testing build:

$ make

It will generate a static library libchacha20.a, containing the just the single block ChaCha20 cipher, build its unit test chacha20_tests and run it, then build gen_tests and execute it, generating a chacha20_tables.c. Finally it will generate another static library libchacha20_whitebox.a which exports the function chacha20_whitebox_block and depends on the libchacha20.a (it is a simple dependency on the chacha20_serialize function, it is easy to isolate it if needed). And then it will build the chacha20_whitebox_tests and run it.

The final unit test compares the output of the generated function with the original code.

In order to decrypt, run the function a second time, using the ciphertext as the input, maintaining the same nonce used to encrypt.

Security

The current implementation is not secure at all as the nonce length is too short (only 16 bits), so an attacker can break the ciphertext in time 2^16 and very low memory resources.

Notice that the key is not easily extractable from the tables, by the way.