On Tue, Oct 27, 2015 at 14:16 +0100, Mike Belopuhov wrote:
> On Mon, Oct 26, 2015 at 18:29 +0100, Mike Belopuhov wrote:
> > OK?
> >
>
> Update due to poly1305.{c,h} changes.
>
3rd update.
I've been asked to use numbers (20 for Chacha and 1305 for Poly)
in function/object names more consistently or rather always.
This also includes a minor change in the Update method: due to the
fact that we use a stock poly1305.c implementation that supports
arbitrary input lengths we can use the same trick reyk@ does in his
Libressl code and avoid additional code performing a data copy into
a temporary buffer.
Note that this will *not* avoid data copy: when poly1305_update is
called on an incomplete buffer it will store up to 15 last bytes of
input in the buffer within its context and will perform an actual
computation when remaining bytes (data or zeroes) are provided or
poly1305_finish is called whichever occurs first. Therefore this
change just simplifies the Chacha20_Poly1305_Update method slightly.
I have verified that this passes test vectors (an update is needed
due to the change of function names) and works against old code as
well as against itself in IPsec.
Please note that the next diff ChachaPoly-04 will require an update
as well due to the function name changes.
OK?
---
sys/crypto/chachapoly.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
sys/crypto/chachapoly.h | 66 +++++++++++++++++++++++++++++
2 files changed, 173 insertions(+)
create mode 100644 sys/crypto/chachapoly.c
create mode 100644 sys/crypto/chachapoly.h
diff --git sys/crypto/chachapoly.c sys/crypto/chachapoly.c
new file mode 100644
index 0000000..647a8dd
--- /dev/null
+++ sys/crypto/chachapoly.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 Mike Belopuhov
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <crypto/chacha_private.h>
+#include <crypto/poly1305.h>
+#include <crypto/chachapoly.h>
+
+int
+chacha20_setkey(void *sched, u_int8_t *key, int len)
+{
+ struct chacha20_ctx *ctx = (struct chacha20_ctx *)sched;
+
+ if (len != CHACHA20_KEYSIZE + CHACHA20_SALT)
+ return (-1);
+
+ /* initial counter is 1 */
+ ctx->nonce[0] = 1;
+ memcpy(ctx->nonce + CHACHA20_CTR, key + CHACHA20_KEYSIZE,
+ CHACHA20_SALT);
+ chacha_keysetup((chacha_ctx *)&ctx->block, key, CHACHA20_KEYSIZE * 8);
+ return (0);
+}
+
+void
+chacha20_reinit(caddr_t key, u_int8_t *iv)
+{
+ struct chacha20_ctx *ctx = (struct chacha20_ctx *)key;
+
+ chacha_ivsetup((chacha_ctx *)ctx->block, iv, ctx->nonce);
+}
+
+void
+chacha20_crypt(caddr_t key, u_int8_t *data)
+{
+ struct chacha20_ctx *ctx = (struct chacha20_ctx *)key;
+
+ chacha_encrypt_bytes((chacha_ctx *)ctx->block, data, data,
+ CHACHA20_BLOCK_LEN);
+}
+
+void
+Chacha20_Poly1305_Init(CHACHA20_POLY1305_CTX *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+void
+Chacha20_Poly1305_Setkey(CHACHA20_POLY1305_CTX *ctx, const uint8_t *key,
+ uint16_t klen)
+{
+ /* salt is part of the nonce */
+ memcpy(ctx->nonce + CHACHA20_CTR, key + CHACHA20_KEYSIZE,
+ CHACHA20_SALT);
+ chacha_keysetup((chacha_ctx *)&ctx->chacha, key, CHACHA20_KEYSIZE * 8);
+}
+
+void
+Chacha20_Poly1305_Reinit(CHACHA20_POLY1305_CTX *ctx, const uint8_t *iv,
+ uint16_t ivlen)
+{
+ /* initial counter is 0 */
+ chacha_ivsetup((chacha_ctx *)&ctx->chacha, iv, ctx->nonce);
+ chacha_encrypt_bytes((chacha_ctx *)&ctx->chacha, ctx->key, ctx->key,
+ POLY1305_KEYLEN);
+ poly1305_init((poly1305_state *)&ctx->poly, ctx->key);
+}
+
+int
+Chacha20_Poly1305_Update(CHACHA20_POLY1305_CTX *ctx, const uint8_t *data,
+ uint16_t len)
+{
+ static const char zeroes[POLY1305_BLOCK_LEN];
+ size_t rem;
+
+ poly1305_update((poly1305_state *)&ctx->poly, data, len);
+
+ /* Number of bytes in the last 16 byte block */
+ rem = (len + POLY1305_BLOCK_LEN) & (POLY1305_BLOCK_LEN - 1);
+ if (rem > 0)
+ poly1305_update((poly1305_state *)&ctx->poly, zeroes,
+ POLY1305_BLOCK_LEN - rem);
+ return (0);
+}
+
+void
+Chacha20_Poly1305_Final(uint8_t tag[POLY1305_TAGLEN],
+ CHACHA20_POLY1305_CTX *ctx)
+{
+ poly1305_finish((poly1305_state *)&ctx->poly, tag);
+ explicit_bzero(ctx, sizeof(*ctx));
+}
diff --git sys/crypto/chachapoly.h sys/crypto/chachapoly.h
new file mode 100644
index 0000000..b2f1622
--- /dev/null
+++ sys/crypto/chachapoly.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 Mike Belopuhov
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CHACHAPOLY_H_
+#define _CHACHAPOLY_H_
+
+#define CHACHA20_KEYSIZE 32
+#define CHACHA20_CTR 4
+#define CHACHA20_SALT 4
+#define CHACHA20_NONCE 8
+#define CHACHA20_BLOCK_LEN 64
+
+struct chacha20_ctx {
+ uint8_t block[CHACHA20_BLOCK_LEN];
+ uint8_t nonce[CHACHA20_NONCE];
+};
+
+int chacha20_setkey(void *, u_int8_t *, int);
+void chacha20_reinit(caddr_t, u_int8_t *);
+void chacha20_crypt(caddr_t, u_int8_t *);
+
+
+#define POLY1305_KEYLEN 32
+#define POLY1305_TAGLEN 16
+#define POLY1305_BLOCK_LEN 16
+
+struct poly1305_ctx {
+ /* r, h, pad, leftover */
+ unsigned long state[5+5+4];
+ size_t leftover;
+ unsigned char buffer[POLY1305_BLOCK_LEN];
+ unsigned char final;
+};
+
+typedef struct {
+ uint8_t key[POLY1305_KEYLEN];
+ /* counter, salt */
+ uint8_t nonce[CHACHA20_NONCE];
+ struct chacha20_ctx chacha;
+ struct poly1305_ctx poly;
+} CHACHA20_POLY1305_CTX;
+
+void Chacha20_Poly1305_Init(CHACHA20_POLY1305_CTX *);
+void Chacha20_Poly1305_Setkey(CHACHA20_POLY1305_CTX *, const uint8_t *,
+ uint16_t);
+void Chacha20_Poly1305_Reinit(CHACHA20_POLY1305_CTX *, const uint8_t *,
+ uint16_t);
+int Chacha20_Poly1305_Update(CHACHA20_POLY1305_CTX *, const uint8_t *,
+ uint16_t);
+void Chacha20_Poly1305_Final(uint8_t[POLY1305_TAGLEN],
+ CHACHA20_POLY1305_CTX *);
+
+#endif /* _CHACHAPOLY_H_ */
--
2.6.2