332 lines
17 KiB
HTML
332 lines
17 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta charset="utf-8"/>
|
||
|
<style>
|
||
|
table.head, table.foot { width: 100%; }
|
||
|
td.head-rtitle, td.foot-os { text-align: right; }
|
||
|
td.head-vol { text-align: center; }
|
||
|
div.Pp { margin: 1ex 0ex; }
|
||
|
</style>
|
||
|
<link rel="stylesheet" href="style.css" type="text/css" media="all"/>
|
||
|
<title>CRYPTO_CHACHA20(3MONOCYPHER)</title>
|
||
|
</head>
|
||
|
<body>
|
||
|
<table class="head">
|
||
|
<tr>
|
||
|
<td class="head-ltitle">CRYPTO_CHACHA20(3MONOCYPHER)</td>
|
||
|
<td class="head-vol">3MONOCYPHER</td>
|
||
|
<td class="head-rtitle">CRYPTO_CHACHA20(3MONOCYPHER)</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<div class="manual-text">
|
||
|
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
|
||
|
<b class="Nm" title="Nm">crypto_chacha20</b>,
|
||
|
<b class="Nm" title="Nm">crypto_chacha20_ctr</b>,
|
||
|
<b class="Nm" title="Nm">crypto_xchacha20</b>,
|
||
|
<b class="Nm" title="Nm">crypto_xchacha20_ctr</b> —
|
||
|
<span class="Nd" title="Nd">Chacha20 and XChacha20 encryption functions</span>
|
||
|
<h1 class="Sh" title="Sh" id="SYNOPSIS"><a class="selflink" href="#SYNOPSIS">SYNOPSIS</a></h1>
|
||
|
<b class="In" title="In">#include
|
||
|
<<a class="In" title="In">monocypher.h</a>></b>
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_chacha20</b>(<var class="Fa" title="Fa">uint8_t
|
||
|
*cipher_text</var>, <var class="Fa" title="Fa">const uint8_t
|
||
|
*plain_text</var>, <var class="Fa" title="Fa">size_t text_size</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t key[32]</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t nonce[8]</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20</b>(<var class="Fa" title="Fa">uint8_t
|
||
|
*cipher_text</var>, <var class="Fa" title="Fa">const uint8_t
|
||
|
*plain_text</var>, <var class="Fa" title="Fa">size_t text_size</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t key[32]</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t nonce[24]</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">uint64_t</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_chacha20_ctr</b>(<var class="Fa" title="Fa">uint8_t
|
||
|
*cipher_text</var>, <var class="Fa" title="Fa">const uint8_t
|
||
|
*plain_text</var>, <var class="Fa" title="Fa">size_t text_size</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t key[32]</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t nonce[8]</var>,
|
||
|
<var class="Fa" title="Fa">uint64_t ctr</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">uint64_t</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20_ctr</b>(<var class="Fa" title="Fa">uint8_t
|
||
|
*cipher_text</var>, <var class="Fa" title="Fa">const uint8_t
|
||
|
*plain_text</var>, <var class="Fa" title="Fa">size_t text_size</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t key[32]</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t nonce[24]</var>,
|
||
|
<var class="Fa" title="Fa">uint64_t ctr</var>);
|
||
|
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
|
||
|
These functions provide an interface for the Chacha20 encryption primitive.
|
||
|
<div class="Pp"></div>
|
||
|
Chacha20 is a low-level primitive. Consider using authenticated encryption,
|
||
|
implemented by
|
||
|
<a class="Xr" title="Xr" href="crypto_lock.html">crypto_lock(3monocypher)</a>.
|
||
|
<div class="Pp"></div>
|
||
|
The arguments are:
|
||
|
<dl class="Bl-tag">
|
||
|
<dt class="It-tag"> </dt>
|
||
|
<dd class="It-tag"> </dd>
|
||
|
<dt class="It-tag"><var class="Fa" title="Fa">key</var></dt>
|
||
|
<dd class="It-tag">A 32-byte secret key.</dd>
|
||
|
<dt class="It-tag"> </dt>
|
||
|
<dd class="It-tag"> </dd>
|
||
|
<dt class="It-tag"><var class="Fa" title="Fa">nonce</var></dt>
|
||
|
<dd class="It-tag">An 8-byte or 24-byte number, used only once with any given
|
||
|
key. It does not need to be secret or random, but it does have to be
|
||
|
unique. Repeating a nonce with the same key reveals the XOR of two
|
||
|
different messages, which allows decryption. 24-byte nonces can be
|
||
|
selected at random. 8-byte nonces <i class="Em" title="Em">cannot</i>.
|
||
|
They are too small, and the same nonce may be selected twice by accident.
|
||
|
See <a class="Xr" title="Xr" href="intro.html">intro(3monocypher)</a> for
|
||
|
advice about generating random numbers (use the operating system's random
|
||
|
number generator).</dd>
|
||
|
<dt class="It-tag"> </dt>
|
||
|
<dd class="It-tag"> </dd>
|
||
|
<dt class="It-tag"><var class="Fa" title="Fa">plain_text</var></dt>
|
||
|
<dd class="It-tag">The message to encrypt. It is allowed to be
|
||
|
<code class="Dv" title="Dv">NULL</code>, in which case it will be
|
||
|
interpreted as an all zero input.
|
||
|
<var class="Fa" title="Fa">cipher_text</var> will then contain the raw
|
||
|
Chacha20 stream.</dd>
|
||
|
<dt class="It-tag"> </dt>
|
||
|
<dd class="It-tag"> </dd>
|
||
|
<dt class="It-tag"><var class="Fa" title="Fa">cipher_text</var></dt>
|
||
|
<dd class="It-tag">The encrypted message.</dd>
|
||
|
<dt class="It-tag"> </dt>
|
||
|
<dd class="It-tag"> </dd>
|
||
|
<dt class="It-tag"><var class="Fa" title="Fa">text_size</var></dt>
|
||
|
<dd class="It-tag">Length of both <var class="Fa" title="Fa">plain_text</var>
|
||
|
and <var class="Fa" title="Fa">cipher_text</var>, in bytes.</dd>
|
||
|
<dt class="It-tag"> </dt>
|
||
|
<dd class="It-tag"> </dd>
|
||
|
<dt class="It-tag"><var class="Fa" title="Fa">ctr</var></dt>
|
||
|
<dd class="It-tag">The number of 64-byte blocks since the beginning of the
|
||
|
stream.</dd>
|
||
|
</dl>
|
||
|
<div class="Pp"></div>
|
||
|
The <var class="Fa" title="Fa">key</var> and
|
||
|
<var class="Fa" title="Fa">nonce</var> buffers may overlap.
|
||
|
<var class="Fa" title="Fa">plain_text</var> and
|
||
|
<var class="Fa" title="Fa">cipher_text</var> must either be the same buffer
|
||
|
(for in-place encryption), or non-overlapping.
|
||
|
<div class="Pp"></div>
|
||
|
<b class="Fn" title="Fn">crypto_chacha20</b>() performs a Chacha20 operation. It
|
||
|
uses an 8-byte nonce, which is too small to be selected at random. Use a
|
||
|
message counter as a nonce instead.
|
||
|
<div class="Pp"></div>
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20</b>() performs an XChacha20 operation.
|
||
|
It uses a 24-byte nonce, which is large enough to be selected at random.
|
||
|
<div class="Pp"></div>
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20</b>() is recommended over
|
||
|
<b class="Fn" title="Fn">crypto_chacha20</b>(). The ability to use random
|
||
|
nonces makes it easier to use securely, and the performance hit is often
|
||
|
negligible in practice.
|
||
|
<div class="Pp"></div>
|
||
|
The <b class="Fn" title="Fn">crypto_chacha20</b>() and
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20</b>() encrypt
|
||
|
<var class="Fa" title="Fa">plain_text</var> by XORing it with a pseudo-random
|
||
|
stream of numbers, seeded by the provided <var class="Fa" title="Fa">key</var>
|
||
|
and <var class="Fa" title="Fa">nonce</var>.
|
||
|
<div class="Pp"></div>
|
||
|
Since XOR is its own inverse, decryption is the same operation as encryption. To
|
||
|
decrypt the cipher text, “encrypt” it again with the same key
|
||
|
and nonce. You will likely want to wipe the key when you are done with
|
||
|
encryption or decryption. Use
|
||
|
<a class="Xr" title="Xr" href="crypto_wipe.html">crypto_wipe(3monocypher)</a>
|
||
|
to wipe them.
|
||
|
<div class="Pp"></div>
|
||
|
The <var class="Fa" title="Fa">plain_text</var> pointer is allowed to be
|
||
|
<code class="Dv" title="Dv">NULL</code>, in which case it will be interpreted
|
||
|
as an all zero input. This is useful as a user space random number generator.
|
||
|
While <b class="Sy" title="Sy">this should not be used as a random number
|
||
|
generator for secrets</b>, for which the operating system random number
|
||
|
generator should be preferred, it can be handy outside of a security context.
|
||
|
Deterministic procedural generation and reproducible property-based tests come
|
||
|
to mind. Additionally, it <i class="Em" title="Em">can</i> be used to generate
|
||
|
large amounts of random-looking data quickly, for example to generate padding.
|
||
|
<div class="Pp"></div>
|
||
|
The <b class="Fn" title="Fn">crypto_chacha20_ctr</b>() and
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20_ctr</b>() perform a Chacha20 or
|
||
|
XChacha20 encryption, respectively, starting the stream at the block
|
||
|
<var class="Fa" title="Fa">ctr</var> (which is the byte
|
||
|
‘<code class="Li">ctr × 64</code>’). This can be used to
|
||
|
encrypt (or decrypt) part of a long message, or to implement some AEAD
|
||
|
constructions such as the one described in RFC 8439. Be careful when using
|
||
|
this not to accidentally reuse parts of the random stream as that would
|
||
|
destroy confidentiality.
|
||
|
<h1 class="Sh" title="Sh" id="RETURN_VALUES"><a class="selflink" href="#RETURN_VALUES">RETURN
|
||
|
VALUES</a></h1>
|
||
|
<b class="Fn" title="Fn">crypto_chacha20</b>() and
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20</b>() return nothing.
|
||
|
<b class="Fn" title="Fn">crypto_chacha20_ctr</b>() and
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20_ctr</b>() functions return the next
|
||
|
<var class="Fa" title="Fa">ctr</var> to use with the same key and nonce
|
||
|
values; this is always <var class="Fa" title="Fa">text_size</var> divided by
|
||
|
64; plus one if there was a remainder.
|
||
|
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
|
||
|
The following examples assume the existence of
|
||
|
<b class="Fn" title="Fn">arc4random_buf</b>(), which fills the given buffer
|
||
|
with cryptographically secure random bytes. If
|
||
|
<b class="Fn" title="Fn">arc4random_buf</b>() does not exist on your system,
|
||
|
see <a class="Xr" title="Xr" href="intro.html">intro(3monocypher)</a> for
|
||
|
advice about how to generate cryptographically secure random bytes.
|
||
|
<div class="Pp"></div>
|
||
|
Simple encryption:
|
||
|
<div class="Pp"></div>
|
||
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||
|
<pre class="Li">
|
||
|
uint8_t key [ 32]; /* Secret random key */
|
||
|
uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
|
||
|
uint8_t plain_text [500] = {1}; /* Secret message */
|
||
|
uint8_t cipher_text[500]; /* Encrypted message */
|
||
|
arc4random_buf(key, 32);
|
||
|
arc4random_buf(nonce, 24);
|
||
|
crypto_xchacha20(cipher_text, plain_text, 500, key, nonce);
|
||
|
/* Wipe secrets if they are no longer needed */
|
||
|
crypto_wipe(key, 32);
|
||
|
crypto_wipe(plain_text, 500);
|
||
|
</pre>
|
||
|
</div>
|
||
|
<div class="Pp"></div>
|
||
|
To decrypt the above:
|
||
|
<div class="Pp"></div>
|
||
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||
|
<pre class="Li">
|
||
|
uint8_t key [ 32]; /* Same key as above */
|
||
|
const uint8_t nonce [ 24]; /* Same nonce as above */
|
||
|
uint8_t plain_text [500]; /* Message to decrypt */
|
||
|
uint8_t cipher_text[500]; /* Secret message */
|
||
|
crypto_xchacha20(cipher_text, plain_text, 500, key, nonce);
|
||
|
/* Wipe secrets if they are no longer needed */
|
||
|
crypto_wipe(key, 32);
|
||
|
/* The plain text likely needs to be processed before you wipe it */
|
||
|
crypto_wipe(plain_text, 12);
|
||
|
</pre>
|
||
|
</div>
|
||
|
<div class="Pp"></div>
|
||
|
Incremental encryption (in blocks of 64 bytes):
|
||
|
<div class="Pp"></div>
|
||
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||
|
<pre class="Li">
|
||
|
uint8_t key [ 32]; /* Secret random key */
|
||
|
uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
|
||
|
uint8_t plain_text [500]; /* Secret message */
|
||
|
uint8_t cipher_text[500]; /* Encrypted message */
|
||
|
uint64_t ctr = 0; /* Block counter */
|
||
|
unsigned int i;
|
||
|
arc4random_buf(key, 32);
|
||
|
arc4random_buf(nonce, 24);
|
||
|
for(i = 0; i < 500; i += 64) {
|
||
|
ctr = crypto_xchacha20_ctr(cipher_text+i, plain_text+i, 64,
|
||
|
key, nonce, ctr);
|
||
|
}
|
||
|
/* Process data that didn't fit into 64 byte pieces */
|
||
|
crypto_xchacha20_ctr(cipher_text+500-(i-64),
|
||
|
plain_text+500-(i-64),
|
||
|
500-(i-64),
|
||
|
key, nonce, ctr);
|
||
|
/* Wipe secrets if they are no longer needed */
|
||
|
crypto_wipe(key, 32);
|
||
|
crypto_wipe(plain_text, 500);
|
||
|
</pre>
|
||
|
</div>
|
||
|
<div class="Pp"></div>
|
||
|
Encryption by jumping around (do not do that, this is only meant to show how
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20_ctr</b>() works):
|
||
|
<div class="Pp"></div>
|
||
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||
|
<pre class="Li">
|
||
|
uint8_t key [ 32]; /* Secret random key */
|
||
|
uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
|
||
|
uint8_t plain_text [500] = {1}; /* Message to be encrypted */
|
||
|
uint8_t cipher_text[500]; /* Will be the encrypted message */
|
||
|
arc4random_buf(key, 32);
|
||
|
arc4random_buf(nonce, 24);
|
||
|
/* Encrypt the second part of the message first... */
|
||
|
crypto_xchacha20_ctr(cipher_text + (3 * 64),
|
||
|
plain_text + (3 * 64),
|
||
|
500 - (3 * 64),
|
||
|
key, nonce, 3);
|
||
|
/* ...then encrypt the first part */
|
||
|
crypto_xchacha20_ctr(cipher_text, plain_text, 3 * 64, key, nonce, 0);
|
||
|
/* Wipe secrets if they are no longer needed */
|
||
|
crypto_wipe(key, 32);
|
||
|
crypto_wipe(plain_text, 500);
|
||
|
</pre>
|
||
|
</div>
|
||
|
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
|
||
|
ALSO</a></h1>
|
||
|
<a class="Xr" title="Xr" href="crypto_ietf_chacha20.html">crypto_ietf_chacha20(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="crypto_lock.html">crypto_lock(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="crypto_wipe.html">crypto_wipe(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="intro.html">intro(3monocypher)</a>
|
||
|
<h1 class="Sh" title="Sh" id="STANDARDS"><a class="selflink" href="#STANDARDS">STANDARDS</a></h1>
|
||
|
These functions implement Chacha20 and XChacha20. Chacha20 is described in:
|
||
|
<cite class="Rs" title="Rs"><span class="RsA">Daniel J. Bernstein</span>,
|
||
|
<span class="RsT">ChaCha, a variant of Salsa20</span>, <i class="RsJ">SASC
|
||
|
2008 – The State of the Art of Stream Ciphers</i>,
|
||
|
<span class="RsP">pp. 273–278</span>.</cite> The nonce and counter
|
||
|
sizes were modified in RFC 8439. 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).
|
||
|
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
|
||
|
<b class="Fn" title="Fn">crypto_chacha20</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_chacha20_ctr</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20</b>(), and
|
||
|
<b class="Fn" title="Fn">crypto_xchacha20_ctr</b>() were added in Monocypher
|
||
|
3.0.0. They replace <b class="Fn" title="Fn">crypto_chacha20_encrypt</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_chacha20_init</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_chacha20_stream</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_chacha20_x_init</b>(), and
|
||
|
<b class="Fn" title="Fn">crypto_chacha20_set_ctr</b>() that were deprecated in
|
||
|
Monocypher 3.0.0.
|
||
|
<h1 class="Sh" title="Sh" id="SECURITY_CONSIDERATIONS"><a class="selflink" href="#SECURITY_CONSIDERATIONS">SECURITY
|
||
|
CONSIDERATIONS</a></h1>
|
||
|
<h2 class="Ss" title="Ss" id="Encrypted_does_not_mean_secure"><a class="selflink" href="#Encrypted_does_not_mean_secure">Encrypted
|
||
|
does not mean secure</a></h2>
|
||
|
Chacha20 only protects against eavesdropping, not forgeries. Most applications
|
||
|
need protection against forgeries to be properly secure. To ensure the
|
||
|
integrity of a message, use Blake2b in keyed mode, or authenticated
|
||
|
encryption; see
|
||
|
<a class="Xr" title="Xr" href="crypto_blake2b.html">crypto_blake2b(3monocypher)</a>
|
||
|
and
|
||
|
<a class="Xr" title="Xr" href="crypto_lock.html">crypto_lock(3monocypher)</a>.
|
||
|
<h2 class="Ss" title="Ss" id="Nonce_reuse"><a class="selflink" href="#Nonce_reuse">Nonce
|
||
|
reuse</a></h2>
|
||
|
Repeating a nonce with the same key exposes the XOR of two or more plain text
|
||
|
messages, effectively destroying confidentiality.
|
||
|
<div class="Pp"></div>
|
||
|
For the same reason, <b class="Sy" title="Sy">do not select small nonces at
|
||
|
random</b>. The <b class="Fn" title="Fn">crypto_chacha20</b>() nonce spans
|
||
|
only 64 bits, which is small enough to trigger accidental reuses. A message
|
||
|
counter should be used instead. If multiple parties send out messages, Each
|
||
|
can start with an initial nonce of 0, 1 .. n-1 respectively, and increment
|
||
|
them by n for each new message. Make sure the counters never wrap around.
|
||
|
<h2 class="Ss" title="Ss" id="Secure_random_number_generation"><a class="selflink" href="#Secure_random_number_generation">Secure
|
||
|
random number generation</a></h2>
|
||
|
Do not use these functions as a cryptographic random number generator. Always
|
||
|
use the operating system's random number generator for cryptographic purposes,
|
||
|
see <a class="Xr" title="Xr" href="intro.html">intro(3monocypher)</a>.
|
||
|
<h2 class="Ss" title="Ss" id="Protection_against_side_channels"><a class="selflink" href="#Protection_against_side_channels">Protection
|
||
|
against side channels</a></h2>
|
||
|
Secrets should not dwell in memory longer than needed. Use
|
||
|
<a class="Xr" title="Xr" href="crypto_wipe.html">crypto_wipe(3monocypher)</a>
|
||
|
to erase secrets you no longer need. For Chacha20, this means the key and in
|
||
|
some cases the plain text itself.</div>
|
||
|
<table class="foot">
|
||
|
<tr>
|
||
|
<td class="foot-date">March 31, 2020</td>
|
||
|
<td class="foot-os">Linux 4.15.0-106-generic</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</body>
|
||
|
</html>
|