【2018-2019-1】20165223-20165218 实验二 固件程序设计


小组成员:20165223 ,20165218

实验名称:固件程序设计


目录


一、实验内容

二、实验总结


一、实验内容


任务一:固件程序设计-1-MDK

(一)实验要求

0.注意不经老师允许不准烧写自己修改的代码
1.三人一组
2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.1-1.5安装MDK,ULink驱动

注意:要用系统管理员身分运行uVision4,破解MDK(破解程序中target一定选ARM)

3.提交破解程序中产生LIC的截图
4.提交破解成功的截图

(二)实验步骤

  • 1.安装MDK4.74

  • 2.安装ULink驱动

  • 3.运行UV4

  • 4.按实验指导步骤用注册机产生LIC

  • 5.按实验指导步骤破解MDK

返回目录


任务二:固件程序设计-2-LED

(一)实验要求

0.注意不经老师允许不准烧写自己修改的代码
1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.9”完成LED实验,提交运行结果截图

注意:打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试

3.实验报告中分析代码

(二)实验步骤

(1)向KEIL-MDK 中添加 Z32 SC-000 芯片库

  • 1.安装SC-000 库

  • 2.建立新工程时使用SC-000

  • 3.确定cpu型号时选SC-000

  • 4.成功搭建Z32工程基础环境截图

  • 打开Part2-Z32-安全/实验1-LED闪烁/Z32HUA.uvproj,编译LED工程,产生bin文件

(2)将程序下载到Z32实验箱上,观察结果

  • 1.用USB下载线连接电脑与实验箱,按住reboot键连开Z32两次开关,连接设备

  • 2.下载代码

  • 3.关掉Z32电源再打开,程序自动运行,观察结果

(3)实验结果

关闭Z32电源开关,再打开,程序自动运行,Z32核心板上L2灯(上方的红灯)持续闪烁,实验成功。

(三)代码分析

(1)实验代码及注释

  • 完整代码:LED.cpp

  • 主要代码:

int main(void)
{
	SystemInit ();
	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
	}
}

(2)细节分析

1.SystemInit ():系统初始化,设置中断向量,使能所有中断;
2.if(0 == GPIO_GetVal(0)):判断按键,返回 boot 条件,进行程序下载;
3.GPIO0:设置其状态为上拉输出;
4.while循环:进入循环程序,delay(100)设置LED 灯间隔 100ms 持续闪烁;
5.delay延时函数:当系统时钟为内部 OSC 时钟时,延时 1ms。

返回目录


任务三:固件程序设计-3-UART

(一)实验要求

0.注意不经老师允许不准烧写自己修改的代码
1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.0”完成UART发送与中断接收实验,提交运行结果截图

注意:打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试

3.实验报告中分析代码

(二)实验步骤

(1)下载程序到Z32并运行

  • 1.同任务二一样先用USB下载线连接设备并下载程序

  • 2.用9针串口线将Z32模块的串口与电脑USB接口连接

  • 3.打开串口调试助手(sscom),设置各个参数,观察串口通信收发的数据

    • 选择Z32对应串口(COM6)
    • 选择波特率为115200
    • 选择校验位为Even
    • 勾选“发送新行”
    • 点击“打开串口”
  • 4.串口调试助手中看到收发信息

(2)实验结果

关闭Z32电源开关,再打开,程序自动运行,可以在串口调试助手看到如下实验现象:显示“A Welcome to Z32HUA! 1234567890 0xAA”,证明PC机串口已经接收到Z32串口发送来的信息。在串口调试助手的字符串输入框输入字符串“abcdefg”,点击发送按钮,可以看到串口调试助手接收到我们发送输入的字符串“abcdefg”,并显示在串口助手上。实验成功。

(三)代码分析

(1)实验代码及注释

  • 完整代码:UART.cpp

  • 主要代码:

int main(void)
{
	SystemInit ();
	if(0 == GPIO_GetVal(0))
	{
		BtApiBack(0x55555555, 0xAAAAAAAA);
	}
	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);
		}
	}        //等待接收中断。
}

(2)细节分析

1.SystemInit ():系统初始化,中断设置,使能所有中断;
2.if(0 == GPIO_GetVal(0)):判断按键,返回boot条件,确认是否进行程序下载;
3.UART_Init():初始化Uart,使能Uart接口,配置Uart中断并使能;
4.PC机串口向Z32串口逐行发送:单个字符“A”,字符串“Welcome to Z32HUA!”,十进制数字串“1234567890”,16进制数“0xAA”;
5.while循环:进入循环程序,等待串口中断到来并判断数据是否接收完毕,若中断到来,转入执行串口中断服务程序,待接收数据完毕,Z32将数据发回串口助手。
6.delay延时函数:当系统时钟为内部 OSC 时钟时,延时 1ms。

返回目录


任务四:固件程序设计-4-国密算法

(一)实验要求

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

(二)实验步骤

  • 1.网上搜集国密算法标准SM1、SM2、SM3、SM4,回答实验要求中T2和T3提问
// T2:四个算法的用途?
答:
       SM1为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
       SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。
       SM3为消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
       SM4为无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。

// T3:《密码学》课程中分别有哪些对应的算法?
答:
       SM1对应AES算法;
       SM2对应ECC算法;
       SM3对应MD5算法;
       SM4对应3DES算法。

  • 2.网上找一下相应的代码和标准测试代码,在Ubuntu中分别用gcc和gcc-arm编译
  • 3.提交在Ubuntu中运行国密算法测试程序的截图

(三)代码分析

实验代码及注释分析(点击链接查看)

(1)SM1未公开,无代码

(2)SM2.cSM2test.c

(3)SM3.cSM3test.c

(4)SM4.cSM4test.c

返回目录


任务五:固件程序设计-5-SM1

(一)实验要求

0.注意不经老师允许不准烧写自己修改的代码
1.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.4” KEIL-MDK 中添加 Z32 SC-000 芯片库,提交安装截图
2.参考云班课资源中“信息安全系统实验箱指导书.pdf “第一章,1.16”完成SM1加密实验,提交运行结果截图

注意:打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试

3.实验报告中分析代码

(二)实验步骤

(1)将程序下载到Z32并运行

  • 1.先用USB下载线连接设备并下载程序

  • 2.用9针串口线将Z32模块的串口与电脑USB接口连接

  • 3.打开串口助手,设置参数

    • 选择Z32对应串口(COM6)
    • 选择波特率为115200
    • 选择校验位为Even
    • 点击“打开串口”
  • 4.关闭电源,再打开,程序自动运行。

(2)实验箱上的操作

  • 1.此时,显示屏显示:“SLE4428实验!请插入IC卡...”

  • 2.插入SLE4428 IC卡,显示屏显示:“已插入SLE4428 用户代码为:D27600000400”

  • 3.按下矩阵键盘的A键,显示屏显示:“按-A键校验密码 校验0xFF,0xFF”

  • 4.按照显示屏提示,按下矩阵键盘的A键,显示屏接着显示:“校验成功 剩余机会:8次”

  • 5.再次按下矩阵键盘的A键,进入加解密实验,显示屏显示:“加密解密实验 1.加密 2.解密”

  • 6.按下矩阵键盘的1键,进行加密,此时显示屏上显示:“看串口调试助手 A键确认加密”,观察串口助手看到加密结果

  • 7.按下矩阵键盘的A键确认加密,显示屏显示:“加密完成 A键存入IC卡”,观察串口助手也显示“已将数据写入IC卡”

  • 8.再按A键屏幕回到步骤5中加解密实验界面

  • 9.额外将解密部分也运行了一下,串口助手的截图如下

(三)代码分析

(1)实验代码及注释

//主函数
int main(void)
{
	SystemInit ();
	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段程序
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段程序
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("将加密以下数据:\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;
//解密程序
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)
	{

	}
}

(2)细节分析

  • 主函数:
1.SystemInit ():系统初始化,中断设置,使能所有中断;
2.if(0 == GPIO_GetVal(0)):判断按键,返回boot条件,确认是否进行程序下载;
3.GPIO_Config(6):初始化IC卡插入检测端口GPIO6;
4.GPIO:将GPIO设为上拉输入;
5.UART_Init()、cd_init()、KEY_Init():串口初始化;LCD12864初始化;矩阵键盘初始化;
6.lcd_pos(x,0):用于定位显示屏上第x+1行(例 lcd_pos(1,0),定位第二行);
7.lcd_string("xxxxxxx"):显示屏上显示的内容。

  • A段程序(A):
//if-else 结构:判断是否收到ATR(矩阵键盘按下A键),是则继续,否则执行else部分

1.第二行显示“请插入IC卡”,等待卡片插入;
2.SLE4428 IC卡正确插入,第二行显示“已插入SLE4428”,卡片插入错误则第二行显示“卡不正确     ”;
3.IC卡正确插入,则显示“用户代码为:XXXXXXXXXX”(XXXXXXXXXX代表用户的代码),等待按下键盘的“A”键;
4.按下“A”键,显示屏第一行显示“按-A键校验密码”,第二行显示“校验0xFF,0xFF”,等待“A”键按下。
5.按下“A”键,若校验密码正确,显示屏第三行显示“校验成功”,否则显示“校验失败”,第四行显示剩余密码验证机会次数“剩余机会: X次”(X初始最大为8,最小0,当校验密码错误验证一次后,X减1),等待“A”键按下。

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

  • 加密程序段(jiami):
1.第一行显示“观看串口调试助手”,第二行显示“A键确认加密”,通过串口发送字符串“将加密以下数据:”并将加密前的数据发送至PC机,发送换行,串口继续发送“加密密钥:”并将加密密钥数组发送至PC机,发送完毕等待“A”键按下;
2.按下“A”键后,SM1初始化;
3.进行SM1加密;
4.关闭SM1加密安全模块;
5.通过串口发送字符串“加密后的数据:”并将加密后的数据发送至PC机,换行,在液晶屏第三行显示“加密完成”,第四行显示“A键存入IC卡”,等待“A”键按下。当“A”键按下后,向SLE4428 IC卡加密后的数据,通过串口向PC发送“已将数据写入IC卡。”跳转至B段程序。

  • 解密程序段(jiemi):
1.屏幕第一行显示“观看串口调试助手”,第二行显示“A键读取IC卡数据”,当“A”键按下,读取SLE4428 IC卡解密前数据,通过串口发送“读取的数据为:”至PC机并发送解密前的数据至PC机。在显示屏的四行分别显示“读取成功”,“选择密钥解密”,“1.正确密钥”,“错误密钥”,等待按键“1”或“2”按下。如果“1”按下,解密密钥为正确的密钥,“2”按下,解密密钥为错误的密钥,然后通过串口发送“将使用以下密钥进行解密:”并将相应的解密密钥数据发送至PC机。发送完毕,第一行显示“A键确认解密”,等待“A”键按下。
2.按下“A”键后,SM1初始化;
3.进行SM1解密;
4.关闭SM1解密安全模块;
5.显示屏第二行显示“解密完成”,第三行显示“A键返回”,通过串口将“解密后的数据为:”和解密后的数据发送至PC机,发送完毕等待“A”键按下,若“A”键按下,跳转至B段程序。
6.断电,去除IC卡激活,实验结束。

返回目录


二、实验总结


(一)遇到的问题

(1)任务一,在破解MDK时遇到如下问题:

  • 直接打开uVision4后,点File>>License Management,报错如下

  • 点击确定后却仍能进入到License Management中,于是按照实验指导步骤复制CID,再运行keil-MDK注册机,粘贴CID并选择ARM,点击generate生成LIC

  • 将生成的LIC复制回License Management下方的LIC空格中,点击Add LIC,报错如下

解决方法:

  • 上网搜索后发现原因是没有以管理员的身份打开uVision4,重新用管理员身份打开UV4后一路无报错,最终成功完成破解

(2)任务四,在编译运行SM2test.c测试代码时遇到如下报错:

解决方法:

  • 再次编译运行即可

(二)分析与总结

  • 经过上一次实验,我和队友已经对Z32实验箱有了基本的认识,因此本次实验在环境设置方面没有遇到什么障碍。
  • 在将代码从本机下载到实验箱的过程中有遇到难题,即用USB连接好后,无论如何都无法连接上设备,后来发现在按住reboot键后打开关闭开关一次的时候已经连接上了,可能是实验箱的原因(?)
  • 实验时在任务四中耗时最长,除了在网上搜索代码花了很长时间以外,测试代码的运行也让人头痛了很久,最终还是成功编译运行了这几个算法。
  • 实验时间虽短,但前期的准备工作是必不可少的,实验之前我和队友就已经将各个任务都捋了一遍,以便真正在实验室中能顺利完成实验,最终也还完成的较成功,这与两个人的努力是分不开的。希望下次实验也能顺利完成。

(三)参考资料

  1. STM32使用MDK5时遇到TOOLS.INI: TOOLCHAIN NOT INSTALLED 及破解方法
  2. 关于国密算法 SM1,SM2,SM3,SM4 的笔记
  3. 信息安全实验箱指导书

返回目录

posted @ 2018-10-31 13:28  乐十六君  阅读(497)  评论(0编辑  收藏  举报