/* USER CODE BEGIN Header */
/* you can remove the copyright */

/*
 *  Copyright 2020-2023 Yuntu Microelectronics co.,ltd
 *  All rights reserved.
 *
 *  YUNTU Confidential. This software is owned or controlled by YUNTU and may only be
 *  used strictly in accordance with the applicable license terms. By expressly
 *  accepting such terms or by downloading, installing, activating and/or otherwise
 *  using the software, you are agreeing that you have read, and that you agree to
 *  comply with and are bound by, such license terms. If you do not agree to be
 *  bound by the applicable license terms, then you may not retain, install,
 *  activate or otherwise use the software. The production use license in
 *  Section 2.3 is expressly granted for this software.
 *
 * @file main.c
 * @brief
 *
 */

/* USER CODE END Header */
#include "sdk_project_config.h"
/* Includes ------------------------------------------------------------------*/

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "printf.h"
#include "psa/crypto.h"
#include "mbedtls/platform.h"
#include "AES_example.h"
#include "RSA_example.h"
#include "ECDSA_example.h"
#include <string.h>

#include "sha256.h"

#include "rsa.h"
#include "system_YTM32B1ME0.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define READ_FLASH_TEST_APPLICATION                 1              // (1-从Flash中读取数据，计算hash值后验签，接近实际应用场景)
#define USED_SWOFTWARE_SHA256_TEST                  0
#define USED_THIRD_PARTY_TOOL_GENERATED_KEYS        1              // (1-使用第三方工具生成密钥; 0-使用本工程中的ECDSA_key_generate函数生成密钥)

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
extern uint8_t message[];
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t shaResult_test[32] = {0};     // SHA-256结果缓冲区_测试(32字节=8个uint32_t)
uint8_t hwshaResult[32] = {0};     // SHA-256结果缓冲区(32字节=8个uint32_t)
uint8_t swshaResult[32] = {0};     // SHA-256结果缓冲区(32字节=8个uint32_t)
uint8_t longMessage[512] = {0};

mbedtls_sha256_context Mbedtls_Context;

mbedtls_rsa_context RSA_Context;
/* USER CODE END PV */

/* Private function declare --------------------------------------------------*/
/* USER CODE BEGIN PFDC */
extern void mbedtls_config_init();
/* USER CODE END PFDC */
static void Board_Init(void);

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
 * @brief 从Flash读取数据并使用ME05的HCU引擎硬件SHA-256计算哈希值
 * 
 * 从Flash 0地址开始，每次读取8K数据，共读取512K数据(64次)
 */
void StepReadFlash_And_HardWare_CalculateSHA(void)
{
    uint8_t* flashAddr = (uint8_t*)0x80000;  // Flash起始地址
    uint32_t chunkSize = 8192;                  // 每次读取8K (8192字节)
    uint32_t totalSize = 524288;                // 总共读取512K (524288字节)

    // 分步计算SHA-256
    uint32_t bytesRead = 0;

    // 第一块: 使用MSG_START标志
    HCU_DRV_GenerateSHA(flashAddr, chunkSize, totalSize, HCU_SHA_256, MSG_START, NULL);
    bytesRead += chunkSize;
    
    // 中间块: 使用MSG_MIDDLE标志
    while (bytesRead + chunkSize < totalSize) {
        uint8_t* currentAddr = flashAddr + bytesRead;          
        
        HCU_DRV_GenerateSHA(currentAddr, chunkSize, 0, HCU_SHA_256, MSG_MIDDLE, NULL);
        bytesRead += chunkSize;
    }

    // 最后一块: 使用MSG_END标志并获取结果
    uint8_t *lastAddr = flashAddr + bytesRead;
    uint32_t lastChunkSize = totalSize - bytesRead;
    HCU_DRV_GenerateSHA(lastAddr, lastChunkSize, 0, HCU_SHA_256, MSG_END, hwshaResult);
}

/**
 * @brief 从Flash读取数据并使用mbedtls库中的软件SHA-256计算哈希值
 * 
 * 从Flash 0地址开始，每次读取8K数据，共读取512K数据(64次)
 */
void StepReadFlash_And_SoftWare_CalculateSHA(void)
{
    uint8_t* flashAddr = (uint8_t*)0x80000;  // Flash起始地址
    uint32_t chunkSize = 8192;                  // 每次读取8K (8192字节)
    uint32_t totalSize = 524288;                // 总共读取512K (524288字节)
    
    // 分步计算SHA-256
    uint32_t bytesRead = 0;

    //start，需用到sha56，第二个参数填0
    mbedtls_sha256_starts(&Mbedtls_Context, 0); 

    //计算最后一块数据之前所有数据块的hash
    while (bytesRead + chunkSize < totalSize)
    {
        uint8_t* currentAddr = flashAddr + bytesRead;
        mbedtls_sha256_update(&Mbedtls_Context,currentAddr,chunkSize);
        bytesRead += chunkSize;
    }
    // 只剩最后一块数据需要计算
    uint8_t *lastAddr = flashAddr + bytesRead;
    uint32_t lastChunkSize = totalSize - bytesRead;
    mbedtls_sha256_update(&Mbedtls_Context,lastAddr,lastChunkSize);

    //结束软件sha256 hash运算
    mbedtls_sha256_finish(&Mbedtls_Context,swshaResult);

}
/* USER CODE END 0 */


/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
    /* USER CODE BEGIN 1 */
    /* USER CODE END 1 */ 
    Board_Init();
    /* USER CODE BEGIN 2 */
    HCU_DRV_Init(&hcu_config0,&hcu_config0_State);
    FLASH_DRV_Init(0,&flash_config0,&flash_config0_State);
    mbedtls_config_init();
    // 初始化 PSA Crypto
    psa_status_t psa_status = psa_crypto_init();
    if (psa_status != PSA_SUCCESS)
    {
        PRINTF("PSA init failed! (status = %d)\n\r", psa_status);
    }


#if (USED_THIRD_PARTY_TOOL_GENERATED_KEYS == 0)
    PRINTF("\nMbedTLS ECDSA Key Generation Test:\n\r");
    if (ECDSA_key_generate(256) == 0)
    {
        PRINTF("ECDSA key generation test succeeded!\n\r");
    }
#endif

#if READ_FLASH_TEST_APPLICATION
    
#if USED_SWOFTWARE_SHA256_TEST
    GPIOE -> PSOR = 1 << 23;
    //初始化mbedtls sha56
    mbedtls_sha256_init(&Mbedtls_Context);
    StepReadFlash_And_SoftWare_CalculateSHA();//Sofrware 296.247ms      
    GPIOE -> PCOR = 1 << 23;
    //将软件计算的hash值填到本工程的message数组
    for(uint8_t i = 0; i < 32; i++)
    {
        message[i] = swshaResult[i];
    }
#else
    GPIOE -> PSOR = 1 << 23;
    StepReadFlash_And_HardWare_CalculateSHA();   //Hardrware 29.3081ms
    GPIOE -> PCOR = 1 << 23;
    //将软件计算的hash值填到本工程的message数组
    for(uint8_t i = 0; i < 32; i++)
    {
        message[i] = hwshaResult[i];
    }
    //全FF的Flash数据，sha256：043e238a765f7cfbc62596a50e53c8ffb6b188a99357b0ebede251725d67589f
#endif
#endif

    PRINTF("\nMbedTLS ECDSA Sign and Verify Test:\n\r");
    ECDSA_sign_verify_test();                                               //1.42507 S

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

static void Board_Init(void)
{
    CLOCK_SYS_Init(g_clockManConfigsArr,CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr,CLOCK_MANAGER_CALLBACK_CNT);
    CLOCK_SYS_UpdateConfiguration(CLOCK_MANAGER_ACTIVE_INDEX,CLOCK_MANAGER_POLICY_AGREEMENT);
    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS0,g_pin_mux_InitConfigArr0);
    UTILITY_PRINT_Init();
}

/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
