341 lines
10 KiB
Plaintext
341 lines
10 KiB
Plaintext
|
.\" This file is dual-licensed. Choose whichever you want.
|
||
|
.\"
|
||
|
.\" The first licence is a regular 2-clause BSD licence. The second licence
|
||
|
.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
|
||
|
.\" to the public domain. The BSD licence serves as a fallback option.
|
||
|
.\"
|
||
|
.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
|
||
|
.\"
|
||
|
.\" ----------------------------------------------------------------------------
|
||
|
.\"
|
||
|
.\" Copyright (c) 2017-2019 Loup Vaillant
|
||
|
.\" Copyright (c) 2017-2018 Michael Savage
|
||
|
.\" Copyright (c) 2017, 2019-2020 Fabio Scotoni
|
||
|
.\" All rights reserved.
|
||
|
.\"
|
||
|
.\"
|
||
|
.\" Redistribution and use in source and binary forms, with or without
|
||
|
.\" modification, are permitted provided that the following conditions are
|
||
|
.\" met:
|
||
|
.\"
|
||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||
|
.\" notice, this list of conditions and the following disclaimer.
|
||
|
.\"
|
||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||
|
.\" documentation and/or other materials provided with the
|
||
|
.\" distribution.
|
||
|
.\"
|
||
|
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
.\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
.\"
|
||
|
.\" ----------------------------------------------------------------------------
|
||
|
.\"
|
||
|
.\" Written in 2017-2020 by Loup Vaillant, Michael Savage and Fabio Scotoni
|
||
|
.\"
|
||
|
.\" To the extent possible under law, the author(s) have dedicated all copyright
|
||
|
.\" and related neighboring rights to this software to the public domain
|
||
|
.\" worldwide. This software is distributed without any warranty.
|
||
|
.\"
|
||
|
.\" You should have received a copy of the CC0 Public Domain Dedication along
|
||
|
.\" with this software. If not, see
|
||
|
.\" <https://creativecommons.org/publicdomain/zero/1.0/>
|
||
|
.\"
|
||
|
.Dd February 29, 2020
|
||
|
.Dt CRYPTO_LOCK 3MONOCYPHER
|
||
|
.Os
|
||
|
.Sh NAME
|
||
|
.Nm crypto_lock_aead ,
|
||
|
.Nm crypto_unlock_aead ,
|
||
|
.Nm crypto_lock ,
|
||
|
.Nm crypto_unlock
|
||
|
.Nd authenticated encryption with additional data
|
||
|
.Sh SYNOPSIS
|
||
|
.In monocypher.h
|
||
|
.Ft void
|
||
|
.Fo crypto_lock
|
||
|
.Fa "uint8_t mac[16]"
|
||
|
.Fa "uint8_t *cipher_text"
|
||
|
.Fa "const uint8_t key[32]"
|
||
|
.Fa "const uint8_t nonce[24]"
|
||
|
.Fa "const uint8_t *plain_text"
|
||
|
.Fa "size_t text_size"
|
||
|
.Fc
|
||
|
.Ft int
|
||
|
.Fo crypto_unlock
|
||
|
.Fa "uint8_t *plain_text"
|
||
|
.Fa "const uint8_t key[32]"
|
||
|
.Fa "const uint8_t nonce[24]"
|
||
|
.Fa "const uint8_t mac[16]"
|
||
|
.Fa "const uint8_t *cipher_text"
|
||
|
.Fa "size_t text_size"
|
||
|
.Fc
|
||
|
.Ft void
|
||
|
.Fo crypto_lock_aead
|
||
|
.Fa "uint8_t mac[16]"
|
||
|
.Fa "uint8_t *cipher_text"
|
||
|
.Fa "const uint8_t key[32]"
|
||
|
.Fa "const uint8_t nonce[24]"
|
||
|
.Fa "const uint8_t *ad"
|
||
|
.Fa "size_t ad_size"
|
||
|
.Fa "const uint8_t *plain_text"
|
||
|
.Fa "size_t text_size"
|
||
|
.Fc
|
||
|
.Ft int
|
||
|
.Fo crypto_unlock_aead
|
||
|
.Fa "uint8_t *plain_text"
|
||
|
.Fa "const uint8_t key[32]"
|
||
|
.Fa "const uint8_t nonce[24]"
|
||
|
.Fa "const uint8_t mac[16]"
|
||
|
.Fa "const uint8_t *ad"
|
||
|
.Fa "size_t ad_size"
|
||
|
.Fa "const uint8_t *cipher_text"
|
||
|
.Fa "size_t text_size"
|
||
|
.Fc
|
||
|
.Sh DESCRIPTION
|
||
|
.Fn crypto_lock
|
||
|
encrypts and authenticates a plaintext.
|
||
|
It can be decrypted by
|
||
|
.Fn crypto_unlock .
|
||
|
The arguments are:
|
||
|
.Bl -tag -width Ds
|
||
|
.It Fa key
|
||
|
A 32-byte session key, shared between the sender and the recipient.
|
||
|
It must be secret and random.
|
||
|
Different methods can be used to produce and exchange this key, such
|
||
|
as Diffie-Hellman key exchange, password key derivation (the password
|
||
|
must be communicated on a secure channel), or even meeting physically.
|
||
|
See
|
||
|
.Xr crypto_key_exchange 3monocypher
|
||
|
for key exchange, and
|
||
|
.Xr crypto_argon2i 3monocypher
|
||
|
for password key derivation.
|
||
|
.It Fa nonce
|
||
|
A 24-byte number, used only once with any given session key.
|
||
|
It does not need to be secret or random, but it does have to be
|
||
|
unique.
|
||
|
.Em Never
|
||
|
use the same nonce twice with the same key.
|
||
|
This would reveal the XOR of 2 different messages, which allows
|
||
|
decryption and forgeries.
|
||
|
The easiest (and recommended) way to generate this nonce is to
|
||
|
select it at random.
|
||
|
See
|
||
|
.Xr intro 3monocypher
|
||
|
about random number generation (use your operating system's random
|
||
|
number generator).
|
||
|
.It Fa mac
|
||
|
A 16-byte
|
||
|
.Em message authentication code
|
||
|
(MAC), that can only be produced by someone who knows the session key.
|
||
|
This guarantee cannot be upheld if a nonce has been reused with the
|
||
|
session key, because doing so allows the attacker to learn the
|
||
|
authentication key associated with that nonce.
|
||
|
The MAC is intended to be sent along with the ciphertext.
|
||
|
.It Fa plain_text
|
||
|
The secret message.
|
||
|
Its contents will be kept hidden from attackers.
|
||
|
Its length however, will
|
||
|
.Em not .
|
||
|
Be careful when combining encryption with compression.
|
||
|
See
|
||
|
.Xr intro 3monocypher
|
||
|
for details.
|
||
|
.It Fa cipher_text
|
||
|
The encrypted message.
|
||
|
.It Fa text_size
|
||
|
Length of both
|
||
|
.Fa plain_text and
|
||
|
.Fa cipher_text ,
|
||
|
in bytes.
|
||
|
.El
|
||
|
.Pp
|
||
|
The
|
||
|
.Fa cipher_text
|
||
|
and
|
||
|
.Fa plain_text
|
||
|
arguments may point to the same buffer for in-place encryption.
|
||
|
Otherwise, the buffers they point to must not overlap.
|
||
|
.Pp
|
||
|
.Fn crypto_unlock
|
||
|
first checks the integrity of an encrypted message.
|
||
|
If it has been corrupted,
|
||
|
.Fn crypto_unlock
|
||
|
returns -1 immediately.
|
||
|
Otherwise, it decrypts the message, then returns zero.
|
||
|
.Em Always check the return value .
|
||
|
.Pp
|
||
|
.Fn crypto_lock_aead
|
||
|
and
|
||
|
.Fn crypto_unlock_aead
|
||
|
are variants of
|
||
|
.Fn crypto_lock
|
||
|
and
|
||
|
.Fn crypto_unlock ,
|
||
|
permitting additional data.
|
||
|
Additional data is authenticated, but
|
||
|
.Em not
|
||
|
encrypted.
|
||
|
This is used to authenticate relevant data that cannot be encrypted.
|
||
|
The arguments are:
|
||
|
.Bl -tag -width Ds
|
||
|
.It Fa ad
|
||
|
Additional data to authenticate.
|
||
|
It will not be encrypted.
|
||
|
May be
|
||
|
.Dv NULL
|
||
|
if
|
||
|
.Fa ad_size
|
||
|
is zero.
|
||
|
Setting
|
||
|
.Fa ad_size
|
||
|
to zero yields the same results as
|
||
|
.Fn crypto_lock
|
||
|
and
|
||
|
.Fn crypto_unlock .
|
||
|
.It Fa ad_size
|
||
|
Length of the additional data, in bytes.
|
||
|
.El
|
||
|
.Sh RETURN VALUES
|
||
|
.Fn crypto_lock
|
||
|
and
|
||
|
.Fn crypto_lock_aead
|
||
|
return nothing.
|
||
|
.Fn crypto_unlock
|
||
|
and
|
||
|
.Fn crypto_unlock_aead
|
||
|
return 0 on success or -1 if the message was corrupted (i.e.
|
||
|
.Fa mac
|
||
|
mismatched the combination of
|
||
|
.Fa key ,
|
||
|
.Fa nonce ,
|
||
|
.Fa ad
|
||
|
and
|
||
|
.Fa cipher_text ) .
|
||
|
Corruption can be caused by transmission errors, programmer error, or an
|
||
|
attacker's interference.
|
||
|
.Fa plain_text
|
||
|
does not need to be wiped if the decryption fails.
|
||
|
.Sh EXAMPLES
|
||
|
The following examples assume the existence of
|
||
|
.Fn arc4random_buf ,
|
||
|
which fills the given buffer with cryptographically secure random bytes.
|
||
|
If
|
||
|
.Fn arc4random_buf
|
||
|
does not exist on your system, see
|
||
|
.Xr intro 3monocypher
|
||
|
for advice about how to generate cryptographically secure random bytes.
|
||
|
.Pp
|
||
|
Encryption:
|
||
|
.Bd -literal -offset indent
|
||
|
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.
|
||
|
*/
|
||
|
.Ed
|
||
|
.Pp
|
||
|
To decrypt the above:
|
||
|
.Bd -literal -offset indent
|
||
|
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);
|
||
|
}
|
||
|
.Ed
|
||
|
.Pp
|
||
|
In-place encryption:
|
||
|
.Bd -literal -offset indent
|
||
|
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.
|
||
|
*/
|
||
|
.Ed
|
||
|
.Pp
|
||
|
In-place decryption:
|
||
|
.Bd -literal -offset indent
|
||
|
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);
|
||
|
}
|
||
|
.Ed
|
||
|
.Sh SEE ALSO
|
||
|
.Xr crypto_key_exchange 3monocypher ,
|
||
|
.Xr crypto_wipe 3monocypher ,
|
||
|
.Xr intro 3monocypher
|
||
|
.Sh STANDARDS
|
||
|
These functions implement RFC 8439, with XChacha20 instead of Chacha20.
|
||
|
XChacha20 derives from Chacha20 the same way XSalsa20 derives from
|
||
|
Salsa20, and benefits from the same security reduction (proven secure
|
||
|
as long as Chacha20 itself is secure).
|
||
|
.Sh HISTORY
|
||
|
The
|
||
|
.Fn crypto_lock
|
||
|
and
|
||
|
.Fn crypto_unlock
|
||
|
functions first appeared in Monocypher 0.1.
|
||
|
.Fn crypto_lock_aead
|
||
|
and
|
||
|
.Fn 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
|
||
|
.Fn crypto_lock_encrypt
|
||
|
and
|
||
|
.Fn crypto_lock_auth
|
||
|
functions were removed in Monocypher 2.0.0.
|