diff options
Diffstat (limited to '')
-rw-r--r-- | web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c new file mode 100644 index 00000000..34bd1562 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c @@ -0,0 +1,164 @@ +/* + * 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 "salsa20.h" +#include "bitops.h" +#include "blockwise.h" + +#include <string.h> +#include <stdlib.h> + +void cf_salsa20_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]) +{ + /* unpack sequence is: + * + * c0 + * key0 + * c1 + * nonce + * c2 + * key1 + * c3 + * + * where c0, c1, c2, c3 = constant + */ + + 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(key0 + 0), + x2 = z2 = read32_le(key0 + 4), + x3 = z3 = read32_le(key0 + 8), + x4 = z4 = read32_le(key0 + 12), + x5 = z5 = read32_le(constant + 4), + x6 = z6 = read32_le(nonce + 0), + x7 = z7 = read32_le(nonce + 4), + x8 = z8 = read32_le(nonce + 8), + x9 = z9 = read32_le(nonce + 12), + xa = za = read32_le(constant + 8), + xb = zb = read32_le(key1 + 0), + xc = zc = read32_le(key1 + 4), + xd = zd = read32_le(key1 + 8), + xe = ze = read32_le(key1 + 12), + xf = zf = read32_le(constant + 12); + +#define QUARTER(v0, v1, v2, v3) \ + v1 ^= rotl32(v0 + v3, 7); \ + v2 ^= rotl32(v1 + v0, 9); \ + v3 ^= rotl32(v2 + v1, 13);\ + v0 ^= rotl32(v3 + v2, 18) + +#define ROW \ + QUARTER(z0, z1, z2, z3); \ + QUARTER(z5, z6, z7, z4); \ + QUARTER(za, zb, z8, z9); \ + QUARTER(zf, zc, zd, ze) + +#define COLUMN\ + QUARTER(z0, z4, z8, zc); \ + QUARTER(z5, z9, zd, z1); \ + QUARTER(za, ze, z2, z6); \ + QUARTER(zf, z3, z7, zb) + + for (int i = 0; i < 10; i++) + { + COLUMN; + ROW; + } + + 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 *salsa20_tau = (const uint8_t *) "expand 16-byte k"; +static const uint8_t *salsa20_sigma = (const uint8_t *) "expand 32-byte k"; + +void cf_salsa20_init(cf_salsa20_ctx *ctx, const uint8_t *key, size_t nkey, const uint8_t nonce[8]) +{ + switch (nkey) + { + case 16: + memcpy(ctx->key0, key, 16); + memcpy(ctx->key1, key, 16); + ctx->constant = salsa20_tau; + break; + case 32: + memcpy(ctx->key0, key, 16); + memcpy(ctx->key1, key + 16, 16); + ctx->constant = salsa20_sigma; + break; + default: + abort(); + } + + memset(ctx->nonce, 0, sizeof ctx->nonce); + memcpy(ctx->nonce + 8, nonce, 8); + ctx->nblock = 0; + ctx->ncounter = 8; +} + +static void cf_salsa20_next_block(void *vctx, uint8_t *out) +{ + cf_salsa20_ctx *ctx = vctx; + cf_salsa20_core(ctx->key0, + ctx->key1, + ctx->nonce, + ctx->constant, + out); + incr_le(ctx->nonce, ctx->ncounter); +} + +void cf_salsa20_cipher(cf_salsa20_ctx *ctx, const uint8_t *input, uint8_t *output, size_t bytes) +{ + cf_blockwise_xor(ctx->block, &ctx->nblock, 64, + input, output, bytes, + cf_salsa20_next_block, + ctx); +} |