초보의 아웅다웅 설계하기/STM32

STM32H7과 KCMVP 암호모듈을 사용한 데이터 암호화 전송

로망와니 2021. 2. 16. 17:55

DreamSecurity 社의 MagicFCrypto를 사용하여 암복호화 하였고 PixHawk를 사용하여 암복호화 테스트를 완료하였습니다.

실제 사용은 128bit의 비도가 아닌 256bit를 사용하였습니다.

 

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "mfapi.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* UART handler declaration */
UART_HandleTypeDef Uart1Handle, Uart3Handle;

/* Private functions ---------------------------------------------------------*/
/* Type declarations ---------------------------------------------------------*/

/* External variable declarations ----------------------------------------------*/

/* Uart */
tUart Uart1,Uart3;
/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   : 
*******************************************************************************/
void UART1_FlushRx(void)
{
    Uart1.RxInCnt = 0;
    Uart1.RxOutCnt = 0;
}

/*******************************************************************************
* Function Name : u8 UART1_GetChar(char *data)
* Description   : UART1·Î ¼ö½Å¹öÆÛ¿¡¼­ µ¥ÀÌŸ(1byte) °¡Á®¿À±â
* Parameters    : none
* Return        : µ¥ÀÌŸ ¼ö½Å ¿©ºÎ(0: ¼ö½Å¹öÆÛ°¡ ºñ¾úÀ½, 1: ¼ö½Å¹öÆÛ¿¡ µ¥ÀÌŸ°¡ ÀÖÀ½)
*******************************************************************************/
uint8_t UART1_GetChar(uint8_t *data)
{
    if(Uart1.RxInCnt == Uart1.RxOutCnt) return 0;
    else *data = Uart1.RxBuf[Uart1.RxOutCnt];
    if(Uart1.RxOutCnt<RBUF_SIZE-1) Uart1.RxOutCnt++;
    else Uart1.RxOutCnt = 0;

    return 1;
}

#define USART_ISR_TXE_TXFNF_Pos         (7U)
#define USART_ISR_TXE_TXFNF_Msk         (0x1UL << USART_ISR_TXE_TXFNF_Pos)     /*!< 0x00000080 */
#define USART_ISR_TXE_TXFNF             USART_ISR_TXE_TXFNF_Msk                /*!< Transmit Data Register Empty or TX FIFO Not Full Flag */

uint32_t LL_USART_IsActiveFlag_TXE_TXFNF(USART_TypeDef *USARTn)
{
  return ((READ_BIT(USARTn->ISR, USART_ISR_TXE_TXFNF) == (USART_ISR_TXE_TXFNF)) ? 1UL : 0UL);
}
#define LL_USART_IsActiveFlag_TXE  LL_USART_IsActiveFlag_TXE_TXFNF
/*******************************************************************************
* Function Name : void UART1_PutChar(char data)
* Description   : UART1 1¹®ÀÚ Ãâ·Â
* Parameters    : ¾Æ½ºÅ°ÄÚµå
* Return        : None
*******************************************************************************/
void UART1_PutChar(uint8_t data)
{
	USART1->TDR = data;
	while (!LL_USART_IsActiveFlag_TXE(USART1));
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void UART1_PutStr(char *string)
{
	while(*string != '\0') UART1_PutChar(*string++);
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void UART1_printf(const char *fmt, ...)
{
  char gPrintBuf[256];
  va_list args;
   
  va_start(args,fmt);
  vsprintf(gPrintBuf, fmt, args);
  va_end(args);
  
  UART1_PutStr(gPrintBuf);
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void Uart1_Conf(void)
{
	UART1_FlushRx();
	Uart1Handle.Instance        = USART1;

  Uart1Handle.Init.BaudRate     = 115200;
  Uart1Handle.Init.WordLength   = UART_WORDLENGTH_8B;
  Uart1Handle.Init.StopBits     = UART_STOPBITS_1;
  Uart1Handle.Init.Parity       = UART_PARITY_NONE;
  Uart1Handle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
  Uart1Handle.Init.Mode         = UART_MODE_TX_RX;
  Uart1Handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

  if(HAL_UART_DeInit(&Uart1Handle) != HAL_OK){
    UART1_printf("Error\r\n");
  }  
  if(HAL_UART_Init(&Uart1Handle) != HAL_OK){
    UART1_printf("Error\r\n");
  }
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   : 
*******************************************************************************/
void UART3_FlushRx(void)
{
    Uart3.RxInCnt = 0;
    Uart3.RxOutCnt = 0;
}

/*******************************************************************************
* Function Name : u8 UART3_GetChar(char *data)
* Description   : UART1·Î ¼ö½Å¹öÆÛ¿¡¼­ µ¥ÀÌŸ(1byte) °¡Á®¿À±â
* Parameters    : none
* Return        : µ¥ÀÌŸ ¼ö½Å ¿©ºÎ(0: ¼ö½Å¹öÆÛ°¡ ºñ¾úÀ½, 1: ¼ö½Å¹öÆÛ¿¡ µ¥ÀÌŸ°¡ ÀÖÀ½)
*******************************************************************************/
uint8_t UART3_GetChar(uint8_t *data)
{
    if(Uart3.RxInCnt == Uart3.RxOutCnt) return 0;
    else *data = Uart3.RxBuf[Uart3.RxOutCnt];
    if(Uart3.RxOutCnt<RBUF_SIZE-1) Uart3.RxOutCnt++;
    else Uart3.RxOutCnt = 0;

    return 1;
}

/*******************************************************************************
* Function Name : void UART3_PutChar(char data)
* Description   : UART1 1¹®ÀÚ Ãâ·Â
* Parameters    : ¾Æ½ºÅ°ÄÚµå
* Return        : None
*******************************************************************************/
void UART3_PutChar(uint8_t data)
{
	USART3->TDR = data;
	while (!LL_USART_IsActiveFlag_TXE(USART3));	
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void UART3_PutStr(char *string)
{
	while(*string != '\0') UART3_PutChar(*string++);
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void UART3_printf(const char *fmt, ...)
{
  char gPrintBuf[256];
  va_list args;
   
  va_start(args,fmt);
  vsprintf(gPrintBuf, fmt, args);
  va_end(args);
  
  UART3_PutStr(gPrintBuf);
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void Uart3_Conf(void)
{
	UART3_FlushRx();
	Uart3Handle.Instance        = USART3;

  Uart3Handle.Init.BaudRate     = 115200;
  Uart3Handle.Init.WordLength   = UART_WORDLENGTH_8B;
  Uart3Handle.Init.StopBits     = UART_STOPBITS_1;
  Uart3Handle.Init.Parity       = UART_PARITY_NONE;
  Uart3Handle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
  Uart3Handle.Init.Mode         = UART_MODE_TX_RX;
//  Uart3Handle.Init.OverSampling = UART_OVERSAMPLING_16;
  Uart3Handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

  if(HAL_UART_DeInit(&Uart3Handle) != HAL_OK){
    UART1_printf("Error\r\n");
  }  
  if(HAL_UART_Init(&Uart3Handle) != HAL_OK){
    UART1_printf("Error\r\n");
  }
}

TIM_HandleTypeDef    TimHandle;
/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void TIM3_Conf(void)
{
  /* Set TIMx instance */
  TimHandle.Instance = TIM3;

  TimHandle.Init.Period            = 1000;
  TimHandle.Init.Prescaler         = 2400-1;
  TimHandle.Init.ClockDivision     = 0;
  TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  TimHandle.Init.RepetitionCounter = 0;

  if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
		UART1_printf("HAL_TIM_Base_Init Error");

  /*##-2- Start the TIM Base generation in interrupt mode ####################*/
  /* Start Channel1 */
  if (HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
		UART1_printf("HAL_TIM_Base_Start_IT Error");
}


/*******************************************************************************
* Function Name : 
* Parameters    : 
* Return        : None
* Description   : 
*******************************************************************************/
RNG_HandleTypeDef RngHandle;
void Config_RNG(void)
{
  RngHandle.Instance = RNG;
  
  /* DeInitialize the RNG peripheral */
  if (HAL_RNG_DeInit(&RngHandle) != HAL_OK){;}
  /* Initialize the RNG peripheral */
  if (HAL_RNG_Init(&RngHandle) != HAL_OK){;}
}

/*******************************************************************************
* Function Name : 
* Parameters    : 
* Return        : 
* Description   : 
*******************************************************************************/
void Get_TRNG(uint32_t *chpData)
{
  register uint8_t index = 0;
	
	if (HAL_RNG_GenerateRandomNumber(&RngHandle, chpData) != HAL_OK){
		;/* Random number generation error */
	}
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void crypto_lea(
mf_uchar *in, mf_uint inlen,
mf_uchar *out, mf_uint *outlen,
mf_uchar *key, mf_uint keylen,
mf_uchar *iv, mf_uint ivlen)
{
	mf_rv rv = MF_OK;
	mf_ulong sid = 0;
	mf_algorithm alg = {0, NULL, 0};
	mf_data data = {0,};

	mf_ciphermode mode = {0,};

	alg.algid = MF_ALGID_LEA_128BITKEY;
	alg.param = key;
	alg.param_size = keylen;

	rv = mf_open_session(&alg, &sid);
	if (rv != MF_OK) 
		UART1_printf("mf_open_session ERROR : %d\r\n", rv);	

	mode.mode  = MF_MODE_CTR;
	mode.param = iv;
	mode.param_size = ivlen;

	rv = mf_cipher_init(sid, MF_FLAG_ENCRYPT, &mode);
	if (rv != MF_OK) 
		UART1_printf("mf_cipher_init ERROR : %d\r\n", rv);

	data.in = in;
	data.in_size = inlen;
	data.out = out;
	data.out_size = *outlen;

	rv = mf_cipher_final(sid, &data);
	if (rv != MF_OK) 
		UART1_printf("mf_open_session ERROR : %d\r\n", rv);	
	
	*outlen = data.out_size;
	mf_close_session(sid);
}

mf_uchar txplaintext[RBUF_SIZE];
mf_uint txplaintextlen = sizeof(txplaintext);

mf_uchar cyptotext[RBUF_SIZE] = {0,};
mf_uint cyptotextlen = sizeof(cyptotext);

mf_uchar protocoltext[RBUF_SIZE] = {0,};
mf_uint protocoltextlen = sizeof(protocoltext);

mf_uchar enckey[16] = "\xe7\x9e\x8a\x80\x9b\xc2\x97\x2d\x56\x91\xfe\xbd\x98\x30\x9e\xa0";
mf_uint enckeylen = 16; //sizeof(key); // 16,24,32
mf_uchar enciv[16];
mf_uint encivlen = 16;

mf_uint incrand = 4;
mf_uchar encrand[4] = {0, };
mf_uint encrandlen = 4;
mf_uchar encrandbk[4] = {0, };

/*
stx rand[4] length data sum etx
*/
#define STX 0x02
#define ETX 0x03
/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void Gen_iv(mf_uchar *rand, mf_uchar *iv, mf_uint ivlen)
{
	;
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void Gen_rand(mf_uint *num, mf_uchar *rand)
{
 ;
}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
void Gen_Protocol(mf_uchar *rand, mf_uint randlen, mf_uchar *in, mf_uint inlen, mf_uchar *out, mf_uint *outlen)
{

}

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   :  
*******************************************************************************/
uint32_t gTick = 0;
#define GetTdata UART3_GetChar
void Crypto(void)
{
	uint8_t ch = 0;

	while(GetTdata(&ch)){
		gTick = 0;
		txplaintext[txplaintextlen] = ch; 
        txplaintextlen++;
		if(txplaintextlen >= CRYPTO_SIZE){	
			cyptotextlen = txplaintextlen + 16;
			Gen_rand(&incrand, encrand);
			Gen_iv(encrand, enciv, 16);
			crypto_lea(
				txplaintext, txplaintextlen,
				cyptotext, &cyptotextlen,
				enckey, enckeylen,
				enciv, 16
			);
			Gen_Protocol(encrand, encrandlen, cyptotext, cyptotextlen, protocoltext, &protocoltextlen);
			txplaintextlen = 0;
		}			
	}
	if(gTick > TXTICK_LIMIT){
		gTick = 0;
		if(txplaintextlen > 0){
			cyptotextlen = txplaintextlen + 16;
			Gen_rand(&incrand, encrand);
			Gen_iv(encrand, enciv, 16);
			crypto_lea(
				txplaintext, txplaintextlen,
				cyptotext, &cyptotextlen,
				enckey, enckeylen,
				enciv, 16
			);
			Gen_Protocol(encrand, encrandlen, cyptotext, cyptotextlen, protocoltext, &protocoltextlen);
			txplaintextlen = 0;
		}
	}
}

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{  
  /* Enable the CPU Cache */
  CPU_CACHE_Enable();

  HAL_Init();

  /* Configure the system clock to 400 MHz */
  SystemClock_Config();
  
  /* Configure LED1, LED3 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED3);

	mf_initialize();
	Uart1_Conf();
	Uart3_Conf();
	TIM3_Conf();
	Config_RNG();
	Get_TRNG(&incrand);

	txplaintextlen = 0;
	rxplaintextlen = 0;
	while(1){
		Crypto();
	}
}