MXC-A36_2024.04.18/fr3092_mcu/components/drivers/peripheral/Src/driver_sha.c

323 lines
13 KiB
C

/*
******************************************************************************
* @file driver_sha.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief IIR module driver.
* This file provides firmware functions to manage the
* SEC SHA peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
static uint8_t Context[128]; /* orignal data save buffer */
static uint16_t ContextIndex = 0;
static uint64_t TotalBits512[2];
static uint64_t TotalBits256;
/*********************************************************************
* @fn sha_init
*
* @brief SHA256 initialization procedure
*
* @param mode : SHA mode select
*/
void sha_init(enum_sha_mode_t fe_Mode)
{
SEC_SHA->SHA_CTRL.Bits.MODE = fe_Mode;
SEC_SHA->SHA_CTRL.Bits.ENDIAN_MODE = SHA_BIG_ENDIAN;
SEC_SHA->SHA_CTRL.Bits.ISR_EN = 1;
SEC_SHA->SHA_CTRL.Bits.INIT_EN = 1;
/*verity initialize*/
TotalBits256 = 0;
TotalBits512[0] = 0;
TotalBits512[1] = 0;
ContextIndex = 0;
}
static void __sha_updata_256(uint8_t *fp8_Data, uint32_t fu32_Size);
static void __sha_updata_512(uint8_t *fp8_Data, uint32_t fu32_Size);
/*********************************************************************
* @fn sha_update
*
* @brief SHA update procedure.
*
* @param fp8_Data : message to hash.
* @param fu32_Size: length of message to hash.
*/
void sha_update(uint8_t *fp8_Data, uint32_t fu32_Size)
{
if(SEC_SHA->SHA_CTRL.Bits.MODE >= SHA_512)
{
__sha_updata_512(fp8_Data, fu32_Size);
}
else
{
__sha_updata_256(fp8_Data, fu32_Size);
}
}
/*********************************************************************
* @fn sha_final
*
* @brief SHA Final calculation result
*
* @param DataOut : SHA calculation result buffer.
*/
void sha_final(uint8_t *DataOut)
{
uint32_t *DataIn = NULL;
/*sha512 or sha384 or sha512/256 or sha512/224*/
if(SEC_SHA->SHA_CTRL.Bits.MODE >= SHA_512)
{
if((TotalBits512[0] == 0) && (TotalBits512[1] == 0)) return;
uint32_t LeftBits = (ContextIndex << 3);
if(LeftBits == 0)
{
Context[0] = 0x80;
memset(&Context[1], 0, (SHA_512_BLOCK_SIZE - 1 - 16));
Context[SHA_512_BLOCK_SIZE - 1] = (uint8_t) TotalBits512[0];
Context[SHA_512_BLOCK_SIZE - 2] = (uint8_t) (TotalBits512[0] >> 8);
Context[SHA_512_BLOCK_SIZE - 3] = (uint8_t) (TotalBits512[0] >> 16);
Context[SHA_512_BLOCK_SIZE - 4] = (uint8_t) (TotalBits512[0] >> 24);
Context[SHA_512_BLOCK_SIZE - 5] = (uint8_t) (TotalBits512[0] >> 32);
Context[SHA_512_BLOCK_SIZE - 6] = (uint8_t) (TotalBits512[0] >> 40);
Context[SHA_512_BLOCK_SIZE - 7] = (uint8_t) (TotalBits512[0] >> 48);
Context[SHA_512_BLOCK_SIZE - 8] = (uint8_t) (TotalBits512[0] >> 56);
Context[SHA_512_BLOCK_SIZE - 9] = (uint8_t) TotalBits512[1];
Context[SHA_512_BLOCK_SIZE - 10] = (uint8_t) (TotalBits512[1] >> 8);
Context[SHA_512_BLOCK_SIZE - 11] = (uint8_t) (TotalBits512[1] >> 16);
Context[SHA_512_BLOCK_SIZE - 12] = (uint8_t) (TotalBits512[1] >> 24);
Context[SHA_512_BLOCK_SIZE - 13] = (uint8_t) (TotalBits512[1] >> 32);
Context[SHA_512_BLOCK_SIZE - 14] = (uint8_t) (TotalBits512[1] >> 40);
Context[SHA_512_BLOCK_SIZE - 15] = (uint8_t) (TotalBits512[1] >> 48);
Context[SHA_512_BLOCK_SIZE - 16] = (uint8_t) (TotalBits512[1] >> 56);
}
else if(LeftBits >= 896)
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_512_BLOCK_SIZE - ContextIndex));
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
SEC_SHA->DATA_2[i] = DataIn[i + 16];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
/*one more need to process*/
memset(&Context[0], 0, (SHA_512_BLOCK_SIZE - 16));
Context[SHA_512_BLOCK_SIZE - 1] = (uint8_t) TotalBits512[0];
Context[SHA_512_BLOCK_SIZE - 2] = (uint8_t) (TotalBits512[0] >> 8);
Context[SHA_512_BLOCK_SIZE - 3] = (uint8_t) (TotalBits512[0] >> 16);
Context[SHA_512_BLOCK_SIZE - 4] = (uint8_t) (TotalBits512[0] >> 24);
Context[SHA_512_BLOCK_SIZE - 5] = (uint8_t) (TotalBits512[0] >> 32);
Context[SHA_512_BLOCK_SIZE - 6] = (uint8_t) (TotalBits512[0] >> 40);
Context[SHA_512_BLOCK_SIZE - 7] = (uint8_t) (TotalBits512[0] >> 48);
Context[SHA_512_BLOCK_SIZE - 8] = (uint8_t) (TotalBits512[0] >> 56);
Context[SHA_512_BLOCK_SIZE - 9] = (uint8_t) TotalBits512[1];
Context[SHA_512_BLOCK_SIZE - 10] = (uint8_t) (TotalBits512[1] >> 8);
Context[SHA_512_BLOCK_SIZE - 11] = (uint8_t) (TotalBits512[1] >> 16);
Context[SHA_512_BLOCK_SIZE - 12] = (uint8_t) (TotalBits512[1] >> 24);
Context[SHA_512_BLOCK_SIZE - 13] = (uint8_t) (TotalBits512[1] >> 32);
Context[SHA_512_BLOCK_SIZE - 14] = (uint8_t) (TotalBits512[1] >> 40);
Context[SHA_512_BLOCK_SIZE - 15] = (uint8_t) (TotalBits512[1] >> 48);
Context[SHA_512_BLOCK_SIZE - 16] = (uint8_t) (TotalBits512[1] >> 56);
}
else
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_512_BLOCK_SIZE - ContextIndex - 16));
Context[SHA_512_BLOCK_SIZE - 1] = (uint8_t) TotalBits512[0];
Context[SHA_512_BLOCK_SIZE - 2] = (uint8_t) (TotalBits512[0] >> 8);
Context[SHA_512_BLOCK_SIZE - 3] = (uint8_t) (TotalBits512[0] >> 16);
Context[SHA_512_BLOCK_SIZE - 4] = (uint8_t) (TotalBits512[0] >> 24);
Context[SHA_512_BLOCK_SIZE - 5] = (uint8_t) (TotalBits512[0] >> 32);
Context[SHA_512_BLOCK_SIZE - 6] = (uint8_t) (TotalBits512[0] >> 40);
Context[SHA_512_BLOCK_SIZE - 7] = (uint8_t) (TotalBits512[0] >> 48);
Context[SHA_512_BLOCK_SIZE - 8] = (uint8_t) (TotalBits512[0] >> 56);
Context[SHA_512_BLOCK_SIZE - 9] = (uint8_t) TotalBits512[1];
Context[SHA_512_BLOCK_SIZE - 10] = (uint8_t) (TotalBits512[1] >> 8);
Context[SHA_512_BLOCK_SIZE - 11] = (uint8_t) (TotalBits512[1] >> 16);
Context[SHA_512_BLOCK_SIZE - 12] = (uint8_t) (TotalBits512[1] >> 24);
Context[SHA_512_BLOCK_SIZE - 13] = (uint8_t) (TotalBits512[1] >> 32);
Context[SHA_512_BLOCK_SIZE - 14] = (uint8_t) (TotalBits512[1] >> 40);
Context[SHA_512_BLOCK_SIZE - 15] = (uint8_t) (TotalBits512[1] >> 48);
Context[SHA_512_BLOCK_SIZE - 16] = (uint8_t) (TotalBits512[1] >> 56);
}
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
SEC_SHA->DATA_2[i] = DataIn[i + 16];
}
/*start to calculate the last package data*/
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
else /*sha256 or sha1 or sha224*/
{
if(TotalBits256 == 0) return;
uint32_t LeftBits = (ContextIndex << 3);
if(LeftBits == 0)
{
Context[0] = 0x80;
memset(&Context[1], 0, (SHA_256_BLOCK_SIZE - 1 - 8));
Context[SHA_256_BLOCK_SIZE - 1] = (uint8_t) TotalBits256;
Context[SHA_256_BLOCK_SIZE - 2] = (uint8_t) (TotalBits256 >> 8);
Context[SHA_256_BLOCK_SIZE - 3] = (uint8_t) (TotalBits256 >> 16);
Context[SHA_256_BLOCK_SIZE - 4] = (uint8_t) (TotalBits256 >> 24);
Context[SHA_256_BLOCK_SIZE - 5] = (uint8_t) (TotalBits256 >> 32);
Context[SHA_256_BLOCK_SIZE - 6] = (uint8_t) (TotalBits256 >> 40);
Context[SHA_256_BLOCK_SIZE - 7] = (uint8_t) (TotalBits256 >> 48);
Context[SHA_256_BLOCK_SIZE - 8] = (uint8_t) (TotalBits256 >> 56);
}
else if(LeftBits >= 448)
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_256_BLOCK_SIZE - ContextIndex));
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
/*one more need to process*/
memset(&Context[0], 0, (SHA_256_BLOCK_SIZE - 8));
Context[SHA_256_BLOCK_SIZE - 1] = (uint8_t) TotalBits256;
Context[SHA_256_BLOCK_SIZE - 2] = (uint8_t) (TotalBits256 >> 8);
Context[SHA_256_BLOCK_SIZE - 3] = (uint8_t) (TotalBits256 >> 16);
Context[SHA_256_BLOCK_SIZE - 4] = (uint8_t) (TotalBits256 >> 24);
Context[SHA_256_BLOCK_SIZE - 5] = (uint8_t) (TotalBits256 >> 32);
Context[SHA_256_BLOCK_SIZE - 6] = (uint8_t) (TotalBits256 >> 40);
Context[SHA_256_BLOCK_SIZE - 7] = (uint8_t) (TotalBits256 >> 48);
Context[SHA_256_BLOCK_SIZE - 8] = (uint8_t) (TotalBits256 >> 56);
}
else
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_256_BLOCK_SIZE - ContextIndex - 8));
Context[SHA_256_BLOCK_SIZE - 1] = (uint8_t) TotalBits256;
Context[SHA_256_BLOCK_SIZE - 2] = (uint8_t) (TotalBits256 >> 8);
Context[SHA_256_BLOCK_SIZE - 3] = (uint8_t) (TotalBits256 >> 16);
Context[SHA_256_BLOCK_SIZE - 4] = (uint8_t) (TotalBits256 >> 24);
Context[SHA_256_BLOCK_SIZE - 5] = (uint8_t) (TotalBits256 >> 32);
Context[SHA_256_BLOCK_SIZE - 6] = (uint8_t) (TotalBits256 >> 40);
Context[SHA_256_BLOCK_SIZE - 7] = (uint8_t) (TotalBits256 >> 48);
Context[SHA_256_BLOCK_SIZE - 8] = (uint8_t) (TotalBits256 >> 56);
}
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
}
/*start to calculate the last package data*/
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
uint32_t LastDigest[16];
memset(&LastDigest, 0, 64);
/*data out*/
if(SEC_SHA->SHA_CTRL.Bits.MODE >= SHA_512)
{
for(uint32_t i=0;i<8;i++)
{
LastDigest[2*i] = SEC_SHA->HASH_VAL_H[i];
LastDigest[2*i + 1] = SEC_SHA->HASH_VAL_L[i];
*(DataOut++) = (uint8_t)(LastDigest[2*i] >> 24);
*(DataOut++) = (uint8_t)(LastDigest[2*i] >> 16);
*(DataOut++) = (uint8_t)(LastDigest[2*i] >> 8);
*(DataOut++) = (uint8_t)(LastDigest[2*i]);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1] >> 24);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1] >> 16);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1] >> 8);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1]);
}
}
else
{
for(uint32_t i=0;i<8;i++)
{
LastDigest[i] = SEC_SHA->HASH_VAL_L[i];
*(DataOut++) = (uint8_t)(LastDigest[i] >> 24);
*(DataOut++) = (uint8_t)(LastDigest[i] >> 16);
*(DataOut++) = (uint8_t)(LastDigest[i] >> 8);
*(DataOut++) = (uint8_t)(LastDigest[i]);
}
}
}
static void __sha_updata_256(uint8_t *fp8_Data, uint32_t fu32_Size)
{
/*total bits add*/
TotalBits256 += (fu32_Size << 3);
while(fu32_Size-- > 0)
{
Context[ContextIndex++] = *(fp8_Data++);
if(ContextIndex >= SHA_256_BLOCK_SIZE)
{
ContextIndex = 0;
uint32_t *DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
}
}
static void __sha_updata_512(uint8_t *fp8_Data, uint32_t fu32_Size)
{
TotalBits512[0] += (fu32_Size << 3);
if(TotalBits512[0] < (uint64_t)(fu32_Size << 3) ) {
TotalBits512[1]++;
}
while(fu32_Size-- > 0)
{
Context[ContextIndex++] = *(fp8_Data++);
if(ContextIndex >= SHA_512_BLOCK_SIZE)
{
ContextIndex = 0;
uint32_t *DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
SEC_SHA->DATA_2[i] = DataIn[i + 16];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
}
}