TMC32_QJB/App/crypto.c

314 lines
8.7 KiB
C
Raw Normal View History

2026-04-30 08:23:12 +00:00
/**
******************************************************************************
* @file crypto.c
* @author TMS Scan Team
* @version
* @date 2020-04-17
* @brief
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, TMC SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2020 TMS</center></h2>
******************************************************************************
**/
/********************************End of Head************************************/
#include "global.h"
uint16_t CRC_Calculate(uint8_t * inputData,uint16_t len)
{
uint16_t result;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_CRC, ENABLE); //crc clock
CRC->CON1 = 0x08;
result = CRC->DAT;
result = CRC->DAT;
while(len)
{
CRC->DAT = *inputData;
inputData++;
len--;
}
result = CRC->DAT << 8;
result += CRC->DAT;
return result;
}
uint8_t initKey(void)
{
uint32_t i;
CIPHER_KEY *keyAddrPageA;
CIPHER_KEY *keyAddrPageB;
uint16_t crcA, crcB;
uint16_t snA, snB;
memset((uint8_t *)(&gKeyCache), 0, KEY_STEP_LEN);
for(i = 0; i < gCurrentSysCfg->keyNum; i++)
{
keyAddrPageA = (CIPHER_KEY *)(KEY_BASE_ADDR + KEY_STEP_LEN * i * 2);
keyAddrPageB = (CIPHER_KEY *)(KEY_BASE_ADDR + KEY_STEP_LEN * i * 2 + KEY_STEP_LEN);
crcA = CRC_Calculate((uint8_t *) keyAddrPageA + 2, KEY_CRC_LEN);
crcB = CRC_Calculate((uint8_t *) keyAddrPageB + 2, KEY_CRC_LEN);
snA = keyAddrPageA->keySN;
snB = keyAddrPageB->keySN;
if((crcA == keyAddrPageA->keyCRC) && (crcB == keyAddrPageB->keyCRC)) //检验都正确
{
//标记最新页
if(snA == snB + 1)
{
gKeyAddr[i] = (uint32_t)keyAddrPageA;
}
else if(snB == snA + 1)
{
gKeyAddr[i] = (uint32_t)keyAddrPageB;
}
else
{
// 异常流程清除CRC和SN
if(FLASH_Update((uint32_t)keyAddrPageA, (uint8_t *)(&gKeyCache), FLASH_SECTOR_SIZE * 2) != 0)
{
return WRERROR;
}
if(FLASH_Update((uint32_t)keyAddrPageB, (uint8_t *)(&gKeyCache), FLASH_SECTOR_SIZE * 2) != 0)
{
return WRERROR;
}
gKeyAddr[i] = (uint32_t)keyAddrPageB;
}
}
else if(crcA == keyAddrPageA->keyCRC) //A备份正确
{
gKeyAddr[i] = (uint32_t)keyAddrPageA;
}
else if(crcB == keyAddrPageB->keyCRC)
{
gKeyAddr[i] = (uint32_t)keyAddrPageB;
}
else
{
// 异常流程清除CRC和SN
if(FLASH_Update((uint32_t)keyAddrPageA, (uint8_t *)(&gKeyCache), FLASH_SECTOR_SIZE * 2) != 0)
{
return WRERROR;
}
if(FLASH_Update((uint32_t)keyAddrPageB, (uint8_t *)(&gKeyCache), FLASH_SECTOR_SIZE * 2) != 0)
{
return WRERROR;
}
gKeyAddr[i] = (uint32_t)keyAddrPageB;
}
}
return TMC_OK;
}
/**
* @function AppCryptoInit
* @brief
* @param[in]
* @return
*/
void AppCryptoInit(void)
{
RCC_Security2PeriphClockCmd(RCC_SEC2Periph_FLASH,ENABLE);
RCC_Security1PeriphClockCmd(RCC_SEC1Periph_TRNG, ENABLE); //随机数函数存放在ROM内 使用前需要打开门控时钟
RCC_Security1PeriphClockCmd(RCC_SEC1Periph_PKE, ENABLE); //非对称算法库在ROM内掩摸 使用前需打开门控时钟
pkeConfig(0xFF,0x0F,0x01); //PKE初始化函数
initKey();
}
uint16_t encryptData(uint8_t *pInputData, uint8_t *pOutputData, uint16_t inLen)
{
BarData encrypt;
uint8_t *pTempData = (uint8_t *) MIDOUTBUF;
uint16_t dataLen = 0, offset = 0, i, remainder, pkcs, outoffset = 0, outoffs = 0, templen;
uint8_t *pData = (uint8_t *)pInputData;
outoffs = SETCODELEN_MODULE;
encrypt.bartype = QR_Id;
switch(gCurrentSysCfg->cryptoType)
{
case SM2_CRYPTO:
pTempData[outoffs++] = gCurrentSysCfg->keyId;
pTempData[outoffs++] = 0; //加密
pTempData[outoffs++] = (uint8_t) inLen;
pTempData[outoffs++] = (uint8_t) (inLen >> 8);
memcpy(&pTempData[outoffs], pInputData, inLen);
outoffs += inLen;
encrypt.datalen = outoffs;
encrypt.bardata = pTempData;
if(SM2_Oper(&encrypt) == TMC_OK)
{
memcpy(pOutputData, &encrypt.bardata[SETCODELEN_MODULE + CRYPTO_CMD_OFFS], encrypt.datalen);
return encrypt.datalen;
}
break;
case SM3_CRYPTO:
pTempData[outoffs++] = 0;
pTempData[outoffs++] = 0; //加密
pTempData[outoffs++] = (uint8_t) inLen;
pTempData[outoffs++] = (uint8_t) (inLen >> 8);
memcpy(&pTempData[outoffs], pInputData, inLen);
outoffs += inLen;
encrypt.datalen = outoffs;
encrypt.bardata = pTempData;
if(SM3_Oper(&encrypt) == TMC_OK)
{
memcpy(pOutputData, &encrypt.bardata[SETCODELEN_MODULE + CRYPTO_CMD_OFFS], encrypt.datalen);
return encrypt.datalen;
}
break;
case SM4_CRYPTO:
memcpy(&pData[dataLen], pInputData, inLen);
dataLen += inLen;
remainder = dataLen % SYM_GROUP_LEN;
pkcs = SYM_GROUP_LEN - remainder;
for(i = 0; i < (SYM_GROUP_LEN - remainder); i++)
{
pData[dataLen++] = pkcs;
}
while(dataLen > 0)
{
pTempData = (uint8_t *) MIDOUTBUF;
outoffs = SETCODELEN_MODULE;
pTempData[outoffs++] = gCurrentSysCfg->keyId;
pTempData[outoffs++] = 0; //加密
pTempData[outoffs++] = (uint8_t) SYM_GROUP_LEN;
pTempData[outoffs++] = (uint8_t) (SYM_GROUP_LEN >> 8);
memcpy(&pTempData[outoffs], pInputData + offset, SYM_GROUP_LEN);
outoffs += SYM_GROUP_LEN;
encrypt.datalen = outoffs;
encrypt.bardata = pTempData;
if(SM4_Oper(&encrypt) == TMC_OK)
{
memcpy(pOutputData + offset, &encrypt.bardata[SETCODELEN_MODULE + CRYPTO_CMD_OFFS], encrypt.datalen);
offset += SYM_GROUP_LEN;
dataLen -= SYM_GROUP_LEN;
}
else
{
return 0;
}
}
return offset;
case RSA_1024:
dataLen = inLen;
while(dataLen > 0)
{
templen = (dataLen > RSA1024_KEY_LEN) ? RSA1024_KEY_LEN : dataLen;
pTempData = (uint8_t *) MIDOUTBUF;
outoffs = SETCODELEN_MODULE;
pTempData[outoffs++] = gCurrentSysCfg->keyId;
pTempData[outoffs++] = 0; //加密
pTempData[outoffs++] = (uint8_t) templen;
pTempData[outoffs++] = (uint8_t) (templen >> 8);
memcpy(&pTempData[outoffs], pInputData + offset, templen);
outoffs += templen;
encrypt.datalen = outoffs;
encrypt.bardata = pTempData;
if(RSA_Oper(&encrypt) == TMC_OK)
{
memcpy(pOutputData + outoffset, &encrypt.bardata[SETCODELEN_MODULE + CRYPTO_CMD_OFFS], encrypt.datalen);
outoffset += encrypt.datalen;
offset += templen;
dataLen -= templen;
}
else
{
return 0;
}
}
return outoffset;
case RSA_2048:
dataLen = inLen;
while(dataLen > 0)
{
templen = (dataLen > RSA2048_KEY_LEN) ? RSA2048_KEY_LEN : dataLen;
pTempData = (uint8_t *) MIDOUTBUF;
outoffs = SETCODELEN_MODULE;
pTempData[outoffs++] = gCurrentSysCfg->keyId;
pTempData[outoffs++] = 0x80; //2048加密
pTempData[outoffs++] = (uint8_t) templen;
pTempData[outoffs++] = (uint8_t) (templen >> 8);
memcpy(&pTempData[outoffs], pInputData + offset, templen);
outoffs += templen;
encrypt.datalen = outoffs;
encrypt.bardata = pTempData;
if(RSA_Oper(&encrypt) == TMC_OK)
{
memcpy(pOutputData + outoffset, &encrypt.bardata[SETCODELEN_MODULE + CRYPTO_CMD_OFFS], encrypt.datalen);
outoffset += encrypt.datalen;
offset += templen;
dataLen -= templen;
}
else
{
return 0;
}
}
return outoffset;
case DES3:
memcpy(&pData[dataLen], pInputData, inLen);
dataLen += inLen;
remainder = dataLen % DES_GROUP_LEN;
pkcs = DES_GROUP_LEN - remainder;
for(i = 0; i < (DES_GROUP_LEN - remainder); i++)
{
pData[dataLen++] = pkcs;
}
while(dataLen > 0)
{
pTempData = (uint8_t *) MIDOUTBUF;
outoffs = SETCODELEN_MODULE;
pTempData[outoffs++] = gCurrentSysCfg->keyId;
pTempData[outoffs++] = 0x30; //加密
pTempData[outoffs++] = (uint8_t) DES_GROUP_LEN;
pTempData[outoffs++] = (uint8_t) (DES_GROUP_LEN >> 8);
memcpy(&pTempData[outoffs], pInputData + offset, DES_GROUP_LEN);
outoffs += DES_GROUP_LEN;
encrypt.datalen = outoffs;
encrypt.bardata = pTempData;
if(DES_Oper(&encrypt) == TMC_OK)
{
memcpy(pOutputData + offset, &encrypt.bardata[SETCODELEN_MODULE + CRYPTO_CMD_OFFS], encrypt.datalen);
offset += DES_GROUP_LEN;
dataLen -= DES_GROUP_LEN;
}
else
{
return 0;
}
}
return offset;
default:
break;
}
return 0;
}
/********************************End of File************************************/