/*
 * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (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
   Copyright (c) 2012-2014 Daniel J. Bernstein

   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 "crypto/siphash.h"

#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;
}

static size_t siphash_adjust_hash_size(size_t hash_size)
{
    if (hash_size == 0)
        hash_size = SIPHASH_MAX_DIGEST_SIZE;
    return hash_size;
}

int SipHash_set_hash_size(SIPHASH *ctx, size_t hash_size)
{
    hash_size = siphash_adjust_hash_size(hash_size);
    if (hash_size != SIPHASH_MIN_DIGEST_SIZE
        && hash_size != SIPHASH_MAX_DIGEST_SIZE)
        return 0;

    /*
     * It's possible that the key was set first.  If the hash size changes,
     * we need to adjust v1 (see SipHash_Init().
     */

    /* Start by adjusting the stored size, to make things easier */
    ctx->hash_size = siphash_adjust_hash_size(ctx->hash_size);

    /* Now, adjust ctx->v1 if the old and the new size differ */
    if ((size_t)ctx->hash_size != hash_size) {
        ctx->v1 ^= 0xee;
        ctx->hash_size = hash_size;
    }
    return 1;
}

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

    /* If the hash size wasn't set, i.e. is zero */
    ctx->hash_size = siphash_adjust_hash_size(ctx->hash_size);

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

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

    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;
    unsigned 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 */
    unsigned 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 (ctx->crounds == 0 || outlen == 0 || 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;
}
