|
Packit |
141393 |
/*
|
|
Packit |
141393 |
* Copyright (C) 2006-2010 Vincent Hanquez <vincent@snarc.org>
|
|
Packit |
141393 |
*
|
|
Packit |
141393 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
141393 |
* modification, are permitted provided that the following conditions
|
|
Packit |
141393 |
* are met:
|
|
Packit |
141393 |
* 1. Redistributions of source code must retain the above copyright
|
|
Packit |
141393 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
141393 |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
Packit |
141393 |
* notice, this list of conditions and the following disclaimer in the
|
|
Packit |
141393 |
* documentation and/or other materials provided with the distribution.
|
|
Packit |
141393 |
*
|
|
Packit |
141393 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
Packit |
141393 |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
Packit |
141393 |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
Packit |
141393 |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
Packit |
141393 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
Packit |
141393 |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
141393 |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
141393 |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
141393 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
Packit |
141393 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
141393 |
*/
|
|
Packit |
141393 |
|
|
Packit |
141393 |
#include <string.h>
|
|
Packit |
141393 |
#include "cryptonite_skein.h"
|
|
Packit |
141393 |
#include "cryptonite_skein256.h"
|
|
Packit |
141393 |
#include "cryptonite_bitfn.h"
|
|
Packit |
141393 |
#include "cryptonite_align.h"
|
|
Packit |
141393 |
|
|
Packit |
141393 |
static const uint8_t K256_0[2] = { 14, 16, };
|
|
Packit |
141393 |
static const uint8_t K256_1[2] = { 52, 57, };
|
|
Packit |
141393 |
static const uint8_t K256_2[2] = { 23, 40, };
|
|
Packit |
141393 |
static const uint8_t K256_3[2] = { 5, 37, };
|
|
Packit |
141393 |
static const uint8_t K256_4[2] = { 25, 33, };
|
|
Packit |
141393 |
static const uint8_t K256_5[2] = { 46, 12, };
|
|
Packit |
141393 |
static const uint8_t K256_6[2] = { 58, 22, };
|
|
Packit |
141393 |
static const uint8_t K256_7[2] = { 32, 32, };
|
|
Packit |
141393 |
|
|
Packit |
141393 |
static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, uint32_t len)
|
|
Packit |
141393 |
{
|
|
Packit |
141393 |
uint64_t x[4];
|
|
Packit |
141393 |
uint64_t ts[3];
|
|
Packit |
141393 |
uint64_t ks[4+1];
|
|
Packit |
141393 |
|
|
Packit |
141393 |
ks[4] = 0x1bd11bdaa9fc1a22ULL;
|
|
Packit |
141393 |
ks[0] = ctx->h[0]; ks[4] ^= ctx->h[0];
|
|
Packit |
141393 |
ks[1] = ctx->h[1]; ks[4] ^= ctx->h[1];
|
|
Packit |
141393 |
ks[2] = ctx->h[2]; ks[4] ^= ctx->h[2];
|
|
Packit |
141393 |
ks[3] = ctx->h[3]; ks[4] ^= ctx->h[3];
|
|
Packit |
141393 |
|
|
Packit |
141393 |
ts[0] = ctx->t0;
|
|
Packit |
141393 |
ts[1] = ctx->t1;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
ts[0] += len;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
ts[2] = ts[0] ^ ts[1];
|
|
Packit |
141393 |
|
|
Packit |
141393 |
#define INJECTKEY(r) \
|
|
Packit |
141393 |
x[0] += ks[((r)+0) % (4+1)]; \
|
|
Packit |
141393 |
x[1] += ks[((r)+1) % (4+1)] + ts[((r)+0) % 3]; \
|
|
Packit |
141393 |
x[2] += ks[((r)+2) % (4+1)] + ts[((r)+1) % 3]; \
|
|
Packit |
141393 |
x[3] += ks[((r)+3) % (4+1)] + (r)
|
|
Packit |
141393 |
|
|
Packit |
141393 |
#define ROUND(a,b,c,d,k) \
|
|
Packit |
141393 |
x[a] += x[b]; x[b] = rol64(x[b],k[0]); x[b] ^= x[a]; \
|
|
Packit |
141393 |
x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c];
|
|
Packit |
141393 |
|
|
Packit |
141393 |
#define PASS(i) \
|
|
Packit |
141393 |
ROUND(0,1,2,3,K256_0); \
|
|
Packit |
141393 |
ROUND(0,3,2,1,K256_1); \
|
|
Packit |
141393 |
ROUND(0,1,2,3,K256_2); \
|
|
Packit |
141393 |
ROUND(0,3,2,1,K256_3); \
|
|
Packit |
141393 |
INJECTKEY((i*2) + 1); \
|
|
Packit |
141393 |
ROUND(0,1,2,3,K256_4); \
|
|
Packit |
141393 |
ROUND(0,3,2,1,K256_5); \
|
|
Packit |
141393 |
ROUND(0,1,2,3,K256_6); \
|
|
Packit |
141393 |
ROUND(0,3,2,1,K256_7); \
|
|
Packit |
141393 |
INJECTKEY((i*2) + 2)
|
|
Packit |
141393 |
|
|
Packit |
141393 |
x[0] = le64_to_cpu(buf[0]) + ks[0];
|
|
Packit |
141393 |
x[1] = le64_to_cpu(buf[1]) + ks[1] + ts[0];
|
|
Packit |
141393 |
x[2] = le64_to_cpu(buf[2]) + ks[2] + ts[1];
|
|
Packit |
141393 |
x[3] = le64_to_cpu(buf[3]) + ks[3];
|
|
Packit |
141393 |
|
|
Packit |
141393 |
/* 9 pass of 8 rounds = 72 rounds */
|
|
Packit |
141393 |
PASS(0);
|
|
Packit |
141393 |
PASS(1);
|
|
Packit |
141393 |
PASS(2);
|
|
Packit |
141393 |
PASS(3);
|
|
Packit |
141393 |
PASS(4);
|
|
Packit |
141393 |
PASS(5);
|
|
Packit |
141393 |
PASS(6);
|
|
Packit |
141393 |
PASS(7);
|
|
Packit |
141393 |
PASS(8);
|
|
Packit |
141393 |
|
|
Packit |
141393 |
ts[1] &= ~FLAG_FIRST;
|
|
Packit |
141393 |
ctx->t0 = ts[0];
|
|
Packit |
141393 |
ctx->t1 = ts[1];
|
|
Packit |
141393 |
|
|
Packit |
141393 |
ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]);
|
|
Packit |
141393 |
ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]);
|
|
Packit |
141393 |
ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]);
|
|
Packit |
141393 |
ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]);
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
|
|
Packit |
141393 |
void cryptonite_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen)
|
|
Packit |
141393 |
{
|
|
Packit |
141393 |
uint64_t buf[4];
|
|
Packit |
141393 |
memset(ctx, 0, sizeof(*ctx));
|
|
Packit |
141393 |
|
|
Packit |
141393 |
SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG));
|
|
Packit |
141393 |
|
|
Packit |
141393 |
memset(buf, '\0', sizeof(buf));
|
|
Packit |
141393 |
buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING);
|
|
Packit |
141393 |
buf[1] = cpu_to_le64(hashlen);
|
|
Packit |
141393 |
buf[2] = 0; /* tree info, not implemented */
|
|
Packit |
141393 |
skein256_do_chunk(ctx, buf, 4*8);
|
|
Packit |
141393 |
|
|
Packit |
141393 |
SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG));
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
|
|
Packit |
141393 |
void cryptonite_skein256_update(struct skein256_ctx *ctx, const uint8_t *data, uint32_t len)
|
|
Packit |
141393 |
{
|
|
Packit |
141393 |
uint32_t to_fill;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
if (!len)
|
|
Packit |
141393 |
return;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
to_fill = 32 - ctx->bufindex;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
if (ctx->bufindex == 32) {
|
|
Packit |
141393 |
skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);
|
|
Packit |
141393 |
ctx->bufindex = 0;
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
|
|
Packit |
141393 |
/* process partial buffer if there's enough data to make a block
|
|
Packit |
141393 |
* and there's without doubt further blocks */
|
|
Packit |
141393 |
if (ctx->bufindex && len > to_fill) {
|
|
Packit |
141393 |
memcpy(ctx->buf + ctx->bufindex, data, to_fill);
|
|
Packit |
141393 |
skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);
|
|
Packit |
141393 |
len -= to_fill;
|
|
Packit |
141393 |
data += to_fill;
|
|
Packit |
141393 |
ctx->bufindex = 0;
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
|
|
Packit |
141393 |
if (need_alignment(data, 8)) {
|
|
Packit |
141393 |
uint64_t tramp[4];
|
|
Packit |
141393 |
ASSERT_ALIGNMENT(tramp, 8);
|
|
Packit |
141393 |
for (; len > 32; len -= 32, data += 32) {
|
|
Packit |
141393 |
memcpy(tramp, data, 32);
|
|
Packit |
141393 |
skein256_do_chunk(ctx, tramp, 32);
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
} else {
|
|
Packit |
141393 |
/* process as much 32-block as possible except the last one in case we finalize */
|
|
Packit |
141393 |
for (; len > 32; len -= 32, data += 32)
|
|
Packit |
141393 |
skein256_do_chunk(ctx, (uint64_t *) data, 32);
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
|
|
Packit |
141393 |
/* append data into buf */
|
|
Packit |
141393 |
if (len) {
|
|
Packit |
141393 |
memcpy(ctx->buf + ctx->bufindex, data, len);
|
|
Packit |
141393 |
ctx->bufindex += len;
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
|
|
Packit |
141393 |
void cryptonite_skein256_finalize(struct skein256_ctx *ctx, uint32_t hashlen, uint8_t *out)
|
|
Packit |
141393 |
{
|
|
Packit |
141393 |
uint32_t outsize;
|
|
Packit |
141393 |
uint64_t *p = (uint64_t *) out;
|
|
Packit |
141393 |
uint64_t x[4];
|
|
Packit |
141393 |
int i, j, n;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
ctx->t1 |= FLAG_FINAL;
|
|
Packit |
141393 |
/* if buf is not complete pad with 0 bytes */
|
|
Packit |
141393 |
if (ctx->bufindex < 32)
|
|
Packit |
141393 |
memset(ctx->buf + ctx->bufindex, '\0', 32 - ctx->bufindex);
|
|
Packit |
141393 |
skein256_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex);
|
|
Packit |
141393 |
|
|
Packit |
141393 |
memset(ctx->buf, '\0', 32);
|
|
Packit |
141393 |
|
|
Packit |
141393 |
/* make sure we have a 8 bit up rounded value */
|
|
Packit |
141393 |
outsize = (hashlen + 7) >> 3;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
/* backup h[0--4] */
|
|
Packit |
141393 |
for (j = 0; j < 4; j++)
|
|
Packit |
141393 |
x[j] = ctx->h[j];
|
|
Packit |
141393 |
/* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */
|
|
Packit |
141393 |
for (i = 0; i*32 < outsize; i++) {
|
|
Packit |
141393 |
uint64_t w[4];
|
|
Packit |
141393 |
*((uint64_t *) ctx->buf) = cpu_to_le64(i);
|
|
Packit |
141393 |
SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT));
|
|
Packit |
141393 |
skein256_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t));
|
|
Packit |
141393 |
|
|
Packit |
141393 |
n = outsize - i * 32;
|
|
Packit |
141393 |
if (n >= 32) n = 32;
|
|
Packit |
141393 |
|
|
Packit |
141393 |
cpu_to_le64_array(w, ctx->h, 4);
|
|
Packit |
141393 |
memcpy(out + i*32, w, n);
|
|
Packit |
141393 |
|
|
Packit |
141393 |
/* restore h[0--4] */
|
|
Packit |
141393 |
for (j = 0; j < 4; j++)
|
|
Packit |
141393 |
ctx->h[j] = x[j];
|
|
Packit |
141393 |
}
|
|
Packit |
141393 |
}
|