/*
 * blake2b.c - definitions for the blake2b hash function
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif

#include "secerr.h"
#include "blapi.h"
#include "blake2b.h"
#include "crypto_primitives.h"

/**
 * This contains the BLAKE2b initialization vectors.
 */
static const uint64_t iv[8] = {
    0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
    0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
    0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
};

/**
 * This contains the table of permutations for blake2b compression function.
 */
static const uint8_t sigma[12][16] = {
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
    { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
    { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
    { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
    { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
    { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
    { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
    { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
    { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
    { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
    { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
};

/**
 * This function increments the blake2b ctx counter.
 */
void
blake2b_IncrementCounter(BLAKE2BContext* ctx, const uint64_t inc)
{
    ctx->t[0] += inc;
    ctx->t[1] += ctx->t[0] < inc;
}

/**
 * This macro implements the blake2b mixing function which mixes two 8-byte
 * words from the message into the hash.
 */
#define G(a, b, c, d, x, y) \
    a += b + x;             \
    d = ROTR64(d ^ a, 32);  \
    c += d;                 \
    b = ROTR64(b ^ c, 24);  \
    a += b + y;             \
    d = ROTR64(d ^ a, 16);  \
    c += d;                 \
    b = ROTR64(b ^ c, 63)

#define ROUND(i)                                                   \
    G(v[0], v[4], v[8], v[12], m[sigma[i][0]], m[sigma[i][1]]);    \
    G(v[1], v[5], v[9], v[13], m[sigma[i][2]], m[sigma[i][3]]);    \
    G(v[2], v[6], v[10], v[14], m[sigma[i][4]], m[sigma[i][5]]);   \
    G(v[3], v[7], v[11], v[15], m[sigma[i][6]], m[sigma[i][7]]);   \
    G(v[0], v[5], v[10], v[15], m[sigma[i][8]], m[sigma[i][9]]);   \
    G(v[1], v[6], v[11], v[12], m[sigma[i][10]], m[sigma[i][11]]); \
    G(v[2], v[7], v[8], v[13], m[sigma[i][12]], m[sigma[i][13]]);  \
    G(v[3], v[4], v[9], v[14], m[sigma[i][14]], m[sigma[i][15]])

/**
 * The blake2b compression function which takes a full 128-byte chunk of the
 * input message and mixes it into the ongoing ctx array, i.e., permute the
 * ctx while xoring in the block of data.
 */
void
blake2b_Compress(BLAKE2BContext* ctx, const uint8_t* block)
{
    size_t i;
    uint64_t v[16], m[16];

    PORT_Memcpy(m, block, BLAKE2B_BLOCK_LENGTH);
#if !defined(IS_LITTLE_ENDIAN)
    for (i = 0; i < 16; ++i) {
        m[i] = FREEBL_HTONLL(m[i]);
    }
#endif

    PORT_Memcpy(v, ctx->h, 8 * 8);
    PORT_Memcpy(v + 8, iv, 8 * 8);

    v[12] ^= ctx->t[0];
    v[13] ^= ctx->t[1];
    v[14] ^= ctx->f;

    ROUND(0);
    ROUND(1);
    ROUND(2);
    ROUND(3);
    ROUND(4);
    ROUND(5);
    ROUND(6);
    ROUND(7);
    ROUND(8);
    ROUND(9);
    ROUND(10);
    ROUND(11);

    for (i = 0; i < 8; i++) {
        ctx->h[i] ^= v[i] ^ v[i + 8];
    }
}

/**
 * This function can be used for both keyed and unkeyed version.
 */
BLAKE2BContext*
BLAKE2B_NewContext()
{
    return PORT_ZNew(BLAKE2BContext);
}

/**
 * Zero and free the context and can be used for both keyed and unkeyed version.
 */
void
BLAKE2B_DestroyContext(BLAKE2BContext* ctx, PRBool freeit)
{
    PORT_Memset(ctx, 0, sizeof(*ctx));
    if (freeit) {
        PORT_Free(ctx);
    }
}

/**
 * This function initializes blake2b ctx and can be used for both keyed and
 * unkeyed version. It also checks ctx and sets error states.
 */
static SECStatus
blake2b_Begin(BLAKE2BContext* ctx, uint8_t outlen, const uint8_t* key,
              size_t keylen)
{
    PORT_Assert(ctx != NULL);
    if (!ctx) {
        goto failure;
    }
    if (outlen == 0 || outlen > BLAKE2B512_LENGTH) {
        goto failure;
    }
    if (key && keylen > BLAKE2B_KEY_SIZE) {
        goto failure;
    }
    /* Note: key can be null if it's unkeyed. */
    if ((key == NULL && keylen > 0) || keylen > BLAKE2B_KEY_SIZE ||
        (key != NULL && keylen == 0)) {
        goto failure;
    }

    /* Mix key size(keylen) and desired hash length(outlen) into h0 */
    uint64_t param = outlen ^ (keylen << 8) ^ (1 << 16) ^ (1 << 24);
    PORT_Memcpy(ctx->h, iv, 8 * 8);
    ctx->h[0] ^= param;
    ctx->outlen = outlen;

    /* This updates the context for only the keyed version */
    if (keylen > 0 && keylen <= BLAKE2B_KEY_SIZE && key) {
        uint8_t block[BLAKE2B_BLOCK_LENGTH] = { 0 };
        PORT_Memcpy(block, key, keylen);
        BLAKE2B_Update(ctx, block, BLAKE2B_BLOCK_LENGTH);
        PORT_Memset(block, 0, BLAKE2B_BLOCK_LENGTH);
    }

    return SECSuccess;

failure:
    PORT_Memset(ctx, 0, sizeof(*ctx));
    PORT_SetError(SEC_ERROR_INVALID_ARGS);
    return SECFailure;
}

SECStatus
BLAKE2B_Begin(BLAKE2BContext* ctx)
{
    return blake2b_Begin(ctx, BLAKE2B512_LENGTH, NULL, 0);
}

SECStatus
BLAKE2B_MAC_Begin(BLAKE2BContext* ctx, const PRUint8* key, const size_t keylen)
{
    PORT_Assert(key != NULL);
    if (!key) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    return blake2b_Begin(ctx, BLAKE2B512_LENGTH, (const uint8_t*)key, keylen);
}

static void
blake2b_IncrementCompress(BLAKE2BContext* ctx, size_t blockLength,
                          const unsigned char* input)
{
    blake2b_IncrementCounter(ctx, blockLength);
    blake2b_Compress(ctx, input);
}

/**
 * This function updates blake2b ctx and can be used for both keyed and unkeyed
 * version.
 */
SECStatus
BLAKE2B_Update(BLAKE2BContext* ctx, const unsigned char* in,
               unsigned int inlen)
{
    size_t left = ctx->buflen;
    size_t fill = BLAKE2B_BLOCK_LENGTH - left;

    /* Nothing to do if there's nothing. */
    if (inlen == 0) {
        return SECSuccess;
    }

    PORT_Assert(ctx != NULL);
    PORT_Assert(in != NULL);
    PORT_Assert(left <= BLAKE2B_BLOCK_LENGTH);
    if (!ctx || !in) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Is this a reused context? */
    if (ctx->f) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (inlen > fill) {
        if (ctx->buflen) {
            /* There's some remaining data in ctx->buf that we have to prepend
             * to in. */
            PORT_Memcpy(ctx->buf + left, in, fill);
            ctx->buflen = 0;
            blake2b_IncrementCompress(ctx, BLAKE2B_BLOCK_LENGTH, ctx->buf);
            in += fill;
            inlen -= fill;
        }
        while (inlen > BLAKE2B_BLOCK_LENGTH) {
            blake2b_IncrementCompress(ctx, BLAKE2B_BLOCK_LENGTH, in);
            in += BLAKE2B_BLOCK_LENGTH;
            inlen -= BLAKE2B_BLOCK_LENGTH;
        }
    }

    /* Store the remaining data from in in ctx->buf to process later.
     * Note that ctx->buflen can be BLAKE2B_BLOCK_LENGTH. We can't process that
     * here because we have to update ctx->f before compressing the last block.
     */
    PORT_Assert(inlen <= BLAKE2B_BLOCK_LENGTH);
    PORT_Memcpy(ctx->buf + ctx->buflen, in, inlen);
    ctx->buflen += inlen;

    return SECSuccess;
}

/**
 * This function finalizes ctx, pads final block and stores hash.
 * It can be used for both keyed and unkeyed version.
 */
SECStatus
BLAKE2B_End(BLAKE2BContext* ctx, unsigned char* out,
            unsigned int* digestLen, size_t maxDigestLen)
{
    size_t i;
    unsigned int outlen = PR_MIN(BLAKE2B512_LENGTH, maxDigestLen);

    /* Argument checks */
    if (!ctx || !out) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Sanity check against outlen in context. */
    if (ctx->outlen < outlen) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Is this a reused context? */
    if (ctx->f != 0) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Process the remaining data from ctx->buf (padded with 0). */
    blake2b_IncrementCounter(ctx, ctx->buflen);
    /* BLAKE2B_BLOCK_LENGTH - ctx->buflen can be 0. */
    PORT_Memset(ctx->buf + ctx->buflen, 0, BLAKE2B_BLOCK_LENGTH - ctx->buflen);
    ctx->f = UINT64_MAX;
    blake2b_Compress(ctx, ctx->buf);

    /* Write out the blake2b context(ctx). */
    for (i = 0; i < outlen; ++i) {
        out[i] = ctx->h[i / 8] >> ((i % 8) * 8);
    }

    if (digestLen) {
        *digestLen = outlen;
    }

    return SECSuccess;
}

SECStatus
blake2b_HashBuf(uint8_t* output, const uint8_t* input, uint8_t outlen,
                size_t inlen, const uint8_t* key, size_t keylen)
{
    SECStatus rv = SECFailure;
    BLAKE2BContext ctx = { { 0 } };

    if (inlen != 0) {
        PORT_Assert(input != NULL);
        if (input == NULL) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            goto done;
        }
    }

    PORT_Assert(output != NULL);
    if (output == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        goto done;
    }

    if (blake2b_Begin(&ctx, outlen, key, keylen) != SECSuccess) {
        goto done;
    }

    if (BLAKE2B_Update(&ctx, input, inlen) != SECSuccess) {
        goto done;
    }

    if (BLAKE2B_End(&ctx, output, NULL, outlen) != SECSuccess) {
        goto done;
    }
    rv = SECSuccess;

done:
    PORT_Memset(&ctx, 0, sizeof ctx);
    return rv;
}

SECStatus
BLAKE2B_Hash(unsigned char* dest, const char* src)
{
    return blake2b_HashBuf(dest, (const unsigned char*)src, BLAKE2B512_LENGTH,
                           PORT_Strlen(src), NULL, 0);
}

SECStatus
BLAKE2B_HashBuf(unsigned char* output, const unsigned char* input, PRUint32 inlen)
{
    return blake2b_HashBuf(output, input, BLAKE2B512_LENGTH, inlen, NULL, 0);
}

SECStatus
BLAKE2B_MAC_HashBuf(unsigned char* output, const unsigned char* input,
                    unsigned int inlen, const unsigned char* key,
                    unsigned int keylen)
{
    PORT_Assert(key != NULL);
    if (!key && keylen <= BLAKE2B_KEY_SIZE) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    return blake2b_HashBuf(output, input, BLAKE2B512_LENGTH, inlen, key, keylen);
}

unsigned int
BLAKE2B_FlattenSize(BLAKE2BContext* ctx)
{
    return sizeof(BLAKE2BContext);
}

SECStatus
BLAKE2B_Flatten(BLAKE2BContext* ctx, unsigned char* space)
{
    PORT_Assert(space != NULL);
    if (!space) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    PORT_Memcpy(space, ctx, sizeof(BLAKE2BContext));
    return SECSuccess;
}

BLAKE2BContext*
BLAKE2B_Resurrect(unsigned char* space, void* arg)
{
    PORT_Assert(space != NULL);
    if (!space) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    BLAKE2BContext* ctx = BLAKE2B_NewContext();
    if (ctx == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    PORT_Memcpy(ctx, space, sizeof(BLAKE2BContext));
    return ctx;
}

void
BLAKE2B_Clone(BLAKE2BContext* dest, BLAKE2BContext* src)
{
    PORT_Assert(dest != NULL);
    PORT_Assert(src != NULL);
    if (!dest || !src) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }
    PORT_Memcpy(dest, src, sizeof(BLAKE2BContext));
}
