INTRO(3MONOCYPHER) | 3MONOCYPHER | INTRO(3MONOCYPHER) |
intro
—
ChaCha20 is a stream cipher based on a cryptographic hash function. It runs efficiently on a wide variety of hardware, and unlike AES naturally runs in constant time on all hardware.
Poly1305 is a one-time authenticator, derived from Carter & Wegman universal hashing. It is very fast and very simple.
For specialised needs, crypto_chacha20(3monocypher) and crypto_poly1305(3monocypher) are available to implement constructions involving them. Whenever possible, crypto_lock(3monocypher) should be preferred, however.
For specialised protocols that require indistinguishability from random noise, crypto_curve_to_hidden(3monocypher) gives the option to disguise ephemeral (one-time use) X25519 public keys as random noise.
For highly specialised needs, it is possible to use a custom hash function with EdDSA; see crypto_sign_init_first_pass_custom_hash(3monocypher).
USE_ED25519
, SHA-512 functions become available as
well. See
crypto_ed25519_sign(3monocypher),
crypto_ed25519_sign_init_first_pass(3monocypher),
crypto_sha512(3monocypher), and
crypto_hmac_sha512(3monocypher).
Users should follow a formal introduction to cryptography. We currently recommend the Crypto 101 online course.
Different system calls are available on different systems:
getrandom
() in
<linux/random.h>
. Do not
set any flag.arc4random_buf
() in
<stdlib.h>
or
<bsd/stdlib.h>
. This is
easier to use than getrandom
().BCryptGenRandom
().The /dev/urandom special file may be used on systems that do not provide an easy-to-use system call. Be careful though, being a file makes /dev/urandom hard to use correctly and securely. Reads may be interrupted, and more attacks are possible on a file than on a system call.
Comparing secrets should be done with constant-time comparison functions, such as crypto_verify16(3monocypher), crypto_verify32(3monocypher), or crypto_verify64(3monocypher). Do not use standard comparison functions. They tend to stop as soon as a difference is spotted. In many cases, this enables attackers to recover the secrets and destroy all security.
The Poly1305 authenticator, X25519, and EdDSA use multiplication. Some older processors do not multiply in constant time. If the target platform is something other than Intel or AMD x86_64, double check how it handles multiplication. In particular, ARM Cortex-M CPUs may lack constant-time multiplication. Some VIA Nano x86 and x86_64 CPUs may lack constant-time multiplication as well.
In general, secrets that went through a computer should not be compromised when this computer is stolen or infected at a later point.
A first layer of defence is to explicitly wipe secrets as soon as
they are no longer used. Monocypher already wipes its own temporary buffers,
and contexts are erased with the crypto_*_final
()
functions. The secret keys and messages however are the responsibility of
the user. Use
crypto_wipe(3monocypher) to erase
them.
A second layer of defence is to ensure those secrets are not swapped to disk while they are used. There are several ways to do this. The most secure is to disable swapping entirely. Doing so is recommended on sensitive machines. Another way is to encrypt the swap partition (this is less safe). Finally, swap can be disabled locally – this is often the only way.
UNIX systems can disable swap for specific buffers with
mlock
() and disable swap for the whole process with
mlockall
(). Windows can disable swap for specific
buffers with VirtualLock
().
Core dumps cause similar problems. Disable them. Also beware of suspend to disk (deep sleep mode), which writes all RAM to disk regardless of swap policy, as well as virtual machine snapshots. Erasing secrets with crypto_wipe(3monocypher) is often the only way to mitigate these dangers.
Consider binding to a safe language if possible.
February 13, 2022 | Debian |