summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c
new file mode 100644
index 00000000..7a3bf382
--- /dev/null
+++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c
@@ -0,0 +1,161 @@
+/*
+ * cifra - embedded cryptography library
+ * Written in 2014 by Joseph Birr-Pixton <jpixton@gmail.com>
+ *
+ * To the extent possible under law, the author(s) have dedicated all
+ * copyright and related and 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
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "bitops.h"
+#include "salsa20.h"
+#include "blockwise.h"
+#include "tassert.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+void cf_chacha20_core(const uint8_t key0[16],
+ const uint8_t key1[16],
+ const uint8_t nonce[16],
+ const uint8_t constant[16],
+ uint8_t out[64])
+{
+ uint32_t z0, z1, z2, z3, z4, z5, z6, z7,
+ z8, z9, za, zb, zc, zd, ze, zf;
+
+ uint32_t x0 = z0 = read32_le(constant + 0),
+ x1 = z1 = read32_le(constant + 4),
+ x2 = z2 = read32_le(constant + 8),
+ x3 = z3 = read32_le(constant + 12),
+ x4 = z4 = read32_le(key0 + 0),
+ x5 = z5 = read32_le(key0 + 4),
+ x6 = z6 = read32_le(key0 + 8),
+ x7 = z7 = read32_le(key0 + 12),
+ x8 = z8 = read32_le(key1 + 0),
+ x9 = z9 = read32_le(key1 + 4),
+ xa = za = read32_le(key1 + 8),
+ xb = zb = read32_le(key1 + 12),
+ xc = zc = read32_le(nonce + 0),
+ xd = zd = read32_le(nonce + 4),
+ xe = ze = read32_le(nonce + 8),
+ xf = zf = read32_le(nonce + 12);
+
+#define QUARTER(a, b, c, d) \
+ a += b; d = rotl32(d ^ a, 16); \
+ c += d; b = rotl32(b ^ c, 12); \
+ a += b; d = rotl32(d ^ a, 8); \
+ c += d; b = rotl32(b ^ c, 7);
+
+ int i;
+ for (i = 0; i < 10; i++)
+ {
+ QUARTER(z0, z4, z8, zc);
+ QUARTER(z1, z5, z9, zd);
+ QUARTER(z2, z6, za, ze);
+ QUARTER(z3, z7, zb, zf);
+ QUARTER(z0, z5, za, zf);
+ QUARTER(z1, z6, zb, zc);
+ QUARTER(z2, z7, z8, zd);
+ QUARTER(z3, z4, z9, ze);
+ }
+
+ x0 += z0;
+ x1 += z1;
+ x2 += z2;
+ x3 += z3;
+ x4 += z4;
+ x5 += z5;
+ x6 += z6;
+ x7 += z7;
+ x8 += z8;
+ x9 += z9;
+ xa += za;
+ xb += zb;
+ xc += zc;
+ xd += zd;
+ xe += ze;
+ xf += zf;
+
+ write32_le(x0, out + 0);
+ write32_le(x1, out + 4);
+ write32_le(x2, out + 8);
+ write32_le(x3, out + 12);
+ write32_le(x4, out + 16);
+ write32_le(x5, out + 20);
+ write32_le(x6, out + 24);
+ write32_le(x7, out + 28);
+ write32_le(x8, out + 32);
+ write32_le(x9, out + 36);
+ write32_le(xa, out + 40);
+ write32_le(xb, out + 44);
+ write32_le(xc, out + 48);
+ write32_le(xd, out + 52);
+ write32_le(xe, out + 56);
+ write32_le(xf, out + 60);
+}
+
+static const uint8_t *chacha20_tau = (const uint8_t *) "expand 16-byte k";
+static const uint8_t *chacha20_sigma = (const uint8_t *) "expand 32-byte k";
+
+static void set_key(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey)
+{
+ switch (nkey)
+ {
+ case 16:
+ memcpy(ctx->key0, key, 16);
+ memcpy(ctx->key1, key, 16);
+ ctx->constant = chacha20_tau;
+ break;
+ case 32:
+ memcpy(ctx->key0, key, 16);
+ memcpy(ctx->key1, key + 16, 16);
+ ctx->constant = chacha20_sigma;
+ break;
+ default:
+ abort();
+ }
+}
+
+void cf_chacha20_init(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey, const uint8_t nonce[8])
+{
+ set_key(ctx, key, nkey);
+ memset(ctx->nonce, 0, sizeof ctx->nonce);
+ memcpy(ctx->nonce + 8, nonce, 8);
+ ctx->nblock = 0;
+ ctx->ncounter = 8;
+}
+
+void cf_chacha20_init_custom(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey,
+ const uint8_t nonce[16], size_t ncounter)
+{
+ assert(ncounter > 0);
+ set_key(ctx, key, nkey);
+ memcpy(ctx->nonce, nonce, sizeof ctx->nonce);
+ ctx->nblock = 0;
+ ctx->ncounter = ncounter;
+}
+
+static void cf_chacha20_next_block(void *vctx, uint8_t *out)
+{
+ cf_chacha20_ctx *ctx = vctx;
+ cf_chacha20_core(ctx->key0,
+ ctx->key1,
+ ctx->nonce,
+ ctx->constant,
+ out);
+ incr_le(ctx->nonce, ctx->ncounter);
+}
+
+void cf_chacha20_cipher(cf_chacha20_ctx *ctx, const uint8_t *input, uint8_t *output, size_t bytes)
+{
+ cf_blockwise_xor(ctx->block, &ctx->nblock, 64,
+ input, output, bytes,
+ cf_chacha20_next_block,
+ ctx);
+}