#include "test_TA_scrypto.h"
#include <tee_internal_api.h>
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

TEE_Result TA_CreateEntryPoint(void)
{
    return TEE_SUCCESS;
}

void TA_DestroyEntryPoint(void)
{
}

TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes,
    TEE_Param params[4], void **sessionContext)
{
    (void) paramTypes;
    (void) params;
    (void) sessionContext;

    return TEE_SUCCESS;
}

void TA_CloseSessionEntryPoint(void *sessionContext)
{
    (void) sessionContext;
}

TEE_Result digest_test()
{
    TEE_Result result = TEE_ERROR_GENERIC;
    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
    uint8_t digest[EVP_MAX_MD_SIZE];
    uint8_t message[] = "This is SHA256 test!";
    uint8_t expected_digest[] = {0xa3, 0xd1, 0xf1, 0x2e, 0xa5, 0x95, 0x1e, 0x70,
                                 0x94, 0x2f, 0x7d, 0x58, 0x69, 0x2b, 0x41, 0x42,
                                 0xb6, 0xef, 0x68, 0x5b, 0x47, 0xd4, 0x19, 0x7d,
                                 0x57, 0xa1, 0xdf, 0x4f, 0x1f, 0xf4, 0xc0, 0x9b};
    unsigned int digest_len;
    unsigned int expected_digest_len = sizeof(expected_digest);
    unsigned int message_len = sizeof(message) - 1;

    if (!EVP_DigestInit_ex(ctx, EVP_sha256(), NULL)) {
        printf("Error occured while initializing digest!\n");
        goto exit;
    }

    if (!EVP_DigestUpdate(ctx, message, message_len)) {
        printf("Error occured while updating digest!\n");
        goto exit;
    }

    if (!EVP_DigestFinal_ex(ctx, digest, &digest_len)) {
        printf("Error occured while finalizing digest!\n");
        goto exit;
    }

    if (digest_len != expected_digest_len || TEE_MemCompare(digest, expected_digest, digest_len)) {
        printf("Digest doesn't match expected value!\n");
        goto exit;
    }

    result = TEE_SUCCESS;

exit:
    EVP_MD_CTX_destroy(ctx);
    return result;
}

TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext,
    uint32_t commandID, uint32_t paramTypes, TEE_Param params[4])
{
    (void) sessionContext;
    (void) commandID;
    (void) paramTypes;
    (void) params;

    return digest_test();
}
