CEBF746 Module.. with TPM

Dependencies:   cube_CEBF746 cube_crypto cube_crc_16

main.cpp

Committer:
gandol2
Date:
2016-10-24
Revision:
9:43c097befe90
Parent:
8:e20fe81cddbb

File content as of revision 9:43c097befe90:

// firmware for CBEF746
// ======== SPI Slave Pin
// PA5  - SCK
// PA6  - MISO
// PA7  - MOSI
// PA14 - SEL
// ======== I2C Pin for TPM
// PB9  - SDA
// PB8  - SCL

#include "mbed.h"
#include "lib_CEBF746.h"
#include "lib_crc.h"
#include "cube_crypto.h"


#define DEBUG_SPI
#ifdef DEBUG_SPI
#define PRINTD(arg1,arg2...)    printf(arg1,##arg2)
#endif

// ======== SPI Slave Pin define
#define SPI_MOSI    PA_7
#define SPI_MISO    PA_6
#define SPI_SCLK    PA_5
#define SPI_SSEL    PA_4

#define SPI_CONFIG_BIT          8
#define SPI_CONFIG_FREQUENCY    1000000         // 1Mhz
//#define SPI_CONFIG_FREQUENCY    50000000      // 50Mhz

#define SPI_INTERRUPT   0

Serial pc_serial(USBTX, USBRX);
#if SPI_INTERRUPT
InterruptIn spi_interrupt(SPI_SSEL);                     // Falling Edge
#endif  /* SPI_INTERRUPT */

SPISlave spi_slave(SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_SSEL); // MOSI, MISO, SCLK(CLK), SSEL(CS)=NC


uint8_t cebBufEncrypt[CEB_BUF_SIZE] = {};     // 암호화 예정 버퍼
uint8_t cebBufEncrypted[CEB_BUF_SIZE] = {};   // 암호화 완료된 버퍼 

uint8_t cebBufDecrypt[CEB_BUF_SIZE] = {};     // 복호화 예정 버퍼
uint8_t cebBufDecrypted[CEB_BUF_SIZE] = {};   // 복호화 완료된 버퍼 



extern uint8_t readSelfTestValidateData[CEB_BUF_SIZE];
extern uint8_t writeSelfTestValidateData[CEB_BUF_SIZE];


#if SPI_INTERRUPT

bool spi_receive_wait(void)
{
#define ISR_TIMEOUT 100
    int timeout;

    while(!spi_slave.receive())     // wait SPI data input...
    {
        timeout++;
        if(ISR_TIMEOUT <= timeout)
        {
            pc_serial.printf("spi isr timeout\n");
            return false;
        }
    }

    return true;
}

void execute_spi_slave_isr( void )
{

    char cebf746Func;

    spi_receive_wait();

    cebf746Func = spi_slave.read();


    switch(cebf746Func)
    {
        case  0x01:     // FUNC_STATUS_REG

            //spi_receive_wait();


            //printf("[DEBUG] [M to S] eepAddr=0x%02x\n",eepAddr);
            //for(int i=0;i<3;i++)
            {
                spi_slave.reply( retCnt );

                //++eepAddr;
                //printf("[0x%02x] ",spiMulti);
            }

            printf("[DEBUG] [M to S] retCnt [0x%02X]\n", retCnt);
            retCnt--;
        break;
    }

    /*      // backup code
#define ISR_TIMEOUT 100
    int timeout;
    char cebf746Func = 0;
    //pc_serial.printf("init spi inturrupt!!\n");



    timeout = 0;
    while(!spi_slave.receive())   // wiat for cebf746 func byte (first byte)
    {
        timeout++;
        if(ISR_TIMEOUT <= timeout)
        {
            pc_serial.printf("spi isr timeout\n");
            return;
        }
    }

    cebf746Func = spi_slave.read(); // read cebf746 func byte
    //pc_serial.printf("[0x%02X]\n", cebf746Func);



    switch(cebf746Func)
    {
    case 0x01:      // FUNC_STATUS_REG
        while(!spi_slave.receive());
        spi_slave.reply( retCnt );        // return code
        while(!spi_slave.receive());
        spi_slave.reply( retCnt+1 );        // return code
        while(!spi_slave.receive());
        spi_slave.reply( retCnt+2 );        // return code
        break;
    }



    pc_serial.printf("return code : 0x%02X \n", 0xBB);
    pc_serial.printf("data : 0x%02X \n", retCnt);
    retCnt++;
    */
}

void SPI_InitInterrupt()
{
    spi_interrupt.rise(&execute_spi_slave_isr);
    spi_interrupt.enable_irq();
    //spi_interrupt.mode(PullDown);    // Pull down input
    //spi_interrupt.fall(&execute_spi_slave_isr);      // Attach the isr address to the falling edge interrupt
    PRINTD("SPI Interrupt Init.. OK\n");
}
#endif  /* SPI_INTERRUPT */

/** @brief slave init
 *
 */
void SPI_InitSlave()
{
    spi_slave.format(SPI_CONFIG_BIT,0);
    spi_slave.frequency(SPI_CONFIG_FREQUENCY);
    PRINTD("SPI Init.. Packet bit size=[%d] Frequency=[%d]Mhz\n", SPI_CONFIG_BIT, (SPI_CONFIG_FREQUENCY/1000000));
    PRINTD("SPI Init.. OK\n");
}






Timeout receiveTimeOut;
bool timeOut = false;
#define CEBF746_TIMEOUT    10    // 1 sec

uint8_t slave_read_byte()
{    
    while(!spi_slave.receive());        // ★★★★  마스터 쪽에서 패킷이 수신 안됐을 경우 loop에서 나오지 못함. 예외 처리(time out) 적용 해야함.
    return spi_slave.read();    
}
void slave_write_byte(uint8_t txData)
{
    spi_slave.reply( txData );
    while(!spi_slave.receive());        // ★★★★   마스터 쪽에서 패킷이 수신 안됐을 경우 loop에서 나오지 못함. 예외 처리(time out) 적용 해야함.
    spi_slave.read();
}

void slave_read_uint16(uint16_t* buf16)
{
    uint16_t temp;
    
    temp = slave_read_byte();    
    *buf16 = temp << 8;

    temp = slave_read_byte();
    *buf16 |= temp;
    
    //*buf16 = (slave_read_byte() << 8) | (slave_read_byte());
}
void slave_read_multi_byte(uint8_t* buf, int size)
{
    for(int iCnt = 0 ; iCnt < size ; ++iCnt)
        *(buf+iCnt) = slave_read_byte();
}

void slave_write_multi_byte(uint8_t* buf, int size)
{
    for(int iCnt = 0 ; iCnt < size ; ++iCnt)
        slave_write_byte(*(buf+iCnt));
}


void slave_write_packet(spiDataStr* packet)
{    
    slave_write_byte((packet->size >> 8) & 0xFF);
    slave_write_byte((packet->size     ) & 0xFF);      
    slave_write_multi_byte(packet->buf, packet->size);
    slave_write_byte((packet->crc16 >> 8) & 0xFF);
    slave_write_byte((packet->crc16     ) & 0xFF);    
}

#define YSH_CODE    1
#if YSH_CODE




cube_sec_context tempContext;

#endif



/** @brief main function ###################################################################
 *
 */
int main()
{
    sec_spi_data tempConvertStruct;   
    

    uint8_t  spiRxTempBuf = 0;
    
    
    bool crcCheck = false;
    
    
    uint16_t genCrc = 0;

    spiDataStr txData; 
    spiDataStr rxData; 
    
    pc_serial.printf("\n\n========== CEBF746 SPI Slave [Start] ==========\n");

    SPI_InitSlave();
    
    cube_sec_init();
    Thread encrypt(cube_Thread_AES_encrypt, NULL, osPriorityNormal, DEFAULT_STACK_SIZE);
    Thread decrypt(cube_Thread_AES_decrypt, NULL, osPriorityNormal, DEFAULT_STACK_SIZE);
    
#if SPI_INTERRUPT
    SPI_InitInterrupt();
    while(1);
#endif /* SPI_INTERRUPT */

    
    while(1)
    {
        pc_serial.printf("\n\nwaiting CEBF746 cmd...\n");    
        
        
        spiRxTempBuf = slave_read_byte();        
        //printf("menu[%02X]\n", spiRxTempBuf);
        //cebf746_print_cmd(spiRxTempBuf);

        switch(spiRxTempBuf)
        {
            case FUNC_READ_STATUS:
                slave_write_byte( cube_get_status() );
                printf("[INFO] Response Status reg [%02X]\n", cube_get_status());
            break;
            
            case FUNC_WRITE_ENC_DATA:       // 161020_1차 테스트 완료 
                
                uint16_t packetSize = 0;
                uint8_t tempBuf[CEB_BUF_SIZE] = {0, };
                uint16_t retCrc = 0;
                
                packetSize = 0;
                slave_read_uint16(&packetSize);                
                if(packetSize != CEB_BUF_SIZE)
                {
                    printf("[ERROR] %s : %d : packet size error, recived packet size[%d]\n", __FILE__, __LINE__, packetSize);
                    continue;
                }                
                slave_read_multi_byte(tempBuf, CEB_BUF_SIZE);                   
                slave_read_uint16(&retCrc);
                
                cube_crc_16(CEB_BUF_SIZE, tempBuf, &genCrc);
                crcCheck = cube_crc_compare(retCrc, genCrc);
                if(true == crcCheck )
                    slave_write_byte(WRITE_SELF_TEST_RET_CODE);  
                else
                    slave_write_byte(0x00);
                _cebf746_print_packet(packetSize, tempBuf, retCrc);
                
                
                if(true == crcCheck )
                {
                    /// ★★★여기서 윤주임코드 암호화 스레드 동작할수 있게 flag setting 해야함!!
                    
                    tempConvertStruct.cmd = 0x42;       // 0b01000010                    
                    tempConvertStruct.data = tempBuf;
                    tempConvertStruct.key_crc = NULL;
                    
                    //cube_crypt_spi_cmd_set(&tempContext, 0x02,tempBuf, 0);
                    cube_crypt_spi_cmd_set(&tempConvertStruct);
                    pc_serial.printf("call \"cube_crypt_spi_cmd_set()\"\n");
                    
                }
                else
                {
                    printf("[ERROR] %s : %d : FUNC_WRITE_ENC_DATA CRC Error\n", __FILE__, __LINE__);
                }
                
            break;
            
            case FUNC_READ_ENC_DATA:
                //uint16_t keyCrc = 0xAABB;               // ★★★★ 윤주임 코드 들어오면 keyCrc 참조 변경 해야함 
                //packetLength = CEB_BUF_SIZE+2;
               
                // ★★★★ status reg 읽어오는 부분이 문제가 있는듯함 여기를 먼저 고쳐야함 
                if(cube_get_status() == 0x02)   // 암호화가 완료 되었으면 
                {   
                    //printf("..\n");
                    /*
                    tempConvertStruct.cmd = 0x02;       // 0b01000010                    
                    tempConvertStruct.data = tempBuf;
                    tempConvertStruct.key_crc = NULL;
                                        
                    cube_crypt_spi_cmd_set(&tempConvertStruct);
                    */
                    
                    txData = getEncTxPacket();
                    slave_write_packet(&txData);
                    
                    cebf746_print_packet(&txData);
                    
                    
                    /*
                    
                    
                    
                    
                    */
                    /*
                    memcpy(spiTXBuf, cebBufEncrypted, CEB_BUF_SIZE);        // encrypted data copy
                    spiTXBuf[CEB_BUF_SIZE + 0] = ((keyCrc >> 8) & 0xFF);    // upper key crc copy 
                    spiTXBuf[CEB_BUF_SIZE + 1] = ((keyCrc     ) & 0xFF);    // lower key crc copy                    
                    
                    
                    cebf746_set_packet(&txData, packetLength, spiTXBuf);
                    */
                    //_cebf746_print_packet(packetLength, spiTXBuf, genCrc);
                    
                }
                else
                {
                  //  printf("xx\n");
                }
            break;
            
            case FUNC_WRITE_DEC_DATA:
            break;
            
            case FUNC_READ_DEC_DATA:
            break;
            
            
            case FUNC_WRITE_SELF_TEST:         // 161017_KSS_Test OK
                
                slave_read_uint16(&rxData.size);
                
                rxData.buf = (uint8_t*)malloc(rxData.size);
                slave_read_multi_byte(rxData.buf, rxData.size);     
                
                slave_read_uint16(&rxData.crc16);
                
                
                
                cube_crc_16(rxData.size, rxData.buf, &genCrc);

                crcCheck = cube_crc_compare(rxData.crc16, genCrc);
                if(true == crcCheck )
                    slave_write_byte(WRITE_SELF_TEST_RET_CODE);  
                else
                    slave_write_byte(0x00);

                // ----- print rx buf
                cebf746_print_packet(&rxData);
                
                pc_serial.printf("crc read[%04X], gen[%04X] check...", rxData.crc16, genCrc);
                if(true == crcCheck )
                    pc_serial.printf("[OK]\n");
                else
                    pc_serial.printf("[FAIL]\n");

                // ----- free()
                free(rxData.buf);
                
            break;
            
            case FUNC_READ_SELF_TEST:         // 161017_KSS_Test OK                
                
                cebf746_set_packet(&txData, CEB_BUF_SIZE, readSelfTestValidateData);
                slave_write_packet(&txData);
                
                printf("--FUNC_READ_SELF_TEST end\n");
            break;

        }

            

        
    }







}//end of main