?? esam_function.c
字號:
/****************************************************************/
/* 文件名: Esam_Function.c */
/* 功能: 定義ESAM卡的操作函數 */
/* 設計者: 陳湘和 */
/* 設計日期: 10/20/2004 */
/*--------------------------------------------------------------*/
/* 說明: */
/* 該文件設計了通過DSP的UART操作ESAM卡進行數據保護 */
/* 的所有相關指令,這些指令是基于T=0協議設計的,如果 */
/* 用戶的ESAM芯片基于T=1協議,請在使用這些函數前用 */
/* 讀寫器或者在通過認證后用Set_Protocol指令將ESAM */
/* 芯片的協議改為T=0. */
/****************************************************************/
#include <stdio.h>
#include <csl.h>
#include "Uart_Function.h"
#include "DEC5502_DES.h"
#include "DEC5502_MAC.h"
/* 定義兩個宏來訪問系統控制寄存器 */
#define SYSCNTL1 (*(volatile int *)(0x280000))
#define SYSCNTL2 (*(volatile int *)(0x280001))
#define DES8 0
#define DES16 1
#define RSTTIME 0xAD6B // RST信號低電平時間長度取500個時鐘周期
#define MAXDATA 0xA7 // 一次最多能夠讀寫167個數據
#define DATALENGTH MAXDATA+7 // 接收命令緩沖區最大長度 =
// MAXDATA+1字節數據位+4字節MAC碼+2字節狀態位
Uint16 CommandLength; // 定義命令報文的實際長度變量
Uint16 Command[DATALENGTH]; // 定義存放命令報文的緩沖區,為了初始化方便
// 長度設為與接收緩沖區長度一致
Uint16 ReplyData[DATALENGTH]; // 定義接收信號緩沖區
extern Uint16 Get_Random(Uint16 *OutputPtr, Uint16 Length);
/****************************************************************/
/* 函數名: Reset_Esam() */
/* 功能: 對ESAM卡復位,并取得返回的復位應答信息 */
/* 參數: */
/* DataPtr----指向存放序列號的數組的指針 */
/* 返回值: */
/* 返回unsigned short int型的16bits整數 */
/* 如果正確,返回值等于9000 */
/****************************************************************/
extern Uint16 Reset_Esam(Uint16 *DataPtr)
{
Uint16 i,FeedValue;
/* 初始化接收ESAM卡應答信號的數據結構 */
for(i=0; i<DATALENGTH; i++)
{
ReplyData[i] = 0;
}
/* RST信號變為低電平 */
SYSCNTL2 = 0x00;
Delay_Time(200);
/* 將ESAM卡的I/O端設為輸出,準備從ESAM卡接收復位應答信號 */
SYSCNTL1 = 0x20;
Delay_Time(200);
/* 讓復位信號等待一段時間,滿足復位時序要求 */
Delay_Time(RSTTIME);
/* 讓ESAM脫離復位狀態,從而實現ESAM復位 */
SYSCNTL2 = 0x08;
/* 讀復位應答信號 */
Read_Esam(ReplyData,13);
/* 從復位應答信號中分離出序列號 */
for(i=0; i<8; i++)
{
*DataPtr++ = ReplyData[i+5];
}
/* 獲取狀態字 */
FeedValue = 0x9000;
return FeedValue;
}
/****************************************************************/
/* 函數名: Get_Response() */
/* 功能: 取回ESAM反饋的數據和MAC碼 */
/* 參數: */
/* DataPtr-----指向存放返回數據指針數組的指針 */
/* DataLen-----欲取回的數據和MAC碼總長度(以16進制 */
/* 表示,單字節長度) */
/* 返回值: */
/* 返回unsigned short int型的16bits整數 */
/* 如果正確,返回值等于9000 */
/****************************************************************/
extern Uint16 Get_Response(Uint16* DataPtr, Uint16 DataLen)
{
Uint16 i,State;
/* 清空命令緩沖區和接收數據緩沖區 */
for(i=0; i<DATALENGTH; i++)
{
Command[i] = 0;
}
/* 填寫接收返回數據的命令報文 */
CommandLength = 5;
Command[0] = 0x00;
Command[1] = 0xC0;
Command[2] = 0x00;
Command[3] = 0x00;
Command[4] = DataLen;
/* 將ESAM卡的I/O端設為輸入,準備向ESAM卡發接收返回數據命令 */
SYSCNTL1 = 0x60;
Delay_Time(200);
/* 向ESAM卡發接收返回數據命令 */
Write_Esam();
/* 將ESAM卡的I/O端設為輸出,準備從ESAM卡接收返回信息 */
SYSCNTL1 = 0x20;
Delay_Time(200);
/* 先清除接收緩沖區 */
i = UART_RGET(URRBR);
/* 取出ESAM反饋的命令報文中的第二個字節,丟棄 */
while(!UART_FGET(URLSR,DR));
i = UART_RGET(URRBR);
/* 獲取返回信息 */
Read_Esam(ReplyData,DataLen+2);
/* 從返回信息中分離出數據和MAC碼 */
for(i=0; i<DataLen; i++)
{
*DataPtr++ = ReplyData[i];
}
/* 獲取狀態字 */
State = (ReplyData[DataLen]<<8)|ReplyData[DataLen+1];
return State;
}
/****************************************************************/
/* 函數名: Del_Direct() */
/* 功能: 刪除以前建立的目錄文件(不包括MF文件) */
/* 參數: */
/* 無 */
/* 返回值: */
/* 返回unsigned short int型的16bits整數 */
/* 如果正確,返回值等于9000 */
/****************************************************************/
extern Uint16 Del_Direct(void)
{
Uint16 i,State;
/* 清空命令緩沖區 */
for(i=0; i<DATALENGTH; i++)
{
Command[i] = 0;
}
/* 填寫刪除目錄的命令報文 */
CommandLength = 5;
Command[0] = 0x80;
Command[1] = 0x0E;
Command[2] = 0x00;
Command[3] = 0x00;
Command[4] = 0x00;
/* 將ESAM卡的I/O端設為輸入,準備向ESAM卡發刪除目錄命令 */
SYSCNTL1 = 0x60;
Delay_Time(200);
/* 向ESAM卡發刪除目錄命令 */
Write_Esam();
/* 將ESAM卡的I/O端設為輸出,準備從ESAM卡接收返回信息 */
SYSCNTL1 = 0x20;
Delay_Time(200);
/* 先清除接收緩沖區 */
i = UART_RGET(URRBR);
/* 獲取返回信息 */
Read_Esam(ReplyData,2);
/* 獲取狀態字 */
State = (ReplyData[0]<<8)|ReplyData[1];
return State;
}
/****************************************************************/
/* 函數名: Create_Keyfile() */
/* 功能: 建立密鑰文件 */
/* 參數: */
/* FileID-----2字節長度的文件標識符 */
/* FileLen----2字節長度的文件空間大小 */
/* IncRight---增加密鑰權限 */
/* 返回值: */
/* 返回unsigned short int型的16bits整數 */
/* 如果正確,返回值等于9000 */
/****************************************************************/
extern Uint16 Create_Keyfile(Uint16 FileID, Uint16 FileLen, Uint16 IncRight)
{
Uint16 i,State;
/* 清空命令緩沖區和接收返回信息的數據結構 */
for(i=0; i<DATALENGTH; i++)
{
ReplyData[i] = 0;
Command[i] = 0;
}
/* 第一次發送創建Key文件的命令頭,如果正確,應該返回0xE0 */
CommandLength = 5;
Command[0] = 0x80; // 填寫命令報文的頭域
Command[1] = 0xE0;
Command[2] = (FileID&0xFF00)>>8;
Command[3] = FileID&0x00FF;
Command[4] = 0x07;
/* 將ESAM卡的I/O端設為輸入,準備向ESAM卡發創建Key文件命令 */
SYSCNTL1 = 0x60;
Delay_Time(200);
/* 發送創建Key文件命令的命令頭域 */
Write_Esam();
/* 將ESAM卡的I/O端設為輸出,準備從ESAM卡接收返回狀態 */
SYSCNTL1 = 0x20;
Delay_Time(200);
/* 讀空接收緩沖區 */
i = UART_RGET(URRBR);
/* 讀返回的狀態信號,以確定創建Key文件操作是否正確 */
Read_Esam(ReplyData,1);
/* 第二次發送創建Key文件命令的數據域,如果正確,應該返回狀態9000 */
CommandLength = 7;
Command[0] = 0x3F; // 填寫命令報文的數據域
Command[1] = (FileLen&0xFF00)>>8;
Command[2] = FileLen&0x00FF;
Command[3] = 0xFF;
Command[4] = IncRight;
Command[5] = 0xFF;
Command[6] = 0xFF;
/* 將ESAM卡的I/O端設為輸入,準備向ESAM卡發送創建Key文件命令的數據域 */
SYSCNTL1 = 0x60;
Delay_Time(200);
/* 向ESAM卡發創建Key文件命令的數據域 */
Write_Esam();
/* 將ESAM卡的I/O端設為輸出,準備從ESAM卡接收返回狀態 */
SYSCNTL1 = 0x20;
Delay_Time(200);
/* 讀空接收緩沖區 */
i = UART_RGET(URRBR);
/* 讀返回的狀態信號,以確定創建Key文件操作是否正確 */
Read_Esam(ReplyData,2);
/* 獲取狀態字 */
State = (ReplyData[0]<<8)|ReplyData[1];
return State;
}
/****************************************************************/
/* 函數名: Increase_Key() */
/* 功能: 建立(39-外部認證/主控或36-線路保護)密鑰 */
/* 參數: */
/* KeyID----- 密鑰標識符 */
/* KeyType----密鑰類型(0x39或0x36) */
/* UseRight---密鑰使用權 */
/* AltRight---密鑰更改權限 */
/* NextState--后續狀態(如果密鑰類型0x36保留為0xFF) */
/* ErrCount---錯誤計數器 */
/* Keys-------指向存放欲建立密鑰的數組的指針 */
/* Mode-------加解密密鑰方式(如果是8字節密鑰選 */
/* DES8=0;否則為16字節密鑰選DES16=1) */
/* 返回值: */
/* 返回unsigned short int型的16bits整數 */
/* 如果正確,返回值等于9000 */
/****************************************************************/
extern Uint16 Increase_Key(Uint16 KeyID, Uint16 KeyType, Uint16 UseRight, Uint16 AltRight, Uint16 NextState, Uint16 ErrCount, Uint16 *Keys,Uint16 Mode)
{
Uint16 i,State,KeyLen;
/* 清空命令緩沖區和接收返回信息的數據結構 */
for(i=0; i<DATALENGTH; i++)
{
ReplyData[i] = 0;
Command[i] = 0;
}
if(Mode == DES8)
KeyLen = 8;
else
KeyLen = 16;
/* 第一次發送創建Key的命令頭,如果正確,應該返回0xD4 */
CommandLength = 5;
Command[0] = 0x80; // 填寫命令報文的頭域
Command[1] = 0xD4;
Command[2] = 0x01;
Command[3] = KeyID;
Command[4] = KeyLen+5;
/* 將ESAM卡的I/O端設為輸入,準備向ESAM卡發創建Key命令 */
SYSCNTL1 = 0x60;
Delay_Time(200);
/* 發送創建Key命令的命令頭域 */
Write_Esam();
/* 將ESAM卡的I/O端設為輸出,準備從ESAM卡接收返回狀態 */
SYSCNTL1 = 0x20;
Delay_Time(200);
/* 讀空接收緩沖區 */
i = UART_RGET(URRBR);
/* 讀返回的狀態信號,以確定創建Key操作是否正確 */
Read_Esam(ReplyData,1);
/* 第二次發送創建Key命令的數據域,如果正確,應該返回狀態9000 */
CommandLength = KeyLen+5;
Command[0] = KeyType; // 填寫命令報文的數據域
Command[1] = UseRight;
Command[2] = AltRight;
if(KeyType == 0x39) // 如果是外部認證密鑰,有后續狀態
Command[3] = NextState;
else // 如果是線路保護密鑰,該域保留為0xFF
Command[3] = 0xFF;
Command[4] = ErrCount;
for(i=0; i<KeyLen; i++)
{
Command[5+i] = *Keys++;
}
/* 將ESAM卡的I/O端設為輸入,準備向ESAM卡發送創建Key命令的數據域 */
SYSCNTL1 = 0x60;
Delay_Time(200);
/* 向ESAM卡發創建Key命令的數據域 */
Write_Esam();
/* 將ESAM卡的I/O端設為輸出,準備從ESAM卡接收返回狀態 */
SYSCNTL1 = 0x20;
Delay_Time(200);
/* 讀空接收緩沖區 */
i = UART_RGET(URRBR);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -