欢迎您访问九游体育·官方网站官方网站!
阿里巴巴诚信通企业
全国咨询热线:40000-63966
兴邦电子,中国水控机第一品牌

联系兴邦电子

全国咨询热线:40000-63966

售后:0371-55132951/55132952

工厂:河南省 郑州市 高新区莲花街电子电器产业园

ATMEL接触式IC卡及开发实例

文章出处:http://www.nexussmartsolutions.com 作者:单片机技术网   人气: 发表时间:2011年09月17日

[文章内容简介]:ATMEL接触式IC卡及开发实例

目 录

第一章 几种常见的ATMEL接触式IC卡的存储结构及其保密特性 2
一、AT24C01A、AT24C02、AT24C04、AT24C08、AT24C16、AT24C32、AT24C64 2
二、AT88SC102、AT88SC1604、AT88SC1608、AT88SC153 3
1.AT88SC102加密卡 3
2.AT88SC1604加密卡 5
3.AT88SC1608加密卡 8
4.AT88SC153加密卡 12
三、AT45D041 16
第二章 接触式IC卡的接口函数 19
一、函数列表(函数名, 简单说明) 19
1.通用函数 19
2.ATMEL AT88SC102/AT88SC1604加密卡专用函数 19
3.ATMEL AT88SC1608及AT88SC153加密卡专用函数 20
4.ATMEL AT45D041 Flash存储卡专用函数 20
二、函数说明 21
附录一:卡类型预定义 29
附录二:ICFOX.PLB测试例程 30
第三章 接触式IC卡底层软件开发实例 31
一、IC卡操作底层函数 31
1.IC卡操作底层函数说明: 31
2.IC卡低层通讯头文件(Base.h) 32
二、AT24C64卡应用实例 32
1.AT24C64卡函数头文件(AT24C64.h) 32
2.AT24C64卡函数 33
3.AT24C64卡应用例程(App24C64.c) 35

第一章 几种常见的ATMEL接触式IC卡的存储结构及其保密特性
为了能够使IC卡应用到自已的系统中,系统开发公司的工程师应了解一些卡的基本技术资料,下面就ATMEL公司生产的接触式IC卡在应用中常见的和性能比较好的型号做一简单介绍,希望能对IC卡的选型及开发有所帮助。
??1 AT24C01A、AT24C02、AT24C04、AT24C08、AT24C16、AT24C32、AT24C64
这几个型号的IC卡为ATMEL存储卡,是一种不具备加密功能的EEPROM卡,AT24C为系列号,数字部分为K位容量,分别为1K、2K、4K、8K、16K、32K、64K位。它的使用方法与EEPROM完全相同,存储结构简单,只有读写两种操作功能,主要用于存放一些保密性要求不高的数据。
AT24C系列的工作频率为1MHz(5V),1MHz(2.7V),400KHz(1.8V);工作电压为5V±10%,根据要求最低可至1.8V;Icc电流读最大为1mA,写最大为3mA;写/擦除次数为100万次;数据保持100年;工作温度为0—70℃,根据要求可超过指定工作温度;通讯协议符合ISO/IEC 7816-3同步协议,双线串行接口。

存储结构:

AT24C系列型号的后两位数字为该型号的最大K位数(1K=1024),8位为1字节,最大字节存储容量的算法为K位数×1024÷8。如:AT24C01A的最大存储容量的1×1024÷8=128,其字节地址空间为0—127(16进制为0x00—0x7F)。

下面的伪码程序在AT24C系列卡的ADDR地址开始写LEN个字节,并且读出校对。
Open(AT24Cxxx)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
Close()
IF WDATA = RDATA THEN 写成功 ELSE 写失败

下面的伪码程序在AT24C系列卡的ADDR地址开始读LEN个字节。
Open(AT24Cxxx)
RDATA = Read(ADDR,LEN)
Close()
二、AT88SC102、AT88SC1604、AT88SC1608、AT88SC153
这几个型号的IC卡为ATMEL加密卡,采用CMOS低功耗技术,具有传输代码、生产代码,密码及错误计数器、熔丝保护等安全保护功能。存储空间分成设置区和应用区两大功能区,应用区又可分为不同的分区,每个区具有各自独立的保密功能。从型号上看,AT88SC为系列号,最后一位数字为应用区分区数,分别为2、4、8、3个分区,中间的数字10、160、15为K位容量,分别为1K、16K、16K、1.5K位。其中不同应用分区另有自已的分区密码。AT88SC1604又可分为等分区卡和不等分区卡两种。
1.AT88SC102加密卡
AT88SC102加密卡的访问时间读为2us/位,写为5ms/位;工作电压为5V±10%;写/擦除次数为10万次;数据保持100年;工作温度为-25—70℃;通讯协议符合ISO/IEC 7816-3同步协议。

存储结构:
存储分区 位地址 位数 字节地址 字节数
FZ 厂商代码区 0-15 16 0-1 2
IZ 发行者区 16-79 64 2-9 8
SC 主密码区 80-95 16 10-11 2
SCAC 主密码错误计数区 96-111 16 12-13 2
CPZ 代码保护区 112-175 64 14-21 8
AZ1 应用区一 176-687 512 22-85 64
EZ1 一区擦除密码 688-735 48 86-91 6
AZ2 应用区二 736-1247 512 92-155 64
EZ2 二区擦除密码 1248-1279 32 156-159 4
EAC2 二区擦除密码错误计数 1280-1407 128 160-175 16
MTZ 测试区 1408-1423 16 176-177 2
注:擦、写是两种不同的操作,擦是位写1操作,写是位写0操作。修改数据时,只有先擦除才能再写数据。
在熔丝熔断(FUSE2)前与熔丝熔断后它的保密特性是不同的。

熔丝熔断前的保密特性:
FZ:由ATMEL公司出厂时设置(FUSE1),只读不可更改。ATMEL公司可以为批量用户定制此代码,以保证卡片的唯一性。
IZ:可读。SC核对正确,IZ可以反复擦写。
SC:SC核对正确时,SC可读和擦写,SC核对不正确时,SC不能读和擦写。
SCAC:初始值为4,SC核对每错1次SCAC减1,SCAC等于0时,卡自毁,如果SC核对正确SCAC恢复为初始值4。SCAC永远可读。
CPZ:为用户标注,用于对卡中信息操作过程的标注,永远可读,SC核对正确后可擦写。
AZ1,AZ2;前2位为写读保护位,即176位为AZ1写保护位(1PR),177位为AZ1读保护位(1RD),736位为AZ2写保护位(2PR),737位为AZ2读保护位(2RD)。 SC核对正确时,AZn可读(n代表1或者2,下同),如果SC核对不正确时,nRD控制着AZn的可读性,即如果nRD=1时,AZn可读;如果nRD=0时,AZn不可读。
在熔丝熔断(FUSE2)前,nPR不起作用,只要SC核对正确,AZn就可擦写,
EZ1,EZ2:SC核对不正确时,EZn不能读和擦写。SC核对正确时,EZn可读和擦写。在熔丝熔断(FUSE2)前,EZn不起什么作用。
EAC2:熔丝熔断(FUSE2)前,EAC2不起什么作用。
MTZ:用于测试卡的擦写性能。任意条件下均可测试。

熔丝熔断后的保密特性:
FZ:由ATMEL公司出厂时设置(FUSE1),只读不可更改。ATMEL公司可以为批量用户定制此代码,以保证卡片的唯一性。
IZ:永远可读。但熔丝熔断(FUSE2)后IZ内容被固化,IZ将永远不能再改。
SC:不可读,SC核对正确时,SC可擦写,SC核对不正确时,SC不能擦写。
SCAC:初始值为4,SC核对每错1次SCAC减1,SCAC等于0时,卡自毁,如果SC核对正确SCAC恢复为初始值4。SCAC永远可读。
CPZ:为用户标注,用于对卡中信息操作过程的标注,永远可读,SC核对正确后可擦写。
AZ1,AZ2;前2位为写读保护位,即176位为AZ1写保护位(1PR),177位为AZ1读保护位(1RD),736位为AZ2写保护位(2PR),737位为AZ2读保护位(2RD)。 SC核对正确时, AZn可读(n代表1或者2,下同),如果SC核对不正确时,nRD保护着AZn的可读性,即如果nRD=1时,AZn可读;如果nRD=0时,AZn不可读。
在熔丝熔断(FUSE2)后,即使SC核对正确,也要看nPR是否为1,如果是0,AZn被写保护永远不能写。
EZ1,EZ2:SC核对不正确时,EZn不能读和擦写。SC核对正确时,EZn可读和擦写。在熔丝熔丝熔断(FUSE2)后,只有EZn核对正确,才能对AZn进行擦除操作,同时不可能再对EZn进行读和擦写操作。
EAC2:熔丝熔断(FUSE2)后,AZ2只有128次擦除机会,每擦1次计数减1。
MTZ:用于测试卡的擦写性能。任意条件下均可测试。

下面的伪码程序在AT88SC102卡完成初始化操作和在一应用区ADDR地址开始写LEN个字节,并读出校对。
Open(AT88SC102)
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
WriteCPZ(CPZ) ;可以写一些系统标识
UpdateSC(NewPwd)
SetZone(1)
UpdateEZ(NewEZ)
Erase(ADDR,LEN)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Fuse()
Close()

下面的伪码程序判断AT88SC102卡是否是本系统支持的卡和对一应用区ADDR地址开始的LEN个字节完成某种操作。
Open(AT88SC102)
ReadCPZ(CPZ) ;读出系统标识
if CPZ = 系统标识 THEN 继续 ELSE 非法卡
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
SetZone(1)
RDATA = Read(ADDR,LEN)
<一些其它操作>
IF CheckEZ(Pwd) = OK THEN 继续 ELSE 非法卡
Erase(ADDR,LEN)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Close()
2.AT88SC1604加密卡
AT88SC1604加密卡的访问时间读为2us/位,写为5ms/位;工作电压为5V±10%;写/擦除次数为10万次;数据保持10年;工作温度为0—70℃;通讯协议符合ISO/IEC 7816-3同步协议。
AT88SC1604又可分为等分区卡和不等分区卡两种,它们各区和熔丝地址不一样。二、三、四应用区不等分区卡没有区密码错误计数,而等分区卡有,不等分区卡在性能上比较明显地偏重第一区。在选择AT88SC1604卡时应注意它是不等分区卡还是等分区卡。

不等分区卡的存储结构:(二、三、四应用区没有区密码错误计数)
存储分区 位地址 位数 字节地址 字节数
FZ 厂商代码区 0-15 16 0-1 2
IZ 发行者区 16-79 64 2-9 8
SC 主密码区 80-95 16 10-11 2
SCAC 主密码错误计数区 96-103 8 12 1
CPZ 代码保护区 104-167 64 13-20 8
SC1 一区密码 168-183 16 21-22 2
S1AC 一区密码错误计数 184-191 8 23 1
EZ1 一区擦除密码 192-207 16 24-25 2
E1AC 一区擦除密码错误计数 208-215 8 26 1
AZ1 应用区一 216-9775 9560 27-1221 1195
SC2 二区密码 9776-9791 16 1222-1223 2
EZ2 二区擦除密码 9792-9807 16 1224-1225 2
E2AC 二区擦除密码错误计数 9808-9815 8 1226 1
AZ2 应用区二 9816-11863 2048 1227-1482 256
SC3 三区密码 11864-11879 16 1483-1484 2
EZ3 三区擦除密码 11880-11895 16 1485-1486 2
E3AC 三区擦除密码错误计数 11896-11903 8 1487 1
AZ3 应用区三 11904-13951 2048 1488-1743 256
SC4 四区密码 13952-13967 16 1744-1745 2
EZ4 四区擦除密码 13968-13983 16 1746-1747 2
E4AC 四区擦除密码错误计数 13984-13991 8 1748 1
AZ4 应用区四 13992-16039 2048 1749-2004 256
MTZ 测试区 16040-16055 16 2005-2006 2
FUSE 熔丝 16288-16303
最后地址 16383 2047
等分区卡的存储结构:(二、三、四应用区有区密码错误计数)
存储分区 位地址 位数 字节地址 字节数
FZ 厂商代码区 0-15 16 0-1 2
IZ 发行者区 16-79 64 2-9 8
SC 主密码区 80-95 16 10-11 2
SCAC 主密码错误计数区 96-103 8 12 1
CPZ 代码保护区 104-167 64 13-20 8
SC1 一区密码 168-183 16 21-22 2
S1AC 一区密码错误计数 184-191 8 23 1
EZ1 一区擦除密码 192-207 16 24-25 2
E1AC 一区擦除密码错误计数 208-215 8 26 1
AZ1 应用区一 216-4311 4096 27-538 512
SC2 二区密码 4312-4327 16 539-540 2
S2AC 二区密码错误计数 4328-4335 8 541 1
EZ2 二区擦除密码 4336-4351 16 542-543 2
E2AC 二区擦除密码错误计数 4352-4359 8 544 1
AZ2 应用区二 4360-8455 4096 545-1056 512
SC3 三区密码 8456-8471 16 1057-1058 2
S3AC 三区密码错误计数 8472-8479 8 1059 1
EZ3 三区擦除密码 8480-8495 16 1060-1061 2
E3AC 三区擦除密码错误计数 8496-8503 8 1062 1
AZ3 应用区三 8504-12599 4096 1063-1574 512
SC4 四区密码 12600-12615 16 1575-1576 2
S4AC 四区密码错误计数 12616-12623 8 1577 1
EZ4 四区擦除密码 12624-12639 16 1578-1579 2
E4AC 四区擦除密码错误计数 12640-12647 8 1580 1
AZ4 应用区四 12648-16303 3656 1581-2037 457
MTZ 测试区 16304-16319 16 2038-2039 2
FUSE 熔丝 16352-16367
最后地址 16383 2047
注:擦、写是两种不同的操作,擦是位写1操作,写是位写0操作。修改数据时,只有先擦除才能再写数据。
在熔丝熔断(FUSE2)前与熔丝熔断后它的保密特性是不同的。

熔丝熔断前的保密特性:
FZ:由ATMEL公司出厂时设置(FUSE1),只读不可更改,不等分卡一般为0F0F,等分卡一般为7156。ATMEL公司可以为批量用户定制此代码,以保证卡片的唯一性。
IZ:可读。SC核对正确,IZ可以反复擦写。
SC:SC核对正确时,SC可读和擦写,SC核对不正确时,SC不能读和擦写。
SCAC:初始值为8,SC核对每错1次SCAC减1,SCAC等于0时,卡自毁,如果SC核对正确SCAC恢复为初始值8。SCAC永远可读。
CPZ:为用户标注,用于对卡中信息操作过程的标注,永远可读,SC核对正确后可擦写。
SC1,SC2,SC3,SC4,EZ1,EZ2,EZ3,EZ4:熔丝熔断(FUSE2)前,不起什么作用。SC核对正确时,SCn、EZn可读和擦写(n代表1或2或3或4,下同),
S1AC,S2AC,S3AC,S4AC,E1AC,E2AC,E3AC,E4AC:永远可读,熔丝熔断(FUSE2)前,不起什么作用。SC核对正确时,SnAC、EnAC可擦写,
AZ1,AZ2,AZ3,AZ4;前2位为AZn的写读保护位,即写保护位(nPR),读保护位(nRD)。 SC核对正确时,AZn可读,如果SC核对不正确时,nRD控制着AZn的可读性,即如果nRD=1时,AZn可读;如果nRD=0时,AZn不可读。
在熔丝熔断(FUSE2)前,nPR不起作用,只要SC核对正确,AZn就可擦写,
MTZ:用于测试卡的擦写性能。任意条件下均可测试。 熔丝熔断后的保密特性:
FZ:由ATMEL公司出厂时设置(FUSE1),只读不可更改,不等分卡一般为0F0F,等分卡一般为7156。ATMEL公司可以为批量用户定制此代码,以保证卡片的唯一性。
IZ:永远可读。但熔丝熔断(FUSE2)后IZ内容被固化,IZ将永远不能再改。
SC:不可读,SC核对正确时,SC可擦写,SC核对不正确时,SC不能擦写。
SCAC:初始值为8,SC核对每错1次SCAC减1,SCAC等于0时,卡自毁,如果SC核对正确SCAC恢复为初始值8。SCAC永远可读。
CPZ:为用户标注,用于对卡中信息操作过程的标注,永远可读,SC核对正确后可擦写。
SC1,SC2,SC3,SC4:不可读,SC核对正确时,SCn可校对,SC核对不正确时,SCn不能校对。SCn核对正确时,SCn可擦写。
S1AC,S2AC,S3AC,S4AC:初始值为8,SCn核对每错1次SnAC减1,SnAC等于0时,n区自毁,如果SCn核对正确SnAC恢复为初始值8。SnAC永远可读。
EZ1,EZ2,EZ3,EZ4:不可读,SCn核对正确时,EZn可校对,SCn核对不正确时,EZn不能校对。EZn核对正确时,EZn可擦写。
E1AC,E2AC,E3AC,E4AC:初始值为8,EZn核对每错1次EnAC减1,EnAC等于0时,n区自毁,如果EZn核对正确EnAC恢复为初始值8。EnAC永远可读。
AZ1,AZ2,AZ3,AZ4;前2位为AZn的写读保护位,即写保护位(nPR),读保护位(nRD)。 SCn核对正确时,AZn可读,如果SCn核对不正确时,nRD控制着AZn的可读性,即如果nRD=1时,AZn可读;如果nRD=0时,AZn不可读。
EZn核对正确时,AZn可擦, EZn核对不正确时,Azn不可擦。
在熔丝熔断(FUSE2)后,即使SCn核对正确,也要看nPR是否为1,如果是0,AZ被写保护永远不能写。同时不可能再对EZ1进行读和擦写操作。
MTZ:用于测试卡的擦写性能。任意条件下均可测试。

下面的伪码程序在AT88SC1604卡完成初始化操作和在一应用区ADDR地址开始写LEN个字节,并读出校对。
Open(AT88SC1604)
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
WriteCPZ(CPZ) ;可以写一些系统标识
UpdateSC(NewPwd)
SetZone(1)
UpdateSC(NewPwd)
UpdateEZ(NewEZ)
Erase(ADDR,LEN)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Fuse()
Close()
下面的伪码程序判断AT88SC1604卡是否是本系统支持的卡和对一应用区ADDR地址开始的LEN个字节完成某种操作。
Open(AT88SC1604)
ReadCPZ(CPZ) ;读出系统标识
if CPZ = 系统标识 THEN 继续 ELSE 非法卡
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
SetZone(1)
RDATA = Read(ADDR,LEN)
<一些其它操作>
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
IF CheckEZ(Pwd) = OK THEN 继续 ELSE 非法卡
Erase(ADDR,LEN)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Close()
3.AT88SC1608加密卡
如果说AT88SC1064是在AT88SC102、AT24C16的基础上作了一些改进的话,那么AT88SC1608则是接触式IC卡的一次成熟稳定的飞跃,在一卡多用上更能体现它的长处,它的保密性能强,读写速度快,无需先擦除就可以进行写操作。
AT88SC1608加密卡时钟频率为1MHz,支持页写方式(16字节/页),如果以页写方式访问的话,访问时间为10ms(最大)/页;工作电压为2.7V—5.5V;写/擦除次数为10万次;数据保持100年;工作温度为0—70℃;通讯协议符合ISO/IEC 7816-3同步协议。
尤其是AT88SC1608加密卡的高保密性能十分突出,除了带加密逻辑,还具有高保密认证及反截取跟踪技术,64位相互认证及认证错误计数器,错误计数8次。
AT88SC1608具有1个128字节设置区和8个256字节应用分区,8个区可以自由合并,分别受读密码、写密码(16套密码、各3个字节)控制,错误计数8次。
AT88SC1608共有17408位(2176字节)存储空间,其中前16K位(2K字节)为应用区,后1K位(128字节)为设置区。

存储结构:(字节地址以16进制表示)
存储分区 $0 $1 $2 $3 $4 $5 $6 $7 地址
应用分区0(User0) 256字节 $000
应用分区1(User1) 256字节 $100
应用分区2(User2) 256字节 $200
应用分区3(User3) 256字节 $300
应用分区4(User4) 256字节 $400
应用分区5(User5) 256字节 $500
应用分区6(User6) 256字节 $600
应用分区7(User7) 256字节 $700
设置区 128字节 $800

其中设置区存储结构:(字节地址以16进制表示)
$0 $1 $2 $3 $4 $5 $6 $7 地址
厂商信息 复位应答(ATR) 历史代码(HC) $00
厂商代码(FZ) 保留 卡商代码(CMC) $08
访问权限 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7 $10
保留 $18
认证区 AAC 识别码(Nc) $20
密文(Ci) $28
密钥 密钥(Gc) $30
测试区 测试区(MTZ) $38
密码区 PAC 写密码0(WP0) PAC 读密码0(RP0) $40
PAC 写密码1(WP1) PAC 读密码1(RP1) $48
PAC 写密码2(WP2) PAC 读密码2(RP2) $50
PAC 写密码3(WP3) PAC 读密码3(RP3) $58
PAC 写密码4(WP4) PAC 读密码4(RP4) $60
PAC 写密码5(WP5) PAC 读密码5(RP5) $68
PAC 写密码6(WP6) PAC 读密码6(RP6) $70
PAC 写密码7(WP7/SC) PAC 读密码7(RP7) $78
注:哪个区用哪套密码或是否要认证要由访问权限AR0-AR7 来决定。

ATR:复位应答,由ATMEL定义,不可改。
HC:历史代码,由ATMEL定义,不可改。
FZ:厂商代码,由ATMEL定义,不可改。
CMC:卡商代码,由卡厂定义,不可改。
AR0-7:访问权限。个人化前定义。(详细用法参见访问权限)
Nc:识别码,通常用作卡的唯一标识--卡号。个人化前定义。
Ci:密文,个人化前可写一随机数,认证卡时使用,每次认证会被自动改写。
Gc:密钥,64位的保密种子,由Nc通过F1公式推算出来,在个人化前,写入卡中。个人化后不可访问,认证时作为该卡的F2公式的参数。(详细用法参见认证协议)
AAC:为认证错误计数器。初始值为8。
MTZ:用于测试卡的读写性能。任意条件下均可测试。
WP0-WP7,RP0-RP7:8套读写密码集, 每个分区可以分别指向唯一的密码集,也可以指向同一套密码集,这样就可以只核对一套密码而进入多个分区,使多个分区合成为一个大的分区。默认WP7、RP7为读写密码。写密码7(WP7)还作为传输密码(SC)。另外,如果需要修改读写密码时,也必须核对同一套密码集的写密码。
SC:传输密码。初始值由ATMEL定认,发到每个卡厂都不同。可以修改,在个人化前一直使用SC,个人化后其它密码才会被用到。
PAC:为分区密码错误计数器。初始值为8。

熔丝标志(FUSE)
熔丝标志位于设置区的$80地址,存储结构:(地址以16进制表示)
位7 位6 位5 位4 位3 位2 位1 位0 地址
0 0 0 0 0 PER CMA FAB $80
注:FAB、CMA、FAB为AT88SC1608的EEPROM的三级熔丝保护标志,“0”表示已熔断。在熔丝标志全为“1”时,所有的存储空间都可读。每一步熔断操作都不能返回。
FAB为ATMEL的芯片出厂时的熔断标志。
CMA为卡厂的卡片出厂时的熔断标志。
PER为应用系统启动前个人化时的熔断标志。

当我们把 AT88SC1608卡交付使用之前,卡内信息应已作完以下的操作:
ATMEL写完厂商信息(除卡商代码)、传输密码(SC),把其余的存储空间都写成“1”,做FAB熔断操作,使FAB=0。
卡厂写入自已的卡商代码后,做CMA熔断操作,使CMA=0。
系统商对卡做初始化,或卡在发行之前由系统做初始化,然后做PER熔断操作,使CMA=0。

访问权限
熔丝熔断前后的访问权限表:
区 访问 FAB=0 CMA=0 Per=0
厂商信息 (除卡商代码) 读 可以 可以 可以
写 禁止 禁止 禁止
卡商代码 读 可以 可以 可以
写 传输密码(SC) 禁止 禁止
访问权限 读 可以 可以 可以
写 传输密码(SC) 传输密码(SC) 禁止
认证区 读 可以 可以 可以
写 传输密码(SC) 传输密码(SC) 禁止
密钥 读 传输密码(SC) 传输密码(SC) 禁止
写 传输密码(SC) 传输密码(SC) 禁止
测试区 读 可以 可以 可以
写 可以 可以 可以
密码 读 传输密码(SC) 传输密码(SC) 写密码(WP)
写 传输密码(SC) 传输密码(SC) 写密码(WP)
PAC(计数器) 读 可以 可以 可以
写 传输密码(SC) 传输密码(SC) 写密码(WP)
应用区 读 访问权限(AR) 访问权限(AR) 访问权限(AR)
写 访问权限(AR) 访问权限(AR) 访问权限(AR)

访问权限AR0-AR7的存储结构:(使能为“0”,默认为“1”)
位7 位6 位5 位4 位3 位2 位1 位0
WPE RPE ATE PW2 PW1 PW0 MDF PGO
WPE:为写密码使能标志。值为0时,对应用分区进行写操作时,必须通过写密码。在个人化后,核对写密码,也决定着是否能改变读密码和写密码。
RPE:为读密码使能标志。值为0时,通过读密码或写密码,才能读某应用分区。如果密码核对错误将返回熔丝状态位。
ATE:认证使能标志。为0时,认证必须通过才能操作当前应用分区。
PW2,PW1,PW0:这3位指定当前应用分区使用哪一套密码集。每个分区可以分别指向唯一的密码集,也可以指向同一套密码集,这样就可以只核对一套密码而进入多个分区,使多个分区合成为一个大的分区。
MDF:为禁止修改操作标志。值为0时,当前应用分区被写保护,被写保护区的内容必须在个人化之前写入。
PGO:只写标志。如果为0,当前应用分区的每一位只能从“1”写成“0”,而不能从“0”改回为“1”。

认证协议
产出随机数Nc(往往当作卡号)和Ci,计算出Gc=F1(Ks,Nc),把Nc、Ci、Gc写入卡中
卡 Nc Gc Ci 认证协议 读写器 Ks Q0(随机数)
识别码: Nc Ci Ci+1=F2(Gc,Ci,Q0); if(Ci+1==Q1) Ci+2=F2(Gc,C1+1); Ci=Ci+2; //修改Ci 认证正确; else Ci=Ci; 认证错误; Ci (使用读命令) (初始化认证命令) (校验认证命令) (读命令) Gc=F1(Ks,Nc); Q0 Q1=F2(Gc,Ci,Q0); Q1 Q2=F2(Gc,Q1); if(Q2=Ci) 认证正确; else 认证错误;
F1算法:64BIT 用户自定义算法。
F2算法:卡内64BIT 算法(Des 算法的变种,提供C语言和51汇编语言程序)
该协议包括卡和读写器CPU的互相认证(ELVA专利),而且认证数据加密传送,可以防止通讯数据被窃取。

下面的伪码程序在AT88SC1608卡完成初始化操作和在一应用区ADDR地址开始写LEN个字节,并读出校对。
Open(AT88SC1608)
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
InitAuth(Nc,Ci,Gc)
SetZone(1)
SetAR(AR)
UpdateWP(NewWP)
UpdateRP(NewRP)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Fuse()
Close()
下面的伪码程序判断AT88SC1608卡是否是本系统支持的卡和对一应用区ADDR地址开始的LEN个字节完成某种操作。
Open(AT88SC1608)
CheckAuth(Gc)
SetZone(1)
IF CheckRP(Pwd) = OK THEN 继续 ELSE 非法卡
RDATA = Read(ADDR,LEN)
<一些其它操作>
IF CheckWP(Pwd) = OK THEN 继续 ELSE 非法卡
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Close()
4.AT88SC153加密卡
AT88SC153是ATMEL继AT88SC1068之后新推出的一种卡型,它继承了AT88SC1608的全部优点,只是存储容量及分区数有所改变,基本上可以理解为小容量的AT88SC1608。
AT88SC153加密卡时钟频率为1MHz,支持页写方式(8字节/页),如果以页写方式访问的话,访问时间为10ms(最大)/页;工作电压为2.7V—5.5V;写/擦除次数为10万次;数据保持100年;工作温度为0—70℃;通讯协议符合ISO/IEC 7816-3同步协议。
与AT88SC1608一样,AT88SC153加密卡的高保密性能十分突出,除了带加密逻辑,还具有高保密认证及反截取跟踪技术,64位相互认证及认证错误计数器,错误计数8次。
AT88SC153具有1个64字节设置区和3个64字节应用分区,3个区可以自由合并,分别受读密码、写密码(4套密码、各3个字节)控制,错误计数4/8次。
AT88SC153共有2048位(256字节)存储空间,其中前1536位(192字节)为应用区,后512位(64字节)为设置区。

存储结构:(字节地址以16进制表示)
存储分区 $0 $1 $2 $3 $4 $5 $6 $7 地址
应用分区0(User0) 64字节 $00
应用分区1(User1) 64字节 $40
应用分区2(User2) 64字节 $80
设置区 64字节 $C0

其中设置区存储结构:(字节地址以16进制表示)
$0 $1 $2 $3 $4 $5 $6 $7 地址
厂商信息 复位应答(ATR) 历史代码(HC) $00
厂商代码(FZ) 卡商码(CMC) AR0 AR1 AR2 MTZ $08
识别区 发布号(IC) $10
DCR 识别码(Nc) $18
AAC 密文(Ci) $20
密钥 密钥(Gc) $28
密码区 PAC 写密码0(WP0) PAC 读密码0(RP0) $30
PAC 写密码1(WP1/SC) PAC 读密码1(RP1) $38
注:哪个区用哪套密码或是否要认证要由访问权限AR0-AR2 来决定。
在采用校验和认证方式时,地址$20也可以用作校验和认证寄存器(CAR)。

ATR:复位应答,由ATMEL定义,不可改。
HC:历史代码,由ATMEL定义,不可改。
FZ:厂商代码,由ATMEL定义,不可改。
CMC:卡商代码,由卡厂定义,不可改。
AR0-2:访问权限。个人化前定义。(详细用法参见访问权限)
MTZ:用于测试卡的读写性能。任意条件下均可测试。
IC:发布号。个人化前定义。。
DCR:设备设置寄存器。
Nc:识别码,通常用作卡的唯一标识--卡号。个人化前定义。
Ci:密文,个人化前可写一随机数,认证卡时使用,每次认证会被自动改写。
Gc:密钥,64位的保密种子,由Nc通过F1公式推算出来,在个人化前,写入卡中。个人化后不可访问,认证时作为该卡的F2公式的参数。(详细用法参见认证协议)
AAC:为认证错误计数器。初始值为8,但每次校验出错减2,所以共有4次连续校验出错的机会,可扩展为8次(见DCR的设置方法)。也用作Ci的一部分,注意如果修改了AAC,会影响下一次认证的Ci值。
CAR:校验和认证寄存器。只有认证完成时才有用,每次写操作都会激活校验和方式,并把写或连续写的校验和自动写入CAR,此时可以读出校验和,以确定写操作是否完成。任何读操作都会结束校验和方式。
WP0,WP1,RP0,RP1:2套读写密码集, 每个分区可以分别指向唯一的密码集,也可以指向同一套密码集,这样就可以只核对一套密码而进入多个分区,使多个分区合成为一个大的分区。默认WP1、RP1为读写密码。写密码1(WP1)还作为传输密码(SC)。另外,如果需要修改读写密码时,也必须核对同一套密码集的写密码。
SC:传输密码。初始值由ATMEL定认,发到每个卡厂都不同。可以修改,在个人化前一直使用SC,个人化后其它密码才会被用到。
PAC:为分区密码错误计数器。初始值为8,但每次校验出错减2,所以共有4次连续校验出错的机会。可扩展为8次。(见DCR的设置方法)

熔丝标志(FUSE)
熔丝标志位于设置区的$40地址,存储结构:(地址以16进制表示)
位7 位6 位5 位4 位3 位2 位1 位0 地址
0 0 0 0 0 PER CMA FAB $40
注:FAB、CMA、FAB为AT88SC153的EEPROM的三级熔丝保护标志,“0”表示已熔断。在熔丝标志全为“1”时,所有的存储空间都可读。每一步熔断操作都不能返回。
FAB为ATMEL的芯片出厂时的熔断标志。
CMA为卡厂的卡片出厂时的熔断标志。
PER为应用系统启动前个人化时的熔断标志。

当我们把 AT88SC153卡交付使用之前,卡内信息应已作完以下的操作:
ATMEL写完厂商信息(除卡商代码、访问权限和测试区)、传输密码(SC),把其余的存储空间都写成“1”,做FAB熔断操作,使FAB=0。
卡厂写入自已的卡商代码后,做CMA熔断操作,使CMA=0。
系统商对卡做初始化,或卡在发行之前由系统做初始化,然后做PER熔断操作,使CMA=0。

访问权限
熔丝熔断前后的访问权限表:
区 访问 FAB=0 CMA=0 Per=0
厂商信息 (除CMC,AR,MTZ) 读 可以 可以 可以
写 禁止 禁止 禁止
卡商代码 读 可以 可以 可以
写 传输密码(SC) 禁止 禁止
访问权限 读 可以 可以 可以
写 传输密码(SC) 传输密码(SC) 禁止
测试区 读 可以 可以 可以
写 可以 可以 可以
识别区 读 可以 可以 可以
写 传输密码(SC) 传输密码(SC) 禁止
密钥 读 传输密码(SC) 传输密码(SC) 禁止
写 传输密码(SC) 传输密码(SC) 禁止
密码 读 传输密码(SC) 传输密码(SC) 写密码(WP)
写 传输密码(SC) 传输密码(SC) 写密码(WP)
PAC(计数器) 读 可以 可以 可以
写 传输密码(SC) 传输密码(SC) 写密码(WP)
应用区 读 访问权限(AR) 访问权限(AR) 访问权限(AR)
写 访问权限(AR) 访问权限(AR) 访问权限(AR)

访问权限AR0-AR2的存储结构:(使能为“0” ,默认为“1”)
位7 位6 位5 位4 位3 位2 位1 位0
WPE RPE ATE AOW PWS WLM MDF PGO
WPE:为写密码使能标志。值为0时,对应用分区进行写操作时,必须通过写密码。在个人化后,核对写密码,也决定着是否能改变读密码和写密码。
RPE:为读密码使能标志。值为0时,通过读密码或写密码,才能读某应用分区。如果密码核对错误将返回熔丝状态位。
ATE:认证使能标志。为0时,认证必须通过才能操作当前应用分区。
AOW:只有写时才需要认证标志。只有写操作时才需要进行认证,读不需要进行认证操作,如果ATE=0,则AOW被忽略。
PWS:指定当前应用分区使用哪一套密码集。每个分区可以分别指向唯一的密码集,也可以指向同一套密码集,这样就可以只核对一套密码而进入多个分区,使多个分区合成为一个大的分区。
WLM:写锁模式使能。每个区的8个字节为一页。如果WLM=0,使每页的第一个字节(byte0)的每一位分别为该页8个字节的写锁标志,0为写锁(即只能从“1”写成“0”,而不能从“0”改回为“1”),1为解锁。
MDF:为禁止修改操作标志。值为0时,当前应用分区被写保护,被写保护区的内容必须在个人化之前写入。
PGO:只写标志。如果为0,当前应用分区的每一位只能从“1”写成“0”,而不能从“0”改回为“1”。


设备设置寄存器(DCR)
设备设置寄存器位于设置区的$18地址,存储结构:(使能为“0”,默认为“1”)
位7 位6 位5 位4 位3 位2 位1 位0
SME UCR UAT ETA CS3 CS2 CS1 CS0
CS0-CS3:可编程片选。ATMEL出厂时写为$B(即1011)。它为访问卡的所有命令字的高4位。
ETA:8次计数使能。ETA=0,可以使AAC和PAC的计数次数为8,否则为4。
UAT:使认证错误计数无校标志。UAT=0,AAC无校,否则AAC有校。
UCR:不限制读校验和次数标志。UCR=1时,每次认证只能读校验和方式一次(默认),UCR=0时,没有次数限制。
SME:超级管理方式。SME=0时,通过1WP校验,就可以读写全部的读写密码及密码错误计数器。

认证协议
产出随机数Nc(往往当作卡号)和Ci,计算出Gc=F1(Ks,Nc),把Nc、Ci、Gc写入卡中
卡 Nc Gc Ci 认证协议 读写器 Ks Q0(随机数)
识别码: Nc Ci Ci+1=F2(Gc,Ci,Q0); if(Ci+1==Q1) Ci+2=F2(Gc,C1+1); Ci=Ci+2; //修改Ci 认证正确; else Ci=Ci; 认证错误; Ci (使用读命令) (初始化认证命令) (校验认证命令) (读命令) Gc=F1(Ks,Nc); Q0 Q1=F2(Gc,Ci,Q0); Q1 Q2=F2(Gc,Q1); if(Q2=Ci) 认证正确; else 认证错误;
F1算法:64BIT 用户自定义算法。
F2算法:卡内64BIT 算法(Des 算法的变种,提供C语言和51汇编语言程序)
该协议包括卡和读写器CPU的互相认证(ELVA专利),而且认证数据加密传送,可以防止通讯数据被窃取。

下面的伪码程序在AT88SC153卡完成初始化操作和在一应用区ADDR地址开始写LEN个字节,并读出校对。
Open(AT88SC153)
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
WriteIC(IC) ;写发布号
WriteDCR(DCR)
InitAuth(Nc,Ci,Gc)
SetZone(1)
SetAR(AR)
UpdateWP(NewWP)
UpdateRP(NewRP)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Fuse()
Close()

下面的伪码程序判断AT88SC153卡是否是本系统支持的卡和对一应用区ADDR地址开始的LEN个字节完成某种操作。
Open(AT88SC153)
ReadIC(IC) ;读出发布号
if IC = 发布号 THEN 继续 ELSE 非法卡
CheckAuth(Gc)
SetZone(1)
IF CheckRP(Pwd) = OK THEN 继续 ELSE 非法卡
RDATA = Read(ADDR,LEN)
<一些其它操作>
IF CheckWP(Pwd) = OK THEN 继续 ELSE 非法卡
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Close()
三、AT45D041
这种型号的IC卡为ATMEL存储卡,是一种不具备加密功能大容量的FLASH 存储卡,存储容量为4M位,主存储区有2048页(每页容量为264字节),同时还提供两个独立双向的数据缓存区(每个数据缓存区容量为264字节),页写方式为264字节,页写入时间为7ms。存储结构简单,主要用于存放一些保密性要求不高、数据量极大的数据,如声音、图像或数据。
AT45D041的工作频率为10MHz(最大);工作电压为5V±10%;工作电流读为25mA,写为50mA;数据保持100年;工作温度为0—70℃,根据要求可超过指定工作温度;通讯协议为SPI串行接口方式0和方式3。

缓存区1、缓存区2和主存储区的读写方式如上图所示,分别为:
1. 直接从主存储区的某页读数据;
2. 把主存储区的某页数据写入缓存区1或缓存区2;
3. 把主存储区的某页数据和缓存区1或缓存区2的数据进行比较;
4. 把缓存区1或缓存区2的数据写入主存储区的某页(带内建式擦除);
5. 把缓存区1或缓存区2的数据写入主存储区的某页(不6. 带内建式擦除);
7. 把数据写入主存储区的某页;
8. 自动页回写;
9. 读缓存区1、缓存区2;
10. 写缓存区1、缓存区2;
11. 读状态位。

状态位结构:
位7 位6 位5 位4 位3 位2 位1 位0
忙闲 比较 0 1 1 x x x
注:位7为0表示忙;为1表示闲,可以接收下一条指令。
位6为0表示主存储区数据与缓存区比较匹配,否则为不匹配。
位5、位4、位3对于AT45D041为“011”(二进制)。

下面的伪码程序通过AT45D041卡的缓存1更新主存储区的页1的某些数据:
OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
PageToBuff()
WHILE ReadStatus() = Busy LOOP
WriteBuff(Addr,Len,cData)
BuffToPage()
WHILE ReadStatus() = Busy LOOP
AutoRWrite()
WHILE ReadStatus() = Busy LOOP
Close()

OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
WritePage(Addr,Len.cData)
WHILE ReadStatus() = Busy LOOP
AutoRWrite()
WHILE ReadStatus() = Busy LOOP
Close()

下面的伪码程序通过AT45D041卡的缓存1页写主存储区的页1:
OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
WriteBuff(0,264,cData)
BuffToPage()
WHILE ReadStatus() = Busy LOOP
Close()

OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
WritePage(0,264.cData)
WHILE ReadStatus() = Busy LOOP
Close()

注:本章内容可为用户在接触式IC卡选型时参考。


第二章 接触式IC卡的接口函数
IC卡软件应用系统的开发是在读写器提供的接口函数基础上进行软件开发的。每个系统公司的接口函数虽有不同,但大同小异。下面以德诚系统有限公司的MCS-C接触式IC卡通用读写器提供的FoxPro for DOS的PLB接口函数为例,用户由此可基本上对接触式IC卡接口函数有所了解。
在FoxPro程序执行开始前,先执行语句SET LIBRARY TO ICFOX.PBL。FoxPro将会自动登录库ICFOX.PLB中的IC卡函数,您可以象使用FoxPro的内部函数一样的使用接口函数。编译成EXE文件时,将ICFOX.PLB链入。
1、 函数列表(函数名2? , 简单说明)
1. 通用函数
InitComm 初始化指定的串口并连接读写设备
ExitComm 退出串口连接
ErrorMsg 返回错误信息
GetInfo 获取设备的版本号

TestCard 测试读写器内是否插卡
OpenCard 打开对某种型号卡的操作
ReadChr 从卡上指定地址读取指定长度的字符串
WriteChr 向卡内指定地址写入指定长度的字符串
ReadInt 从卡上指定地址读取一个双精度数
WriteInt 向卡内指定地址写入一个双精度数
CloseCard 关闭卡操作
2? ATMEL AT88SC102/AT88SC1604加密卡专用函数
ReadFZ 读厂商代码
ReadIZ 读卡商代码
ReadCPZ 读代码保护区
WriteCPZ 写代码保护区
ReadMTZ 读测试区
WriteMTZ 写测试区

SetZone 选择应用区
CheckSC 比较密码(或区密码)
UpdateSC 更新密码(或区密码)
ReadSCAC 读密码(或区密码)校验错误计数
CheckEZ 比较区擦除密码
UpdateEZ 更新区擦除密码
ReadEAC 读区擦除密码校验错误计数
Erase 从卡内指定位置起擦除指定长度字节

Fuse 烧断卡上熔丝
3? ATMEL AT88SC1608及AT88SC153加密卡专用函数
ReadFZ 读厂商代码
ReadIZ 读卡商代码
ReadIC 读发布号(AT88SC153专用)
WriteIC 写发布号(AT88SC153专用)
ReadDCR 读设备设置寄存器(AT88SC153专用)
WriteDCR 写设备设置寄存器(AT88SC153专用)
ReadMTZ 读测试区
WriteMTZ 写测试区

InitAuth 初始化认证状态
CheckAuth 认证校验
ReadAAC 读认证错误计数

CheckSC 比较传输密码
UpdateSC 更新传输密码
ReadSCAC 读传输密码校验错误计数

SetZone 选择应用区
ReadAR 读应用区的访问权限
WriteAR 设置应用区的访问权限

CheckWP 比较写密码
UpdateWP 更新写密码
ReadWPAC 读写密码校验错误计数
CheckRP 比较读密码
UpdateRP 更新写密码
ReadRPAC 读读密码校验错误计数

FuseStatus 读取卡内熔丝状态
Fuse 烧断卡上熔丝
4? ATMEL AT45D041 Flash存储卡专用函数
SetPage 选择主存储区的当前页
SetBuff 选择缓冲区
ReadPage 读取主存储区页内的字符
ReadBuff 读取缓冲区1/缓冲区2内的字符
WritePage 写字符到主存储区页
WriteBuff 写字符到缓冲区1/缓冲区2
CompPB 比较主存储区页与缓冲区1/缓冲区2的内容
PageToBuff 从主存储区页提取数据到缓冲区1/缓冲区2
BuffToPage 从缓冲区1/缓冲区2写数据到主存储区页
ReadStatus 读状态字(忙闲)
AutoRWrite 自动回写
3、 函数说明
InitComm(Port)
说明:初始化指定的串口并连接读写设备。
参数:Port----串口标号,整数0,1分别代表串口1,串口2。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = InitComm(0) 初始化串口1。

ExitComm()
说明:退出串口连接。
参数:无。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = ExitComm() 退出串口。

ErrorMsg(ErrNo)
说明:返回错误信息。
参数:错误号。
返回值: 错误信息。
举例:Msg = ErrorMsg(0) 返回“成功”。

GetInfo()
说明:获取设备的版本号。
参数:无。
返回值: 设备的版本号。
举例:Vno = GetInfo()。

TestCard()
说明:测试读写器内是否插卡。
参数:无。
返回值: =0,正确。
<0,读写器内没有插卡。返回值代表错误号。
举例:Ret = TestCard()

OpenCard(CardType)
说明:打开对某种型号卡的操作
参数:CardType----IC卡类型。具体值参见附录一。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = OpenCard(AT24C01A) 选择卡型为AT24C01A。

ReadChr(Addr,Len)
说明:从卡上指定地址读取指定长度的字符串。
参数:Addr----读操作的卡内起始地址。
Len----字符串长度。
返回值:从卡上读取的字符串。
读操作出错。返回""。
举例:cData = ReadChr(0, 10) 从卡上应用区地址0读取10个字符。

WriteChr(Addr,Len,cData)
说明:将指定长度的字符串写入到卡片的指定起始地址上。
参数:Addr----写操作的卡内起始地址。
Len----字符串长度。
cData----要向卡片写入的字符串。
返回值: =0,正确。
<0,写操作出错。返回值代表错误号。
举例:Ret = WriteChr(0, 14, "Testing MCS-C!") 将字符串写入卡地址0处。

ReadInt(Addr)
说明:从卡上指定的起始地址读取一个双精度数。
参数:Addr----读操作的卡内起始地址。
返回值:从卡上读取的双精度数。
举例:iData = ReadInt(0) 从卡上应用区地址0读取双精度数。

WriteInt(Addr,iData)
说明:将一个双精度数写入到卡内指定起始地址处。
参数:Addr----写操作的卡内起始地址。
iData----要向卡内写入的双精度数。
返回值: =0,正确。
<0,写操作出错。返回值代表错误号。
举例:Ret = WriteInt(0, 12345.6789) 将12345.6789写入到卡内地址0处。

CloseCard()
说明:关闭卡操作
参数:无。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = CloseCard()

ReadFZ()
说明:读厂商代码。
参数:无。
返回值:从卡上读取厂商代码(16进制字符串)。
读操作出错。返回""。
举例:FZ = ReadFZ()

ReadIZ()
说明:读卡商代码。
参数:无。
返回值:从卡上读取卡商代码(16进制字符串)。
读操作出错。返回""。
举例:IZ = ReadIZ()

ReadCPZ()
说明:读代码保护区。
参数:无。
返回值:从卡上读取代码保护区(16进制字符串)。
读操作出错。返回""。
举例:CPZ = ReadCPZ()

WriteCPZ(CPZ)
说明:写代码保护区。
参数:长度为为16个字节的字符串(16进制字符串)。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = WriteCPZ("0123456789ABCDEF")

ReadMTZ()
说明:读测试区。
参数:无。
返回值:从卡上读取代码保护区(16进制字符串)。
读操作出错。返回""。
举例:MTZ = ReadMTZ()

WriteMTZ(MTZ)
说明:写测试区。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = WriteMTZ("ABCDEF")

SetZone(Zone)
说明:选择应用区。
参数:Zone----要选择的应用区号。0-n代表应用区0至应用区n。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = SetZone(1)

CheckSC(SC)
说明:比较密码(或区密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckSC("FFFF")

UpdateSC(SC)
说明:更新密码(或区密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateSC("9999")

ReadSCAC()
说明:读密码(或区密码)校验错误计数。
参数:无。
返回值:密码校验错误计数值。
举例:SCAC = ReadSCAC()

CheckEZ(EZ)
说明:比较擦除密码(或区擦除密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckEZ("FFFF")

UpdateEZ(EZ)
说明:更新擦除密码(或区擦除密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateEZ("9999")

ReadEZAC()
说明:读擦除密码(或区擦除密码)校验错误计数。
参数:无。
返回值:密码校验错误计数值。
举例:EZAC = ReadEZAC()

Erase(Addr,Len)
说明:从指定位置起擦除指定长度的字节。
参数:Addr----要擦除的起始地址。
Len----要擦除的长度。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = Erase(0, 10)

Fuse()
说明:烧断卡上熔丝。
参数:无。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = Fuse()

ReadIC()
说明:读发布号(AT88SC153专用)。
参数:无。
返回值:发布号(16进制字符串)。
举例:Ret = ReadIC()

WriteIC(IC)
说明:写发布号(AT88SC153专用)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = WriteIC("012456789ABCDEF")

ReadDCR()
说明:读设备设置寄存器(AT88SC153专用)。
参数:无。
返回值:设备设置寄存器的值(16进制字符串)。
举例:Ret = ReadDCR()

WriteDCR(DCR)
说明:写设备设置寄存器(AT88SC153专用)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = WriteDCR("FF")

InitAuth(Nc,Ci,Gc)
说明:初始化认证协议。
参数:Nc----识别码。
Ci----密文。
Gc----密钥。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = InitAuth(Nc,Ci,Gc)

CheckAuth(Gc)
说明:认证协议。
参数:Gc----密钥。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckAuth(Gc)

ReadAAC()
说明:读认证错误计数。
参数:无。
返回值:认证校验错误计数值。
举例:AAC = ReadAAC()

ReadAR()
说明:读应用区的访问权限。
参数:无。
返回值:当前访问区权限字节(16进制字符串)。
举例:AR = ReadAR()

WriteAR(AR)
说明:设置应用区的访问权限。
参数:AR----当前访问区权限字节(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = WriteAR("FF")

CheckWP(WP)
说明:比较当前区写密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckWP("FFFFFF")

UpdateWP(WP)
说明:更新当前区写密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateWP("999999")

ReadWPAC()
说明:读当前区写密码校验错误计数。
参数:无。
返回值:当前区写密码校验错误计数值。
举例:WPAC = ReadWPAC()

CheckRP(RP)
说明:比较当前区读密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckRP("FFFFFF")

UpdateRP(RP)
说明:更新当前区读密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateRP("999999")

ReadRPAC()
说明:读当前区读密码校验错误计数。
参数:无。
返回值:当前区读密码校验错误计数值。
举例:RPAC = ReadRPAC()

FuseStatus()
说明:读取卡内熔丝状态
参数:无。
返回值: =0,已熔。
=1,未熔。
举例:PER = FuseStatus()

SetPage(Page)
说明:选择主存储区的当前页。
参数:Page----要选择的页号。1-n代表页1至页n。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = SetPage(1)

SetBuff(Buff)
说明:选择缓冲区。
参数:Buff----要选择的缓冲区。1,2代表缓冲区1,缓冲区2。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = SetBuff(1)

ReadPage(Addr,Len)
说明:读取主存储区页内的字符。
参数:Addr----要读取的起始字节地址。
Len----要读取的长度。
返回值:返回的数据字符串。
举例:cData = ReadPage(0,10)

ReadBuff(Addr,Len)
说明:读取缓冲区内的字符。
参数:Addr----要读取的起始字节地址。
Len----要读取的长度。
返回值:返回的数据字符串。
举例:cData = ReadBuff(0,10)

WritePage(Addr,Len,cData)
说明:写字符到主存储区页。
参数:Addr----要写入的起始字节地址。
Len----要写入的长度。
cData----用于存放写入卡片的数据的字符串。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = WritePage(0,10,"1234567890")

WriteBuff(Addr,Len,cData)
说明:写字符到缓冲区。
参数:Addr----要写入的起始字节地址。
Len----要写入的长度。
cData----用于存放写入缓冲区的数据的字符串。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = WriteBuff(0,10,"1234567890")

CompPB()
说明:比较主存储区页与缓冲区的内容。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = CompPB()

PageToBuff()
说明:主存储区内容向缓冲区传送。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = PageToBuff()

BuffToPage()
说明:从缓冲区写数据到主存储区页。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = BuffToPage()

ReadStatus()
说明:读状态字(忙闲)
参数:无。
返回值: =0,闲。
<0,返回值代表忙或错误号。
举例:Ret = ReadStatus()

AutoRWrite()
说明:自动回写。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = AutoRWrite()
附录一:卡类型预定义
AT24C01 = 0
AT24C01A = 1
AT24C02 = 2
AT24C04 = 3
AT24C08 = 4
AT24C16 = 5
AT24C32 = 6
AT24C64 = 7
AT24C128 = 8
AT24C256 = 9

AT88SC102 = 12
AT88SC1604_E = 15
AT88SC6603 = 15
AT88SC1604_N = 16
AT88SC6601 = 16
AT88SC1608 = 17
AT88SC153 = 18

AT45D041 = 23
附录二:ICFOX.PLB测试例程
SET TALK OFF
SET LIBR TO ICFOX
? ErrorMsg(InitComm(0))
? ErrorMsg(TestCard(0))
? ErrorMsg(OpenCard(1))
? ErrorMsg(WriteChr(0,10,”0123456789”))
rData=ReadChr(0,10)
=Close()
IF rData <> “0123456789”
? “读卡错误”
ELSE
? “测试正常”
ENDIF
RETURN
第三章 接触式IC卡底层软件开发实例
对了更好地说明接触式IC卡读写器是如果工作的,本章公布了部分德诚系统有限公司MCS-C读写器低层CPU的C51程序,包括了IC卡操作底层函数,以AT24C64卡为例的实例程序。这些程序是根据德诚系统有限公司实际使用的函数向用户公开的,也可供其它打算生产接触式IC卡读写器的厂家参考,以便开发自已的IC卡驱动函数。
??2 IC卡操作底层函数
1? IC卡操作底层函数说明:
IC卡座的引脚定义示意图如下:

VCC [C1] [C5] GND
RESET [C2] [C6] No Use
CLK [C3] [C7] I / O
FUS [C4] [C8] PGM

void _CardSetPower(uchar Level);
功能:将IC卡读写器Vcc段上电或下电。
输入:Level
当Level=1,给IC卡读写器上电。
当Level=0,给IC卡读写器下电。
输出:无

void _CardSetReset(uchar Level);
功能:置IC卡读写器Reset高或低。
输入:Level
当Level=1,给IC卡读写器Reset端置高。
当Level=0,给IC卡读写器Reset端置低。
输出:无

void _CardSetClock(uchar Level);
功能:置IC卡读写器Clock高或低。
输入:Level
当Level=1,给IC卡读写器Clock置高。
当Level=0,给IC卡读写器Clock置低。
输出:无

void _CardSetPGM(uchar Level);
功能:置IC卡读写器PGM高或低。
输入:Level
当Level=1,给IC卡读写器PGM置高。
当Level=0,给IC卡读写器PGM置低。
输出:无

void _CardSetFUS(uchar Level);
功能:置IC卡读写器FUS高或低。
输入:Level
当Level=1,给IC卡读写器FUS置高。
当Level=0,给IC卡读写器FUS置低。
输出:无

void _CardPutIO(uchar IOData);
功能:将数据由IC卡读写器IO端输出。
输入:IOData输出数据,值是0或1。
输出:无

uchar _CardReadIO();
功能:读取IC卡读写器IO端数据
输入:无
输出:IC卡输出的数据,值是0或1。
2? IC卡低层通讯头文件(Base.h)
低层通讯函数用户可根据自已的设备编写。
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/****************************************************
IC卡低层通讯头文件:
****************************************************/
void _CardSetPower(uchar Level);
void _CardSetReset(uchar Level);
void _CardSetClock(uchar Level);
void _CardSetPGM(uchar Level);
void _CardSetFUS(uchar Level);
void _CardPutIO(uchar IOData);
uchar _CardReadIO();
2? AT24C64卡应用实例
1.AT24C64卡函数头文件(AT24C64.h)
/****************************************************
the AT24C64 Card Declare:
****************************************************/
uchar AT24C64_Open();
uchar AT24C64_Read(uint Addr,uint DataLen,uchar *DataBuff);
uchar AT24C64_Write(uint Addr,uint DataLen,uchar* DataBuff);
uchar AT24C64_Close();
2.AT24C64卡函数
//**********************************************************
//* This is source of 24C64.LIB *
//* This program demo how to program 24C64.LIB *
//**********************************************************
#include <Base.h>
#include <AT24C64.h>

void AT24C64_Pulse();
void AT24C64_Start();
void AT24C64_Stop();
void AT24C64_OutB(uchar OutData);
uchar AT24C64_InB();

/*******************************
This function used by the
external user's function
*******************************/
void AT24C64_Pulse()
{
_CardSetClock(1);
_CardSetClock(0);
}
void AT24C64_Start()
{
_CardPutIO(1); _CardSetClock(1);
_CardPutIO(0); _CardSetClock(0);
}
void AT24C64_Stop()
{
_CardPutIO(0); _CardSetClock(1);
_CardPutIO(1); _CardSetClock(0);
}

void AT24C64_OutB(uchar OutData)
{
uchar i;
for (i = 0;i < 8;i++)
{
if ( (OutData & 0x80) == 0x80 ) _CardPutIO(1); else _CardPutIO(0);
AT24C64_Pulse(); OutData = OutData << 1;
}
_CardPutIO(1); AT24C64_Pulse();
}

uchar AT24C64_InB()
{
uchar i,InData = 0;
for (i = 0;i < 8;i++)
{
InData = InData << 1; _CardSetClock(1);
InData = InData + _CardReadIO(); _CardSetClock(0);
}
return InData;
}

/***************************************
This function used by user
****************************************/
// open card
uchar AT24C64_Open()
{
uchar i,InData,TmpSt[10];
_CardSetPower(1);
_CardSetClock(0);
_CardSetReset(0);
_CardSetReset(1);
_CardPutIO(1);
AT24C64_Pulse();
_CardSetReset(0);
for(i = 0;i < 4;i++) TmpSt[i] = AT24C64_InB();
if (TmpSt[0] == 0xFF) return 1;
if (TmpSt[1] == 0xFF) return 1;
if (TmpSt[2] == 0xFF) return 1;
if (TmpSt[3] == 0xFF) return 1;
return 0;
}

uchar AT24C64_Read(uint Addr,uint DataLen,uchar *DataBuff)
{
uint i;

_CardSetReset(1); _CardSetReset(0);
AT24C64_Start();
AT24C64_OutB(0xA0);
AT24C64_OutB((uchar)(Addr >> 8));
AT24C64_OutB((uchar)Addr);
AT24C64_Start();
_CardPutIO(1);
AT24C64_OutB(0xA1);
for (i = 0;i < DataLen;i++) {
*(DataBuff + i) = AT24C64_InB();
_CardPutIO(0); AT24C64_Pulse(); _CardPutIO(1);
}
AT24C64_Stop();
for (i = 0;i < 32; i++) AT24C64_Pulse();
return 0;
}

uchar AT24C64_Write(uint Addr,uint DataLen,uchar* DataBuff)
{
uint i;

for (i = 0;i < DataLen;i++) {
AT24C64_Start();
AT24C64_OutB(0xA0);
AT24C64_OutB((uchar)((Addr + i) >> 8));
AT24C64_OutB((uchar)(Addr + i));
AT24C64_OutB(*(DataBuff + i));
AT24C64_Stop();
_Delay(20);
}
return 0;
}

uchar AT24C64_Close()
{
// set power pin low
_CardPutIO(0);
_CardSetClock(0);
_CardSetReset(0);
_CardSetPower(0);
return 0;
}
3? AT24C64卡应用例程(App24C64.c)
#include<AT24C64.h>

uchar _App24C64(uchar *cData)
{
AT24C64_Open();
AT24C64_Write(0x0050, 16,cData);
AT24C64_Close();

AT24C64_Open();
AT24C64_Read(0x0050, 16,cData);
AT24C64_Close();

return 0x00;
}

第一章 ATMEL CPU卡简介
AT89SC系列是低电压、高性能的8位微处理器。内含可编程的FLASH、只可一次编程的内存单元(PEROM)和电可擦写数据存储单元(EEPROM)。该89SC系列产品运用ATMEL的高密度CMOS工艺制造,同工业标准的80C51和80C52指令集相兼容。
AT90SC系列产品与ATMEL的AVR指令集相兼容,内部带有协处理器。
通过将FLASH和一个多性能的8位微处理器集成在单一片上,AT89SC/90SC系列为多种智能卡的应用提供了高度灵活和性能完备的解决方案。
值得一提的是,AT89SC/90SC具有专为智能卡应用而设计的特性:如符合ISO7816标准的串行接口,随机数发生器,电源和频率保护逻辑。

Device Name Flash EEPROM RAM
AT89SC168 16 K bytes 8 K bytes 256 bytes
AT89SC168A 16 K bytes 8 K bytes 512 bytes
AT89SC1616A 16 K bytes 16 K bytes 512 bytes
AT90SC3232 32 K bytes 32K bytes 1.5Kbytes
AT90SC3232C (协处理器) 32 K bytes 32K bytes 1K bytes

我们为喜爱用ATMEL CPU卡和设计COS的客户提供了如下的解决方案:
Help customers to use DEMOCOS and design their own COS.
--帮助客户使用DEMOCOS和设计自己的COS。
DEMOCOS ( source code ) : it is a completed COS, supports ISO-7816 command and t=0 protocol.
--DEMOCOS(提供源代码)是一个完整的COS,支持ISO-7816 命令和T=0协议。
51 ASSEMBLER COMPILER: --51汇编语言编译器
COS (for AT89SC168 ) SOFTWARE SIMULATOR:
--COS 软件仿真器(支持AT89SC168)。
READER SOFTWARE SIMULATOR:
--读卡器软件仿真器。
READER(support T=0) for upload COS:
--可以下载COS的读卡器。
第二章 ATMEL AT89SC系列CPU卡介绍
ATMEL公司的AT89SC系列CPU卡微处理器集成了FLASH程序存储器、EEPROM数据存储器和ISO7816通讯接口,并且引脚符合ISO7816标准。
该CPU卡的FLASH程序存储器是可以让用户自行下载的,这样就可以保证用户的COS源代码不会泄露出去。更为优异的是:是否可以重新下载FLSAH完全由用户的COS来设置,这样可以实现重复可下载和一次性下载两种模式。
AT89SC系列微处理器提供了两种软件控制的低电压工作方式:
闲置模式:CPU停止工作,芯片上其他部分继续工作。在闲置状态下,电流大约是芯片处于完全工作状态时电流的15%。
休眠模式: 芯片上一切活动均被挂起,RAM中还保留数据。在休眠状态下,芯片的电流通常低于15A,最低可达到0.6A。
同时,由于芯片使用静态逻辑设计,无须时钟持续工作。这就是说,在等待一个内部事件的触发时,时钟频率可以减缓,甚至停止。
安全特性:
AT89SC系列微处理器提供了下述安全特性:
低电压保护;
低频保护,防止静态分析;
高频滤波,防止干扰;
传输代码,保护芯片在运输过程中不被盗用;
唯一系列代码;
当时钟频率低于500KHz或电压低于4V时,芯片会产生一个安全保护中断;
当时钟频率高于10MHz或电压低于3V时,芯片处于复位状态,直至电压或时钟频率恢复正常;
芯片在运输过程及初始化时受到64位的传输代码的保护。
Device Name Flash EEPROM RAM
AT89SC168 16 K bytes 8 K bytes 256 bytes
AT89SC168A 16 K bytes 8 K bytes 512 bytes
AT89SC1616A 16 K bytes 16 K bytes 512 bytes

第三章 ATMEL 89SC168卡 DemoCos 简介
如果用户获得了一套ATMEL 168 DEMOCOS,即使不做任何改动,就可以利用它灵活地创建自己的文件和安全系统。DEMOCOS的代码大小为4.5K,分为通讯模块、文件系统模块、和算法模块,但是认证算法比较简单,如果想改变算法(这是目前大多数客户的想法),请将DEMOCOS读懂(这有一定的挑战性,但DEMOCOS是模块化编程,注释详细)后重写算法,也可以添加其他的功能,用户还有很多的程序空间可用。
另外,由于ATMEL的CPU卡的不断更新,如容量大小的改变,通讯方式的改变,以及REBOOT方式的改变,ATMEL公司会指导用户对DEMOCOS做相应的调整。

一、文件系统

1、文件分类
设多层目录:MF(3F00)、DF(具体应用目录,最多可以建立15级目录)
EF分为SF、KF和WF:
SF是密码文件,各层目录均可有一个,存放用户密码。
KF是密钥文件,各层目录均可有一个,存放发行商密钥。
WF是工作文件,数据文件EF。
支持两种标准EF文件结构:线性定长记录、透明二进制。
本结构支持一卡多用。

2、文件访问方式
使用文件标识符(FID)进行访问:
每一文件中有两字节长的标识符,允许不同的文件具有相同的标识符,在直接处于给定DF下的所有EF和DF应具有不同的文件标识符。
使用短EF文件标识符(SFI)进行访问:
短EF文件标识符用5位二进制码(1~30)表示。短EF文件标识符不能用在路径中或作为文件标识符,如不能用在Select File命令中进行选择。

3、数据访问方式
访问记录:
在记录结构的EF中,可以用记录编号访问记录数据。记录编号是一个无符号的8位整数,其可用值为01H~FEH,00H保留于专用,FFH保留于将来使用。
访问数据单元:
在透明二进制结构的EF文件中,每一个数据单元的位置由命令的偏移值给出,其下一个数据单元的位置由偏移值加数据单元长度后产生。

二、安全系统

1、密码和密钥管理
1)密码类型
SF文件最多由4个密码记录组成,密码编号从0到3依次排列。其中:
0号密码默认为用户个人密码;
1号密码默认为解锁密码(发行商用);
2号密码默认为个人化密码(发行商用);
3号密码默认为重装密码(发行商用);

2)密钥
KF文件最多由8个密钥记录组成,密码编号从0到7依次排列

2、安全规程
①卡的确认:内部鉴别(鉴别密钥)。
②终端确认:外部鉴别(鉴别密钥)。
③持卡人确认:PIN密码提交验证。
④发行者确认:发行密码提交验证。
⑤其他密码验证。
⑥对安全系统文件进行写操作时的反插拔与自动恢复。

三、命令系统

1、命令报文
1)命令结构:

命令头 命令体
CLA INS P1 P2 Lc Data Le

2)命令分类:
COS命令由具体应用分为4种命令报文结构如下:
①情形1
CLA INS P1 P2 ‘00’
②情形2
CLA INS P1 P2 Le
?情形3
CLA INS P1 P2 Lc Data
?情形4
CLA INS P1 P2 Lc Data Le

2、响应报文
1)响应结构

响应数据 响应状态码
Data SW1 SW1

DATA: 返回给用户的数据,即命令的执行结果。
SW1、SW2: 返回命令处理的状态。

3、命令集

1)Read Binary
功能:
此命令用于读取二进制文件部分或全部的内容。
格式:
代码 值
CLA ‘00’
INS ‘B0’
P1 见参数说明
P2 从文件中读取的第一字节的偏移地址
Le 期望读出数据的长度

2)Update Binary
功能:
此命令使用给定的数据来更新二进制文件部分或全部的内容。
格式:
代码 值
CLA ‘00’
INS ‘D6’
P1 见参数说明
P2 要修改的第一字节的偏移地址
Lc 后续数据域的长度
Data 修改用的数据

3)Read Record
功能:
此命令用于读取记录文件中指定记录的内容。
格式:
代码 值
CLA ‘00’
INS ‘B2’
P1 记录号
P2 见参数说明
Le 期望读出数据的长度

4)Update record
功能:
此命令使用给定的数据来更新记录文件中指定记录的内容。当所指定的文件非记录文件时,命令将终止。
格式:
代码 值
CLA ‘00’
INS ‘DC’
P1 P1=‘00’表示当前记录 P1≠‘00’表示指定的记录号
P2 见参数说明
Lc 后续数据域的长度
Data 更新原有记录的新记录

5)Verify PIN
功能:
此命令将校验给定的密码的正确性,根据比较的结果修改安全状态,若校验失败次数达到PIN尝试上限,则PIN自动锁定。
格式:
代码 值
CLA ‘00’
INS ‘20’
P1 ‘00’
P2
Lc ’02’~‘10’
Data 外部输入的个人密码

6)Select File
功能:
此命令使用文件名或应用标示符来选择IC卡内DF或EF。
格式:
代码 值
CLA ‘00’
INS ‘A4’
P1 ‘00’
P2 ‘00’
Lc ‘00’(选择MF文件)/ ‘02’
Data 无 / FID

7)Get Challenge
功能:
此命令请求IC卡返回一个用于安全相关过程的随机数。
格式:
代码 值
CLA ‘00’
INS ‘84’
P1 ‘00’
P2 ‘00’
Le ‘04’

8)Get Response
功能:
此命令为T=0协议情形4状态下,用来取卡中返回的数据。
格式:
代码 值
CLA ‘00’
INS ‘C0’
P1 ‘00’
P2 ‘00’
Le 响应的期望数据最大长度

9)Internal Authenticate
功能:
此命令将为外部设备验证卡中的秘密模块的有效性提供数据。
格式:
代码 值
CLA ‘00’
INS ‘88’
P1 ‘00’
P2 ‘00’~‘07’密钥号
Lc ‘04’
Data 外部随机数(4字节)

10)External Authenticate
功能:
此命令将验证外部设备中的秘密模块的有效性。
格式:
代码 值
CLA ‘00’
INS ‘82’
P1 ‘00’
P2 ‘00’ ~‘07’密钥号
Lc ‘0C’
Data 发卡方认证数据

11)Change / Unlock PIN
功能:修改、解锁、安装卡片个人密码。
格式:
代码 值
CLA ‘00’
INS ‘5E’
P1 ‘00’ 修改卡片个人密码;‘01’ 解锁卡片个人密码;‘02’ 安(重)装卡片个人密码
P2 密码号
Lc
Data
12)Unlock Key
功能:
解锁卡片应用密钥。
格式:
代码 值
CLA ‘00’
INS ‘5C’
P1 ‘01’ 解锁应用密钥 ‘02’ 安装卡片应用密钥
P2 密钥号
Lc 无 / 密钥长度
Data 无 / 加密的密钥

13)Create File
功能:
此命令创建卡片文件系统。
格式:
代码 值
CLA ‘00’/ ’80’
INS ‘F2’
P1 ‘00’/ FTP 文件类型
P2 ‘00’/ FAC 文件访问控制条件
Lc 无 / ‘07’
Data
第四章 AT90SC3232C带有协处理器的CPU卡
AT90SC3232C是ATMEL公司最新推出的内含协处理器的CPU卡,它以高性能、低功耗的AVR 8位CPU为核心,配合一个16位的协处理器(SC16)完成高速的保密和认证功能。

1)AT90SCC系列CPU卡的型号如下:
型号 程序空间 EEPROM空间 RAM空间 协处理器 RF接口
AT90SC1616C 16K Flash 16K 1K YES NO
AT90SC3232 32K Flash 32K 1K NO NO
AT90SC3232C 32K Flash 32K 1K YES NO
AT90SC3232CRF 32K ROM 32K 1K YES YES

2)AT90SC3232C的特征如下:
高效、低功耗的AVR RISC CPU:含有120条指令,大多数指令为单个时钟周期;
32K字节(16K字)的可下载一千次的程序存储器;
32K字节的EEPROM数据存储器;
1K字节RAM;
16位协处理器,预编程功能可用于保密和认证,一次1024位RSA的算法用220ms;
监管模式(存储器管理);
ISO-7816接口;
随机数发生器;
16位定时器;
5个中断源,两个优先级;
安全特征:掉电保护,低频保护,高频滤波,程序代码加密;
低功耗闲置模式和掉电模式;
2.7V-5.5V的工作电压。

一、AT90SC3232C结构概述:
AT90SC3232C是基于AVR RISC增强型结构,有32个工作寄存器均可以单时钟周期访问,高性能的ALU(算术逻辑单元)可在一个时钟周期内完成取指、运算、和输出结果的工作。ALU的操作分为3类:算术、逻辑和位操作功能。
在32个工作寄存器中,有6个寄存器可以被组成3对16位的间接寻址指针X、Y、Z。用以提高数据空间的访问速度,其中一个指针还可以用于常数查表。

图1,AT90SC3232C结构图

I/O空间包括64个地址,用于CPU对外设的访问,如对控制寄存器、定时/计数器、外部中断及ISO 7816引脚的访问。
AVR CPU采用哈佛结构,程序区和数据区是分开的,程序存储器使用单级管道流水线访问,即:当一条指令被执行时,下条指令被预先取出,这种机制使得在每个时钟周期CPU都可以执行指令。
AT90SCC 的程序计数器(PC)是16位,可以访问64K字的地址空间,大多数的AVR指令都采用16位的字结构。

二、协处理器和RAM
AT90SC3232C内含一个16位的协处理器(SC16)和1K字节的RAM,可以方便地实现公共密钥算法(如RSA),它与AVR CPU的接口采用RAM X空间而RAM Y空间被协处理器用做工作区。
公共密钥算法(简称公钥算法)简介:算法使用2个密钥,公共密钥(简称公钥)和私有密钥(简称私钥),他们是一对儿。当一个密钥用于加密时,仅有另一个密钥可用于解密,关键特点是在实践中从公钥不能推出私钥,也不能用公钥来完成私钥的解密过程,这样就可以把公钥公开而不会泄密。
公钥算法有两个应用:一是信息加密传送,二是认证(如数字签名)。
RSA算法是公钥算法的一种,他基于数学上的对大数分解因子的难度。算法中私钥包括两个互质的大数P、Q,和一个幂E,公钥包含一个大数N=P*Q和幂E。设M(明文)是0至N-1之间的数。
则加密过程如下:
密文C=MEmod(N)
而解密过程相反。
AT90SC3232C的协处理器(SC16)可以实现公钥和私钥的运算,但是并不能直接生成密钥。它有三个主要的运算功能(均可以对1024位的数据操作)。
1.“LOAD MODULUS”功能,即装载N。
2.“LOAD PRIMES”功能,即装载P、Q。
3.“MODULAR EXPONENTIATION”模幂运算功能。
模幂运算的操作为:DataEXPmod(Modulus),[按照符合中国剩余原理或者不符合的规则]。显然,模幂运算功能的实现大大加快了RSA算法的运算过程。

三、ISO-7816接口:AT90SC3232C的引脚符合ISO-7816标准。
ISO-7816的接口包含以下引脚:
GND:地线;
VCC:电源;
I/O:串行数据;
CLK:时钟;
RST:复位;
I/O口由I/0控制寄存器的某一位来控制(置位/清除),输入由I/O数据寄存器的某一位来获得,I/O口也可以产生中断。

四、安全保护机制
AT90SC3232C片内含有监管系统,该系统可以管理内存,监督用户程序对内存的非法操作。
为了防止外部对芯片的探测,AT90SC3232C还具有如下措施:
内部总线特殊处理,外观没有明显结构,数据和地址总线均被埋入金属层之下。
程序和数据均可以扰乱加密,在ATMEL工厂可以完成对总线的熔丝,使得同一条指令在不同的位置时代码也不同,用户还可以设置自己的扰乱密钥。

五、结束语
AT90SC3232C是新一代的高速保密控制器,它具有高度的保密性和高速运算的能力,因此,它非常适用于商业银行的金融业务、政府及军警的机要通信业务。
ATMEL 公司还备有CPU卡的硬件开发系统,如下图所示:

本文关键词:ATMEL,接触式,IC卡
回到顶部