/*
 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/* Based on https://131002.net/siphash C reference implementation */
/*
   SipHash reference C implementation

   Copyright (c) 2012-2016 Jean-Philippe Aumasson
   <jeanphilippe.aumasson@gmail.com>
   Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>

   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 <stdlib.h>
#include <string.h>
#include <openssl/crypto.h>

#include "internal/siphash.h"
#include "siphash_local.h"

/* default: SipHash-2-4 */
#define SIPHASH_C_ROUNDS 2
#define SIPHASH_D_ROUNDS 4

#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))

#define U32TO8_LE(p, v)                                                        \
    (p)[0] = (uint8_t)((v));                                                   \
    (p)[1] = (uint8_t)((v) >> 8);                                              \
    (p)[2] = (uint8_t)((v) >> 16);                                             \
    (p)[3] = (uint8_t)((v) >> 24);

#define U64TO8_LE(p, v)                                                        \
    U32TO8_LE((p), (uint32_t)((v)));                                           \
    U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));

#define U8TO64_LE(p)                                                           \
    (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |                        \
     ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) |                 \
     ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) |                 \
     ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))

#define SIPROUND                                                               \
    do {                                                                       \
        v0 += v1;                                                              \
        v1 = ROTL(v1, 13);                                                     \
        v1 ^= v0;                                                              \
        v0 = ROTL(v0, 32);                                                     \
        v2 += v3;                                                              \
        v3 = ROTL(v3, 16);                                                     \
        v3 ^= v2;                                                              \
        v0 += v3;                                                              \
        v3 = ROTL(v3, 21);                                                     \
        v3 ^= v0;                                                              \
        v2 += v1;                                                              \
        v1 = ROTL(v1, 17);                                                     \
        v1 ^= v2;                                                              \
        v2 = ROTL(v2, 32);                                                     \
    } while (0)

size_t SipHash_ctx_size(void)
{
    return sizeof(SIPHASH);
}

size_t SipHash_hash_size(SIPHASH *ctx)
{
    return ctx->hash_size;
}

/* hash_size = crounds = drounds = 0 means SipHash24 with 16-byte output */
int SipHash_Init(SIPHASH *ctx, const unsigned char *k, int hash_size, int crounds, int drounds)
{
    uint64_t k0 = U8TO64_LE(k);
    uint64_t k1 = U8TO64_LE(k + 8);

    if (hash_size == 0)
        hash_size = SIPHASH_MAX_DIGEST_SIZE;
    else if (hash_size != SIPHASH_MIN_DIGEST_SIZE &&
             hash_size != SIPHASH_MAX_DIGEST_SIZE)
        return 0;

    if (drounds == 0)
        drounds = SIPHASH_D_ROUNDS;
    if (crounds == 0)
        crounds = SIPHASH_C_ROUNDS;

    ctx->crounds = crounds;
    ctx->drounds = drounds;
    ctx->hash_size = hash_size;

    ctx->len = 0;
    ctx->total_inlen = 0;

    ctx->v0 = 0x736f6d6570736575ULL ^ k0;
    ctx->v1 = 0x646f72616e646f6dULL ^ k1;
    ctx->v2 = 0x6c7967656e657261ULL ^ k0;
    ctx->v3 = 0x7465646279746573ULL ^ k1;

    if (ctx->hash_size == SIPHASH_MAX_DIGEST_SIZE)
        ctx->v1 ^= 0xee;

    return 1;
}

void SipHash_Update(SIPHASH *ctx, const unsigned char *in, size_t inlen)
{
    uint64_t m;
    const uint8_t *end;
    int left;
    int i;
    uint64_t v0 = ctx->v0;
    uint64_t v1 = ctx->v1;
    uint64_t v2 = ctx->v2;
    uint64_t v3 = ctx->v3;

    ctx->total_inlen += inlen;

    if (ctx->len) {
        /* deal with leavings */
        size_t available = SIPHASH_BLOCK_SIZE - ctx->len;

        /* not enough to fill leavings */
        if (inlen < available) {
            memcpy(&ctx->leavings[ctx->len], in, inlen);
            ctx->len += inlen;
            return;
        }

        /* copy data into leavings and reduce input */
        memcpy(&ctx->leavings[ctx->len], in, available);
        inlen -= available;
        in += available;

        /* process leavings */
        m = U8TO64_LE(ctx->leavings);
        v3 ^= m;
        for (i = 0; i < ctx->crounds; ++i)
            SIPROUND;
        v0 ^= m;
    }
    left = inlen & (SIPHASH_BLOCK_SIZE-1); /* gets put into leavings */
    end = in + inlen - left;

    for (; in != end; in += 8) {
        m = U8TO64_LE(in);
        v3 ^= m;
        for (i = 0; i < ctx->crounds; ++i)
            SIPROUND;
        v0 ^= m;
    }

    /* save leavings and other ctx */
    if (left)
        memcpy(ctx->leavings, end, left);
    ctx->len = left;

    ctx->v0 = v0;
    ctx->v1 = v1;
    ctx->v2 = v2;
    ctx->v3 = v3;
}

int SipHash_Final(SIPHASH *ctx, unsigned char *out, size_t outlen)
{
    /* finalize hash */
    int i;
    uint64_t b = ctx->total_inlen << 56;
    uint64_t v0 = ctx->v0;
    uint64_t v1 = ctx->v1;
    uint64_t v2 = ctx->v2;
    uint64_t v3 = ctx->v3;

    if (outlen != (size_t)ctx->hash_size)
        return 0;

    switch (ctx->len) {
    case 7:
        b |= ((uint64_t)ctx->leavings[6]) << 48;
        /* fall thru */
    case 6:
        b |= ((uint64_t)ctx->leavings[5]) << 40;
        /* fall thru */
    case 5:
        b |= ((uint64_t)ctx->leavings[4]) << 32;
        /* fall thru */
    case 4:
        b |= ((uint64_t)ctx->leavings[3]) << 24;
        /* fall thru */
    case 3:
        b |= ((uint64_t)ctx->leavings[2]) << 16;
        /* fall thru */
    case 2:
        b |= ((uint64_t)ctx->leavings[1]) <<  8;
        /* fall thru */
    case 1:
        b |= ((uint64_t)ctx->leavings[0]);
    case 0:
        break;
    }

    v3 ^= b;
    for (i = 0; i < ctx->crounds; ++i)
        SIPROUND;
    v0 ^= b;
    if (ctx->hash_size == SIPHASH_MAX_DIGEST_SIZE)
        v2 ^= 0xee;
    else
        v2 ^= 0xff;
    for (i = 0; i < ctx->drounds; ++i)
        SIPROUND;
    b = v0 ^ v1 ^ v2  ^ v3;
    U64TO8_LE(out, b);
    if (ctx->hash_size == SIPHASH_MIN_DIGEST_SIZE)
        return 1;
    v1 ^= 0xdd;
    for (i = 0; i < ctx->drounds; ++i)
        SIPROUND;
    b = v0 ^ v1 ^ v2  ^ v3;
    U64TO8_LE(out + 8, b);
    return 1;
}
