2017-2018-1 20155304 20155332 实验二 固件程序设计

2017-2018-1 20155304 20155332 实验二 固件程序设计

实验目的

  1. 学习 GPIO 原理
  2. 掌握 Z32 安全模块驱动 LED 的工作原理
  3. 学习串口通信原理
  4. 掌握 SP3232 芯片的使用方法
  5. 掌握 Z32 的串行口工作原理
  6. 学习 SM1 加解密算法原理,掌握 SM1 加、解密算法用法

实验步骤

  • 任务1-MDK

1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.1-1.5安装MDK,JLink驱动,注意,要用系统管理员身分运行uVision4,破解MDK(破解程序中target一定选ARM)

2. 提交破解程序中产生LIC的截图

image

3. 提交破解成功的截图

image

  • 任务2-LED

1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图

image

2. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.9”完成LED实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图

3. 实验报告中分析代码

int main(void)
{
/*********************此段代码勿动***********************/
//系统中断向量设置,使能所有中断
SystemInit ();
 // 返回 boot 条件
if(0 == GPIO_GetVal(0))
{
BtApiBack(0x55555555, 0xAAAAAAAA);
}
/*********************此段代码勿动***********************/
GPIO_PuPdSel(0,0); //设置 GPIO0 为上拉
GPIO_InOutSet(0,0); //设置 GPIO0 为输出
- 66 -
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++) ;
}
}

主函数代码的执行过程为:

  1. 系统初始化,中断设置,使能所有中断;
  2. 判断按键,返回 boot 条件,确认是否进行程序下载;
  3. 设置 GPIO0 状态为上拉输出;
  4. 进入循环程序,LED 灯间隔 100ms 闪烁;
  • 任务3-UART

1. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图

2. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.10”完成UART发送与中断接收实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图

3. 实验报告中分析代码

  1. void UART_IrqService(void)是串口中断服务函数,本实验中实现串口中
    断执行子程序,从 PC 端串口调试助手发送数据至 Z32,Z32 再经串口
    发送给 PC 机;
  2. void UART_BrpSet(UINT16 set)是波特率设置函数,串口实验波特率设置
    为 115200;
  3. void UART_Init(void)是串口初始化函数,实现配置串口时钟、使能中断;
  4. void UART_SendByte(UINT8 dat)是发送单字节函数,使用此函数一次发
    送一个字节数据;
  5. void UART_SendString(UINT8 * str)是发送字符串函数,使用此函数发送
    字符串数据;
  6. void uart_SendString(UINT8 buf[],UINT8 length)是发送某一长度的字符
    串函数,实现发送一定长度的字符串数据。
  7. void UART_SendNum(INT32 num)是发送单个十进制整数函数,使用此
    函数发送一个十进制整数;
  8. void UART_SendHex(UINT8 dat)是发送单个十六进制整数函数,使用此
    函数发送一个十六进制整数;
  9. UINT8 UART_GetByte(UINT8 *data)是接收单字节函数,使用此函数接
    收单字节数据;
  10. void UART_Receive(UINT8 *receive, UINT8 len) 是接收多字节函数,使
    用此函数接收多个字节数据;

主函数如下:

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);
}
- 84 -
/*********************此段代码勿动***********************/
UART_Init(); //初始化 Uart
UART_SendByte('A'); //Uart 发送一个字符 A
UART_SendByte('\r');UART_SendByte('\n');//换行
UART_SendString("Welcome to Z32HUA!"); //Uart 发送字符串
UART_SendByte('\r');UART_SendByte('\n');//换行
UART_SendNum(1234567890); //Uart 发送一个十进制数
UART_SendByte('\r');UART_SendByte('\n');//换行
UART_SendHex(0xAA); //Uart 发送一个十六进制数
UART_SendByte('\r');UART_SendByte('\n');//换行
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 将数据
    发回串口助手。
  • 任务4-国密算法

SM4 AES国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。

SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。

SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。

SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。

SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位

SM1 AES
SM2 RSA
SM3 MD5
SM4 AES

  • 任务5-SM1

1. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图

2. 参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.16”完成SM1加密实验,注意“打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。提交运行结果截图

3. 实验报告中分析代码

主函数:

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 实验!");

主函数代码的执行过程为:

  1. 系统初始化,中断设置,使能所有中断;
  2. 判断按键,返回 boot 条件,确认是否进行程序下载;
  3. 初始化 IC 卡插入检测端口 GPIO6;
  4. 串口初始化;
  5. LCD12864 初始化;
  6. 矩阵键盘初始化;
  7. 液晶屏第一行显示字符串“SLE4428 实验!”。

A段:

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 键按下

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段:

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 ;

B 段程序:
13) 按下“A”键,显示屏第一行显示“加密解密试验”,第二、三行分别显
示“1.加密”、“2.解密”两个选项。等待按键按下:如果“1”按下,
跳转至加密程序段,如果“2”按下,跳转至解密程序段;

加密:

jiami:
lcd_pos(0,0);//定位第一行
lcd_string("观看串口调试助手");
lcd_pos(1,0);//定位第二行
lcd_string("A 键确认加密");
UART_SendString("将加密以下数据:\r\n");
for(UINT8 i=0;i<16;i++)
{
UART_SendHex(jiamiqian[i]);
}
UART_SendString("\r\n");
UART_SendString("加密密钥:\r\n");
for(UINT8 i=0;i<16;i++)
{
UART_SendHex(jiamimiyue[i]);
}
UART_SendString("\r\n");
while(KEY_ReadValue()!='A'); //等待 A 键按下
SM1_Init(jiamimiyue); //SM1 初始化
SM1_Crypto(jiamiqian, 16, 0, 0, 0,jiamihou); //进行加密
SM1_Close(); //关闭安全模块
UART_SendString("加密后的数据:\r\n");
for(UINT8 i=0;i<16;i++)
{
UART_SendHex(jiamihou[i]);
}
UART_SendString("\r\n");
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 卡。\r\n");
UART_SendString("\r\n");
goto B;

加密程序段:
14) 第一行显示“观看串口调试助手”,第二行显示“A 键确认加密”,通过
串口发送字符串“将加密以下数据:”并将加密前的数据发送至 PC 机,
发送换行,串口继续发送“加密密钥:”并将加密密钥数组发送至 PC 机,
发送完毕等待“A”键按下;
15) 按下“A”键后,SM1 初始化;
16) 进行 SM1 加密;
17) 关闭 SM1 加密安全模块;
18) 通过串口发送字符串“加密后的数据:”并将加密后的数据发送至 PC 机,
换行,在液晶屏第三行显示“加密完成”,第四行显示“A 键存入 IC 卡”,
等待“A”键按下。当“A”键按下后,向 SLE4428 IC 卡加密后的数据,
通过串口向 PC 发送“已将数据写入 IC 卡。”跳转至 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("读取的数据为:\r\n");
for(UINT8 i=0;i<16;i++)
{
UART_SendHex(jiemiqian[i]);
}
UART_SendString("\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_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("将使用以下密钥进行解密:\r\n");
for(UINT8 i=0;i<16;i++)
{
UART_SendHex(jiemimiyue[i]);
}
UART_SendString("\r\n");
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("解密后的数据为:\r\n");
for(UINT8 i=0;i<16;i++)
{
UART_SendHex(jiemihou[i]);
}
UART_SendString("\r\n");
UART_SendString("\r\n");
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++) ;
}
}

解密程序段:
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 卡激活,实验结束。

实验中的问题及解决过程

1.传输链接不成功,因为少插了一根线……

2.链接不成功,因为在操作时没有按reboot键重启两次。

主要都是一些操作问题,没有遇到什么实质性问题。

新学到的知识点

  1. 学习了 GPIO 原理
  2. 掌握了 Z32 安全模块驱动 LED 的工作原理
  3. 学习了串口通信原理
  4. 掌握了 SP3232 芯片的使用方法
  5. 掌握了 Z32 的串行口工作原理
  6. 学习了 SM1 加解密算法原理,掌握 SM1 加、解密算法用法
posted @ 2017-11-01 09:19  田宜楠20155304  阅读(337)  评论(1编辑  收藏  举报