summaryrefslogtreecommitdiff
path: root/sys/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'sys/crypto')
-rw-r--r--sys/crypto/chachapoly.c107
-rw-r--r--sys/crypto/chachapoly.h66
2 files changed, 173 insertions, 0 deletions
diff --git a/sys/crypto/chachapoly.c b/sys/crypto/chachapoly.c
new file mode 100644
index 00000000000..76d3e591729
--- /dev/null
+++ b/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 provided with the key material */
+ 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 a/sys/crypto/chachapoly.h b/sys/crypto/chachapoly.h
new file mode 100644
index 00000000000..b2f162248ff
--- /dev/null
+++ b/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_ */