/** ****************************************************************************** * @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. * *

© COPYRIGHT 2020 TMS

****************************************************************************** **/ /********************************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************************************/