/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#include <mbedtls/sha256.h>

#if defined(MBEDTLS_SHA256_ALT)

#include <string.h>

#include <ti/drivers/SHA2.h>
#include <ti/drivers/dpl/HwiP.h>
#include <ti/drivers/sha2/SHA2CC26X2.h>

/*!
 *  Hardware-specific configuration attributes, may be replaced with SysConfig
 *  ti_drivers.h structure.
 */
const SHA2CC26X2_HWAttrs sha2CC26X2HWAttrs_sha = {
    .intPriority = ~0,
};

void mbedtls_sha256_init(mbedtls_sha256_context * ctx)
{
    SHA2_Params sha2Params;

    memset(ctx, 0, sizeof(mbedtls_sha256_context));
    SHA2_Params_init(&sha2Params);

    sha2Params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;

    ctx->config.object  = &ctx->object;
    ctx->config.hwAttrs = &sha2CC26X2HWAttrs_sha;

    ctx->hndl = SHA2_construct(&ctx->config, &sha2Params);
}

void mbedtls_sha256_free(mbedtls_sha256_context * ctx)
{
    if (NULL == ctx)
    {
        return;
    }

    if (ctx->hndl != NULL)
    {
        SHA2_close(ctx->hndl);

        memset(ctx, 0, sizeof(mbedtls_sha256_context));
    }
}

/*
 * Deviation from documentation in sha256.h.
 *
 * It has been noticed that some code using mbedtls does not call `init` before
 * starting a SHA operation. Rather these implementations assume the `ctx`
 * structure may be zero'ed out as initialization. To support this usage the
 * driver instance is assumed to be uninitialized if the context's `hndl` is a
 * NULL pointer. Start will initialize the driver and assign the handle to the
 * context in this case.
 */
int mbedtls_sha256_starts_ret(mbedtls_sha256_context * ctx, int is224)
{
    SHA2_HashType type;

    // open the driver here because no-one called init
    if (ctx->hndl == NULL)
    {
        SHA2_Params sha2Params;

        SHA2_Params_init(&sha2Params);

        sha2Params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;

        ctx->config.object  = &ctx->object;
        ctx->config.hwAttrs = &sha2CC26X2HWAttrs_sha;

        ctx->hndl = SHA2_construct(&ctx->config, &sha2Params);

        if (NULL == ctx->hndl)
        {
            return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
        }
    }
    else
    {
        SHA2_reset(ctx->hndl);
    }

    if (is224)
    {
        type = SHA2_HASH_TYPE_224;
    }
    else
    {
        type = SHA2_HASH_TYPE_256;
    }

    SHA2_setHashType(ctx->hndl, type);

    return 0;
}

/**
 * Deviation from documentation in sha256.h.
 *
 * It has been noticed that some code using mbedtls does not call `init` on the
 * contexts being passed into this function. This seems to be done to avoid
 * allocating hardware to cloned context instances. To support this use-case,
 * only internal buffers to the SHA2 structure are copied without checking the
 * driver handles.
 */
void mbedtls_sha256_clone(mbedtls_sha256_context * dst, const mbedtls_sha256_context * src)
{
    dst->object.hashType       = src->object.hashType;
    dst->object.bytesInBuffer  = src->object.bytesInBuffer;
    dst->object.bytesProcessed = src->object.bytesProcessed;
    memcpy(dst->object.buffer, src->object.buffer, sizeof(dst->object.buffer));
    // copy the digest to support cloning after finalization has happened
    memcpy(dst->object.digest, src->object.digest, sizeof(dst->object.digest));
}

int mbedtls_sha256_finish_ret(mbedtls_sha256_context * ctx, unsigned char output[32])
{
    int_fast16_t result;
    uint32_t key;

    key    = HwiP_disable();
    result = SHA2_finalize(ctx->hndl, output);
    HwiP_restore(key);

    if (SHA2_STATUS_SUCCESS != result)
    {
        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
    }
    else
    {
        return 0;
    }
}

int mbedtls_sha256_update_ret(mbedtls_sha256_context * ctx, const unsigned char * input, size_t ilen)
{
    int_fast16_t result;
    uint32_t key;

    key = HwiP_disable();
    // Process data in chunks. The driver buffers incomplete blocks internally.
    result = SHA2_addData(ctx->hndl, input, ilen);
    HwiP_restore(key);

    if (SHA2_STATUS_SUCCESS != result)
    {
        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
    }
    else
    {
        return 0;
    }
}

int mbedtls_internal_sha256_process(mbedtls_sha256_context * ctx, const unsigned char data[64])
{
    int_fast16_t result;
    uint32_t key;

    key = HwiP_disable();

    // Process data in chunks. The driver buffers incomplete blocks internally.
    result = SHA2_addData(ctx->hndl, data, SHA2_BLOCK_SIZE_BYTES_256);
    HwiP_restore(key);

    if (SHA2_STATUS_SUCCESS != result)
    {
        return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
    }
    else
    {
        return 0;
    }
}

#endif /* MBEDTLS_SHA256_ALT */
