1. 程式人生 > >2018-2019-1 20165318 20165322 20165326 實驗二 韌體程式設計

2018-2019-1 20165318 20165322 20165326 實驗二 韌體程式設計

目錄

  1. 參考雲班課資源中“資訊安全系統實驗箱指導書.pdf “第一章,1.1-1.5安裝MDK,JLink驅動,注意,要用系統管理員身分執行uVision4,破解MDK(破解程式中target一定選ARM)
  2. 提交破解程式中產生LIC的截圖
  3. 提交破解成功的截圖
  • 按照實驗指導書上的操作進行軟體安裝-->執行 uVision4,點 File>>License Management-->複製 CID-->執行keil-MDK註冊機(在“Z32開發指南\2.軟體資料\keil-MDK 註冊機”雙擊“keil mdk474註冊機”)-->貼上 CID 並選擇 ARM。

2-LED
  1. 參考雲班課資源中“資訊安全系統實驗箱指導書.pdf “第一章,1.4” KEIL-MDK 中新增 Z32 SC-000 晶片庫,提交安裝截圖
  2. 參考雲班課資源中“資訊安全系統實驗箱指導書.pdf “第一章,1.9”完成LED實驗,注意“開啟Z32的電源開關前,按住Reboot按鍵不放,兩次開啟電源開關,Z32即可被電腦識別,進行下載除錯。提交執行結果截圖
  3. 實驗報告中分析程式碼
  • 首先先在 KEIL-MDK 中新增 Z32 SC-000 晶片庫,操作過程為:

    • 開啟 keil uVision4 MDK。

    • 新建工程選擇 Project——>New uVision Project。

    • 在彈出的安裝路徑視窗選擇安裝路徑資料夾,併為工程命名。

    • 在晶片庫選擇框選擇庫 Generic SC000 Device Database。

    • 點開 ARM 結構目錄,選擇 SC000,點選 OK,搭建完成。

    • 搭建成功截圖:

  • 然後完成讓LED燈閃爍實驗:

    • 在 user 組和 driver組下分別雙擊Main.c和Gpio.c,就可以看到程式的原始碼。開啟 Main.c,程式碼如下:
    int main(void)
    {
    /*********************此段程式碼勿動***********************/
    //系統中斷向量設定,使能所有中斷
      SystemInit ();
    // 返回 boot 條件
      if(0 == GPIO_GetVal(0))
      {
          BtApiBack(0x55555555, 0xAAAAAAAA);
      }
    /*********************此段程式碼勿動***********************/
      GPIO_PuPdSel(0,0); //設定 GPIO0 為上拉
      GPIO_InOutSet(0,0); //設定 GPIO0 為輸出
      while(1)
      {
          delay(100);
          GPIO_SetVal(0,0); //輸出低電平,點亮 LED
          delay(100);
          GPIO_SetVal(0,1); //輸出高電平,熄滅 LED 
      }
    }
      //延時函式,當系統時鐘為內部 OSC 時鐘時,延時 1ms
    void delay(int ms)
    {
      int i;
      while(ms--)
      {
          for(i=0;i<950;i++) ;
      }
    }
    • 開啟“Z32 開發指南\實驗1-LED閃爍”目錄的工程檔案。編譯工程,產生字尾名為.bin 的可執行程式碼。

    • 將實驗箱接入電源,用USB公對公線將實驗箱的USB介面連線到電腦的USB介面上,在電腦上找到“Z32開發指南\2.軟體資料\Z32下載除錯工具”目錄打Z32 下載除錯工具NZDownloadTool.exe。開啟Z32的電源開關前,按住Reboot按鍵不放,兩次開啟電源開關,Z32即可被電腦識別,進行下載除錯。

    • 當左邊框出現“1裝置已連線”,裝置選擇中顯示晶片型號,此時就可以下載程式了。我們點選視窗右下方“確認下載”一欄的“瀏覽”,選擇程式路徑為“Z32開發指南\實驗 1-LED閃爍\bin\Z32HUA.bin”)開啟,最後點選下載。

    • 結果截圖:
  • 主函式程式碼分析

    • 系統初始化,中斷設定,使能所有中斷

    • 判斷按鍵,返回 boot 條件,確認是否進行程式下載

    -設定 GPIO0 狀態為上拉輸出

    • 進入迴圈程式,LED 燈間隔 100ms 閃爍
3-UART
  1. 注意不經老師允許不準燒寫自己修改的程式碼
  2. 參考雲班課資源中“資訊安全系統實驗箱指導書.pdf “第一章,1.4” KEIL-MDK 中新增 Z32 SC-000 晶片庫,提交安裝截圖
  3. 參考雲班課資源中“資訊安全系統實驗箱指導書.pdf “第一章,1.0”完成UART傳送與中斷接收實驗,注意“開啟Z32的電源開關前,按住Reboot按鍵不放,兩次開啟電源開關,Z32即可被電腦識別,進行下載除錯。提交執行結果截圖
  4. 實驗報告中分析程式碼
  • 首先和實驗二中一樣在 KEIL-MDK 中新增 Z32 SC-000 晶片庫
  • 然後完成UART傳送與中斷接收實驗:
    • 在user組和driver組下分別雙擊Main.c和Uart.c,就可以看到程式的原始碼。開啟 Uart.c,首先介紹串列埠相關函式,程式碼如下:
**Uart.c**
extern UINT8 shuju_lens; 
extern UINT8 uart_rx_num; 
extern UINT8 uart_rx_end; 

void UART_Irq Service(void) 
{ 
  //*****your code*****/ 
  UARTCR &= ~TRS_EN; 
  { 
   do 
      { 
       shuju[uart_rx_num] = UARTDR; 
     if(shuju[uart_rx_num]=='\r'||shuju[uart_rx_num]=='\n') 
     { 
        shuju_lens = uart_rx_num; 
      uart_rx_num=0; 
      uart_rx_end=1; 
     } 
     else uart_rx_num++; 
      } 
      while(FIFO_NE & UARTISR);     
  } 
  UARTCR |= TRS_EN; 
} 

/**  
  * @
函式:波特率設定

  * @set
:
  0-
預設波特率 
115200
,其他:需根據時鐘源和分頻計算出 
set =  
時
鍾
(hz)/
波特率

  * @
返回
: none 
  */ 
void UART_Brp Set(UINT16 set) 
{ 
  UINT16 brp=0; 
     UINT8 fd=0;  
     if(0 == set) 
     { 
      //[email protected] 
       fd = SCU->UARTCLKCR & 0x80;  
       switch(fd) 
         { 
         case 0x80:     /*
外部時鐘 
12M 
晶振
*/ 
              brp = 0x0068; 
              break; 
             case 0x00:     /*
內部時鐘
*/ 
     brp = 0x00AD;   
                 break;     
             default: 
                brp = 0x00AD; 
                break; 
         } 
    fd = SCU->UARTCLKCR & 0x7f ;  
     brp =  brp/(fd+1); 
     } 
     else 
     { 
      brp = set; 
     } 
  UARTBRPH = (UINT8)((brp >> 8) & 0x FF); 
     UARTBRPL = (UINT8)((brp) & 0x FF); 
} 



/**  
  * @
函式:初始化

  * @
返回:
none 
  */ 
void UART_Init(void) 
{ 
  IOM->CRA |= (1<<0);  //
使能 
Uart 
介面

  SCU->MCGR2 |= (1<<3); //
使能 
Uart 
匯流排時鐘


  /******
配置 
Uart 
時鐘(建議使用外部晶振)
******/ 
  SCU->SCFGOR |= (1<<6);//  
使能外部晶振

  SCU->UARTCLKCR |= (1<<7);//
使用外部時鐘

// SCU->UARTCLKCR &= ~(1<<7);//
使用內部 
OSC 
時鐘


  UART_Brp Set(0);   //
設定波特率為預設 
115200 
  UARTISR = 0x FF;   //
狀態暫存器全部清除

  UARTCR |= FLUSH; //
清除接收 
fifo 
  UARTCR = 0;    //
偶校驗


  /******
配置中斷使能
******/ 
  UARTIER |= FIFO_NE; 
// UARTIER |= FIFO_HF; 
// UARTIER |= FIFO_FU; 
// UARTIER |= FIFO_OV; 
// UARTIER |= TXEND; 
// UARTIER |= TRE;  
  Module Irq Register(Uart_Exception, UART_Irq Service); //
掛載中斷號

}     


/**  
  * @
函式:
Uart 
傳送一個位元組

  * @dat:   
要傳送的資料位元組

  * @
返回:
None 
  */ 
void UART_Send Byte(UINT8 dat) 
{   
  UARTCR |= TRS_EN; 
  UARTDR = dat; 
     do 
     { 
     if(UARTISR & TXEND) 
         {             
             UARTISR |= TXEND;//
清除傳送完成標誌,寫 
1 
清除

             break; 
         } 
     } 
     while (1); 
     UARTCR &= (~TRS_EN); 
} 

/**  
  * @
函式:
Uart 
傳送一個字串

  * @str:   
要傳送的字串

- 76 - 
      shuju_lens = uart_rx_num; 
      uart_rx_num=0; 
      uart_rx_end=1; 
     } 
     else uart_rx_num++; 
      } 
      while(FIFO_NE & UARTISR);     
  } 
  UARTCR |= TRS_EN; 
} 

/**  
  * @
函式:波特率設定

  * @set
:
  0-
預設波特率 
115200
,其他:需根據時鐘源和分頻計算出 
set =  
時
鍾
(hz)/
波特率

  * @
返回
: none 
  */ 
void UART_Brp Set(UINT16 set) 
{ 
  UINT16 brp=0; 
     UINT8 fd=0;  
     if(0 == set) 
     { 
      //[email protected] 
       fd = SCU->UARTCLKCR & 0x80;  
       switch(fd) 
         { 
         case 0x80:     /*
外部時鐘 
12M 
晶振
*/ 
              brp = 0x0068; 
              break; 
             case 0x00:     /*
內部時鐘
*/ 
     brp = 0x00AD;   
                 break;     
             default: 
                brp = 0x00AD; extern UINT8 shuju[64]; 
extern UINT8 shuju_lens; 
extern UINT8 uart_rx_num; 
extern UINT8 uart_rx_end; 

void UART_Irq Service(void) 
{ 
  //*****your code*****/ 
  UARTCR &= ~TRS_EN; 
  { 
   do 
      { 
       shuju[uart_rx_num] = UARTDR; 
     if(shuju[uart_rx_num]=='\r'||shuju[uart_rx_num]=='\n') 
     {  
- 80 - 
  * @
返回:
None 
  */ 
void UART_Send Num(INT32 num) 
{ 
  INT32 cnt = num,k; 
  UINT8 i,j; 
  if(num<0) {UART_Send Byte('-');num=-num;} 
  //
計算出 
i 
為所發資料的位數

  for(i=1;;i++) 
  { 
   cnt = cnt/10; 
   if(cnt == 0) break; 
  } 
  //
算出最大被除數從高位分離

  k = 1; 
  for(j=0;j<i-1;j++) 
  { 
   k = k*10; 
  } 
  //
分離併發送各個位

  cnt = num; 
  for(j=0;j<i;j++) 
  { 
   cnt = num/k; 
   num = num%k; 
   UART_Send Byte(0x30+cnt); 
   k /= 10; 
  } 
} 


/**  
  * @
函式:
Uart 
傳送一個 
16 
進位制整數

  * @dat:   
要傳送的 
16 
進位制數

  * @
返回:
None  
- 79 - 
  * @
返回:
None 
  */ 
void UART_Send String(UINT8 * str) 
{ 
  UINT8 *p ; 
  p=str; 
  while(*p!=0) 
  { 
   UART_Send Byte(*p++); 
  } 
} 


/**  
  * @
函式:
Uart 
傳送某一長度的字串

  * @buf:   
要傳送的字串

  * @length:   
要傳送的長度

  * @
返回:
None 
  */ 

void uart_Send String(UINT8 buf[],UINT8 length) 
{ 
  UINT8 i=0; 
  while(length>i) 
  { 

   UART_Send Byte(buf[i]); 
   i=i+1; 
  } 
} 


/**  
  * @
函式:
Uart 
傳送一個十進位制整數

  * @num:   
要傳送的整數
                 break; 
         } 
    fd = SCU->UARTCLKCR & 0x7f ;  
     brp =  brp/(fd+1); 
     } 
     else 
     { 
      brp = set; 
     } 
  UARTBRPH = (UINT8)((brp >> 8) & 0x FF); 
     UARTBRPL = (UINT8)((brp) & 0x FF); 
} 



/**  
  * @
函式:初始化

  * @
返回:
none 
  */ 
void UART_Init(void) 
{ 
  IOM->CRA |= (1<<0);  //使能Uart介面

  SCU->MCGR2 |= (1<<3); //
使能 
Uart 
匯流排時鐘


  /******
配置 
Uart 
時鐘(建議使用外部晶振)
******/ 
  SCU->SCFGOR |= (1<<6);//  
使能外部晶振

  SCU->UARTCLKCR |= (1<<7);//
使用外部時鐘

// SCU->UARTCLKCR &= ~(1<<7);//
使用內部 
OSC 
時鐘


  UART_Brp Set(0);   //
設定波特率為預設 
115200 
  UARTISR = 0x FF;   //
狀態暫存器全部清除

  UARTCR |= FLUSH; //
清除接收 
fifo 
  UARTCR = 0;    //
偶校驗

  */ 
void UART_Send Hex(UINT8 dat) 
{ 
  UINT8 ge,shi; 
  UART_Send Byte('0'); 
  UART_Send Byte('x'); 
  ge = dat%16; 
  shi = dat/16; 
  if(ge>9) ge+=7;     //
轉換成大寫字母

  if(shi>9) shi+=7; 
  UART_Send Byte(0x30+shi); 
  UART_Send Byte(0x30+ge); 
  UART_Send Byte(' '); 
} 


/**  
  * @
函式:
Uart 
接收一個位元組

  * @param receive addsress 
  * @
返回:
  flag 
  */ 
UINT8 UART_Get Byte(UINT8 *data) 
{ 

     UINT8 ret= 0;  
     if(0 != (UARTISR & FIFO_NE)) 
     { 
         *data = UARTDR; 
         ret = 1; 
     }  
     return ret; 
} 

/**  
  * @
函式:
Uart  
接收多個位元組
   * @param receive addsress 
  * @len
:

長度

  * @
返回:
none 
  */ 
void UART_Receive(UINT8 *receive, UINT8 len) 
{   
  while(len != 0) 
  { 
   if(len >= 4) 
   { 
    while (!(UARTISR & FIFO_FU)); 
    *receive++ = UARTDR; 
        *receive++ = UARTDR; 
    *receive++ = UARTDR; 
        *receive++ = UARTDR;     
        len -= 4; 

   }  
   else if(len >= 2) 
   { 
    while (!(UARTISR & FIFO_HF));              
     *receive++ = UARTDR; 
      *receive++ = UARTDR;     
      len -= 2; 
   }        
   else 
   { 
     while (!(UARTISR & FIFO_NE)); 
       *receive++ = UARTDR; 
     len--; 
   } 
  } 
} 

-------------
**main.c**

UINT8 shuju_lens; 
UINT8 shuju[64]; 
UINT8 uart_rx_num; 
UINT8 uart_rx_end; 

int main(void) 
{ 
/*********************
此段程式碼勿動
***********************/ 
  //
系統中斷向量設定,使能所有中斷

  System Init (); 
     //  
返回 
boot 
條件

  if(0 == GPIO_Get Val(0)) 
  { 
   Bt Api Back(0x55555555, 0x AAAAAAAA); 
  }
  /*********************
此段程式碼勿動
***********************/ 

  UART_Init();     //
初始化 
Uart 

  UART_Send Byte('A');                   //Uart 
傳送一個字元 
A 
  UART_Send Byte('\r');UART_Send Byte('\n');//
換行


  UART_Send String("Welcome to Z32HUA!");   //Uart 
傳送字串

  UART_Send Byte('\r');UART_Send Byte('\n');//
換行


  UART_Send Num(1234567890);                //Uart 
傳送一個十進位制數

  UART_Send Byte('\r');UART_Send Byte('\n');//
換行


  UART_Send Hex(0x AA);                   //Uart 
傳送一個十六進位制數

  UART_Send Byte('\r');UART_Send Byte('\n');//
換行


  while(1) 
  { 
   if(uart_rx_end) 
   { 
    uart_rx_end=0; 
    uart_Send String(shuju,shuju_lens); 
   } 
  }   //
等待接收中斷。

} 

//
延時函式,當系統時鐘為內部 
OSC 
時鐘時,延時 
1ms 
void delay(int ms) 
{ 
  int i; 
  while(ms--) 
  { 
  for(i=0;i<950;i++) ; 
  } 
}  
  • 開啟“Z32 開發指南\實驗8-SM1”目錄的工程檔案。編譯工程,產生字尾名為.bin 的可執行程式碼。
  • 將實驗箱接入電源,用USB公對公線將實驗箱的USB介面連線到電腦的USB介面上,在電腦上找到“Z32開發指南\2.軟體資料\Z32下載除錯工具”目錄開啟 Z32 下載除錯工具 NZDownloadTool.exe。開啟Z32的電源開關前,按住Reboot按鍵不放,兩次開啟電源開關,Z32 即可被電腦識別,進行下載除錯。
  • 當左邊框出現“1裝置已連線”,裝置選擇中顯示晶片型號,此時就可以下載程式了。我們點選視窗右下方“確認下載”一欄的“瀏覽”,選擇程式路徑為“Z32開發指南\實驗 8-SM1\bin\Z32HUA.bin”並開啟,最後點選下載。
  • 結果截圖:

  • 程式碼分析

    • 串列埠相關函式:包括串列埠中斷服務、波特率設定、串列埠初始化、傳送/接收單位元組、傳送字串、傳送單個十進位制整數、傳送單個十六進位制整數、傳送某一長度的字串、接收多位元組函式

    • void UART_IrqService(void)是串列埠中斷服務函式,本實驗中實現串列埠中斷執行子程式,從PC端串列埠除錯助手傳送資料至Z32,Z32再經串列埠傳送PC機

    • void UART_BrpSet(UINT16set)是波特率設定函式,串列埠實驗波特率設定為 115200

    • void UART_Init(void)是串列埠初始化函式,實現配置串列埠時鐘、使能中斷

    • void UART_SendByte(UINT8 dat)是傳送單位元組函式,使用此函式一次傳送一個位元組資料

    • void UART_SendString(UINT8 *str)是傳送字串函式,使用此函式傳送字串資料

    • void uart_Send String(UINT8 buf[],UINT8length)是傳送某一長度的字串函式,實現傳送一定長度的字串資料

    • void UART_Send Num(INT32 num)是傳送單個十進位制整數函式,使用此函式傳送一個十進位制整數

    • void UART_Send Hex(UINT8 dat)是傳送單個十六進位制整數函式,使用此函式傳送一個十六進位制整數

    • UINT8 UART_Get Byte(UINT8 *data)是接收單位元組函式,使用此函式接收單位元組資料

    • void UART_Receive(UINT8 *receive, UINT8 len)是接收多位元組函式,使用此函式接收多個位元組資料

    • 主函式

      • 系統初始化,中斷設定,使能所有中斷

      • 判斷按鍵,返回 boot 條件,確認是否進行程式下載

      • 初始化Uart,使能Uart介面,配置Uart中斷並使能

      • 先發送單個字元“A”,換行,再發送字串“Welcome to Z32HUA!”,換行,傳送數字串“1234567890”,換行,再發送 16位數“0x AA”,換行

      • 進入while迴圈程式,等待串列埠中斷到來並判斷資料是否接收完畢,若中斷到來,轉入執行串列埠中斷服務程式,待接收資料完畢,Z32將資料發回串列埠助手

4-國密演算法

實驗要求
  1. 網上搜集國密演算法標準SM1,SM2,SM3,SM4

  2. 網上找一下相應的程式碼和標準測試程式碼,在Ubuntu中分別用gcc和gcc-arm編譯

  3. 四個演算法的用途?

  4. 《密碼學》課程中分別有哪些對應的演算法?

  5. 提交2,3兩個問題的答案

  6. 提交在Ubuntu中執行國密演算法測試程式的截圖

實驗過程
  • SM1

    • 型別:對稱分組演算法

    • 用途:晶片、智慧IC卡、智慧密碼鑰匙、加密卡、加密機等安全產品,廣泛應用於電子政務、電子商務及國民經濟的各個應用領域(包括國家政務通、警務通等重要領域)。

    • 《密碼學》課程對應演算法:DES,AES

    • 該演算法不公開,所以無法獲得原始碼

  • SM2

    • 型別:橢圓曲線公鑰密碼演算法

    • 用途:金鑰管理,數字簽名,電子商務,PKI,資訊及身份認證等資訊保安應用領域

    • 《密碼學》課程對應演算法:ECC橢圓曲線演算法

    • 執行結果截圖:

  • SM3

    • 型別:雜湊演算法

    • 用途:商用密碼應用中的數字簽名和驗證,訊息認證碼的生成與驗證以及隨機數的生成。

    • 《密碼學》課程對應演算法::SHA系列演算法,MD系列演算法、MAC

    • 執行結果截圖:

  • SM4

    • 型別:對稱分組演算法

    • 用途:無線區域網產品, 用於實現資料的加密/解密運算,以保證資料和資訊的機密性。

    • 密碼學對應演算法:DES,AES

    • 執行結果截圖:

5-SM1
  1. 參考雲班課資源中“資訊安全系統實驗箱指導書.pdf “第一章,1.4” KEIL-MDK 中新增 Z32 SC-000 晶片庫,提交安裝截圖

2.完成SM1加密實驗:
開啟“Z32 開發指南\實驗8-SM1”目錄的工程檔案。編譯工程,產生字尾名為.bin 的可執行程式碼
在 user 組下分別雙擊Main.c和SLE4428.c,就可以看到主函式程式碼和SLE4428程式的原始碼。其中工程檔案目錄的 algorithm 資料夾包含了Z32HUA_ALG.ALG函式庫,其中包含了國密的加解密演算法相關函式庫,SM1加解密函式的呼叫需要這個庫的支援。開啟Main.c,介紹一下主函式,程式碼如下:

   lcd_Hex(User Code[i]) ; 
  while(KEY_Read Value()!='A'); //等待 A 鍵按下
  lcd_wcmd(0x01);//清屏
  lcd_pos(0,0);//定位第一行
  lcd_string("按-A 鍵校驗密碼"); 
  lcd_pos(1,0);//定位第二行
  lcd_string("校驗 0x FF,0x FF"); 
  while(KEY_Read Value()!='A'); //等待 A 鍵按下
  lcd_pos(2,0);//定位第三行
  if(SLE4428_Pass Word(0x FF,0x FF)==1)    
   lcd_string("校驗成功"); 
  else 
   {lcd_string("
校驗失敗
"); return 0;} 

  lcd_pos(3,0);//
定位第四行


  switch(SLE4428_Read Byte(0x03fd))    //
檢視剩餘密碼驗證機會

  { 
   case 0xff: lcd_string("
剩餘機會:
  8 
次
");break; 
   case 0x7f: lcd_string("
剩餘機會:
  7 
次
");break; 
   case 0x3f: lcd_string("
剩餘機會:
  6 
次
");break; 
   case 0x1f: lcd_string("
剩餘機會:
  5 
次
");break; 
   case 0x0f: lcd_string("
剩餘機會:
  4 
次
");break; 
   case 0x07: lcd_string("
剩餘機會:
  3 
次
");break; 
   case 0x03: lcd_string("
剩餘機會:
  2 
次
");break; 
   case 0x01: lcd_string("
剩餘機會:
  1 
次
");break; 
   case 0x00: lcd_string("
剩餘機會:
  0 
次
");break; 
   default: break; 
  } UINT8 
jiamiqian[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x
0B,0x0C,0x0D,0x0E,0x0F}; 
UINT8 
jiamimiyue[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,
0x0B,0x0C,0x0D,0x0E,0x0F}; 
UINT8 jiamihou[16]; 

UINT8 jiemiqian[16],jiemimiyue[16],jiemihou[16]; 
UINT8 
cuowumiyue[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00};  


  while(KEY_Read Value()!='A'); //
等待 
A 
鍵按下

B:  lcd_wcmd(0x01);//
清屏

  lcd_pos(0,0);//
定位第一行

  lcd_string("
加密解密實驗
"); 
  lcd_pos(1,0);//
定位第二行

  lcd_string("1.
加密
"); 
  lcd_pos(2,0);//
定位第三行

  lcd_string("2.
解密
"); 

  do 
  { 
   C=KEY_Read Value(); 
  } 
  while(C!='1'&&C!='2'); //
等待 
1 
或 
2 
鍵按下

  lcd_wcmd(0x01);//
清屏

  if(C=='1')  goto jiami; 
  else if(C=='2')  goto jiemi; 
  else ; 


jiami: 
  lcd_pos(0,0);//
定位第一行

  lcd_string("
觀看串列埠除錯助手
"); 
  lcd_pos(1,0);//
定位第二行

  lcd_string("A  
鍵確認加密
"); 
  UART_Send String("
將加密以下資料
:\r\n"); 
  for(UINT8 i=0;i<16;i++) 
  { 
   UART_Send Hex(jiamiqian[i]); 
  } 
  UART_Send String("\r\n"); 
  UART_Send String("
加密金鑰
:\r\n"); 
  for(UINT8 i=0;i<16;i++)  

   if(GPIO_Get Val(6)==0) break; 

   lcd_pos(1,0);//
定位第二行

   lcd_string("
請插入 
IC 
卡
.. "); 
   delay(1000); 
   if(GPIO_Get Val(6)==0) break; 

   lcd_pos(1,0);//
定位第二行

   lcd_string("
請插入 
IC 
卡
..."); 
   delay(1000); 
   if(GPIO_Get Val(6)==0) break; 

  } 

  if(SLE4428_Init And RST(2)!=0x FFFFFFFF)   //
收到 
ATR 
  { 
   lcd_pos(1,0);//
定位第二行

   lcd_string("
已插入 
SLE4428"); 
  } 
  else 
  { 
   lcd_pos(1,0);//
定位第二行

   lcd_string("
卡不正確
      "); 
   SLE4428_Deactivation(); //
下電,去啟用

   delay(1000); 
   goto A;  
  } 

  lcd_pos(2,0);//
定位第三行

  lcd_string("
使用者程式碼為:
"); 

  SLE4428_Read Data(0x15,User Code,6); //
讀取使用者程式碼

  lcd_pos(3,0);//
定位第四行

  for(UINT8 i=0;i<6;i++)  


UINT8 User Code[5]; 
UINT8 C; 


int main(void) 
{ 

/*********************
此段程式碼勿動
***********************/ 
  //
系統中斷向量設定,使能所有中斷

  System Init (); 
     //  
返回 
boot 
條件

  if(0 == GPIO_Get Val(0)) 
  { 
   Bt Api Back(0x55555555, 0x AAAAAAAA); 
  } 
/*********************
此段程式碼勿動
***********************/  

  /*
初始化 
IC 
卡插入檢測 
IO 
口 
GPIO6*/ 
  GPIO_Config(6);   
  GPIO_Pu Pd Sel(6,0);  //
上拉

  GPIO_In Out Set(6,1); //
輸入


  UART_Init(); 
  lcd_init(); 
  KEY_Init(); 
  lcd_pos(0,0);//
定位第一行

  lcd_string("SLE4428  
實驗!
"); 

A:  while(1) 
  { 
   lcd_pos(1,0);//
定位第二行

   lcd_string("
請插入 
IC 
卡
.   "); 
   delay(1000);  

   jiemimiyue[i] = cuowumiyue[i]; 
  } 
  else ; 

  UART_Send String("
將使用以下金鑰進行解密:
\r\n"); 
  for(UINT8 i=0;i<16;i++) 
  { 
   UART_Send Hex(jiemimiyue[i]); 
  } 
  UART_Send String("\r\n"); 
  lcd_pos(0,0);//
定位第一行

  lcd_string("A  
鍵確認解密
"); 
  while(KEY_Read Value()!='A'); //
等待 
A 
鍵按下

  SM1_Init(jiemimiyue);    //SM1 
初始化

  SM1_Crypto(jiemiqian, 16, 1, 0, 0,jiemihou); //
進行解密

  SM1_Close(); //
關閉安全模組

  lcd_pos(1,0);//
定位第二行

  lcd_string("
解密完成
"); 
  lcd_pos(2,0);//
定位第三行

  lcd_string("A  
鍵返回
"); 
  UART_Send String("
解密後的資料為:
\r\n"); 
  for(UINT8 i=0;i<16;i++) 
  { 
   UART_Send Hex(jiemihou[i]); 
  } 
  UART_Send String("\r\n"); 
  UART_Send String("\r\n"); 
  while(KEY_Read Value()!='A'); //
等待 
A 
鍵按下


  goto B; 


  SLE4428_Deactivation(); //
下電,去啟用
,
實驗結束



  { 
   UART_Send Hex(jiamimiyue[i]); 
  } 
  UART_Send String("\r\n"); 
  while(KEY_Read Value()!='A'); //
等待 
A 
鍵按下


  SM1_Init(jiamimiyue);    //SM1 
初始化

  SM1_Crypto(jiamiqian, 16, 0, 0, 0,jiamihou); //
進行加密

  SM1_Close(); //
關閉安全模組

  UART_Send String("
加密後的資料
:\r\n"); 
  for(UINT8 i=0;i<16;i++) 
  { 
   UART_Send Hex(jiamihou[i]); 
  } 
  UART_Send String("\r\n"); 
  lcd_pos(2,0);//
定位第三行

  lcd_string("
加密完成
"); 
  lcd_pos(3,0);//
定位第四行

  lcd_string("A  
鍵存入 
IC 
卡
"); 
  while(KEY_Read Value()!='A'); //
等待 
A 
鍵按下

  for(UINT8 i=0;i<16;i++) 
  { 
   SLE4428_Write_Byte(0x20+i,jiamihou[i]); //
設定 
IC 
卡
  0x20 
地址為儲存
加密資料的地址

  } 
  UART_Send String("
已將資料寫入 
IC 
卡。
\r\n"); 
  UART_Send String("\r\n"); 
  goto B; 


jiemi: 
  lcd_pos(0,0);//定位第一行
  lcd_string("觀看串列埠除錯助手"); 
  lcd_pos(1,0);//定位第二行
   while(1) 
  { 
  } 
} 
//延時函式,當系統時鐘為內部 OSC 時鐘時,延時 1ms 
void delay(int ms) 
{ 
  int i; 
  while(ms--) 
  { 
  for(i=0;i<950;i++) ; 
  } 
} 
  lcd_string(" A 鍵讀取 IC 卡資料"); 
  while(KEY_Read Value()!='A'); //等待 A 鍵按下
  SLE4428_Read Data(0x20,jiemiqian,16); 
  UART_Send String("讀取的資料為:\r\n"); 
  for(UINT8 i=0;i<16;i++) 
  { 
   UART_Send Hex(jiemiqian[i]); 
  } 
  UART_Send String("\r\n"); 
  lcd_wcmd(0x01);//清屏
  lcd_pos(0,0);//定位第一行
  lcd_string("讀取成功"); 
  lcd_pos(1,0);//定位第二行
  lcd_string("選擇金鑰解密:"); 
  lcd_pos(2,0);//定位第三行
  lcd_string("1.正確金鑰"); 
  lcd_pos(3,0);//定位第四行
  lcd_string("2.錯誤金鑰"); 
  do 
  { 
   C=KEY_Read Value(); 
  } 
  while(C!='1'&&C!='2'); //等待 1 或 2 鍵按下
  lcd_wcmd(0x01);//清屏
  if(C=='1')  
  { 
  for(UINT8 i=0;i<16;i++) 
   jiemimiyue[i] = jiamimiyue[i];  
  } 
  else if(C=='2') 
  { 
  for(UINT8 i=0;i<16;i++) 
  1. 將實驗箱接入電源,用USB公對公線將實驗箱的USB介面連線到電腦的USB介面上,在電腦上找到“Z32 開發指南\2.軟體資料\Z32 下載除錯工具”目錄開啟 Z32 下載除錯工具 NZDownloadTool.exe。開啟Z32的電源開關前,按住Reboot 按鍵不放,兩次開啟電源開關,Z32 即可被電腦識別,進行下載除錯
  2. 實驗截圖
6-清理
  1. 提交收拾後的照片
  2. 提交蓋好後蓋的照片

實驗中的問題及解決方法

  1. gcc編譯時提示錯誤:openssl/*.h:沒有那個檔案或目錄
    sudo gcc *.c -o sm2test -lssl -lcrypto加上庫。
    再次使用該命令發現依然出現相同情況,搜尋發現原因是ubuntu下缺少了部分元件,輸入命令sudo apt-get install libssl-dev
  2. arm-gcc編譯時報錯
    專案依賴:libcyptolibssl,但是這都是用基於linux編譯的,不能再arm-gcc上用,所以需要重新編譯

    參考資料

    fatal error: openssl/evp.h:沒有那個檔案或目錄
    openssl動態庫生成以及交叉編譯
    SM2,SM3,SM4學習