zoukankan      html  css  js  c++  java
  • 2019-2020-1 20175307 20175308 20175319 实验二 固件程序设计

    2019-2020-1 20175307 20175308 20175319 实验二 固件程序设计

    小组成员

    20175307高士淳
    20175308杨元
    20175319江野

    实验步骤

    1.MDK

    • 实验要求
      0.注意不经老师允许不准烧写自己修改的代码
      1.三人一组
      2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.1-1.5安装MDK,JLink驱动,注意,要用系统管理员身分运行uVision4,破解MDK(破解程序中target一定选ARM)
      3.提交破解程序中产生LIC的截图
      4.提交破解成功的截图

    • 实验步骤

      • 下载并运行安装程序,安装MDK
      • MDK安装结束页面,点击安装ULINK驱动
      • Ulink安装结束后自动退出,安装结束
      • 运行uVision4,点击文件>>许可证管理,复制CID
      • 运行keil-MDK注册机,粘贴CID并选择ARM,点击generate生成 LIC
      • 将生成的LIC复制到keil4中的LIC输入框中,点击Add LIC,破解完成。

    2.LED

    • 实验要求
      0.注意不经老师允许不准烧写自己修改的代码
      1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
      2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.9”完成LED实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图
      3.实验报告中分析代码

    • 实验步骤

      • 下载安装Z32 SC-000文件,安装路径与MDK安装目录相同
      • 打开MDK,新建工程,芯片库选择框选择库Generic SC000 Device Database,CPU 型号选择SC000
      • 在MDK打开LED闪烁工程文件并编译,产生可执行代码*.bin
      • 将实验箱与电脑相连,打开Z32下载调试工具NZDownloadTool,按住 Reboot 按键不放,两次打开电源开关,Z32被电脑识别
      • NZDownloadTool显示设备已连接后,选择程序路径到*.bin,点击下载
      • 提示框显示程序下载成功!,则程序下载进实验板中
    • 程序分析
      主函数执行过程

      • 系统初始化,中断设置使能所有;
      • 判断按键,返回 boot 条件,确认是否进行程序下载;
      • 设置 GPIO0 状态为上拉输出;
      • 进入循环程序, LED 灯间隔 100ms 闪烁。
        主函数代码
    //系统中断向量设置,使能所有中断
    SystemInit ();
    // 判断按键,返回 boot 条件,确认是否进行程序下载;
    if(0 == GPIO_GetVal(0))
    {
    BtApiBack(0x55555555, 0xAAAAAAAA);
    }
    GPIO_PuPdSel(0,0); //设置 GPIO0 为上拉
    GPIO_InOutSet(0,0); //设置 GPIO0 为输出
    while(1)//进入循环程序, LED 灯间隔 100ms 闪烁。
    {
    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++) ;
    }
    }
    
    • 实验结果截图

    3.UART

    • 实验要求
      0.注意不经老师允许不准烧写自己修改的代码
      1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
      2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.0”完成UART发送与中断接收实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图
      3.实验报告中分析代码

    • 实验步骤

      • 打开工程文件,编译工程,产生可执行代码*.bin
      • 将实验箱与电脑相连,按住Reboot 按键不放,两次打开电源开关,下载调试
      • 打开串口助手,选择对应的串口号,设置波特率为115200偶校验(Even),选中发送新行,然后打开串口。
      • 关闭Z32电源开关,再打开,程序自动运行,在串口调试助手看到:A Welcome to Z32HUA! 1234567890 0xAA,证明PC机串口已经接收到Z32串口发送来的信息。
      • 在串口调试助手的字符串输入框输入字符串,点击发送按钮,看到串口调试助手接收到我们发送输入的字符串
    • 程序分析

      • 主函数代码如下:
    UINT8 shuju_lens;
    UINT8 shuju[64];
    UINT8 uart_rx_num;
    UINT8 uart_rx_end;
    int main(void)
    {
    //系统中断向量设置,使能所有中断
    SystemInit ();
    // 返回 boot 条件
    if(0 == GPIO_GetVal(0))
    {
    BtApiBack(0x55555555, 0xAAAAAAAA);
    }
    UART_Init(); //初始化 Uart
    UART_SendByte('A'); //Uart 发送一个字符 A
    UART_SendByte('
    ');UART_SendByte('
    ');//换行
    UART_SendString("Welcome to Z32HUA!"); //Uart 发送字符串
    UART_SendByte('
    ');UART_SendByte('
    ');//换行
    UART_SendNum(1234567890); //Uart 发送一个十进制数
    UART_SendByte('
    ');UART_SendByte('
    ');//换行
    UART_SendHex(0xAA); //Uart 发送一个十六进制数
    UART_SendByte('
    ');UART_SendByte('
    ');//换行
    while(1)
    {
    if(uart_rx_end)
    {
    uart_rx_end=0;
    uart_SendString(shuju,shuju_lens);
    }
    } //等待接收中断。
    }
    //延时函数,当系统时钟为内部 OSC 时钟时,延时 1ms
    void delay(int ms)
    {
    int i;
    while(ms--)
    {
    for(i=0;i<950;i++) ;
    }
    }
    
    • 主函数执行过程
      1. 系统初始化,中断设置,使能所有中断;
      2. 判断按键,返回 boot 条件,确认是否进行程序下载;
      3. 初始化 Uart,使能 Uart 接口,配置 Uart 中断并使能;
      4. 先发送单个字符“A”,换行,再发送字符串“Welcome to Z32HUA!”,换行,发送数字串“1234567890”,换行,再发送 16 位数“0xAA”,换行。
      5. 进入 while 循环程序,等待串口中断到来并判断数据是否接收完毕,若中断到来,转入执行串口中断服务程序,待接收数据完毕,Z32 将数据发回串口助手。
    • Uart函数代码
         extern UINT8 shuju[64];
         extern UINT8 shuju_lens;
         extern UINT8 uart_rx_num;
         extern UINT8 uart_rx_end;
         void UART_IrqService(void)
         {
         //*****your code*****/
         UARTCR &= ~TRS_EN;
         {
         do
         {
         shuju[uart_rx_num] = UARTDR;
         if(shuju[uart_rx_num]=='
    '||shuju[uart_rx_num]=='
    ')
         {
         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_BrpSet(UINT16 set)
         {
         UINT16 brp=0;
         UINT8 fd=0;
         if(0 == set)
         {
         //uartband@115200bps
         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) & 0xFF);
         UARTBRPL = (UINT8)((brp) & 0xFF);
         }
         /**
         * @函数:初始化
         * @返回: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_BrpSet(0); //设置波特率为默认 115200
         UARTISR = 0xFF; //状态寄存器全部清除
         UARTCR |= FLUSH; //清除接收 fifo
         UARTCR = 0; //偶校验
         /******配置中断使能******/
         UARTIER |= FIFO_NE;
         // UARTIER |= FIFO_HF;
         // UARTIER |= FIFO_FU;
         // UARTIER |= FIFO_OV;
         // UARTIER |= TXEND;
         // UARTIER |= TRE;
         ModuleIrqRegister(Uart_Exception, UART_IrqService); //挂载中断号
         }
         /**
         * @函数:Uart 发送一个字节
         * @dat: 要发送的数据字节
         * @返回:None
         */
         void UART_SendByte(UINT8 dat)
         {
         UARTCR |= TRS_EN;
         UARTDR = dat;
         do
         {
         if(UARTISR & TXEND)
         {
         UARTISR |= TXEND;//清除发送完成标志,写 1 清除
         break;
         }
         }
         while (1);
         UARTCR &= (~TRS_EN);
         }
         /**
         * @函数:Uart 发送一个字符串
         * @str: 要发送的字符串
         * @返回:None
         */
         void UART_SendString(UINT8 * str)
         {
         UINT8 *p ;
         p=str;
         while(*p!=0)
         {
         UART_SendByte(*p++);
         }
         }
         /**
         * @函数:Uart 发送某一长度的字符串
         * @buf: 要发送的字符串
         * @length: 要发送的长度
         * @返回:None
         */
         void uart_SendString(UINT8 buf[],UINT8 length)
         {
         UINT8 i=0;
         while(length>i)
         {
         UART_SendByte(buf[i]);
         i=i+1;
         }
         }
         /**
         * @函数:Uart 发送一个十进制整数
         * @num: 要发送的整数
         * @返回:None
         */
         void UART_SendNum(INT32 num)
         {
         INT32 cnt = num,k;
         UINT8 i,j;
         if(num<0) {UART_SendByte('-');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_SendByte(0x30+cnt);
         k /= 10;
         }
         }
         /**
         * @函数:Uart 发送一个 16 进制整数
         * @dat: 要发送的 16 进制数
         * @返回:None
         */
         void UART_SendHex(UINT8 dat)
         {
         UINT8 ge,shi;
         UART_SendByte('0');
         UART_SendByte('x');
         ge = dat%16;
         shi = dat/16;
         if(ge>9) ge+=7; //转换成大写字母
         if(shi>9) shi+=7;
         UART_SendByte(0x30+shi);
         UART_SendByte(0x30+ge);
         UART_SendByte(' ');
         }
         /**
         * @函数:Uart 接收一个字节
         * @param receive addsress
         * @返回: flag
         */
         UINT8 UART_GetByte(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--;
         }
         }
         }
    
    • Uart函数分析
      • void UART_IrqService(void)是串口中断服务函数,本实验中实现串口中断执行子程序,从 PC 端串口调试助手发送数据至 Z32,Z32 再经串口发送给 PC 机;
      • void UART_BrpSet(UINT16 set)是波特率设置函数,串口实验波特率设置为 115200;
      • void UART_Init(void)是串口初始化函数,实现配置串口时钟、使能中断;
      • void UART_SendByte(UINT8 dat)是发送单字节函数,使用此函数一次发送一个字节数据;
      • void UART_SendString(UINT8 * str)是发送字符串函数,使用此函数发送字符串数据;
      • void uart_SendString(UINT8 buf[],UINT8 length)是发送某一长度的字符串函数,实现发送一定长度的字符串数据。
      • void UART_SendNum(INT32 num)是发送单个十进制整数函数,使用此函数发送一个十进制整数;
      • void UART_SendHex(UINT8 dat)是发送单个十六进制整数函数,使用此函数发送一个十六进制整数;
      • UINT8 UART_GetByte(UINT8 *data)是接收单字节函数,使用此函数接收单字节数据;
      • void UART_Receive(UINT8 *receive, UINT8 len) 是接收多字节函数,使用此函数接收多个字节数据;

    4.国密算法

    • 实验要求
      0.网上搜集国密算法标准SM1,SM2,SM3,SM4
      1.网上找一下相应的代码和标准测试代码,在Ubuntu中分别用gcc和gcc-arm编译
      2.四个算法的用途?
      3.《密码学》课程中分别有哪些对应的算法?
      4.提交2,3两个问题的答案
      5.提交在Ubuntu中运行国密算法测试程序的截图

    • SM1

      • 类型:对称分组算法
      • 用途:芯片、智能IC卡、智能密码钥匙、加密卡、加密机等安全产品,广泛应用于电子政务、电子商务及国民经济的各个应用领域(包括国家政务通、警务通等重要领域)。
      • 《密码学》课程对应算法:DES,AES
      • 该算法不公开,所以无法获得源
    • SM2

      • 类型:椭圆曲线公钥密码算法
      • 用途:密钥管理,数字签名,电子商务,PKI,信息及身份认证等信息安全应用领域
      • 《密码学》课程对应算法:ECC椭圆曲线算法
    • SM3

      • 类型:杂凑算法
        用途:商用密码应用中的数字签名和验证,消息认证码的生成与验证以及随机数的生成。
        《密码学》课程对应算法::SHA系列算法,MD系列算法、MAC
    • SM4

      • 类型:对称分组算法
      • 用途:无线局域网产品, 用于实现数据的加密/解密运算,以保证数据和信息的机密性。
      • 密码学对应算法:DES,AES
    • 运行结果截图

    5.SM1

    • 实验要求
      0.注意不经老师允许不准烧写自己修改的代码
      1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
      2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.16”完成SM1加密实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图
      3.实验报告中分析代码

    • 实验步骤

      • 打开工程文件,编译工程,产生可执行代码*.bin,将实验箱与电脑相连,按住Reboot 按键不放,两次打开电源开关,下载调试
      • 打开串口助手,选择对应的串口号,设置波特率为115200偶校验(Even),选中发送新行,然后打开串口。
      • 关闭 Z32 电源开关,再打开,程序自动运行,插入 SLE4428 IC 卡
      • 若插入了正确的卡片,显示出用户代码,再按下矩阵键盘的“A”键,屏幕显示提示按-A 键校验密码,再按下矩阵键盘的“A”键
      • 再按下矩阵键盘的“A”键
      • 首先进行加密实验。按“1”键选择加密,此时,串口调试助手显示原始数据和加密密钥

      • 按下“A”键确认加密
      • 串口调试助手显示加密后的数据。再按“A”键,将加密数据存入IC卡,此时串口显示已将数据写入 IC 卡,屏幕回到加密解密实验选择菜单。
      • 下面进行解密实验。按“2”键选择解密
      • 按“A”键后,屏幕显示读取成功 选择密钥解密:1.正确密钥 2.错误密钥,串口显示读取的数据:为:0x7E 0xDC 0xA3 0x7B 0xBA 0x53 0x84 0xAC 0x0B 0x75 0x50 0x45 0x2E 0xEC 0x4F 0x4F
      • 按“1”键选择正确的密钥后,屏幕提示A 键确认解密,此时串口显示将使用以下密钥进行解密:0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x080x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
      • 按“A”键确认解密后,屏幕提示解密完成 A 键返回,此时串口显示解密后的数据为:0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F

      • 按“A”键返回加/解密选择菜单
    • 代码分析

      • 主函数代码
    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};
    UINT8 UserCode[5];
    UINT8 C;
    int main(void)
    {
    /*********************此段代码勿动***********************/
    //系统中断向量设置,使能所有中断
    SystemInit ();
    // 返回 boot 条件
    if(0 == GPIO_GetVal(0))
    {
    BtApiBack(0x55555555, 0xAAAAAAAA);
    }
    /*********************此段代码勿动***********************/
    /*初始化 IC 卡插入检测 IO 口 GPIO6*/
    GPIO_Config(6);
    GPIO_PuPdSel(6,0); //上拉
    GPIO_InOutSet(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);
    if(GPIO_GetVal(6)==0) break;
    lcd_pos(1,0);//定位第二行
    lcd_string("请插入 IC 卡.. ");
    delay(1000);
    if(GPIO_GetVal(6)==0) break;
    lcd_pos(1,0);//定位第二行
    lcd_string("请插入 IC 卡...");
    delay(1000);
    if(GPIO_GetVal(6)==0) break;
    }
    if(SLE4428_InitAndRST(2)!=0xFFFFFFFF) //收到 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_ReadData(0x15,UserCode,6); //读取用户代码
    lcd_pos(3,0);//定位第四行
    for(UINT8 i=0;i<6;i++)
    lcd_Hex(UserCode[i]) ;
    while(KEY_ReadValue()!='A'); //等待 A 键按下
    lcd_wcmd(0x01);//清屏
    lcd_pos(0,0);//定位第一行
    lcd_string("按-A 键校验密码");
    lcd_pos(1,0);//定位第二行
    lcd_string("校验 0xFF,0xFF");
    while(KEY_ReadValue()!='A'); //等待 A 键按下
    lcd_pos(2,0);//定位第三行
    if(SLE4428_PassWord(0xFF,0xFF)==1)
    lcd_string("校验成功");
    else
    {lcd_string("校验失败"); return 0;}
    lcd_pos(3,0);//定位第四行
    switch(SLE4428_ReadByte(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;
    }
    while(KEY_ReadValue()!='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_ReadValue();
    }
    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_SendString("将加密以下数据:
    ");
    for(UINT8 i=0;i<16;i++)
    {
    UART_SendHex(jiamiqian[i]);
    }
    UART_SendString("
    ");
    UART_SendString("加密密钥:
    ");
    for(UINT8 i=0;i<16;i++)
    {
    UART_SendHex(jiamimiyue[i]);
    }
    UART_SendString("
    ");
    while(KEY_ReadValue()!='A'); //等待 A 键按下
    SM1_Init(jiamimiyue); //SM1 初始化
    SM1_Crypto(jiamiqian, 16, 0, 0, 0,jiamihou); //进行加密
    SM1_Close(); //关闭安全模块
    UART_SendString("加密后的数据:
    ");
    for(UINT8 i=0;i<16;i++)
    {
    UART_SendHex(jiamihou[i]);
    }
    UART_SendString("
    ");
    lcd_pos(2,0);//定位第三行
    lcd_string("加密完成");
    lcd_pos(3,0);//定位第四行
    lcd_string("A 键存入 IC 卡");
    while(KEY_ReadValue()!='A'); //等待 A 键按下
    for(UINT8 i=0;i<16;i++)
    {
    SLE4428_Write_Byte(0x20+i,jiamihou[i]); //设置IC卡 0x20地址为存储
    加密数据的地址
    }
    UART_SendString("已将数据写入 IC 卡。
    ");
    UART_SendString("
    ");
    goto B;
    jiemi:
    lcd_pos(0,0);//定位第一行
    lcd_string("观看串口调试助手");
    lcd_pos(1,0);//定位第二行
    lcd_string(" A 键读取 IC 卡数据");
    while(KEY_ReadValue()!='A'); //等待 A 键按下
    SLE4428_ReadData(0x20,jiemiqian,16);
    UART_SendString("读取的数据为:
    ");
    for(UINT8 i=0;i<16;i++)
    {
    UART_SendHex(jiemiqian[i]);
    }
    UART_SendString("
    ");
    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_ReadValue();
    }
    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++)
    jiemimiyue[i] = cuowumiyue[i];
    }
    else ;
    UART_SendString("将使用以下密钥进行解密:
    ");
    for(UINT8 i=0;i<16;i++)
    {
    UART_SendHex(jiemimiyue[i]);
    }
    UART_SendString("
    ");
    lcd_pos(0,0);//定位第一行
    lcd_string("A 键确认解密");
    while(KEY_ReadValue()!='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_SendString("解密后的数据为:
    ");
    for(UINT8 i=0;i<16;i++)
    {
    UART_SendHex(jiemihou[i]);
    }
    UART_SendString("
    ");
    UART_SendString("
    ");
    while(KEY_ReadValue()!='A'); //等待 A 键按下
    goto B;
    SLE4428_Deactivation(); //下电,去激活,实验结束
    while(1)
    {
    }
    }
    //延时函数,当系统时钟为内部 OSC 时钟时,延时 1ms
    void delay(int ms)
    {
    int i;
    while(ms--)
    {
    for(i=0;i<950;i++) ;
    }
    }
    
    • 主函数执行过程
      1. 系统初始化,中断设置,使能所有中断;
      2. 判断按键,返回 boot 条件,确认是否进行程序下载;
      3. 初始化 IC 卡插入检测端口 GPIO6;
      4. 串口初始化;
      5. LCD12864 初始化;
      6. 矩阵键盘初始化;
      7. 液晶屏第一行显示字符串SLE4428 实验!
    • A段程序:
      8) 第二行显示请插入 IC 卡,等待卡片插入;
      9) SLE4428 IC 卡正确插入,第二行显示已插入 SLE4428,卡片插入错误则第二行显示卡不正确
      10) IC 卡正确插入,则显示用户代码为:XXXXXXXXXX(XXXXXXXXXX 代表用户的代码),等待按下键盘的“A”键;
      11) 按下“A”键,显示屏第一行显示按-A 键校验密码,第二行显示校验 0xFF,0xFF,等待“A”键按下。
      12) 按下“A”键,若校验密码正确,显示屏第三行显示校验成功,否则显示校验失败,第四行显示剩余密码验证机会次数剩余机会: X次(X初始最大为8,最小0,当校验密码错误验证一次后,X减1),等待“A”键按下;
    • B段程序:
      13) 按下“A”键,显示屏第一行显示“加密解密试验”,第二、三行分别显
      示“1.加密”、“2.解密”两个选项。等待按键按下:如果“1”按下,
      跳转至加密程序段,如果“2”按下,跳转至解密程序段;
      加密程序段:
      14) 第一行显示“观看串口调试助手”,第二行显示“A 键确认加密”,通过
      串口发送字符串“将加密以下数据:”并将加密前的数据发送至 PC 机,
      发送换行,串口继续发送“加密密钥:”并将加密密钥数组发送至 PC 机,
      发送完毕等待“A”键按下;
      15) 按下“A”键后,SM1 初始化;
      16) 进行 SM1 加密;
      17) 关闭 SM1 加密安全模块;
      18) 通过串口发送字符串加密后的数据:并将加密后的数据发送至 PC 机,换行,在液晶屏第三行显示加密完成,第四行显示A 键存入 IC 卡,等待“A”键按下。当“A”键按下后,向 SLE4428 IC 卡加密后的数据,通过串口向 PC 发送已将数据写入 IC 卡。跳转至 B 段程序。
    • 解密程序段:
      19) 屏幕第一行显示观看串口调试助手,第二行显示A 键读取 IC 卡数据,当“A”键按下,读取 SLE4428 IC 卡解密前数据,通过串口发送读取的数据为:至 PC 机并发送解密前的数据至 PC 机。在显示屏的四行分别显示读取成功选择密钥解密1.正确密钥错误密钥,等待按键“1”或“2”按下。如果“1”按下,解密密钥为正确的密钥,“2”按下,解密密钥为错误的密钥,然后通过串口发送将使用以下密钥进行解密:并将相应的解密密钥数据发送至 PC 机。发送完毕,第一行显示A 键确认解密,等待“A”键按下。
      20) 按下“A”键后,SM1 初始化;
      21) 进行 SM1 解密;
      22) 关闭 SM1 解密安全模块;
      23) 显示屏第二行显示解密完成,第三行显示“A 键返回”,通过串口将解密后的数据为:和解密后的数据发送至 PC 机,发送完毕等待“A”键按下,若“A”键按下,跳转至 B 段程序。
      24) 断电,去除 IC 卡激活,实验结束。

    6.清理

    • 实验要求
      实验结束后,把实验室原来的网线插回,否则以后做实验的同学无法开机
      0.只有用实验室机器的小组做
      1.提交你们小组使用的计算机的编号照片
      2.提交插好网线的照片
      3.提交盖好后盖的照片

    • 实验结果截图

    实验中的问题及解决过程

    • 步骤四中,在Ubuntu中运行sm3,出现错误提示openssl/ssl.h: No such file or directory
      解决方案:出现问题的原因是在Linux平台上缺少和OpenSSL链接的文件(库和头文件),在Linux终端运行sudo apt-get install libssl-dev安装OpenSSL开发包:
  • 相关阅读:
    null in ABAP and nullpointer in Java
    SAP ABAP SM50事务码和Hybris Commerce的线程管理器
    Hybris service layer和SAP CRM WebClient UI架构的横向比较
    SAP ABAP和Linux系统里如何检查网络传输的数据量
    SAP CRM WebClient UI和Hybris的controller是如何被调用的
    SAP CRM和Cloud for Customer订单中的业务伙伴的自动决定机制
    SAP CRM WebClient UI和Hybris CommerceUI tag的渲染逻辑
    SAP BSP和JSP页面里UI元素的ID生成逻辑
    微信jsapi支付
    微信jsapi退款操作
  • 原文地址:https://www.cnblogs.com/killer-queen/p/11874652.html
Copyright © 2011-2022 走看看