/* 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 "prtypes.h"
#include "blapit.h"
#include "blapii.h"
#include "ctr.h"
#include "pkcs11t.h"
#include "secerr.h"

#ifdef USE_HW_AES
#include "intel-aes.h"
#include "rijndael.h"
#endif

SECStatus
CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
                const unsigned char *param)
{
    const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param;

    if (ctrParams->ulCounterBits == 0 ||
        ctrParams->ulCounterBits > AES_BLOCK_SIZE * PR_BITS_PER_BYTE) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Invariant: 0 < ctr->bufPtr <= AES_BLOCK_SIZE */
    ctr->checkWrap = PR_FALSE;
    ctr->bufPtr = AES_BLOCK_SIZE; /* no unused data in the buffer */
    ctr->cipher = cipher;
    ctr->context = context;
    ctr->counterBits = ctrParams->ulCounterBits;
    if (AES_BLOCK_SIZE > sizeof(ctr->counter) ||
        AES_BLOCK_SIZE > sizeof(ctrParams->cb)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    PORT_Memcpy(ctr->counter, ctrParams->cb, AES_BLOCK_SIZE);
    if (ctr->counterBits < 64) {
        PORT_Memcpy(ctr->counterFirst, ctr->counter, AES_BLOCK_SIZE);
        ctr->checkWrap = PR_TRUE;
    }
    return SECSuccess;
}

CTRContext *
CTR_CreateContext(void *context, freeblCipherFunc cipher,
                  const unsigned char *param)
{
    CTRContext *ctr;
    SECStatus rv;

    /* first fill in the Counter context */
    ctr = PORT_ZNew(CTRContext);
    if (ctr == NULL) {
        return NULL;
    }
    rv = CTR_InitContext(ctr, context, cipher, param);
    if (rv != SECSuccess) {
        CTR_DestroyContext(ctr, PR_TRUE);
        ctr = NULL;
    }
    return ctr;
}

void
CTR_DestroyContext(CTRContext *ctr, PRBool freeit)
{
    PORT_Memset(ctr, 0, sizeof(CTRContext));
    if (freeit) {
        PORT_Free(ctr);
    }
}

/*
 * Used by counter mode. Increment the counter block. Not all bits in the
 * counter block are part of the counter, counterBits tells how many bits
 * are part of the counter. The counter block is blocksize long. It's a
 * big endian value.
 *
 * XXX Does not handle counter rollover.
 */
static void
ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits,
               unsigned int blocksize)
{
    unsigned char *counterPtr = counter + blocksize - 1;
    unsigned char mask, count;

    PORT_Assert(counterBits <= blocksize * PR_BITS_PER_BYTE);
    while (counterBits >= PR_BITS_PER_BYTE) {
        if (++(*(counterPtr--))) {
            return;
        }
        counterBits -= PR_BITS_PER_BYTE;
    }
    if (counterBits == 0) {
        return;
    }
    /* increment the final partial byte */
    mask = (1 << counterBits) - 1;
    count = ++(*counterPtr) & mask;
    *counterPtr = ((*counterPtr) & ~mask) | count;
    return;
}

static void
ctr_xor(unsigned char *target, const unsigned char *x,
        const unsigned char *y, unsigned int count)
{
    unsigned int i;
    for (i = 0; i < count; i++) {
        *target++ = *x++ ^ *y++;
    }
}

SECStatus
CTR_Update(CTRContext *ctr, unsigned char *outbuf,
           unsigned int *outlen, unsigned int maxout,
           const unsigned char *inbuf, unsigned int inlen,
           unsigned int blocksize)
{
    unsigned int tmp;
    SECStatus rv;

    if (maxout < inlen) {
        *outlen = inlen;
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        return SECFailure;
    }
    *outlen = 0;
    if (ctr->bufPtr != blocksize) {
        unsigned int needed = PR_MIN(blocksize - ctr->bufPtr, inlen);
        ctr_xor(outbuf, inbuf, ctr->buffer + ctr->bufPtr, needed);
        ctr->bufPtr += needed;
        outbuf += needed;
        inbuf += needed;
        *outlen += needed;
        inlen -= needed;
        if (inlen == 0) {
            return SECSuccess;
        }
        PORT_Assert(ctr->bufPtr == blocksize);
    }

    while (inlen >= blocksize) {
        rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
                            ctr->counter, blocksize, blocksize);
        ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
        if (ctr->checkWrap) {
            if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
                PORT_SetError(SEC_ERROR_INVALID_ARGS);
                return SECFailure;
            }
        }
        if (rv != SECSuccess) {
            return SECFailure;
        }
        ctr_xor(outbuf, inbuf, ctr->buffer, blocksize);
        outbuf += blocksize;
        inbuf += blocksize;
        *outlen += blocksize;
        inlen -= blocksize;
    }
    if (inlen == 0) {
        return SECSuccess;
    }
    rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
                        ctr->counter, blocksize, blocksize);
    ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
    if (ctr->checkWrap) {
        if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return SECFailure;
        }
    }
    if (rv != SECSuccess) {
        return SECFailure;
    }
    ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
    ctr->bufPtr = inlen;
    *outlen += inlen;
    return SECSuccess;
}

#if defined(USE_HW_AES) && defined(_MSC_VER)
SECStatus
CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf,
                  unsigned int *outlen, unsigned int maxout,
                  const unsigned char *inbuf, unsigned int inlen,
                  unsigned int blocksize)
{
    unsigned int fullblocks;
    unsigned int tmp;
    SECStatus rv;

    if (maxout < inlen) {
        *outlen = inlen;
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        return SECFailure;
    }
    *outlen = 0;
    if (ctr->bufPtr != blocksize) {
        unsigned int needed = PR_MIN(blocksize - ctr->bufPtr, inlen);
        ctr_xor(outbuf, inbuf, ctr->buffer + ctr->bufPtr, needed);
        ctr->bufPtr += needed;
        outbuf += needed;
        inbuf += needed;
        *outlen += needed;
        inlen -= needed;
        if (inlen == 0) {
            return SECSuccess;
        }
        PORT_Assert(ctr->bufPtr == blocksize);
    }

    if (inlen >= blocksize) {
        rv = intel_aes_ctr_worker(((AESContext *)(ctr->context))->Nr)(
            ctr, outbuf, outlen, maxout, inbuf, inlen, blocksize);
        if (rv != SECSuccess) {
            return SECFailure;
        }
        fullblocks = (inlen / blocksize) * blocksize;
        *outlen += fullblocks;
        outbuf += fullblocks;
        inbuf += fullblocks;
        inlen -= fullblocks;
    }

    if (inlen == 0) {
        return SECSuccess;
    }
    rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
                        ctr->counter, blocksize, blocksize);
    ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
    ctr->bufPtr = inlen;
    *outlen += inlen;
    return SECSuccess;
}
#endif
