/* 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 <string.h>
#include <stdio.h>

#include "seccomon.h"
#include "secerr.h"
#include "blapit.h"
#include "blapii.h"

#ifndef NSS_DISABLE_CHACHAPOLY
#include "chacha20poly1305.h"
// Forward declaration from "Hacl_Chacha20_Vec128.h".
extern void Hacl_Chacha20_Vec128_chacha20(uint8_t *output, uint8_t *plain,
                                          uint32_t len, uint8_t *k, uint8_t *n1,
                                          uint32_t ctr);
// Forward declaration from "Hacl_Chacha20.h".
extern void Hacl_Chacha20_chacha20(uint8_t *output, uint8_t *plain, uint32_t len,
                                   uint8_t *k, uint8_t *n1, uint32_t ctr);

#if defined(HAVE_INT128_SUPPORT) && (defined(NSS_X86_OR_X64) || defined(__aarch64__))
/* Use HACL* Poly1305 on 64-bit Intel and ARM */
#include "verified/Hacl_Poly1305_64.h"
#define NSS_POLY1305_64 1
#define Hacl_Poly1305_update Hacl_Poly1305_64_update
#define Hacl_Poly1305_mk_state Hacl_Poly1305_64_mk_state
#define Hacl_Poly1305_init Hacl_Poly1305_64_init
#define Hacl_Poly1305_finish Hacl_Poly1305_64_finish
typedef Hacl_Impl_Poly1305_64_State_poly1305_state Hacl_Impl_Poly1305_State_poly1305_state;
#else
/* All other platforms get the 32-bit poly1305 HACL* implementation. */
#include "verified/Hacl_Poly1305_32.h"
#define NSS_POLY1305_32 1
#define Hacl_Poly1305_update Hacl_Poly1305_32_update
#define Hacl_Poly1305_mk_state Hacl_Poly1305_32_mk_state
#define Hacl_Poly1305_init Hacl_Poly1305_32_init
#define Hacl_Poly1305_finish Hacl_Poly1305_32_finish
typedef Hacl_Impl_Poly1305_32_State_poly1305_state Hacl_Impl_Poly1305_State_poly1305_state;
#endif /* HAVE_INT128_SUPPORT */

static void
Poly1305PadUpdate(Hacl_Impl_Poly1305_State_poly1305_state state,
                  unsigned char *block, const unsigned char *p,
                  const unsigned int pLen)
{
    unsigned int pRemLen = pLen % 16;
    Hacl_Poly1305_update(state, (uint8_t *)p, (pLen / 16));
    if (pRemLen > 0) {
        memcpy(block, p + (pLen - pRemLen), pRemLen);
        Hacl_Poly1305_update(state, block, 1);
    }
}

/* Poly1305Do writes the Poly1305 authenticator of the given additional data
 * and ciphertext to |out|. */
static void
Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
           const unsigned char *ciphertext, unsigned int ciphertextLen,
           const unsigned char key[32])
{
#ifdef NSS_POLY1305_64
    uint64_t stateStack[6U] = { 0U };
    size_t offset = 3;
#elif defined NSS_POLY1305_32
    uint32_t stateStack[10U] = { 0U };
    size_t offset = 5;
#else
#error "This can't happen."
#endif
    Hacl_Impl_Poly1305_State_poly1305_state state =
        Hacl_Poly1305_mk_state(stateStack, stateStack + offset);

    unsigned char block[16] = { 0 };
    Hacl_Poly1305_init(state, (uint8_t *)key);

    Poly1305PadUpdate(state, block, ad, adLen);
    memset(block, 0, 16);
    Poly1305PadUpdate(state, block, ciphertext, ciphertextLen);

    unsigned int i;
    unsigned int j;
    for (i = 0, j = adLen; i < 8; i++, j >>= 8) {
        block[i] = j;
    }
    for (i = 8, j = ciphertextLen; i < 16; i++, j >>= 8) {
        block[i] = j;
    }

    Hacl_Poly1305_update(state, block, 1);
    Hacl_Poly1305_finish(state, out, (uint8_t *)(key + 16));
#undef NSS_POLY1305_64
#undef NSS_POLY1305_32
}
#endif /* NSS_DISABLE_CHACHAPOLY */

SECStatus
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
                             const unsigned char *key, unsigned int keyLen,
                             unsigned int tagLen)
{
#ifdef NSS_DISABLE_CHACHAPOLY
    return SECFailure;
#else
    if (keyLen != 32) {
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }
    if (tagLen == 0 || tagLen > 16) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        return SECFailure;
    }

    PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
    ctx->tagLen = tagLen;

    return SECSuccess;
#endif
}

ChaCha20Poly1305Context *
ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
                               unsigned int tagLen)
{
#ifdef NSS_DISABLE_CHACHAPOLY
    return NULL;
#else
    ChaCha20Poly1305Context *ctx;

    ctx = PORT_New(ChaCha20Poly1305Context);
    if (ctx == NULL) {
        return NULL;
    }

    if (ChaCha20Poly1305_InitContext(ctx, key, keyLen, tagLen) != SECSuccess) {
        PORT_Free(ctx);
        ctx = NULL;
    }

    return ctx;
#endif
}

void
ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
{
#ifndef NSS_DISABLE_CHACHAPOLY
    PORT_Memset(ctx, 0, sizeof(*ctx));
    if (freeit) {
        PORT_Free(ctx);
    }
#endif
}

void
ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k,
            uint8_t *nonce, uint32_t ctr)
{
    if (ssse3_support() || arm_neon_support()) {
        Hacl_Chacha20_Vec128_chacha20(output, block, len, k, nonce, ctr);
    } else {
        Hacl_Chacha20_chacha20(output, block, len, k, nonce, ctr);
    }
}

SECStatus
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
                      unsigned int *outputLen, unsigned int maxOutputLen,
                      const unsigned char *input, unsigned int inputLen,
                      const unsigned char *nonce, unsigned int nonceLen,
                      const unsigned char *ad, unsigned int adLen)
{
#ifdef NSS_DISABLE_CHACHAPOLY
    return SECFailure;
#else
    unsigned char block[64];
    unsigned char tag[16];

    if (nonceLen != 12) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        return SECFailure;
    }
    *outputLen = inputLen + ctx->tagLen;
    if (maxOutputLen < *outputLen) {
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        return SECFailure;
    }

    PORT_Memset(block, 0, sizeof(block));
    // Generate a block of keystream. The first 32 bytes will be the poly1305
    // key. The remainder of the block is discarded.
    ChaCha20Xor(block, (uint8_t *)block, sizeof(block), (uint8_t *)ctx->key,
                (uint8_t *)nonce, 0);
    ChaCha20Xor(output, (uint8_t *)input, inputLen, (uint8_t *)ctx->key,
                (uint8_t *)nonce, 1);

    Poly1305Do(tag, ad, adLen, output, inputLen, block);
    PORT_Memcpy(output + inputLen, tag, ctx->tagLen);

    return SECSuccess;
#endif
}

SECStatus
ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
                      unsigned int *outputLen, unsigned int maxOutputLen,
                      const unsigned char *input, unsigned int inputLen,
                      const unsigned char *nonce, unsigned int nonceLen,
                      const unsigned char *ad, unsigned int adLen)
{
#ifdef NSS_DISABLE_CHACHAPOLY
    return SECFailure;
#else
    unsigned char block[64];
    unsigned char tag[16];
    unsigned int ciphertextLen;

    if (nonceLen != 12) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        return SECFailure;
    }
    if (inputLen < ctx->tagLen) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        return SECFailure;
    }
    ciphertextLen = inputLen - ctx->tagLen;
    *outputLen = ciphertextLen;
    if (maxOutputLen < *outputLen) {
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        return SECFailure;
    }

    PORT_Memset(block, 0, sizeof(block));
    // Generate a block of keystream. The first 32 bytes will be the poly1305
    // key. The remainder of the block is discarded.
    ChaCha20Xor(block, (uint8_t *)block, sizeof(block), (uint8_t *)ctx->key,
                (uint8_t *)nonce, 0);
    Poly1305Do(tag, ad, adLen, input, ciphertextLen, block);
    if (NSS_SecureMemcmp(tag, &input[ciphertextLen], ctx->tagLen) != 0) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }

    ChaCha20Xor(output, (uint8_t *)input, ciphertextLen, (uint8_t *)ctx->key,
                (uint8_t *)nonce, 1);

    return SECSuccess;
#endif
}
