274 lines
8.6 KiB
Plaintext
274 lines
8.6 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-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 March 31, 2020
|
|
.Dt CRYPTO_POLY1305 3MONOCYPHER
|
|
.Os
|
|
.Sh NAME
|
|
.Nm crypto_poly1305 ,
|
|
.Nm crypto_poly1305_init ,
|
|
.Nm crypto_poly1305_update ,
|
|
.Nm crypto_poly1305_final
|
|
.Nd Poly1305 one-time message authentication codes
|
|
.Sh SYNOPSIS
|
|
.In monocypher.h
|
|
.Ft void
|
|
.Fo crypto_poly1305
|
|
.Fa "uint8_t mac[16]"
|
|
.Fa "const uint8_t *message"
|
|
.Fa "size_t message_size"
|
|
.Fa "const uint8_t key[32]"
|
|
.Fc
|
|
.Ft void
|
|
.Fo crypto_poly1305_init
|
|
.Fa "crypto_poly1305_ctx *ctx"
|
|
.Fa "const uint8_t key[32]"
|
|
.Fc
|
|
.Ft void
|
|
.Fo crypto_poly1305_update
|
|
.Fa "crypto_poly1305_ctx *ctx"
|
|
.Fa "const uint8_t *message"
|
|
.Fa "size_t message_size"
|
|
.Fc
|
|
.Ft void
|
|
.Fo crypto_poly1305_final
|
|
.Fa "crypto_poly1305_ctx *ctx"
|
|
.Fa "uint8_t mac[16]"
|
|
.Fc
|
|
.Sh DESCRIPTION
|
|
Poly1305 is a one-time message authentication code.
|
|
.Dq One-time
|
|
means the authentication key can be used only once.
|
|
.Sy This makes Poly1305 easy to misuse .
|
|
On the other hand, Poly1305 is fast, and provably secure if used
|
|
correctly.
|
|
.Pp
|
|
Poly1305 is a low-level primitive.
|
|
Consider using authenticated encryption, implemented by
|
|
.Xr crypto_lock 3monocypher .
|
|
.Pp
|
|
The arguments are:
|
|
.Bl -tag -width Ds
|
|
.It Fa mac
|
|
The authentication code.
|
|
.It Fa key
|
|
The secret authentication key.
|
|
Use only once per message.
|
|
Do not use the session key to authenticate messages.
|
|
It should be wiped with
|
|
.Xr crypto_wipe 3monocypher
|
|
after use.
|
|
.It Fa message
|
|
The message to authenticate.
|
|
May overlap with the
|
|
.Fa mac
|
|
argument.
|
|
.It Fa message_size
|
|
Length of
|
|
.Fa message ,
|
|
in bytes.
|
|
.El
|
|
.Ss Direct interface
|
|
.Fn crypto_poly1305
|
|
produces a message authentication code for the given message and
|
|
authentication key.
|
|
To verify the integrity of a message, use
|
|
.Xr crypto_verify16 3monocypher
|
|
to compare the received MAC to the output
|
|
.Fa mac .
|
|
.Ss Incremental interface
|
|
.Fn crypto_poly1305_init
|
|
initialises a context.
|
|
.Fa key
|
|
should be wiped once the context is initialised.
|
|
Then,
|
|
.Fn crypto_poly1305_update
|
|
authenticates the message chunk by chunk.
|
|
Once the message is entirely processed,
|
|
.Fn crypto_poly1305_final
|
|
yields the message authentication code.
|
|
.Sh RETURN VALUES
|
|
These functions return nothing.
|
|
.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
|
|
To authenticate a message:
|
|
.Bd -literal -offset indent
|
|
const uint8_t msg[ 5] = "Lorem"; /* Message to authenticate */
|
|
uint8_t key[32]; /* Random secret key (use only once) */
|
|
uint8_t mac[16]; /* Message authentication code (MAC) */
|
|
arc4random_buf(key, 32);
|
|
crypto_poly1305(mac, msg, 5, key);
|
|
/* Wipe the key */
|
|
crypto_wipe(key, 32);
|
|
.Ed
|
|
.Pp
|
|
To verify the above message:
|
|
.Bd -literal -offset indent
|
|
const uint8_t msg [ 5] = "Lorem"; /* Message to verify */
|
|
uint8_t key [32]; /* The above key */
|
|
const uint8_t mac [16]; /* The above MAC */
|
|
uint8_t real_mac[16]; /* The actual MAC */
|
|
crypto_poly1305(real_mac, msg, 5, key);
|
|
/* Wipe the key */
|
|
crypto_wipe(key, 32);
|
|
if (crypto_verify16(mac, real_mac)) {
|
|
/* Corrupted message, abort processing */
|
|
} else {
|
|
/* Genuine message */
|
|
}
|
|
/* The real mac is secret. Wipe it */
|
|
crypto_wipe(real_mac, 16);
|
|
.Ed
|
|
.Pp
|
|
Incremental authentication:
|
|
.Bd -literal -offset indent
|
|
const uint8_t msg[500]= {1}; /* Message to authenticate */
|
|
uint8_t key[ 32]; /* Random secret key (use only once) */
|
|
uint8_t mac[ 16]; /* Message authentication code (MAC) */
|
|
crypto_poly1305_ctx ctx;
|
|
arc4random_buf(key, 32);
|
|
crypto_poly1305_init(&ctx, key);
|
|
/* Wipe the key */
|
|
crypto_wipe(key, 32);
|
|
for (int i = 0; i < 500; i += 100) {
|
|
crypto_poly1305_update(&ctx, msg, 100);
|
|
}
|
|
crypto_poly1305_final(&ctx, mac);
|
|
.Ed
|
|
.Sh SEE ALSO
|
|
.Xr crypto_blake2b 3monocypher ,
|
|
.Xr crypto_lock 3monocypher ,
|
|
.Xr crypto_verify16 3monocypher ,
|
|
.Xr intro 3monocypher
|
|
.Sh STANDARDS
|
|
These functions implement Poly1305, described in RFC 8439.
|
|
.Sh HISTORY
|
|
The
|
|
.Fn crypto_poly1305_init ,
|
|
.Fn crypto_poly1305_update ,
|
|
and
|
|
.Fn crypto_poly1305_final
|
|
functions first appeared in Monocypher 0.1.
|
|
.Fn crypto_poly1305
|
|
first appeared in Monocypher 1.1.0.
|
|
.Sh SECURITY CONSIDERATIONS
|
|
Poly1305 is difficult to use correctly.
|
|
Do not use it unless you are absolutely sure what you are doing.
|
|
Use authenticated encryption instead; see
|
|
.Xr crypto_lock 3monocypher .
|
|
If you are certain you do not want encryption, refer to
|
|
.Xr crypto_blake2b 3monocypher
|
|
on how to use Blake2b to generate message authentication codes.
|
|
.Ss Authentication key requirements
|
|
Poly1305 is a
|
|
.Em one-time
|
|
authenticator.
|
|
This puts rather stringent constraints on the authentication key:
|
|
.Bl -bullet
|
|
.It
|
|
Any given key must be used only once.
|
|
Using the same key for two different messages reveals it to the
|
|
attacker.
|
|
Do not use the session key, or it will void all security.
|
|
.It
|
|
Authentication keys must be random, and independent from each other.
|
|
Do not use non-random nonces.
|
|
Do not use related keys.
|
|
Use fresh, unpredictable, uniformly distributed random numbers.
|
|
.It
|
|
The key must be transmitted to the recipient without revealing it to the
|
|
attacker.
|
|
Somehow.
|
|
.El
|
|
.Pp
|
|
The only practical source for the authentication key is a chunk of the
|
|
encryption stream used to encrypt the message.
|
|
That chunk must be
|
|
.Em dedicated
|
|
to the authentication key:
|
|
if it is reused to encrypt the message itself, the attacker may recover
|
|
that chunk by guessing the message, then forge arbitrary messages.
|
|
.Pp
|
|
To get this right, you need a session key, a
|
|
.Em unique
|
|
nonce, and a
|
|
stream cipher.
|
|
Generate a stream with the session key and nonce.
|
|
Take the first 32 bytes of that stream as your authentication key, then
|
|
use the
|
|
.Em rest
|
|
of the stream to encrypt your message.
|
|
This is the approach used by
|
|
.Xr crypto_lock_aead 3monocypher .
|
|
.Ss Protection against side channels
|
|
Use
|
|
.Xr crypto_verify16 3monocypher
|
|
to compare message authentication codes.
|
|
Avoid standard buffer comparison functions.
|
|
They may not run in constant time, enabling an attacker to exploit timing
|
|
attacks to recover the MAC.
|
|
.Pp
|
|
The authentication key should be wiped with
|
|
.Xr crypto_wipe 3monocypher
|
|
after use.
|
|
.Pp
|
|
The incremental interface automatically wipes its context when finished
|
|
so users do not need to do it themselves.
|