CRYPTO_LOCK(3MONOCYPHER) | 3MONOCYPHER | CRYPTO_LOCK(3MONOCYPHER) |
crypto_lock_aead
,
crypto_unlock_aead
,
crypto_lock
, crypto_unlock
—
#include <monocypher.h>
void
crypto_lock
(uint8_t mac[16],
uint8_t *cipher_text, const uint8_t
key[32], const uint8_t nonce[24],
const uint8_t *plain_text, size_t
text_size);
int
crypto_unlock
(uint8_t
*plain_text, const uint8_t key[32],
const uint8_t nonce[24], const uint8_t
mac[16], const uint8_t *cipher_text,
size_t text_size);
void
crypto_lock_aead
(uint8_t
mac[16], uint8_t *cipher_text,
const uint8_t key[32], const uint8_t
nonce[24], const uint8_t *ad,
size_t ad_size, const uint8_t
*plain_text, size_t text_size);
int
crypto_unlock_aead
(uint8_t
*plain_text, const uint8_t key[32],
const uint8_t nonce[24], const uint8_t
mac[16], const uint8_t *ad,
size_t ad_size, const uint8_t
*cipher_text, size_t text_size);
crypto_lock
() encrypts and authenticates a plaintext. It
can be decrypted by crypto_unlock
(). The arguments
are:
The cipher_text and plain_text arguments may point to the same buffer for in-place encryption. Otherwise, the buffers they point to must not overlap.
crypto_unlock
() first checks the integrity
of an encrypted message. If it has been corrupted,
crypto_unlock
() returns -1 immediately. Otherwise,
it decrypts the message then returns zero. Always check the
return value.
crypto_lock_aead
() and
crypto_unlock_aead
() are variants of
crypto_lock
() and
crypto_unlock
(), permitting additional data.
Additional data is authenticated but not encrypted. This
is used to authenticate relevant data that cannot be encrypted. The
arguments are:
NULL
if ad_size is zero.
Setting ad_size to zero yields the same results as
crypto_lock
() and
crypto_unlock
().crypto_lock
() and
crypto_lock_aead
() return nothing.
crypto_unlock
() and
crypto_unlock_aead
() return 0 on success or -1 if the
message was corrupted (i.e. mac mismatched the
combination of key, nonce,
ad, and cipher_text). Corruption
can be caused by transmission errors, programmer error, or an attacker's
interference. plain_text does not need to be wiped if
the decryption fails.
arc4random_buf
(), which fills the given buffer with
cryptographically secure random bytes. If
arc4random_buf
() does not exist on your system, see
intro(3monocypher) for advice about how to
generate cryptographically secure random bytes.
Encryption:
uint8_t key [32]; /* Random, secret session key */ uint8_t nonce [24]; /* Use only once per key */ uint8_t plain_text [12] = "Lorem ipsum"; /* Secret message */ uint8_t mac [16]; /* Message authentication code */ uint8_t cipher_text[12]; /* Encrypted message */ arc4random_buf(key, 32); arc4random_buf(nonce, 24); crypto_lock(mac, cipher_text, key, nonce, plain_text, sizeof(plain_text)); /* Wipe secrets if they are no longer needed */ crypto_wipe(plain_text, 12); crypto_wipe(key, 32); /* Transmit cipher_text, nonce, and mac over the network, * store them in a file, etc. */
To decrypt the above:
uint8_t key [32]; /* Same as the above */ uint8_t nonce [24]; /* Same as the above */ const uint8_t cipher_text[12]; /* Encrypted message */ const uint8_t mac [16]; /* Received along with text */ uint8_t plain_text [12]; /* Secret message */ if (crypto_unlock(plain_text, key, nonce, mac, cipher_text, 12)) { /* The message is corrupted. * Wipe key if it is no longer needed, * and abort the decryption. */ crypto_wipe(key, 32); } else { /* ...do something with the decrypted text here... */ /* Finally, wipe secrets if they are no longer needed */ crypto_wipe(plain_text, 12); crypto_wipe(key, 32); }
In-place encryption:
uint8_t key [32]; /* Random, secret session key */ uint8_t nonce[24]; /* Use only once per key */ uint8_t text [12] = "Lorem ipsum"; /* Secret message */ uint8_t mac [16]; /* Message authentication code */ arc4random_buf(key, 32); arc4random_buf(nonce, 24); crypto_lock(mac, text, key, nonce, text, 12); /* Wipe secrets if they are no longer needed */ crypto_wipe(key, 32); /* Transmit cipher_text, nonce, and mac over the network, * store them in a file, etc. */
In-place decryption:
uint8_t key [32]; /* Same as the above */ const uint8_t nonce[24]; /* Same as the above */ const uint8_t mac [16]; /* Received from along with text */ uint8_t text [12]; /* Message to decrypt */ if (crypto_unlock(text, key, nonce, mac, text, 12)) { /* The message is corrupted. * Wipe key if it is no longer needed, * and abort the decryption. */ crypto_wipe(key, 32); } else { /* ...do something with the decrypted text here... */ /* Finally, wipe secrets if they are no longer needed */ crypto_wipe(text, 12); crypto_wipe(key, 32); }
crypto_lock
() and
crypto_unlock
() functions first appeared in Monocypher
0.1. crypto_lock_aead
() and
crypto_unlock_aead
() were introduced in Monocypher
1.1.0. In Monocypher 2.0.0, the underlying algorithms for these functions were
changed from a custom XChaCha20/Poly1305 construction to an implementation of
RFC 7539 (now RFC 8439) with XChaCha20 instead of ChaCha20. The
crypto_lock_encrypt
() and
crypto_lock_auth
() functions were removed in
Monocypher 2.0.0.
February 13, 2022 | Debian |